使用DisableAllPrivileges禁用AdjustTokenPrivileges的所有权限



我正试图通过将参数DisableAllPrivileges设置为TRUE:来使用AdjustTokenPrivileges剥夺进程的所有权限

#include <Windows.h>
#include <cwchar>
int main()
{
auto process = GetCurrentProcess();
HANDLE primary_token;
if (OpenProcessToken(process, TOKEN_ADJUST_PRIVILEGES, &primary_token) == FALSE)
{
fwprintf(stderr, L"OpenProcessToken: failed");
}
if (AdjustTokenPrivileges(primary_token, TRUE, nullptr, 0, nullptr, nullptr) == FALSE)
{
fwprintf(stderr, L"AdjustTokenPrivileges: failed");
}
CloseHandle(primary_token);
auto event = CreateEventW(nullptr, FALSE, FALSE, nullptr);
WaitForSingleObject(event, INFINITE);
}

在Sysinternals process Explorer中查看进程权限时,它似乎不起作用。

我通过查询所有权限并将属性更改为SE_PRIVILEGE_REMOVED解决了这个问题,但我不确定为什么将DisableAllPrivileges设置为TRUE不起作用。

在中查看进程权限时,它似乎不起作用Sysinternals Process Explorer。

Sysinternals Process Explorer显示错误的图像。DisableAllPrivileges正常工作-从令牌中的所有特权中删除SE_PRIVILEGE_ENABLED属性。但是某些特权也可以具有CCD_ 9属性。例如CCD_ 10具有该属性。它保持不变,什么和显示你的形象。但无论如何只有CCD_ 12或SePrivilegeCheck api中使用的CCD_。因此,您确实有效地禁用了令牌中的所有特权,包括SeChangeNotifyPrivilege。所有需要具体权限、令牌中没有SE_PRIVILEGE_ENABLED属性的调用都会失败,即使存在SE_PRIVILEGE_ENABLED_BY_DEFAULT属性。

测试代码

#ifndef RtlPointerToOffset
#define RtlPointerToOffset(B,P) ((ULONG)( ((PCHAR)(P)) - ((PCHAR)(B)) ))
#endif
inline ULONG BOOL_TO_ERROR(BOOL fOk)
{
return fOk ? NOERROR : GetLastError();
}
volatile UCHAR guz = 0;
void DumpTokenPrivs(HANDLE hToken)
{
union {
PVOID buf;
PTOKEN_PRIVILEGES ptp;
};
PVOID stack = alloca(guz);
ULONG cb = 0, rcb = 0x40;
ULONG dwError;
do 
{
if (cb < rcb)
{
cb = RtlPointerToOffset(buf = alloca(rcb - cb), stack);
}
if (NOERROR == (dwError = BOOL_TO_ERROR(
GetTokenInformation(hToken, TokenPrivileges, buf, cb, &rcb))))
{
ULONG PrivilegeCount = ptp->PrivilegeCount;
DbgPrint("PrivilegeCount = %un", PrivilegeCount);
if (PrivilegeCount)
{
PLUID_AND_ATTRIBUTES Privileges = ptp->Privileges;
do 
{
WCHAR Name[64];
ULONG cch = RTL_NUMBER_OF(Name);
if (!LookupPrivilegeNameW(0, &Privileges->Luid, Name, &cch))
{
_swprintf(Name, L"{%u-%u}", 
Privileges->Luid.HighPart, Privileges->Luid.LowPart);
}
BOOL fResult;
PRIVILEGE_SET ps = { 
1, PRIVILEGE_SET_ALL_NECESSARY, { 
{ Privileges->Luid.LowPart, Privileges->Luid.HighPart } 
} 
};
if (!PrivilegeCheck(hToken, &ps, &fResult))
{
DbgPrint("PrivilegeCheck=%un", GetLastError());
}
DbgPrint("%08x %x %Sn", Privileges->Attributes, fResult, Name);
} while (Privileges++, --PrivilegeCount);
}
}
} while (dwError == ERROR_INSUFFICIENT_BUFFER);
}
void PrivTest()
{
HANDLE hToken;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &hToken))
{
ULONG rcb;
TOKEN_LINKED_TOKEN tlk;
GetTokenInformation(hToken, TokenLinkedToken, &tlk, sizeof(tlk), &rcb);
CloseHandle(hToken);
hToken = tlk.LinkedToken;
DumpTokenPrivs(hToken);
if (AdjustTokenPrivileges(hToken, TRUE, 0, 0, 0, 0) && GetLastError() == NOERROR)
{
DumpTokenPrivs(hToken);
}
}
CloseHandle(hToken);
}

输出:

PrivilegeCount = 5
00000000 0 SeShutdownPrivilege
00000003 1 SeChangeNotifyPrivilege
00000000 0 SeUndockPrivilege
00000000 0 SeIncreaseWorkingSetPrivilege
00000000 0 SeTimeZonePrivilege
PrivilegeCount = 5
00000000 0 SeShutdownPrivilege
00000001 0 SeChangeNotifyPrivilege
00000000 0 SeUndockPrivilege
00000000 0 SeIncreaseWorkingSetPrivilege
00000000 0 SeTimeZonePrivilege

注意,在呼叫之前是

00000003 1 SeChangeNotifyPrivilege

是平均SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED属性,而PrivilegeCheck表示特权已启用。

呼叫后是

00000001 0 SeChangeNotifyPrivilege

是平均SE_PRIVILEGE_ENABLED_BY_DEFAULT属性,而PrivilegeCheck表示特权被禁用。

相关内容

  • 没有找到相关文章

最新更新