PbootCMS注入漏洞复现:揭秘非法请求是如何穿透数据库防火墙的

在很多站长眼里,PbootCMS属于“轻量、简单、容易上手”的那类CMS。
但也正因为轻量,一些开发者在二开、插件扩展、模板调用时,经常会忽略参数过滤与SQL安全问题。
于是就会出现一个经典场景:
前端只是一个普通搜索框,后台数据库却已经被“打穿”。
很多人第一次看到注入日志时都会懵:
?id=1' UNION SELECT username,password FROM ay_user --
“不是有WAF吗?”
“不是已经过滤单引号了吗?”
“为什么数据库还是被执行了?”
今天这篇文章,我们就从攻击者视角,完整复现一次PbootCMS注入漏洞形成过程,看看非法请求到底是如何一步步绕过过滤并穿透数据库防火墙的。
一、什么是SQL注入?
SQL注入(SQL Injection)本质上是:
用户输入的数据,被拼接进SQL语句中执行。
例如:
$id = $_GET@['id']; $sql = "SELECT * FROM ay_content WHERE id=$id";
正常访问:
?id=1
生成SQL:
SELECT * FROM ay_content WHERE id=1
但如果攻击者输入:
?id=1 OR 1=1
SQL就变成:
SELECT * FROM ay_content WHERE id=1 OR 1=1
结果:
整个数据表被读取。
这就是最基础的注入。
二、PbootCMS为什么容易出现注入问题?
很多并不是官方核心漏洞。
真正危险的,往往是:
模板二开
插件开发
表单功能
搜索接口
自定义API
AJAX接口
标签解析扩展
尤其很多开发者习惯:
$db->query("SELECT * FROM xxx WHERE id=".$_GET@['id']);没有参数绑定。
没有类型限制。
没有白名单。
这就给了攻击者机会。
三、一次真实的PbootCMS注入复现
下面模拟一个常见漏洞场景。
四、漏洞环境搭建
假设存在一个文章详情页:
/apps/home/controller/IndexController.php
代码:
public function detail()
{
$id = get('id');
$sql = "SELECT * FROM ay_content WHERE id=$id";
$data = Db::getInstance()->query($sql);
return json_encode($data);
}访问:
/article?id=1
一切正常。
五、开始测试注入
攻击者第一步:
测试单引号。
/article?id=1'
如果页面报错:
SQL syntax error
说明:
数据库语句被拼接了。
此时基本已经确认存在注入。
六、进一步判断数据库类型
攻击者继续:
?id=1 order by 5
观察是否报错。
如果:
?id=1 order by 100
报错:
说明字段数量不足。
于是攻击者可以确定:
查询字段数。
七、UNION联合查询攻击
继续:
?id=-1 union select 1,2,3,4
如果页面出现:
2 3
说明:
联合查询成功。
数据库已经被读取。
八、读取后台账号密码
进一步:
?id=-1 union select username,password,3,4 from ay_user
如果数据库未做限制:
后台管理员账号密码就会直接泄露。
很多站长以为:
“密码不是MD5加密吗?”
问题是:
大量弱密码依然存在。
例如:
admin 123456 pbootcms admin888
彩虹表几分钟就能撞出来。
九、为什么WAF没有拦住?
这是很多人最疑惑的问题。
原因其实很现实:
1、WAF只拦截“明显特征”
很多防火墙规则:
union select or 1=1 sleep( benchmark(
但攻击者会绕过。
例如:
/*!union*/ /*!select*/
或者:
uNiOn SeLeCt
甚至:
%55nion%20select
URL编码后:
部分WAF根本识别不到。
2、HTTP参数污染
例如:
?id=1&id=2 union select
某些PHP环境:
只读取最后一个参数。
但WAF检测的是第一个。
于是成功绕过。
3、宽字节绕过
部分老旧环境:
%df'
会导致转义失效。
尤其:
GBK编码
老版本MySQL
addslashes过滤
最容易中招。
4、二次注入
更危险的一种。
第一次:
恶意数据被写入数据库。
第二次:
后台读取数据时执行SQL。
很多管理员后台:
搜索日志
用户管理
留言系统
都会触发。
这也是很多PbootCMS插件翻车原因。
十、真正危险的不是“注入”,而是后续利用
很多人以为:
数据库泄露就结束了。
实际上真正危险的是:
1、写入管理员账号
攻击者可以:
insert into ay_user
直接创建后台。
2、写入恶意模板
如果数据库支持文件写入:
into outfile
甚至能直接写WebShell。
3、拖库
包括:
用户手机号
邮箱
密码
留言数据
订单数据
全部泄露。
4、挂黑链
最常见。
数据库批量插入:
<a href='博彩站'>
搜索引擎收录后:
网站彻底废掉。
十一、如何判断自己的网站是否正在被注入?
重点看日志。
Apache日志
路径:
/www/wwwlogs/
搜索:
union sleep benchmark updatexml extractvalue
例如:
grep -Ri "union select" ./
Nginx日志
重点关注:
$request_uri
是否存在:
%27 %22 %20union
MySQL慢查询日志
如果频繁出现:
sleep(5) benchmark()
说明:
有人在盲注测试。
十二、PbootCMS安全加固方案
下面才是真正重要的部分。
十三、参数必须强制类型化
不要:
$id = $_GET@['id'];
应该:
$id = intval($_GET@['id']);
这样:
1 union select
会直接变成:
1
十四、使用参数绑定
错误写法:
$sql = "SELECT * FROM ay_content WHERE id=$id";
正确写法:
$db->prepare("SELECT * FROM ay_content WHERE id=?");这是根本解决方案。
十五、关闭危险数据库权限
数据库账号不要给:
FILE SUPER DROP
权限。
否则:
数据库被注入后直接写马。
十六、限制错误输出
不要显示:
SQL syntax error
否则攻击者会疯狂试探。
生产环境:
display_errors = Off
十七、部署高质量WAF
很多便宜防火墙:
其实只是关键词过滤。
真正有效的是:
行为分析
参数学习
SQL语义识别
否则:
绕过非常容易。
十八、定期审计二开代码
重点排查:
query( execute( $_GET $_POST
尤其:
字符串拼接SQL。
这是事故高发区。
十九、一次注入可能毁掉整个站
很多站长有个误区:
“我网站没什么价值。”
但攻击者并不在乎你网站内容。
他们要的是:
SEO权重
黑链跳转
挂博彩
跳转菠菜
采集蜘蛛流量
服务器权限
甚至只是:
肉鸡资源。
所以很多小站反而更容易成为目标。
经验分享
PbootCMS本身并不是“天然不安全”。
真正的问题通常来自:
不规范二开
参数未过滤
SQL直接拼接
插件安全意识不足
后台权限过大
SQL注入最可怕的地方,不是“报错”。
而是:
你以为系统没事,但数据库已经被悄悄穿透。
很多网站直到:
搜索引擎出现博彩词
百度飘红
后台被锁
服务器CPU爆满
才发现已经被攻击数周。
所以真正应该做的,不是“出了问题再修”。
而是:
在开发阶段就彻底堵住注入入口。