CVE-2024-39930 漏洞分析
字数 1577 2025-09-01 11:26:11
Gogs 0.13.0 SSH 参数注入漏洞(CVE-2024-39930)分析与利用
漏洞概述
Gogs(Go Git Service)是一个基于Go语言的自助Git托管服务。在0.13.0版本中,其内置SSH服务器存在参数注入漏洞,允许攻击者通过精心构造的环境变量实现远程代码执行(RCE)。
漏洞背景
受影响组件
- 软件: Gogs
- 版本: 0.13.0
- 组件:
internal/ssh/ssh.go中的SSH请求处理代码
漏洞原理
漏洞源于Gogs在处理SSH连接中的env请求时,未对传入的环境变量进行充分验证,导致攻击者可以通过环境变量注入env命令的参数,最终实现任意命令执行。
技术细节分析
SSH协议中的env请求
SSH协议允许客户端在"打开通道之后,执行命令之前"通过env请求向服务器发送环境变量设置。当使用ssh命令连接时,可以通过SendEnv指令指定要发送的环境变量。
漏洞代码分析
关键漏洞代码位于internal/ssh/ssh.go中:
com.ExecCmd("env", fmt.Sprintf("%s=%s", env.Name, env.Value))
这段代码将环境变量名和值通过fmt.Sprintf拼接到env命令后面,然后通过com.ExecCmd()执行。
漏洞利用关键点
-
env命令的-S参数:
env命令有一个-S, --split-string=S参数,可以将带空格的字符串拆分为命令及其参数来执行- 例如:
env --split-string="cat /etc/passwd"实际执行的是cat /etc/passwd
- 例如:
-
参数注入:如果构造一个名为
--split-string=<command>的环境变量,拼接后执行的命令将变为:env --split-string=<command>这将导致
<command>被执行 -
环境变量命名限制:Linux中环境变量名不能包含特殊字符如
-,这是利用的主要障碍
漏洞复现步骤
环境准备
-
系统要求:
- Go版本: 1.22.5
- Gogs版本: 0.13.0
- PostgreSQL数据库(默认创建postgres用户)
-
Gogs安装:
- 安装并配置Gogs
- 确保SSH服务开启
- 修改
internal/ssh/ssh.go添加日志打印 - 修改
custom/conf/app.ini将日志级别设置为Trace
攻击步骤
-
设置恶意环境变量:
- 使用Go代码设置包含
-的环境变量:os.Setenv("--split-string", "cat /etc/passwd")
- 使用Go代码设置包含
-
修改SSH配置:
- 修改攻击者本机的
/etc/ssh/ssh_config中SendEnv的值,允许发送该环境变量
- 修改攻击者本机的
-
触发漏洞:
- 注册Gogs用户并添加SSH公钥
- 新建一个仓库
- 通过SSH执行
git clone操作
-
查看结果:
- 在Gogs日志中可以看到payload成功传入
- 修改源码打印命令执行结果后,可以看到
cat /etc/passwd的输出
漏洞利用限制与绕过
主要限制
- Linux环境变量命名规则限制:不能包含
-等特殊字符
绕过方法
-
使用编程语言设置环境变量:
- 通过Go的
os.Setenv()可以设置包含-的环境变量 - C语言的
setenv()函数在此场景下测试不成功
- 通过Go的
-
利用SSH配置:
- 修改
SendEnv配置允许发送非常规环境变量名
- 修改
防御建议
- 升级版本:升级到Gogs修复版本
- 输入验证:
- 严格验证SSH连接中传入的环境变量名
- 禁止环境变量名包含特殊字符
- 命令执行安全:
- 避免直接拼接命令参数
- 使用白名单限制可执行命令
- 日志监控:监控异常的环境变量设置请求
总结
CVE-2024-39930漏洞展示了参数注入如何导致严重的远程代码执行问题。通过精心构造的环境变量名,攻击者可以绕过常规限制,注入恶意命令参数。这提醒开发者在处理外部输入时,必须进行严格的验证和过滤,特别是当这些输入最终会用于系统命令执行时。