SQL注入手工测试,自查CMS网站漏洞
SQL注入是CMS网站最常见的漏洞之一,手工测试能帮你绕过工具误报,精准定位风险点。
本文面向零基础用户,用可复现的步骤教你判断注入点、手工验证漏洞,并给出修复方向。
测试前需要准备什么
动手前先确保你有合法授权,只测试自己的网站或已获得书面许可的目标。
准备一个本地或测试环境的CMS站点,推荐用宝塔面板快速搭建PHP+MySQL环境。
安装好靶场或自己的CMS后,打开浏览器和命令行工具。
需要用到:
- 浏览器:Chrome或Firefox,用于观察页面变化
- 命令行:
curl或sqlmap(可选,用于辅助验证) - 数据库客户端:如
mysql命令行或phpMyAdmin,用于查看数据 - 一个参数可传递的URL,例如
http://test.com/news.php?id=1
手工判断注入点
第一步是找到可能与数据库交互的参数。
常见位置包括:id=、page=、category=、search=等。
在URL后添加单引号',观察页面是否报错或内容异常。
例如原URL:
http://test.com/news.php?id=1
改为:
http://test.com/news.php?id=1'
如果页面返回MySQL错误,如You have an error in your SQL syntax,说明可能存在注入。
如果页面正常但内容变化,也需要进一步测试。
注意:不是所有报错都代表注入,有些CMS会屏蔽错误显示。
此时可以尝试and 1=1和and 1=2对比:
http://test.com/news.php?id=1 and 1=1
http://test.com/news.php?id=1 and 1=2
如果前者正常、后者异常,说明注入点存在。
手工验证注入类型
确认注入点后,需要判断是数字型还是字符型。
数字型通常不需要引号闭合,字符型需要。
测试方法:
- 数字型:
id=1 and 1=1正常,id=1 and 1=2异常 - 字符型:
id=1' and '1'='1正常,id=1' and '1'='2异常
进一步可以尝试联合查询获取数据。
假设字段数为3,构造:
http://test.com/news.php?id=1 union select 1,2,3
观察页面回显位置,替换为database()、user()等函数获取信息。
如果回显被过滤,可以尝试报错注入或盲注。
重要结论:手工测试的核心是观察输入与输出的因果关系,任何异常变化都值得记录。
使用sqlmap辅助验证
手工确认后,可以用sqlmap自动化验证,但不要依赖它替代手工判断。
基本命令:
sqlmap -u "http://test.com/news.php?id=1" --batch
如果存在注入,sqlmap会给出类型和Payload。
常用参数:
--dbs:列出数据库--current-db:当前数据库--tables:列出表--dump:导出数据
注意:sqlmap可能产生大量请求,建议在测试环境使用,并控制线程数--threads=1。
常见避坑与修复建议
避坑指南:
- 不要在生产环境直接测试,避免影响业务
- 不要使用
or 1=1这类可能删除数据的Payload - 遇到WAF拦截时,尝试编码绕过或调整参数,但需谨慎
- 测试后及时清理测试数据,避免留下痕迹
修复建议:
- 使用预处理语句(PDO或mysqli)代替拼接SQL
- 对输入参数进行类型转换,如
intval($_GET['id']) - 开启CMS官方安全更新,及时打补丁
- 部署WAF并定期扫描
如何验证修复效果
修复后重复之前的测试步骤,确认单引号和逻辑判断不再引起异常。
使用sqlmap重新扫描,应返回“not injectable”。
同时检查服务器日志,确认没有异常SQL语句。
可独立摘录的结论:手工测试能发现工具忽略的逻辑漏洞;
修复后必须重新验证,不能假设已安全。
常见疑问
测试时页面没有报错,是否代表没有注入?
不一定。有些CMS关闭了错误显示,需要盲注或时间盲注测试,例如and sleep(5)观察响应延迟。
sqlmap扫描结果准确吗?
sqlmap可能误报,尤其是对布尔盲注。建议结合手工验证,确认Payload确实影响数据库。
测试会不会导致数据泄露?
如果使用union select获取数据,可能读取敏感信息。务必在授权环境测试,并避免导出真实用户数据。
修复后还需要做什么?
建议定期更新CMS和插件,使用最小权限数据库账户,并开启日志审计。