数据库调用型后门通过合法数据库函数(如mysqli_query、pdo::query)动态拼接恶意sql,规避eval/system检测;重点排查未过滤的$_get/$_post参数直拼sql、解码函数结果入查询、非常规字段名及无预处理的字符串拼接。

PHP文件中隐藏的数据库调用型后门怎么识别
数据库调用型后门不直接执行system或eval,而是借合法数据库操作(如mysqli_query、PDO::query)动态拼接并执行恶意SQL,因此常规关键字扫描容易漏掉。
重点排查以下模式:
- 所有接收
$_GET、$_POST、$_COOKIE参数后,未经过滤直接拼入SQL语句的位置,尤其是WHERE、ORDER BY、LIMIT等上下文 - SQL字符串中出现
base64_decode、urldecode、hex2bin等解码函数调用,且解码结果直接进mysqli_query - 存在类似
$sql = "SELECT * FROM users WHERE id = " . $_GET['id'];这种未类型转换、未预处理的拼接 - 查询语句中包含明显非常规字段名,如
cmd、act、z0、_p等,且该字段在正常业务表结构中不存在
如何快速定位可疑数据库操作点
不要靠肉眼扫全站代码。优先用命令行工具精准过滤:
grep -r "\.query\|->query\|mysqli_query\|pdo::query" --include="*.php" /var/www/html/ | grep -E "(\$_GET|\$_POST|\$_REQUEST|\$_COOKIE)"
再对结果逐条检查是否做参数绑定或白名单校验。特别注意那些被封装在“通用查询函数”里的调用,比如db_query($sql)——要顺藤摸到$sql的源头。
立即学习“PHP免费学习笔记(深入)”;
常见陷阱:
- 开发者自写
safe_sql()函数,但内部只是addslashes(),无法防住宽字节或ORDER BY注入 - 使用
intval()转ID却没判断返回值是否为0,导致id=abc变成id=0仍能绕过逻辑 - SQL里用
UNION SELECT加载远程payload,日志里只显示“查询成功”,无报错也不留痕迹
删除后门时最容易忽略的三个位置
很多清理只删了主入口文件,但后门常藏在更隐蔽的地方:
-
/wp-content/plugins/xxx/cache/这类缓存目录下,有伪装成index.php或.jpg.php的文件,内容是mysqli_query($_POST['q']) - 数据库本身被植入持久化后门:检查
mysql.user表是否有异常账号;检查mysql.func是否注册了自定义函数;执行SHOW EVENTS看是否存在定时反弹任务 - Web服务器配置级后门:Apache的
.htaccess里加AddType application/x-httpd-php .jpg,配合上传的shell.jpg实现绕过
务必确认php.ini中disable_functions未被篡改(比如移除了exec但保留了mail,后者仍可调用sendmail执行命令)。
验证是否真正清干净的关键动作
删完不能只测“网站还能不能打开”。必须做三件事:
- 重放所有曾被利用的请求路径(如
?id=1 AND 1=2 UNION SELECT 1,2,3),确认返回500或空数据,而非回显数据库结构 - 开启MySQL通用日志(
general_log = ON),跑一遍业务流程,人工检查日志里有没有异常SQL模板(如含base64_decode或LOAD_FILE) - 对比清理前后
ls -laR输出,确认没有新增或时间戳异常的.php、.inc、.phar文件,尤其关注tmp、cache、uploads目录
数据库调用型后门最难的是“它看起来就是业务代码的一部分”。你得清楚自己哪一行SQL本不该接受用户输入,而不是只盯着有没有eval。











