Slide 1

Slide 1 text

Binary Exploitation - Basic yuawn

Slide 2

Slide 2 text

About • yuawn • Pwn • Balsn / DoubleSigma
 
 
 _yuawn

Slide 3

Slide 3 text

Outline • Binary exploitation • Basic concepts • ELF • x64 calling convention • Stack frame • BOF - Buffer Overflow • Shellcode • Lazy binding - GOT Hijacking PWNED

Slide 4

Slide 4 text

What is Pwn?

Slide 5

Slide 5 text

Binary Exploitation • 透過利利⽤用程式 (Binary) 的漏洞洞 (Vulnerability),在執⾏行行期間控制執⾏行行流程 (Control flow),進⽽而使程式執⾏行行特定⾏行行為。 • Pwn • 胖 or 碰

Slide 6

Slide 6 text

Binary Exploitation User Server Service

Slide 7

Slide 7 text

Binary Exploitation User Server Service Vulnerable?

Slide 8

Slide 8 text

Binary Exploitation Hacker Server Vulnerable
 Service Exploit

Slide 9

Slide 9 text

Binary Exploitation Hacker Vulnerable
 Service RCE PWNED Exploit

Slide 10

Slide 10 text

Basic Concepts

Slide 11

Slide 11 text

ELF Executable and Linkable Format

Slide 12

Slide 12 text

ELF • Executable and Linkable Format • 執⾏行行檔 ex. exe • section • 執⾏行行時會 mapping 到 RAM 上 (virtual memory) • .text .bss .data .rodata .got .plt .fini …

Slide 13

Slide 13 text

ELF - Workflow (static) ./binary fork() execve( “bianry”, *argv[], *envp[] ) sys_execve() do_execve() search_binary_handler() load_elf_binary() _start main() User mode Kernel mode

Slide 14

Slide 14 text

ELF - Workflow (dynamic linking) _libc_start_main _init main() User mode Kernel mode ./binary fork() execve( “bianry”, *argv[], *envp[] ) sys_execve() do_execve() search_binary_handler() load_elf_binary() ld.so _start

Slide 15

Slide 15 text

ELF - section • .bss - 存放未初始化值的全域變數 (global variable) • .data - 存放具初始化值的全域變數 • .rodata - 存放唯讀 (read-only) 資料 • .text - 存放編譯後的 code

Slide 16

Slide 16 text

ELF - section int a; int b = 100; int main(){ int c; puts( "I love pwning." ); return 0; } .bss .data .text .rodata

Slide 17

Slide 17 text

ELF - Protections • PIE - Position-Independent Executable • NX - No-eXecute • Canary - stack protector • RELRO - Relocation Read-Only

Slide 18

Slide 18 text

DEMO

Slide 19

Slide 19 text

x64 • 8 bytes alignment • Stack 0x10 bytes alignment

Slide 20

Slide 20 text

x64 Assembly • Registers • RAX RBX RCX RDX RDI RSI - 64 bit • EAX EBX ECX EDX EDI ESI - 32 bit • AX BX CX DX DI SI - 16 bit • AX -> AH AL - 8 bit RAX EAX AX AH AL

Slide 21

Slide 21 text

x64 Assembly • Registers • RSP - Stack Pointer Register • 指向 stack 頂端(頭) • RBP - Base Pointer Register • 指向 stack 底端(尾) • RIP - Program Counter Register • 指向當前執⾏行行指令instruction位置

Slide 22

Slide 22 text

x64 Assembly • jmp (jump) • 跳⾄至程式某⼀一地址 A(address) 執⾏行行 • jmp A = mov rip, A • call • 將 call 完後回來來緊接著要執⾏行行的下⼀一⾏行行指令位置 push 到 stack 上儲存起來來,再跳 過去執⾏行行。 • call A = push next_rip
 mov rip, A

Slide 23

Slide 23 text

x64 Assembly • leave • 還原⾄至 caller 的 stack frame。 • mov rsp, rbp
 pop rbp • ret (return) • pop rip

Slide 24

Slide 24 text

x64 calling convention • Pass parameters • rdi, rsi, rdx, rcx, r8, r9, (stack) • rdi, rsi, rdx, r10, r8, r9, (stack) • rax - store return value • x64 - register 傳參參 • x86 - stack 傳參參

Slide 25

Slide 25 text

Stack Frame

Slide 26

Slide 26 text

Stack Frame • Function Prologue • Function Epilogue • Stack frame • local variables • [rbp] = old rbp (caller rbp) • [rbp + 0x8] = Return Address Low address High address Arguments Return Address Saved rbp rsp rbp Local variables of func() stack frame of func

Slide 27

Slide 27 text

low address high address func: push rbp mov rbp, rsp sub rsp, 0x70 … mov eax, 0x1 leave ret main: push rbp mov rbp, rsp mov rdi, 1234 mov rsi, 666 call func mov eax, 0 // address = 0x40071A leave ret stack frame of main RAM rsp rbp

Slide 28

Slide 28 text

low address high address func: push rbp mov rbp, rsp sub rsp, 0x70 … mov eax, 0x1 leave ret main: push rbp mov rbp, rsp mov rdi, 1234 mov rsi, 666 call func mov eax, 0 // address = 0x40071A leave ret stack frame of main RAM rsp rbp rip

Slide 29

Slide 29 text

low address high address func: push rbp mov rbp, rsp sub rsp, 0x70 … mov eax, 0x1 leave ret main: push rbp mov rbp, rsp mov rdi, 1234 mov rsi, 666 call func mov eax, 0 // address = 0x40071A leave ret stack frame of main rsp rbp rip Call func = push next-rip jmp func

Slide 30

Slide 30 text

low address high address func: push rbp mov rbp, rsp sub rsp, 0x70 … mov eax, 0x1 leave ret main: push rbp mov rbp, rsp mov rdi, 1234 mov rsi, 666 call func mov eax, 0 // address = 0x40071A leave ret stack frame of main rsp rbp rip 0x40071A Call func = push next-rip jmp func

Slide 31

Slide 31 text

low address high address func: push rbp mov rbp, rsp sub rsp, 0x70 … mov eax, 0x1 leave ret main: push rbp mov rbp, rsp mov rdi, 1234 mov rsi, 666 call func mov eax, 0 // address = 0x40071A leave ret stack frame of main rbp rip 0x40071A Call func = push next-rip jmp func rsp

Slide 32

Slide 32 text

low address high address func: push rbp mov rbp, rsp sub rsp, 0x70 … mov eax, 0x1 leave ret main: push rbp mov rbp, rsp mov rdi, 1234 mov rsi, 666 call func mov eax, 0 // address = 0x40071A leave ret stack frame of main rbp rip 0x40071A saved rbp rsp

Slide 33

Slide 33 text

low address high address func: push rbp mov rbp, rsp sub rsp, 0x70 … mov eax, 0x1 leave ret main: push rbp mov rbp, rsp mov rdi, 1234 mov rsi, 666 call func mov eax, 0 // address = 0x40071A leave ret stack frame of main rbp rip 0x40071A saved rbp rsp

Slide 34

Slide 34 text

low address high address func: push rbp mov rbp, rsp sub rsp, 0x70 … mov eax, 0x1 leave ret main: push rbp mov rbp, rsp mov rdi, 1234 mov rsi, 666 call func mov eax, 0 // address = 0x40071A leave ret stack frame of main rbp rip 0x40071A saved rbp local variables of func() rsp stack frame of func Prologue finished

Slide 35

Slide 35 text

low address high address func: push rbp mov rbp, rsp sub rsp, 0x70 … mov eax, 0x1 leave ret main: push rbp mov rbp, rsp mov rdi, 1234 mov rsi, 666 call func mov eax, 0 // address = 0x40071A leave ret stack frame of main rbp rip 0x40071A saved rbp local variables of func() rsp stack frame of func

Slide 36

Slide 36 text

low address high address func: push rbp mov rbp, rsp sub rsp, 0x70 … mov eax, 0x1 leave ret main: push rbp mov rbp, rsp mov rdi, 1234 mov rsi, 666 call func mov eax, 0 // address = 0x40071A leave ret stack frame of main rbp rip 0x40071A saved rbp local variables of func() rsp stack frame of func leave = mov rsp, rbp pop rbp

Slide 37

Slide 37 text

low address high address func: push rbp mov rbp, rsp sub rsp, 0x70 … mov eax, 0x1 leave ret main: push rbp mov rbp, rsp mov rdi, 1234 mov rsi, 666 call func mov eax, 0 // address = 0x40071A leave ret stack frame of main rip 0x40071A saved rbp local variables of func() stack frame of func leave = mov rsp, rbp pop rbp rbp rsp

Slide 38

Slide 38 text

low address high address func: push rbp mov rbp, rsp sub rsp, 0x70 … mov eax, 0x1 leave ret main: push rbp mov rbp, rsp mov rdi, 1234 mov rsi, 666 call func mov eax, 0 // address = 0x40071A leave ret stack frame of main rip 0x40071A saved rbp local variables of func() stack frame of func leave = mov rsp, rbp pop rbp rsp rbp

Slide 39

Slide 39 text

low address high address func: push rbp mov rbp, rsp sub rsp, 0x70 … mov eax, 0x1 leave ret main: push rbp mov rbp, rsp mov rdi, 1234 mov rsi, 666 call func mov eax, 0 // address = 0x40071A leave ret stack frame of main rip 0x40071A saved rbp local variables of func() stack frame of func ret = pop rip rsp rbp

Slide 40

Slide 40 text

low address high address func: push rbp mov rbp, rsp sub rsp, 0x70 … mov eax, 0x1 leave ret main: push rbp mov rbp, rsp mov rdi, 1234 mov rsi, 666 call func mov eax, 0 // address = 0x40071A leave ret stack frame of main rip 0x40071A saved rbp local variables of func() stack frame of func rbp rsp Epilogue finished

Slide 41

Slide 41 text

DEMO

Slide 42

Slide 42 text

Pwn Binary exploitation

Slide 43

Slide 43 text

Environment • Ubuntu 18.04 • libc-2.27 • x64 Ubuntu 18.04

Slide 44

Slide 44 text

Overflow

Slide 45

Slide 45 text

Overflow • Buffer Overflow • Stack Overflow • Heap Overflow • 覆蓋到理理論上不應該被修改到的資料 • Important data, Secret • Return address

Slide 46

Slide 46 text

BOF Buffer Overflow

Slide 47

Slide 47 text

Buffer Overflow • Local variables • Data on stack low address high address return address saved rbp local variables of func() rbp rsp

Slide 48

Slide 48 text

Buffer Overflow • Local variables • Data on stack low address high address saved rbp int a rbp rsp char buf[0x10] long e int b int c int d return address

Slide 49

Slide 49 text

Buffer Overflow • gets( buf ) • gets() 並不會檢查輸入長度 low address high address saved rbp int a rbp rsp char buf[0x10] long e int b int c int d return address

Slide 50

Slide 50 text

Buffer Overflow • gets( buf ) low address high address saved rbp int a rbp rsp AAAAAAAA long e int b int c int d return address

Slide 51

Slide 51 text

Buffer Overflow • gets( buf ) • Overflow! low address high address saved rbp int a rbp rsp AAAAAAAA AAAAAAAA int b AAAA AAAA return address

Slide 52

Slide 52 text

Buffer Overflow • 控制位於 stack 上的變數值 • int c = 0xdeadbeef • int d = 0xfaceb00c • long e = 0x4141414141414141 low address high address saved rbp int a rbp rsp AAAAAAAA AAAAAAAA int b 0xdeadbeef 0xfaceb00c return address

Slide 53

Slide 53 text

Buffer Overflow • 控制敏感資料 low address high address saved rbp int a rbp rsp char buf[0x10] Password int b Secret Key return address

Slide 54

Slide 54 text

• Control Flow • Return address Buffer Overflow low address high address saved rbp int a rbp rsp char buf[0x10] long e int b int c int d return address

Slide 55

Slide 55 text

• Control Flow • Return address Buffer Overflow low address high address AAAAAAAA AAAAAAAA int a rbp rsp AAAAAAAA AAAAAAAA int b AAAA AAAA

Slide 56

Slide 56 text

• ret • rip = 0x4141414141414141 • Control rip Buffer Overflow low address high address AAAAAAAA AAAAAAAA int a rbp rsp AAAAAAAA AAAAAAAA int b AAAA AAAA

Slide 57

Slide 57 text

• ret • rip = 0x4141414141414141 • Control rip Buffer Overflow low address high address AAAAAAAA AAAAAAAA int a rbp rsp AAAAAAAA AAAAAAAA int b AAAA AAAA PWNED ☠

Slide 58

Slide 58 text

Canary stack protector

Slide 59

Slide 59 text

Canary • Function prologue 時在 stack 上放置程式執⾏行行時
 隨機⽣生成得 8 bytes 在 saved rbp 前,第⼀一個 
 byte 為 null byte • Function epilogue 時會拿儲存在另⼀一 segment
 的值檢查 canary 值是否相同(被修改)來來檢測
 是否發⽣生 overflow,若若相同才正常 return,否則
 直接終⽌止程式 (Abort) • 每次執⾏行行 canary 不同,同⼀一次的 canary 固定 low address high address return address saved rbp local variables of func() rbp rsp canary

Slide 60

Slide 60 text

Canary low address high address return address saved rbp local variables of func() rbp rsp 0x15b2b7eab93d0900 0x15b2b7eab93d0900

Slide 61

Slide 61 text

Canary • Overflow low address high address aaaaaaaa aaaaaaaa aaaaaaaaaaaaaaaa rbp rsp 0x6161616161616161 0x15b2b7eab93d0900

Slide 62

Slide 62 text

Canary • 0x15b2b7eab93d0900 != 0x6161616161616161 0x15b2b7eab93d0900 low address high address aaaaaaaa aaaaaaaa aaaaaaaaaaaaaaaa rbp rsp 0x6161616161616161

Slide 63

Slide 63 text

Canary • 0x15b2b7eab93d0900 != 0x6161616161616161 0x15b2b7eab93d0900 low address high address aaaaaaaa aaaaaaaa aaaaaaaaaaaaaaaa rbp rsp 0x6161616161616161 *** stack smashing detected ***

Slide 64

Slide 64 text

DEMO LAB

Slide 65

Slide 65 text

Shellcode

Slide 66

Slide 66 text

Shellcode int main(){ puts( "Hello World!" ); return 0; } Compiler 55 48 89 e5 48 8d 3d 9f 00 00 00 e8 a3 fe ff ff b8 00 00 00 00 5d c3 Machine Code

Slide 67

Slide 67 text

Shellcode int main(){ puts( "Hello World!" ); return 0; } 55 push rbp 48 89 e5 mov rbp,rsp 48 8d 3d 9f 00 00 00 lea rdi,[rip+0x9f] e8 a3 fe ff ff call 550 b8 00 00 00 00 mov eax,0x0 5d pop rbp c3 ret Compiler Assembler

Slide 68

Slide 68 text

Shellcode int main(){ puts( "Hello World!" ); return 0; } 55 push rbp 48 89 e5 mov rbp,rsp 48 8d 3d 9f 00 00 00 lea rdi,[rip+0x9f] e8 a3 fe ff ff call 550 b8 00 00 00 00 mov eax,0x0 5d pop rbp c3 ret Compiler Assembler Let’s write this!

Slide 69

Slide 69 text

Shellcode push rbp mov rbp,rsp lea rdi,[rip+0x9f] call 550 mov eax,0x0 pop rbp ret 55 48 89 e5 48 8d 3d 9f 00 00 00 e8 a3 fe ff ff b8 00 00 00 00 5d c3 Assembler

Slide 70

Slide 70 text

Linux syscall

Slide 71

Slide 71 text

Syscall • System call • 跟 kernel 做溝通的 interface • x86 - https://syscalls.kernelgrok.com/ • x64 - https://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/

Slide 72

Slide 72 text

Syscall • Instruction - syscall • rax - syscall number • Arguments - rdi rsi rdx r10 r8 r9 • Return value - rax read( 0 , buf , 0x100 ) xor rdi, rdi mov rsi, 0x601000 // buf mov rdx, 0x100 mov eax, 0 syscall

Slide 73

Slide 73 text

Shellcode • execve • int execve( const char *pathname, char *const argv[], char *const envp[]); • Spawn a shell! • execve( “/bin/sh” , NULL, NULL )

Slide 74

Slide 74 text

Shellcode int execve( const char *pathname, char *const argv[], char *const envp[] ); rdi = address of “/bin/sh”
 rsi = 0x0 rdx = 0x0 rax = 0x3b mov rax, 0x68732f6e69622f // “/bin/sh\0” push rax mov rdi, rsp xor rsi, rsi xor rdx, rdx mov rax, 0x3b syscall

Slide 75

Slide 75 text

Shellcode • NX - disable • Return to shellcode low address high address return address saved rbp local variables of func() rsp

Slide 76

Slide 76 text

Shellcode • Overflow low address high address return address saved rbp AAAAAAAAAAAAAAAA
 AAAAAAAAAAAAAAAA
 AAAAAAAAAAAAAAAA

Slide 77

Slide 77 text

Shellcode • 放置惡惡意 payload (shellcode) • Stack is executable low address high address return address saved rbp shellcode AAAAAAAAAAAAAAAA

Slide 78

Slide 78 text

Shellcode • Shellcode is at 0x7fffffffe790 low address high address return address saved rbp shellcode AAAAAAAAAAAAAAAA 0x7fffffffe790

Slide 79

Slide 79 text

Shellcode • 覆蓋 return address 成 shellcode 的位置 low address high address 0x7fffffffe790 saved rbp shellcode AAAAAAAAAAAAAAAA 0x7fffffffe790

Slide 80

Slide 80 text

Shellcode • ret • rip = 0x7fffffffe790 low address high address 0x7fffffffe790 saved rbp shellcode AAAAAAAAAAAAAAAA 0x7fffffffe790 rip

Slide 81

Slide 81 text

Shellcode • 跳上 shellcode 執⾏行行 • Get shell! low address high address 0x7fffffffe790 saved rbp shellcode AAAAAAAAAAAAAAAA 0x7fffffffe790 rip

Slide 82

Slide 82 text

• 跳上 shellcode 執⾏行行 • Get shell! Shellcode low address high address 0x7fffffffe790 saved rbp shellcode AAAAAAAAAAAAAAAA 0x7fffffffe790 rip PWNED ☠

Slide 83

Slide 83 text

NX No-execute

Slide 84

Slide 84 text

NX • No-Execute • Data segment 不應該具有執⾏行行權限 • stack heap • rw- • Code segment 具執⾏行行權限,但不具寫入權限 • r-x

Slide 85

Slide 85 text

NX Start End Perm Name 0x00400000 0x00401000 r-xp /home/yuawn/binary 0x00600000 0x00601000 r--p /home/yuawn/binary 0x00601000 0x00602000 rw-p /home/yuawn/binary 0x00007f5c39819000 0x00007f5c39a00000 r-xp /lib/x86_64-linux-gnu/libc-2.27.so 0x00007f5c39a00000 0x00007f5c39c00000 ---p /lib/x86_64-linux-gnu/libc-2.27.so 0x00007f5c39c00000 0x00007f5c39c04000 r--p /lib/x86_64-linux-gnu/libc-2.27.so 0x00007f5c39c04000 0x00007f5c39c06000 rw-p /lib/x86_64-linux-gnu/libc-2.27.so 0x00007f5c39c06000 0x00007f5c39c0a000 rw-p mapped 0x00007f5c39c0a000 0x00007f5c39c31000 r-xp /lib/x86_64-linux-gnu/ld-2.27.so 0x00007f5c39e26000 0x00007f5c39e28000 rw-p mapped 0x00007f5c39e31000 0x00007f5c39e32000 r--p /lib/x86_64-linux-gnu/ld-2.27.so 0x00007f5c39e32000 0x00007f5c39e33000 rw-p /lib/x86_64-linux-gnu/ld-2.27.so 0x00007f5c39e33000 0x00007f5c39e34000 rw-p mapped 0x00007ffdb0f84000 0x00007ffdb0fa5000 rw-p [stack] 0x00007ffdb0ff6000 0x00007ffdb0ff8000 r--p [vvar] 0x00007ffdb0ff8000 0x00007ffdb0ffa000 r-xp [vdso] 0xffffffffff600000 0xffffffffff601000 r-xp [vsyscall] .bss .text

Slide 86

Slide 86 text

DEMO

Slide 87

Slide 87 text

ASLR Address Space Layout Randomization

Slide 88

Slide 88 text

ASLR • Address Space Layout Randomization • kernel • 每次動態載入時,base 都是隨機的 • library • stack • heap

Slide 89

Slide 89 text

PIE Position-Independent Executable

Slide 90

Slide 90 text

PIE • 可以看成是 ELF code & data section map 到 virtual address 時的 ASLR。 • PIE 開啟時,每次執⾏行行程式 code base 都會不同,否則固定 0x400000 • 紀錄在 ELF file 中

Slide 91

Slide 91 text

Lazy Binding

Slide 92

Slide 92 text

Lazy Binding • Dynamic linking 的程式,有些使⽤用到的 library function 可能因執⾏行行流程到 結束都不會被執⾏行行到。 • Lazy binding 機制為當程式第⼀一次呼叫 library function 時,才會去第⼀一次 尋找 libc function 的位置(function address)進⾏行行 binding,並填入 GOT 表 中,後續呼叫此 function 則直接從 GOT 表中獲取位置。

Slide 93

Slide 93 text

GOT Global Offset Table

Slide 94

Slide 94 text

GOT • library 的位置在載入時才決定,compiler 在編譯時期亦無法得知執⾏行行時期 的 library function address。 • GOT 為儲存 library function 位置的指標陣列列,⽽而 lazy binding 的機制,⼀一 開始不會得知真實位置,⽽而是先填入位於 plt 的 code。

Slide 95

Slide 95 text

puts@plt+6 0x0 Lazy Binding 00000000004003e0 <.plt>: 4003e0: push QWORD PTR [rip+0x200c22] # 601008 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 00000000004003f0 : 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 .. 400700: call 4003f0 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT

Slide 96

Slide 96 text

puts@plt+6 0x0 Lazy Binding 00000000004003e0 <.plt>: 4003e0: push QWORD PTR [rip+0x200c22] # 601008 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 00000000004003f0 : 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 .. 400700: call 4003f0 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT

Slide 97

Slide 97 text

puts@plt+6 0x0 Lazy Binding 00000000004003e0 <.plt>: 4003e0: push QWORD PTR [rip+0x200c22] # 601008 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 00000000004003f0 : 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 .. 400700: call 4003f0 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT

Slide 98

Slide 98 text

puts@plt+6 0x0 Lazy Binding 00000000004003e0 <.plt>: 4003e0: push QWORD PTR [rip+0x200c22] # 601008 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 00000000004003f0 : 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 .. 400700: call 4003f0 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT

Slide 99

Slide 99 text

puts@plt+6 0x0 Lazy Binding 00000000004003e0 <.plt>: 4003e0: push QWORD PTR [rip+0x200c22] # 601008 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 00000000004003f0 : 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 .. 400700: call 4003f0 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT

Slide 100

Slide 100 text

puts@plt+6 0x0 Lazy Binding 00000000004003e0 <.plt>: 4003e0: push QWORD PTR [rip+0x200c22] # 601008 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 00000000004003f0 : 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 .. 400700: call 4003f0 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT

Slide 101

Slide 101 text

puts@plt+6 0x0 Lazy Binding 00000000004003e0 <.plt>: 4003e0: push QWORD PTR [rip+0x200c22] # 601008 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 00000000004003f0 : 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 .. 400700: call 4003f0 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT

Slide 102

Slide 102 text

puts@plt+6 0x0 Lazy Binding 00000000004003e0 <.plt>: 4003e0: push QWORD PTR [rip+0x200c22] # 601008 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 00000000004003f0 : 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 .. 400700: call 4003f0 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT

Slide 103

Slide 103 text

puts@plt+6 0x0 Lazy Binding 00000000004003e0 <.plt>: 4003e0: push QWORD PTR [rip+0x200c22] # 601008 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 00000000004003f0 : 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 .. 400700: call 4003f0 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT

Slide 104

Slide 104 text

puts@plt+6 0x0 Lazy Binding 00000000004003e0 <.plt>: 4003e0: push QWORD PTR [rip+0x200c22] # 601008 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 00000000004003f0 : 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 .. 400700: call 4003f0 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT _dl_runtime_resolve_xsave

Slide 105

Slide 105 text

0x7ffff7a649c0 0x0 Lazy Binding 00000000004003e0 <.plt>: 4003e0: push QWORD PTR [rip+0x200c22] # 601008 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 00000000004003f0 : 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 .. 400700: call 4003f0 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT _dl_runtime_resolve_xsave

Slide 106

Slide 106 text

<_IO_puts> 0x0 Lazy Binding 00000000004003e0 <.plt>: 4003e0: push QWORD PTR [rip+0x200c22] # 601008 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 00000000004003f0 : 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 .. 400700: call 4003f0 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT _dl_runtime_resolve_xsave

Slide 107

Slide 107 text

<_IO_puts> 0x0 Lazy Binding 00000000004003e0 <.plt>: 4003e0: push QWORD PTR [rip+0x200c22] # 601008 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 00000000004003f0 : 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 .. 400700: call 4003f0 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT

Slide 108

Slide 108 text

<_IO_puts> 0x0 Lazy Binding 00000000004003e0 <.plt>: 4003e0: push QWORD PTR [rip+0x200c22] # 601008 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 00000000004003f0 : 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 .. 400700: call 4003f0 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT

Slide 109

Slide 109 text

0x0 Lazy Binding 00000000004003e0 <.plt>: 4003e0: push QWORD PTR [rip+0x200c22] # 601008 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 00000000004003f0 : 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 .. 400700: call 4003f0 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT <_IO_puts>

Slide 110

Slide 110 text

0x0 Lazy Binding 00000000004003e0 <.plt>: 4003e0: push QWORD PTR [rip+0x200c22] # 601008 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 00000000004003f0 : 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 .. 400700: call 4003f0 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT 0x7ffff7a649c0 <_IO_puts> <_IO_puts>

Slide 111

Slide 111 text

DEMO

Slide 112

Slide 112 text

GOTHijacking

Slide 113

Slide 113 text

GOT Hijacking • 因為 Lazy Binding 的機制,GOT 為可寫區域 • 假設程式有漏洞洞可以造成對 GOT 做寫入覆蓋其值,下⼀一次呼叫對應的 library function 時則可以從中劫持,任意控制將要執⾏行行的 funtion pointer。

Slide 114

Slide 114 text

puts@plt+6 0x0 00000000004003e0 <.plt>: 4003e0: push QWORD PTR [rip+0x200c22] # 601008 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 00000000004003f0 : 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT GOT Hijacking

Slide 115

Slide 115 text

0xdeadbeef 0x0 00000000004003e0 <.plt>: 4003e0: push QWORD PTR [rip+0x200c22] # 601008 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 00000000004003f0 : 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT GOT Hijacking

Slide 116

Slide 116 text

0xdeadbeef 0x0 00000000004003e0 <.plt>: 4003e0: push QWORD PTR [rip+0x200c22] # 601008 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 00000000004003f0 : 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT GOT Hijacking

Slide 117

Slide 117 text

0xdeadbeef 0x0 00000000004003e0 <.plt>: 4003e0: push QWORD PTR [rip+0x200c22] # 601008 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 00000000004003f0 : 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT GOT Hijacking

Slide 118

Slide 118 text

0xdeadbeef 0x0 00000000004003e0 <.plt>: 4003e0: push QWORD PTR [rip+0x200c22] # 601008 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 00000000004003f0 : 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT GOT Hijacking

Slide 119

Slide 119 text

0xdeadbeef 0x0 00000000004003e0 <.plt>: 4003e0: push QWORD PTR [rip+0x200c22] # 601008 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 00000000004003f0 : 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT Jump to 0xdeadbeef! rip = 0xdeadbeef GOT Hijacking

Slide 120

Slide 120 text

0xdeadbeef 0x0 00000000004003e0 <.plt>: 4003e0: push QWORD PTR [rip+0x200c22] # 601008 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 00000000004003f0 : 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT Jump to 0xdeadbeef! rip = 0xdeadbeef PWNED ☠ GOT Hijacking

Slide 121

Slide 121 text

DEMO

Slide 122

Slide 122 text

Casino HW

Slide 123

Slide 123 text

HW - Casino • Just Pwn It!

Slide 124

Slide 124 text

Thanks! yuawn _yuawn