老张开了一家小网店,后台用的是自己写的PHP登录页。有天他发现订单数据莫名其妙被删了,查日志才发现——有人在用户名框里输了一串奇怪的字符:' OR '1'='1,结果直接绕过了密码验证。这不是玄学,是典型的SQL注入。
啥是SQL注入?
简单说,就是网站没把用户输入当“人话”看,而是原封不动拼进SQL语句里执行。比如这句登录查询:
SELECT * FROM users WHERE username = '<用户输的内容>' AND password = '<用户输的密码>';如果用户填用户名为 admin' -- ,密码随便输,拼出来就变成:
SELECT * FROM users WHERE username = 'admin' -- ' AND password = 'xxx';后面那句密码校验被--注释掉了,数据库只认前半截,只要admin存在,就直接放行。
怎么测?别瞎试,用Burp Suite搭个“显微镜”
装好Burp Suite(社区版免费),浏览器配好代理,访问你自己的测试环境(千万别扫正式站!)。比如点登录,抓到POST包,右键“Send to Repeater”。
在username字段里依次试试这些payload:
'
' OR 1=1--
' UNION SELECT 1,2,3--
' AND SLEEP(3)-- 发出去后盯住Response时间和返回内容。如果返回页面突然变长、多出数据库字段、或者响应慢了3秒——八成有戏。
实战小技巧
遇到过滤单引号?试试双写:'' 或用URL编码%27;报错不明显?加个AND 1=CONVERT(int,(SELECT @@version)),SQL Server会直接吐版本号;MySQL可以试AND EXTRACTVALUE(1, CONCAT('/', (SELECT database()))),错误信息里就带库名。
提醒一句:所有测试必须在你有明确授权的系统上做。拿别人网站练手,轻则警告,重则吃官司。自己写的后台?赶紧翻出代码,检查所有拼SQL的地方——换成PDO预处理或MyBatis的#{}语法,别用${}。
某次修完一个电商后台的注入点,老板问“真能防住?”我让他现场输' OR 'a'='a,登录框弹出“非法字符”,他当场笑了。