Hello, again. I apologize for taking so long to finish up the Wintermute project. I completed Neuromancer a few months ago, but I haven’t been able to sit down and write up my solution. I really appreciated this set of vulnerable machines because each of them forced me to use tools that I’ve used regularly in a different way. So, I’d like to thank [creosote] again for creating them and https://vulnhub.com for making them available to everyone. Ok, let’s get going.
In my previous post, https://cipherhound.com/blog/wintermute-straylight/, I gained access to Straylight and escalated my privileges to root using a vulnerability in the screen-4.5.0 program. Once I was established, I began looking for information that would grant me access to Neuromancer. An engineering team created a java tool for authorized parties on it. Thanks to the Ntop tool on port 3000 of Straylight, I know the address range of the internal network. All I need to do is find Neuromancer on that network. I transferred a ping sweep script from my attacker machine to Straylight. It tells me which devices respond to a ping from Straylight on the internal network.
Looking at the screenshot, we can see that the first argument is the interface of the internal network on the Straylight machine, the second argument is the network id of the internal network, and the third argument is the range of hosts that I would like my tool to scan ( starting at one ). The tool justs parses the response received from each host and looks for “64 bytes”. As we can see, there are four hosts responding to a ping on the internal network. Now, we can enumerate these targets and look for open ports that match the note found in Straylight.
Unfortunately, Straylight does not have the Nmap package; however, it does have the netcat package. Netcat can be used as a port scanner to identify open ports on a host. So, I began with the first target identified by the ping sweep of the internal network: 192.168.100.4 .
In the first screenshot, I loop through port numbers 1-65534 using netcat. The -z flag is zero input/output mode used for scanning and the -w flag is the timeout for connections. To keep the chattiness of the tool low and my shell clean, I pipe the output and errors into /dev/null. If netcat returns a zero for an open port, my loop will echo the port number into a text file that I can read later. As we can see in the second screenshot, this host has 3 ports open. Since, I see the alternate web port open on this host, I decide to match the information from the root note on Straylight with it.
As we can see from the screenshot, this host seems like a good match for the one described in the Straylight note. On a side note, the 34483 port is actually a secure shell server which may be useful later. However, I still couldn’t see Neuromancer from my Straylight. Using root on Straylight, I could use the secure shell package to tunnel the ports that Straylight could see on Neuromancer directly to local ports on my attacker machine. I opened the port to the secure shell server on my attacker machine and allowed access through my firewall. Now, I only need to move the authorized key from my attacker machine to Straylight, create a script to reliably forward the necessary ports, and move the script over with the key.
Netcat also allows you to transfer files from one machine to another machine. Similar to redirecting the output of a command into a text file, it is possible to redirect the output of a file into a connection made by netcat. In the first screenshot, the red box at the top contains all of the connections made from Straylight to my attacker machine. The cyan boxes inside of the red box show that the redirected files from my attacker machine are being moved into the /root directory of Straylight. The cyan box at the bottom shows the listening port on my attacker machine. The second screenshot shows the connect bash script used to forward the ports to my attacker machine. The ssh_key variable refers to the authorized key file previously sent to Straylight. The ssh_port variable refers to the open port on my attacker machine. The bind_port variable is a port I opened on the Straylight machine that will grant me a root shell on Straylight if the webshell should fail for any reason. The neuro variable is the ip address of Neuromancer. The attacker variable refers to my machine. Finally, the result variable acts as a log file for the script. Secure shell is a tool used to remotely manage a computer. It will grant authorized users encrypted access to the shell. However, the tool can also create encrypted tunnels between two computers by allocating a socket to listen for connections and forwarding those connections to the designated host and port. If we look at the ssh commands in the second screenshot, the -i flag is used to designate a key file used for authentication on the remote server, the -p flag is used to specify a port other than the standard port for secure shell (22), the -N flag is used to tell the ssh program not to connect to the designated remote server, and the -R flag is used to allocate a port on my attacker machine ( 4444 and 4445, respectively ) that will listen for connections and forward them to Neuromancer which is visible to the ssh client from which I’m making the connection. Finally I make the connection to the server on my attacker machine and, if the procedure is successful, log the results. At the end of the script, I open the bind shell on Straylight. Now, all we need to do is run the script and test the connections.
In the first screenshot, the red box shows the result of the connect script run on Straylight. According to the script, the process was successful. The cyan box shows the locally allocated ports on my attacker machine. The second screenshot shows that the process was actually successful. The remote ports for the tomcat and secure shell servers on Neuromancer are visible to my attacker machine. Now we can test the vulnerability of the java web tool on Neuromancer. If we look at the second screenshot more closely, we can see a navigation link for an interactive demo. That link directs us to a demo that will execute supplied java code on Neuromancer.
If we can execute our own java code on Neuromancer, then we already have a foothold.
The first screenshot shows the test for executing java on Neuromancer. The brackets (<% %>) are required to use java inside of the page. First, we import all of the classes inside from java.io. This is necessary to perform input/output operations on streams of data. Two variables are declared as blank strings; they are the command to be run and the output that command will generate. If the command isn’t null, the code declares a null string. Following this declaration, we try to initiate a subrocess returned by the getRuntime method of the Runtime class. This class is available to any java application and allows the application to interact with the environment in which it is running. We return the input stream of the subprocess wrapped by instances of the InputStreamReader and BufferedReader classes to read character streams. We’ll read from that stream until it returns null which signifies the end of the stream. Finally, we print the output. As we can see from the second screenshot, we can run linux commands on Neuromancer and we have information about the kernel that can be used later. Keeping the secure shell port on Neuromancer in mind, I begin looking for ways to leverage it. I’ll need a valid user on the machine.
We can see that the ta user is a valid user on the machine with access to a bash shell. At this point, I assume that I am running as the web user and I try to confirm that assumption. However the java application is running as the ta user, which provides a way to leverage the secure shell server and a potential shell on the system.
Using this new information, I know that I can leverage the public key of my attacker in an authorized_keys file in the ta user’s .ssh default directory. I discover that the user does not currently have a .ssh directory. In the above screenshots, I attempt to create that directory, verify that it has been created, and verify that it is owned by the ta user. Now, I only need to get an authorized_keys file with my attacker’s public key into that directory. Since Neuromancer can see Straylight, I can put that file on the web root of the Straylight web server and use any method to get it into the ta .ssh directory.
The first screenshot above shows me transferring the authorized_keys file from my attacker machine to the web root of Straylight. The cyan box in the second screenshot shows the curl command retrieving the authorized_keys file from Straylight and storing it into the .ssh directory of the ta user. The red box shows the access.log of the Straylight machine. The final screenshot verifies the authorized_keys file. Now I only need to test the port fowarded to my attacker machine from the Neuromancer secure shell server.
The cyan box above shows that the ssh port for Neuromancer has been forwarded successfully and we now have a valid user shell on the Neuromancer machine. Keeping the kernel of the machine in mind, I found a privilege escalation exploit that would reliably grant me root privileges.
In the screenshot above, we can see that the tests for this exploit have been run against the same kernel as Neuromancer. According to the reports on the vulnerability, kernels built with enhanced/extended Berkeley Packet Filter (eBPF) system call support are vulnerable to arbitrary memory read/write access. It’s possible for a unprivileged user to supply code to the eBPF. The verifier is supposed to ensure that the supplied code has a limited number of bytecode instructions, does not contain loops, and can only access authorized sections of memory. However, the verifier fails to sanitize access to memory and allows an unprivileged user the ability to write and change his/her status. The error occurs because the check_alu_op() function fails to distinguish between two possible cases from the input it expects to receive on the system. Now we only need to compile the exploit and move it to Neuromancer. We can use secure copy, a package included with secure shell, to move the file to Neuromancer.
The first screenshot shows the compilation of the exploit. The -o flag is the output file. In the second screenshot, we move the exploit to the Neuromancer machine using secure copy. The -i flag specifies the authorized key used for authentication, the -P flag specifies a port other than the standard port for secure shell, the third argument is the location of the file to be transferred on the local machine, and the fourth argument is the user and server of the remote machine followed by the location where the file will be stored on the remote machine. The final two screenshots show the verification of the file in the ta user directory, the description of the file, the execution of the exploit, and the resulting root privilege escalation.
Photo by Stefan Cosma on Unsplash