Hack Your Heart

Back

2025宁波市第八届网络安全大赛决赛Writeup Blur image

很幸运的拿到了榜一,队友太强了,AWDP玩的很少,不过这次break 和 fix都有成果。

Break 第一,Fix 第四

[web] easyUpload#

break#

F12检查图片,发现通过/show.php?file=img/1.png来读取

任意文件读取,flag被ban,读index.php源码

反序列化,经过一个md5绕过

[web] img2base64#

break#

我觉得这题是最难的一题,现场也没几个人做出来

用到一些小trick

首先要绕一些字符,管道符截断,环境变量反弹shell,无密码读取文件

小明打ctf上头了,发什么消息都用编码发送,于是他搭建了一个web服务用来将图片进行base64编码,粗心的小明没有考虑安全问题,你能帮他看看吗?

平台给了源码

公告有提示反弹shell,那就先把反弹的命令写进文件

代码执行的是cat {file_path} | base64

先通过|截断命令,然后使用$0来执行 cat 输出的内容,也就是反弹shell的命令

$0代表本文件,$1代表第1个参数,以此类推。$#代表参数个数

监听端口

没权限读flag

sudo -l查看有权限的命令,然后在GTFOBins ↗ 查sudo语法

幸好本地部署了GTFOBins

不过这题队友出大力,推荐队友的一键部署环境脚本:https://github.com/dr0n1/CTF_misc_auto_deploy ↗

[web] genshop#

fix#

太逆天了,我正在加各种过滤,结果rot-will把函数去掉就过了。

ssti的模板去掉直接过了

1# return render_template_string(f"<h3>{result}</h3>")
2return f"<h3>{result}</h3>"
python

[web] Easy_shop#

break#

打开是一个商店购买页面

将购买数量改成负数,可以增加金钱

购买flag,得到/showflag路由

访问是一个文件读取功能,读取../app.js

逻辑很简单,copy函数有问题,一眼Node.js原型链污染

secert 是个空对象,但它和 user 在同一作用域下,需要控制 req.body 中的内容,污染secret

1{
2  "__proto__": {
3    "testattack": "admin"
4  }
5}
js

当时截的图:

这题刚开始没说读取../app.js,我在fuzz的时候居然读到了1.txt、2.txt、3.txt,分别是:

1在一个宁静的午后,阳光透过树叶洒在地面上,斑驳陆离。小镇的街道上行人稀少,只有微风轻轻拂过树梢,带来一丝初秋的凉意。远处传来几声悠扬的钟声,仿佛提醒人们,该是泡一壶茶、慢慢享受时光的时候了
2
3夜幕降临,城市的灯光次第亮起,仿佛点燃了沉睡的星辰。街角的咖啡店还亮着温暖的橘黄色灯光,一杯热饮静静地摆在窗边的桌上。外面车水马龙,人来人往,而屋内却是一方静谧的世界,时间在这里缓慢流淌,仿佛与喧嚣隔绝。
4
5清晨的山间薄雾弥漫,露珠挂在草叶上,闪烁着晶莹的光。远处传来鸟鸣声,唤醒了沉睡的森林。一位背着行囊的旅人正沿着蜿蜒的小径缓缓前行,每一步都踩在湿润的土地上,带着对未知的好奇,走向尚未被书写的旅程。
txt

出现7个一,所以我尝试读取f1111111ag,或者其他变体,都不行。或者按照早中晚的顺序,对文件名排序,312,那是不是响应码改成312响应码呢?可是没有这个响应码。直到给出hint,我才知道这个毫无用处,纯属迷惑人的。

fix#

只用修读取flag的关键漏洞就行,但我顺手把增加金钱数、任意文件读取这俩洞也修了。你还真读app.js啊 : )

[pwn] Cake_shop#

break#

存在格式化字符串

exp

fix#

修改使用puts进行输出,成功修复

[pwn] stu_admin#

fix#

edit功能存在堆溢出,溢出了16字节

修复溢出

总结#

整体难度比往年都要简单,就是搞不懂为什么check的轮次这么少,只有两轮,而且不返回check的结果

队友很厉害,不过这次也没有拖后腿,还是有Break 和 Fix成果的。

2025宁波市第八届网络安全大赛决赛Writeup
https://h4cker.zip/12ffc6/
Author Tajang
Published at September 6, 2025
Copyright CC BY-NC-SA 4.0