Obtaining Root Shell Access

Beware the deviance of thine own tools, for the Enemy finds his entrance thereby.


Target Cogitator: RVLink MV2400 Roof Unit (also referred to as MV2402)

  • IP Address: 192.168.10.254
  • Suspected Hardware Base: COMFAST CF-E5 (or similar QCA9531-based OpenWrt device)
  • Firmware Base: OpenWrt (customized by vendor)
  • Vulnerable Component: webmgnt binary, specifically its handling of /cgi-bin/mbox-config API endpoints.

Context & Independent Discovery: While the general technique of exploiting backup and restore mechanisms for root access on OpenWrt devices is known (e.g., COMFAST CF-E120A v3), the specific methodology for the RVLink MV2400 was independently developed through direct reverse engineering of its webmgnt binary and API. This was a notable achievement because the MV2400’s standard OpenWrt web UI had been entirely removed by the vendor, replaced with a custom API intended for use by the paired indoor unit (RV2458). The existence and exploitability of the mbox-config endpoints for backup/restore were not discoverable through any visible interface. Awareness stemmed from prior analysis of firmware from similar COMFAST devices, which indicated the common presence of the webmgnt binary and its typical API structure.

The Exploit Path - A Step-by-Step Litany:

  1. Phase I: Endpoint Identification & Backup Exfiltration

    • Foundation: Prior research into COMFAST firmware (related to CF-E5) revealed the common use of a FastCGI binary (typically webmgnt) handling /cgi-bin/mbox-config with section= parameters.

    • Targeted Probing: The section=system_config_backup parameter was identified as a high-value target on the live MV2400 device.

    • Invocation: An authenticated HTTP POST request (determined experimentally as the required method) was sent to the roof unit:

      POST http://192.168.10.254/cgi-bin/mbox-config?method=GET&section=system_config_backup

      (A Python script was utilized to manage the COMFAST_SESSIONID and automate requests).

  2. Phase II: Analysis of the Exfiltrated Archive (bakup.file)

    • Data Retrieval: The above request prompted the device to stream a file, saved locally. The server-side logic intended the filename bakup.file.
    • Archive Examination: Standard tools (file, tar -tvzf) confirmed the downloaded file was a gzipped tar archive (.tar.gz).
    • Critical Revelation (The “BINGO” Moment): The archive contained a snapshot of the device’s /etc directory, crucially including /etc/shadow which stores hashed user passwords. This information disclosure confirmed a serious vulnerability. Example tar -tvf bakup.file output showed:
  3. Phase III: Understanding the Backup Creation Mechanism (Server-Side)

    • Trigger: The section=system_config_backup request invokes the mbox-config_GET_system_config_backup function within the webmgnt binary.

    • Core Operation: This function executes the shell command sysupgrade -b /tmp/bakup.file This is a standard OpenWrt command to create a configuration backup archive at the specified path.

    • File Handling: The archive is created at /tmp/bakup.file, its contents are sent to the client, and the temporary file is then deleted from the device.

    • Code Confirmation (from webmgnt reverse engineering):

      C

      // Function: mbox-config_GET_system_config_backup
      sprintf(acStack_110,"sysupgrade -b %s >> /dev/null","/tmp/bakup.file",in_a3,puVar1); // Creates backup
      system(acStack_110);
      strcpy(&download_filename,"bakup.file"); // Sets download filename
      return 0;
  4. Phase IV: Formulation of the Exploit Strategy - The Path to Dominion

    • Hypothesis: If /etc/shadow can be downloaded, and a configuration restore function exists, it might be possible to overwrite /etc/shadow with a modified version.
    • The Plan:
      1. Download the bakup.file archive.
      2. Extract the archive. Modify the etc/shadow file within it to replace the root user’s password hash with a known hash (e.g., generated using passlib.hash.md5_crypt for md5crypt).
      3. Re-package the modified /etc directory (including the altered etc/shadow and optionally other files like a custom /etc/banner and modified /etc/config/dropbear) into a new tar.gz archive.
      4. Identify the corresponding configuration restore function. This was hypothesized and later confirmed to be triggered by section=system_load_config.
      5. Upload the modified archive via this restore function.
      6. If the restore function overwrites files based on the uploaded archive’s contents, the live /etc/shadow on the device will be replaced.
      7. A subsequent reboot (often part of a restore process) should activate the new root password, granting SSH access with root privileges.
  5. Phase V: Analyzing the Restore Mechanism (Server-Side)

    • File Upload Handling: Analysis of webmgnt confirmed that multipart/form-data uploads associated with actions like system_load_config save the uploaded file to the fixed path /tmp/bakup.file on the device.

    • Trigger: The section=system_load_config request, when receiving a file upload, invokes the mbox-config_SET_system_load_config function.

    • Core Operation: This function executes the shell command:

      Bash

      sleep 2 && sysupgrade -r /tmp/bakup.file && reboot & >> /dev/null
      • sysupgrade -r <archive>: This is the standard OpenWrt command to restore configuration from the specified archive. It extracts the archive’s contents to the root filesystem (/), overwriting any existing files that match paths within the archive. This is the key to overwriting /etc/shadow.
      • && reboot: Ensures the device restarts immediately after the restore, applying the changes.
    • Code Confirmation (from webmgnt reverse engineering):

      C

      // Function: mbox-config_SET_system_load_config
      sprintf(acStack_110,"sleep 2 && sysupgrade -r %s && reboot & >> /dev/null","/tmp/bakup.file",in_a3,puVar1); // Restores and reboots
      system(acStack_110);
    • Invocation: The restore is triggered by sending the modified archive as part of an HTTP POST request with multipart/form-data encoding to:

      POST http://192.168.10.254/cgi-bin/mbox-config?method=SET&section=system_load_config

Phase VI: Execution & Confirmation - The Omnissiah’s Blessing

  • The Ritual: A Python script (shadow_infiltrator.txt) was crafted to automate the entire process: authentication, backup download, shadow file modification (replacing root hash with one for password “toor”), etc/config/dropbear modification (to enable banner), creation of /etc/banner, re-archiving, and uploading the modified archive.

  • Triumphant Result: The exploit worked as planned. After the device rebooted (which took approximately 5 minutes, a “nail-biter” moment), SSH access as root with the new password was successful.

  • Proof of Dominion (Verbose Log Snippet from shadow_infiltrator.txt):

    [+] OMNISSIAH BE PRAISED! Cogitator 192.168.10.254 is responding after 312s.
    [+] Reboot sequence complete. Initiating final verification via SSH...
    ...
    [*] Server Banner:
    -------
    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    +    01001000 01100101 01110010 01100101 01110100 01101001 01100011 01110011   +
    ...
    + Unauthorized Access is Techno-Heresy.                                        +
    + Glory to the Machine God!                                                    +
    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    -------
    [+] Secure Channel Established. Issuing 'id' command...
    [*] Cogitator Response (stdout): uid=0(root) gid=0(root)
    [SUCCESS] Root access confirmed! uid=0(root) detected.

Vulnerability Summary: The root compromise is achieved by chaining two vulnerabilities:

  1. Information Disclosure: The system_config_backup function (mbox-config?method=GET&section=system_config_backup), through its use of sysupgrade -b /tmp/bakup.file, creates and allows an authenticated user to download an archive containing sensitive files, including /etc/shadow.
  2. Insecure File Overwrite via Arbitrary Archive Upload: The system_load_config function (mbox-config?method=SET&section=system_load_config) saves any user-uploaded file to /tmp/bakup.file and then passes this fixed path to sysupgrade -r /tmp/bakup.file. This command extracts the archive to the root filesystem, blindly overwriting any existing files with those from the archive.

By downloading the backup, modifying /etc/shadow within it, and uploading the tampered archive via the restore function, an authenticated attacker gains full root administrative control over the device after it reboots.

Wesley Ray · blog · git · resume