点击蓝字,关注我们
日期:2025年02月27日
作者:YuKong
介绍:一道代码审计引起的反思。
0x00 前言
一次CTF
比赛中遇到一个PHP
代码审计题。赛中审计发现存在反序列化函数并以此为出发点开始寻找入口点,未果。赛后整理思路并搭建环境重新审计。
0x01 环境搭建
操作系统:macOS
后端环境:MAMP PRO
编辑器:PhpStorm
1.1 MAMP PRO设置
(1)添加Add Host
(2)设置网站根目录
(3)设置PHP
版本、IP
、端口
(4)开启Xdebug
1.2 PhpStorm设置
(1)添加服务器
(2)设置调试配置
(3)添加断点,开启监听
0x02 代码审计
审计平台:yakit
审计规则:Syntaxflow
2.1 审计思路
由于比赛期间一直在找反序列化点没有成功,所以复现过程中选择广撒网的模式,找出全部有可能getshell
的函数逐个审计。最终发现了文件写入+条件竞争的方式在网站根目录写入webshell
。
2.2 审计流程
(1)在yakit
平台,选择代码审计->项目管理,并添加项目,需要等待一段时间对代码进行编译。
(2)编译完成后,写规则匹配所有可疑函数。
desc(
title: 'Classified PHP Vulnerability Function Detection',
type: audit,
level: info,
desc: <<<TEXT
This rule categorizes PHP functions by vulnerability types, such as file operations, command execution, and code execution.
TEXT
)
// 文件操作相关函数
.*?{(include) || (file_put_contents) || (file_get_contents) || (unlink) || (fopen)} as$file_funcs;
// 命令执行相关函数
.*?{(exec) || (system) || (shell_exec) || (passthru) || (popen)} as$cmd_funcs
// 代码执行相关函数
.*?{(eval) || (create_function) || (preg_replace)} as$code_funcs
// 数据库查询相关函数
.*?{(mysqli_query) || ("PDO::query") || (pg_query) || (pg_prepare)} as$sql_funcs
// 反序列化相关函数
.*?{(unserialize)} as$unserialize_funcs
// 分类警报输出
alert $file_funcs for {
title: 'File Operation Function Detected',
type: 'info',
level: 'info',
}
alert $cmd_funcs for {
title: 'Command Execution Function Detected',
type: 'info',
level: 'info',
}
alert $code_funcs for {
title: 'Code Execution Function Detected',
type: 'info',
level: 'info',
}
alert $sql_funcs for {
title: 'SQL Query Function Detected',
type: 'info',
level: 'info',
}
alert $unserialize_funcs for {
title: 'Unserialize Function Detected',
type: 'info',
level: 'info',
}
发现使用了include
、file_put_contents
、unlink
、file_get_contents
函数,依次分析参数是否可控。
(3)经过判断发现只有file_put_contents
可控,其他函数已经写死。
(4)继续根据此处代码,分析得到该函数在修改密码处,会根据用户名和密码生成以用户名为文件名,以密码为文件内容的文件。
(5)继续追踪代码发现同一函数中还存在调用check
函数,通过查看check
内容发现用户名中不可以存在php
。
(6)通过代码审计发现同一函数中存在unlink
函数,在生成到当前目录下的文件被复制到/tmp/users/
文件夹后会被删除。
思路总结:注册用户名为123.PHP
的用户用于绕过check
,随后登录进行修改密码。修改密码时将密码修改为可以在本地生成一句话木马的恶意脚本,同时发包重复访问123.PHP
,实现在123.PHP
被删除之前生成webshell
。
0x03 漏洞复现
(1)注册用户为123.PHP
的用户。
(2)登录后修改密码。
(3)在触发unlink
删除123.PHP
之前打个断点。发现123.PHP
已生成。
(4)将密码改为生成本地webshell
的php
脚本,并同时访问123.PHP
。
file_put_contents('shell.php', '<?php phpinfo(); ?>');
网站根目录生成shell.php
。
0x04 总结
比赛中时间紧迫,容易因误判而在错误的方向上浪费时间。尤其是在代码审计中,一旦分析思路偏离正确轨迹,就离正确的方向越走越远。所以不妨在没有思路的时候,先大吃一顿回头再看说不定会有新的发现。
免责声明:本文仅供安全研究与讨论之用,严禁用于非法用途,违者后果自负。
点此亲启
原文始发于微信公众号(宸极实验室):『代码审计』曲折的代码审计
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论