我有一个流程可以由NT AUTHORITY\Network Service
或NT AUTHORITY\System
的服务生成,我需要检查它。所以我写了这样的代码:
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken)) {
GetTokenInformation(hToken, 1, 0, 0, &dwOut);
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
hTokenUser = (TOKEN_USER*)malloc( dwOut );
if (!GetTokenInformation(hToken, TokenUser, hTokenUser, dwOut, &dwOut))
return false;
}
else
return false;
PSID psid = NULL;
SID_IDENTIFIER_AUTHORITY ntAuth = SECURITY_NT_AUTHORITY;
AllocateAndInitializeSid(&ntAuth, 1, SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0, &psid);
if (EqualSid(psid, hTokenUser->User.Sid)) {
bResult = TRUE;
}
}
所以,我得到当前的进程令牌,然后使用GetTokenInfo
从中获取SID,然后使用NT_AUTHORITY\System
创建AllocateAndInitializeSid
SID,并比较两个值但是,它一起工作,当进程在NT_AUTHORITY\System
下运行时,检查总是失败。这是获取NT_AUTHORITY\System
SID并将其与进程sid进行比较的正确方法吗?
答案 0 :(得分:1)
您的代码泄漏了句柄和内存,但它确实在我的机器上提供了正确的结果。它可能在您的系统上有所不同,因此如果您打印出每个函数调用的结果和GetLastError以帮助您进行调试,它将会非常有用。您还应编写函数代码,以便区分错误和消极(成功)结果。
HRESULT isSystemUser()
{
HRESULT hr = E_FAIL;
HANDLE hToken;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
{
TOKEN_USER *pTU = NULL;
DWORD dwOut;
GetTokenInformation(hToken, TokenUser, 0, 0, &dwOut);
hr = HRESULT_FROM_WIN32(GetLastError());
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
pTU = (TOKEN_USER*) malloc(dwOut), hr = E_OUTOFMEMORY;
if (pTU)
{
if (GetTokenInformation(hToken, TokenUser, pTU, dwOut, &dwOut))
{
PSID psid = NULL;
SID_IDENTIFIER_AUTHORITY ntAuth = SECURITY_NT_AUTHORITY;
if (AllocateAndInitializeSid(&ntAuth, 1, SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0, &psid))
{
hr = EqualSid(psid, pTU->User.Sid) ? S_OK : S_FALSE;
FreeSid(psid);
}
else
hr = HRESULT_FROM_WIN32(GetLastError());
}
else
hr = HRESULT_FROM_WIN32(GetLastError());
free(pTU);
}
CloseHandle(hToken);
}
else
hr = HRESULT_FROM_WIN32(GetLastError());
return hr;
}
...
printf("isSystemUser=%d\n", isSystemUser()); // 0 = true, 1 = false, < 0 = error
并在运行时:
C:\windows\system32>c:\test.exe
isSystemUser=0
C:\windows\system32>whoami
nt authority\system
您是否可能实际上并不是真正的系统用户? {{3}}为您的TokenUser返回什么内容?