Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Binary Exploitation - Basic
Search
yuawn
November 08, 2019
Technology
2
2.9k
Binary Exploitation - Basic
NTU CS 2019 Fall - Binary Exploitation Basic
台大 - 計算機安全 Pwn
交大 - 程式安全
台科大 - 資訊安全實務
yuawn
November 08, 2019
Tweet
Share
More Decks by yuawn
See All by yuawn
MediaTek Fuzzing Workshop
yuawn
2
1.1k
Kernel Exploitation
yuawn
4
3.2k
Heap Exploitation
yuawn
2
1.3k
Binary Exploitation
yuawn
2
1.5k
HITCON Badge 2019 - MCU ARM TrustZone Challenge
yuawn
2
370
Other Decks in Technology
See All in Technology
AWS Media Services 最新サービスアップデート 2024
eijikominami
0
200
DynamoDB でスロットリングが発生したとき_大盛りver/when_throttling_occurs_in_dynamodb_long
emiki
1
420
Adopting Jetpack Compose in Your Existing Project - GDG DevFest Bangkok 2024
akexorcist
0
110
Terraform CI/CD パイプラインにおける AWS CodeCommit の代替手段
hiyanger
1
240
ISUCONに強くなるかもしれない日々の過ごしかた/Findy ISUCON 2024-11-14
fujiwara3
8
870
Lambda10周年!Lambdaは何をもたらしたか
smt7174
2
110
サイバーセキュリティと認知バイアス:対策の隙を埋める心理学的アプローチ
shumei_ito
0
390
組織成長を加速させるオンボーディングの取り組み
sudoakiy
2
180
The Rise of LLMOps
asei
7
1.6k
Zennのパフォーマンスモニタリングでやっていること
ryosukeigarashi
0
130
OS 標準のデザインシステムを超えて - より柔軟な Flutter テーマ管理 | FlutterKaigi 2024
ronnnnn
0
170
Shopifyアプリ開発における Shopifyの機能活用
sonatard
4
250
Featured
See All Featured
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
93
16k
No one is an island. Learnings from fostering a developers community.
thoeni
19
3k
Building Applications with DynamoDB
mza
90
6.1k
Designing for Performance
lara
604
68k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
191
16k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
10
720
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
47
2.1k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
226
22k
For a Future-Friendly Web
brad_frost
175
9.4k
What’s in a name? Adding method to the madness
productmarketing
PRO
22
3.1k
How to Ace a Technical Interview
jacobian
276
23k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
4
370
Transcript
Binary Exploitation - Basic yuawn
About • yuawn • Pwn • Balsn / DoubleSigma
_yuawn
Outline • Binary exploitation • Basic concepts • ELF •
x64 calling convention • Stack frame • BOF - Buffer Overflow • Shellcode • Lazy binding - GOT Hijacking PWNED
What is Pwn?
Binary Exploitation • 透過利利⽤用程式 (Binary) 的漏洞洞 (Vulnerability),在執⾏行行期間控制執⾏行行流程 (Control flow),進⽽而使程式執⾏行行特定⾏行行為。 •
Pwn • 胖 or 碰
Binary Exploitation User Server Service
Binary Exploitation User Server Service Vulnerable?
Binary Exploitation Hacker Server Vulnerable Service Exploit
Binary Exploitation Hacker Vulnerable Service RCE PWNED Exploit
Basic Concepts
ELF Executable and Linkable Format
ELF • Executable and Linkable Format • 執⾏行行檔 ex. exe
• section • 執⾏行行時會 mapping 到 RAM 上 (virtual memory) • .text .bss .data .rodata .got .plt .fini …
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
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
ELF - section • .bss - 存放未初始化值的全域變數 (global variable) •
.data - 存放具初始化值的全域變數 • .rodata - 存放唯讀 (read-only) 資料 • .text - 存放編譯後的 code
ELF - section int a; int b = 100; int
main(){ int c; puts( "I love pwning." ); return 0; } .bss .data .text .rodata
ELF - Protections • PIE - Position-Independent Executable • NX
- No-eXecute • Canary - stack protector • RELRO - Relocation Read-Only
DEMO
x64 • 8 bytes alignment • Stack 0x10 bytes alignment
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
x64 Assembly • Registers • RSP - Stack Pointer Register
• 指向 stack 頂端(頭) • RBP - Base Pointer Register • 指向 stack 底端(尾) • RIP - Program Counter Register • 指向當前執⾏行行指令instruction位置
x64 Assembly • jmp (jump) • 跳⾄至程式某⼀一地址 A(address) 執⾏行行 •
jmp A = mov rip, A • call • 將 call 完後回來來緊接著要執⾏行行的下⼀一⾏行行指令位置 push 到 stack 上儲存起來來,再跳 過去執⾏行行。 • call A = push next_rip mov rip, A
x64 Assembly • leave • 還原⾄至 caller 的 stack frame。
• mov rsp, rbp pop rbp • ret (return) • pop rip
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 傳參參
Stack Frame
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
DEMO
Pwn Binary exploitation
Environment • Ubuntu 18.04 • libc-2.27 • x64 Ubuntu 18.04
Overflow
Overflow • Buffer Overflow • Stack Overflow • Heap Overflow
• 覆蓋到理理論上不應該被修改到的資料 • Important data, Secret • Return address
BOF Buffer Overflow
Buffer Overflow • Local variables • Data on stack low
address high address return address saved rbp local variables of func() rbp rsp
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
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
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
Buffer Overflow • gets( buf ) • Overflow! low address
high address saved rbp int a rbp rsp AAAAAAAA AAAAAAAA int b AAAA AAAA return address
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
Buffer Overflow • 控制敏感資料 low address high address saved rbp
int a rbp rsp char buf[0x10] Password int b Secret Key return address
• 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
• Control Flow • Return address Buffer Overflow low address
high address AAAAAAAA AAAAAAAA int a rbp rsp AAAAAAAA AAAAAAAA int b AAAA AAAA
• ret • rip = 0x4141414141414141 • Control rip Buffer
Overflow low address high address AAAAAAAA AAAAAAAA int a rbp rsp AAAAAAAA AAAAAAAA int b AAAA AAAA
• ret • rip = 0x4141414141414141 • Control rip Buffer
Overflow low address high address AAAAAAAA AAAAAAAA int a rbp rsp AAAAAAAA AAAAAAAA int b AAAA AAAA PWNED ☠
Canary stack protector
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
Canary low address high address return address saved rbp local
variables of func() rbp rsp 0x15b2b7eab93d0900 0x15b2b7eab93d0900
Canary • Overflow low address high address aaaaaaaa aaaaaaaa aaaaaaaaaaaaaaaa
rbp rsp 0x6161616161616161 0x15b2b7eab93d0900
Canary • 0x15b2b7eab93d0900 != 0x6161616161616161 0x15b2b7eab93d0900 low address high address
aaaaaaaa aaaaaaaa aaaaaaaaaaaaaaaa rbp rsp 0x6161616161616161
Canary • 0x15b2b7eab93d0900 != 0x6161616161616161 0x15b2b7eab93d0900 low address high address
aaaaaaaa aaaaaaaa aaaaaaaaaaaaaaaa rbp rsp 0x6161616161616161 *** stack smashing detected ***
DEMO LAB
Shellcode
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
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 <puts@plt> b8 00 00 00 00 mov eax,0x0 5d pop rbp c3 ret Compiler Assembler
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 <puts@plt> b8 00 00 00 00 mov eax,0x0 5d pop rbp c3 ret Compiler Assembler Let’s write this!
Shellcode push rbp mov rbp,rsp lea rdi,[rip+0x9f] call 550 <puts@plt>
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
Linux syscall
Syscall • System call • 跟 kernel 做溝通的 interface •
x86 - https://syscalls.kernelgrok.com/ • x64 - https://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/
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
Shellcode • execve • int execve( const char *pathname, char
*const argv[], char *const envp[]); • Spawn a shell! • execve( “/bin/sh” , NULL, NULL )
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
Shellcode • NX - disable • Return to shellcode low
address high address return address saved rbp local variables of func() rsp
Shellcode • Overflow low address high address return address saved
rbp AAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAA
Shellcode • 放置惡惡意 payload (shellcode) • Stack is executable low
address high address return address saved rbp shellcode AAAAAAAAAAAAAAAA
Shellcode • Shellcode is at 0x7fffffffe790 low address high address
return address saved rbp shellcode AAAAAAAAAAAAAAAA 0x7fffffffe790
Shellcode • 覆蓋 return address 成 shellcode 的位置 low address
high address 0x7fffffffe790 saved rbp shellcode AAAAAAAAAAAAAAAA 0x7fffffffe790
Shellcode • ret • rip = 0x7fffffffe790 low address high
address 0x7fffffffe790 saved rbp shellcode AAAAAAAAAAAAAAAA 0x7fffffffe790 rip
Shellcode • 跳上 shellcode 執⾏行行 • Get shell! low address
high address 0x7fffffffe790 saved rbp shellcode AAAAAAAAAAAAAAAA 0x7fffffffe790 rip
• 跳上 shellcode 執⾏行行 • Get shell! Shellcode low address
high address 0x7fffffffe790 saved rbp shellcode AAAAAAAAAAAAAAAA 0x7fffffffe790 rip PWNED ☠
NX No-execute
NX • No-Execute • Data segment 不應該具有執⾏行行權限 • stack heap
• rw- • Code segment 具執⾏行行權限,但不具寫入權限 • r-x
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
DEMO
ASLR Address Space Layout Randomization
ASLR • Address Space Layout Randomization • kernel • 每次動態載入時,base
都是隨機的 • library • stack • heap
PIE Position-Independent Executable
PIE • 可以看成是 ELF code & data section map 到
virtual address 時的 ASLR。 • PIE 開啟時,每次執⾏行行程式 code base 都會不同,否則固定 0x400000 • 紀錄在 ELF file 中
Lazy Binding
Lazy Binding • Dynamic linking 的程式,有些使⽤用到的 library function 可能因執⾏行行流程到 結束都不會被執⾏行行到。
• Lazy binding 機制為當程式第⼀一次呼叫 library function 時,才會去第⼀一次 尋找 libc function 的位置(function address)進⾏行行 binding,並填入 GOT 表 中,後續呼叫此 function 則直接從 GOT 表中獲取位置。
GOT Global Offset Table
GOT • library 的位置在載入時才決定,compiler 在編譯時期亦無法得知執⾏行行時期 的 library function address。 •
GOT 為儲存 library function 位置的指標陣列列,⽽而 lazy binding 的機制,⼀一 開始不會得知真實位置,⽽而是先填入位於 plt 的 code。
puts@plt+6 0x0 Lazy Binding 00000000004003e0 <.plt>: 4003e0: push QWORD PTR
[rip+0x200c22] # 601008 <got+0x8> 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 <got+0x10> 00000000004003f0 <puts@plt>: 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 <puts@got> 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 <puts@plt> .. 400700: call 4003f0 <puts@plt> 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT
puts@plt+6 0x0 Lazy Binding 00000000004003e0 <.plt>: 4003e0: push QWORD PTR
[rip+0x200c22] # 601008 <got+0x8> 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 <got+0x10> 00000000004003f0 <puts@plt>: 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 <puts@got> 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 <puts@plt> .. 400700: call 4003f0 <puts@plt> 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT
puts@plt+6 0x0 Lazy Binding 00000000004003e0 <.plt>: 4003e0: push QWORD PTR
[rip+0x200c22] # 601008 <got+0x8> 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 <got+0x10> 00000000004003f0 <puts@plt>: 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 <puts@got> 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 <puts@plt> .. 400700: call 4003f0 <puts@plt> 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT
puts@plt+6 0x0 Lazy Binding 00000000004003e0 <.plt>: 4003e0: push QWORD PTR
[rip+0x200c22] # 601008 <got+0x8> 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 <got+0x10> 00000000004003f0 <puts@plt>: 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 <puts@got> 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 <puts@plt> .. 400700: call 4003f0 <puts@plt> 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT
puts@plt+6 0x0 Lazy Binding 00000000004003e0 <.plt>: 4003e0: push QWORD PTR
[rip+0x200c22] # 601008 <got+0x8> 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 <got+0x10> 00000000004003f0 <puts@plt>: 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 <puts@got> 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 <puts@plt> .. 400700: call 4003f0 <puts@plt> 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT
puts@plt+6 0x0 Lazy Binding 00000000004003e0 <.plt>: 4003e0: push QWORD PTR
[rip+0x200c22] # 601008 <got+0x8> 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 <got+0x10> 00000000004003f0 <puts@plt>: 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 <puts@got> 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 <puts@plt> .. 400700: call 4003f0 <puts@plt> 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT
puts@plt+6 0x0 Lazy Binding 00000000004003e0 <.plt>: 4003e0: push QWORD PTR
[rip+0x200c22] # 601008 <got+0x8> 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 <got+0x10> 00000000004003f0 <puts@plt>: 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 <puts@got> 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 <puts@plt> .. 400700: call 4003f0 <puts@plt> 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT
puts@plt+6 0x0 Lazy Binding 00000000004003e0 <.plt>: 4003e0: push QWORD PTR
[rip+0x200c22] # 601008 <got+0x8> 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 <got+0x10> 00000000004003f0 <puts@plt>: 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 <puts@got> 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 <puts@plt> .. 400700: call 4003f0 <puts@plt> 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT
puts@plt+6 0x0 Lazy Binding 00000000004003e0 <.plt>: 4003e0: push QWORD PTR
[rip+0x200c22] # 601008 <got+0x8> 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 <got+0x10> 00000000004003f0 <puts@plt>: 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 <puts@got> 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 <puts@plt> .. 400700: call 4003f0 <puts@plt> 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT
puts@plt+6 0x0 Lazy Binding 00000000004003e0 <.plt>: 4003e0: push QWORD PTR
[rip+0x200c22] # 601008 <got+0x8> 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 <got+0x10> 00000000004003f0 <puts@plt>: 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 <puts@got> 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 <puts@plt> .. 400700: call 4003f0 <puts@plt> 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT _dl_runtime_resolve_xsave
0x7ffff7a649c0 0x0 Lazy Binding 00000000004003e0 <.plt>: 4003e0: push QWORD PTR
[rip+0x200c22] # 601008 <got+0x8> 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 <got+0x10> 00000000004003f0 <puts@plt>: 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 <puts@got> 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 <puts@plt> .. 400700: call 4003f0 <puts@plt> 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT _dl_runtime_resolve_xsave
<_IO_puts> 0x0 Lazy Binding 00000000004003e0 <.plt>: 4003e0: push QWORD PTR
[rip+0x200c22] # 601008 <got+0x8> 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 <got+0x10> 00000000004003f0 <puts@plt>: 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 <puts@got> 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 <puts@plt> .. 400700: call 4003f0 <puts@plt> 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT _dl_runtime_resolve_xsave
<_IO_puts> 0x0 Lazy Binding 00000000004003e0 <.plt>: 4003e0: push QWORD PTR
[rip+0x200c22] # 601008 <got+0x8> 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 <got+0x10> 00000000004003f0 <puts@plt>: 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 <puts@got> 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 <puts@plt> .. 400700: call 4003f0 <puts@plt> 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT
<_IO_puts> 0x0 Lazy Binding 00000000004003e0 <.plt>: 4003e0: push QWORD PTR
[rip+0x200c22] # 601008 <got+0x8> 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 <got+0x10> 00000000004003f0 <puts@plt>: 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 <puts@got> 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 <puts@plt> .. 400700: call 4003f0 <puts@plt> 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT
0x0 Lazy Binding 00000000004003e0 <.plt>: 4003e0: push QWORD PTR [rip+0x200c22]
# 601008 <got+0x8> 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 <got+0x10> 00000000004003f0 <puts@plt>: 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 <puts@got> 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 <puts@plt> .. 400700: call 4003f0 <puts@plt> 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT <_IO_puts>
0x0 Lazy Binding 00000000004003e0 <.plt>: 4003e0: push QWORD PTR [rip+0x200c22]
# 601008 <got+0x8> 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 <got+0x10> 00000000004003f0 <puts@plt>: 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 <puts@got> 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 <puts@plt> .. 400700: call 4003f0 <puts@plt> 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT 0x7ffff7a649c0 <_IO_puts> <_IO_puts>
DEMO
GOTHijacking
GOT Hijacking • 因為 Lazy Binding 的機制,GOT 為可寫區域 • 假設程式有漏洞洞可以造成對
GOT 做寫入覆蓋其值,下⼀一次呼叫對應的 library function 時則可以從中劫持,任意控制將要執⾏行行的 funtion pointer。
puts@plt+6 0x0 00000000004003e0 <.plt>: 4003e0: push QWORD PTR [rip+0x200c22] #
601008 <got+0x8> 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 <got+0x10> 00000000004003f0 <puts@plt>: 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 <puts@got> 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 <puts@plt> 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT GOT Hijacking
0xdeadbeef 0x0 00000000004003e0 <.plt>: 4003e0: push QWORD PTR [rip+0x200c22] #
601008 <got+0x8> 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 <got+0x10> 00000000004003f0 <puts@plt>: 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 <puts@got> 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 <puts@plt> 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT GOT Hijacking
0xdeadbeef 0x0 00000000004003e0 <.plt>: 4003e0: push QWORD PTR [rip+0x200c22] #
601008 <got+0x8> 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 <got+0x10> 00000000004003f0 <puts@plt>: 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 <puts@got> 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 <puts@plt> 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT GOT Hijacking
0xdeadbeef 0x0 00000000004003e0 <.plt>: 4003e0: push QWORD PTR [rip+0x200c22] #
601008 <got+0x8> 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 <got+0x10> 00000000004003f0 <puts@plt>: 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 <puts@got> 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 <puts@plt> 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT GOT Hijacking
0xdeadbeef 0x0 00000000004003e0 <.plt>: 4003e0: push QWORD PTR [rip+0x200c22] #
601008 <got+0x8> 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 <got+0x10> 00000000004003f0 <puts@plt>: 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 <puts@got> 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 <puts@plt> 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT GOT Hijacking
0xdeadbeef 0x0 00000000004003e0 <.plt>: 4003e0: push QWORD PTR [rip+0x200c22] #
601008 <got+0x8> 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 <got+0x10> 00000000004003f0 <puts@plt>: 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 <puts@got> 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 <puts@plt> 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT Jump to 0xdeadbeef! rip = 0xdeadbeef GOT Hijacking
0xdeadbeef 0x0 00000000004003e0 <.plt>: 4003e0: push QWORD PTR [rip+0x200c22] #
601008 <got+0x8> 4003e6: jmp QWORD PTR [rip+0x200c24] # 601010 <got+0x10> 00000000004003f0 <puts@plt>: 4003f0: jmp QWORD PTR [rip+0x200c22] # 601018 <puts@got> 4003f6: push 0x0 4003fb: jmp 4003e0 <.plt> .. 4004f2: call 4003f0 <puts@plt> 0x601010 printf@plt+6 read@plt+6 write@plt+6 system@plt+6 0x601030 0x601020 GOT Jump to 0xdeadbeef! rip = 0xdeadbeef PWNED ☠ GOT Hijacking
DEMO
Casino HW
HW - Casino • Just Pwn It!
Thanks! yuawn _yuawn