T2: Yin and Yang

Penguin Zero, the tech genius of the Frostlings Five infiltrated the company’s network. With a few keystrokes and a sly grin, he uploaded a malicious script into YIN and YANG, seizing control.

The following post by 0xb0b is licensed under CC BY 4.0


L2 Keycard

We find the keycard for the second Side Quest hidden in the task of the fifth day of the TryHackMe Advent Of Cyber. The following task, it gives us a hint to test for other services running on the target machine: Following McSkidy's advice, Software recently hardened the server. It used to have many unneeded open ports, but not anymore. Not that this matters in any way.

Day 5: SOC-mas XX-what-ee?

We continue to test the web application with the available XXE.

We try to include files that give us information about other services that may be running.

The /etc/apache2/sites-enabled/000-default.conf file contains the default configuration for the Apache web server's virtual host. It typically specifies the document root, logging paths, and any default behavior. By inspecting it, it can reveal references to other services or applications hosted on the server. Unfortunately, we cannot include it directly, because it fails to parse XML since the file itself contains XML data.

A workaround is to use PHP filters to encode the data. With that, we are able to retrieve the information hidden in /etc/apache2/sites-enabled/000-default.conf.

After we have decoded the content we see that another service is running on port 8080 on local host. With a very suspicious root directory /var/www/ssfr. We also see that the access.log and error.log are in the web root directory. So we might leverage the XXE to an Server Side Request Forgery SSRF.

We first try to make a request to the index page of the web service on port 8080 running locally. To do that, we reuse the payload using PHP filters.

The page links to access.log.

We now query the access.log page...

And see that the following image /k3yZZZZZZZZZ/t2_sm1L3_4nD_w4v3_boyS.png was being requested.

We can then request this on the exposed web server and find the keycard.

Teardown Firewall

The first thing we have to do is shut down the firewall. We can find the page for this on port 21337.

In this challenge, we operate with two machines, Yin and Yang. The room to the Yang machine is linked separately, but this also requires the Firewall to be shut down.

We visit the web pages to unlock the firewall...

... and enter the keycard key for each machine.

SSH Into The Machines

Since the ports are now open, we can SSH into the yin and...

... yang machine.

Recon

On yin, we can see that we are allowed to run /catkin_ws/yin.sh as root using sudo.

The same goes for yang. Here we are allowed to run /catkin_ws/yang.sh. Inspecting the script, we can see it is running rosrun on runyang.py. The rosrun command is part of ROS, the Robot Operating System. The rosrun command allows running an executable in an arbitrary package.

We give it a try and run yin.sh. But it could not register to the master node on http://localhost:11311. The ROS server is not running locally. We get now a glimpse of why we have two machines to compromise. On each of them, it might have to run the ROS server to get the command executed. But first, let's inspect what is actually running.

Let's inspect the node scripts that are available.

The class Yin, is a ROS (Robot Operating System) node that communicates with a communication system and uses message signing and verification features. The node uses the Comms message type to publish messages to a topic named messagebus.

To sign messages, the class retrieves a private RSA key from a file called privatekey.pem.

To carry out commands given with a secret key for verification, the node provides a service svc_yang.

Using the private RSA key, the script generates messages that contain a timestamp, sender, receiver, action, and feedback. It then sends these messages to the messagebus for signing.

The node periodically sends a "ping" message to a receiver yang with a simple shell command touch /home/yang/yin.txt.

The script on yang is another ROS node that uses secure message handling, command execution, and message signing to communicate with a communication system. If orders are verified, it carries them out and subscribes to messages on the messagebus subject.

It reads a private RSA key for message signing from a file privatekey.pem, just like the last script did.

The node receives inbound messages meant for yang and subscribes to the messagebus topic.

It uses os.system to carry out the commands entered in the message's actionparams field following message validation.

The node requests an action from "Yin" by calling a service svc_yang after completing the action. The command is executed, and a reply message is created, signed, and then published back to the messagebus subject.

Exploit Yang

In the script of yin, we can see a ping is crafted; the script can only be run by root, since the private key used has only read permission for root. So we cannot just change the script to create other files than that in the ping request.

But in the script of yang, we can see that the script is making a callback with the contents of the private key.

The idea is now to run a ROS master on yin, get the communication of both started, and inspect the messagebus topic on yang server to inspect the private key sent in the callback.

With that retrieved private key, we can then can craft our own script that, instead of doing a ping, crafts us a SUID bit /bin/bash binary.

So we are now on yin:

Retreive The Private Key

We run roscore to set up the server and start the yin script.

Next, we need to make the yin master available for yang. To do this, we use port forwarding via SSH. We log in to yang and forward 11311 of yin to yang.

Now we are able to run /catkin_ws/yang.sh on yang and see the handler validate the messages.

On yang, we can now see the messages sent on the topic via rostopic echo /messagebus and see the RSA Private Key transmitted. This is the callback we are inspecting right now.

Exploiting ROS Communication With Yin's Private Key

We copy the src of /catkin_ws/src/ into /home/yin/yin.

There we create a suid.py, which is essentially a copy of /catkin_ws/src/yin/scripts/runyin.py with minor changes.

This uses the retrieved private key we placed in /home/yin/yin/privatekey.pem and instead of just creating an empty file, we now create a SUID bit binary with cp /bin/sh /home/yang/sh && chmod u+s /home/yang/sh.

Now we run the ROS master on yang. The instance on yin has to be terminated.

We run the /catkin_ws/yang.sh script on yang.

And make the server available on yin using port forwarding via SSH.

We save the private key formerly retrieved at /home/yin/yin/privatekey.pem.

And now run our suid.py. Which does not require root permission, since we are now in possession of the private key.

On yang, we can see that the SUID bit binary sh is created. We can now read the /root/yang.txt file, which contains the flag for yang.

We are now also able to read the secret used by yang. So we could potentially craft messages as yang for the svc_yang handler.

Exploit Yin

Instead of crafting a script like before, we could do it more easily, since we are in possession of the secret of yang. With that secret, we can impersonate the yang machine and craft messages as they were sent from yang. We just need to know how to call the services properly. For this, we find the following wiki entry:

We can call the service by the following:

From the following snippet, we can see that there is a yang service served. Which triggers the handle_yang_request, allowing to run system commands via os.system(action).

After running roscore on yang, forwarding the port of the master on yin via ssh -L 11311:localhost:11311 yang@yang_ip, and executing each sudo /catkin_ws/yin.sh and sudo /catkin_ws/yang.sh on the respecting machine, we have the following services available:

Among them is the svc_yang, which allows us to execute commands.

We inspect the svc_yang service to see what parameters are required.

How the arguments have to be supplied can be seen here:

On yin we can now make a service call impersonating yang, that creates us an SUID bit binary sh, with that we can get a root shell and find the yin flag in /root/yin.txt.

Last updated

Was this helpful?