Featured image of post Stocker Machine

Stocker Machine

Reconocimiento

Para comenzar, como es costumbre, comprobamos si la máquina está disponible:

1
 ping -c 1 10.10.11.196
1
2
3
4
5
6
## PING 10.10.11.196 (10.10.11.196) 56(84) bytes of data.
## 64 bytes from 10.10.11.196: icmp_seq=1 ttl=63 time=46.3 ms
## 
## --- 10.10.11.196 ping statistics ---
## 1 packets transmitted, 1 received, 0% packet loss, time 0ms
## rtt min/avg/max/mdev = 46.315/46.315/46.315/0.000 ms

Si echamos un vistazo al valor TTL en la respuesta, vemos que la máquina a la que nos enfrentamos tiene como sistema operativo GNU/Linux.

A continuación vemos que servicios están desplegados haciendo un escaneo de puertos, principalmente por el protocolo TCP:

1
 nmap -p- --open -T5 -Pn -n 1 10.10.11.196 -oG openTCPports
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
## Starting Nmap 7.93 ( https://nmap.org ) at 2023-02-13 20:19 CET
## Nmap scan report for 10.10.11.196
## Host is up (0.046s latency).
## Not shown: 60876 closed tcp ports (conn-refused), 4657 filtered tcp ports (no-response)
## Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
## PORT   STATE SERVICE
## 22/tcp open  ssh
## 80/tcp open  http
## 
## Nmap done: 2 IP addresses (2 hosts up) scanned in 39.03 seconds

Una vez hecho esto, vemos que están expuestos los puertos 22 y 80. Veamos que servicios maneja, lanzando con nmap una serie de scripts de reconocimiento:

1
 nmap -p22,80 -sVC 10.10.11.196 -oN servicesTCPports
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
## Starting Nmap 7.93 ( https://nmap.org ) at 2023-02-13 20:20 CET
## Nmap scan report for stocker.htb (10.10.11.196)
## Host is up (0.049s latency).
## 
## PORT   STATE SERVICE VERSION
## 22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
## | ssh-hostkey: 
## |   3072 3d12971d86bc161683608f4f06e6d54e (RSA)
## |   256 7c4d1a7868ce1200df491037f9ad174f (ECDSA)
## |_  256 dd978050a5bacd7d55e827ed28fdaa3b (ED25519)
## 80/tcp open  http    nginx 1.18.0 (Ubuntu)
## |_http-title: Stock - Coming Soon!
## |_http-generator: Eleventy v2.0.0
## |_http-server-header: nginx/1.18.0 (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 9.26 seconds

Obteniendo acceso a la máquina víctima

Vemos ssh ejecutándose y un servicio web desplegado en el puerto 80. Como no disponemos de credenciales para ssh, vamos a echar un vistazo a la web; primero desde terminal para saber a qué tecnologías nos enfrentamos:

1
 whatweb 10.10.11.196


Al principio no veremos nada ya que nos redirige a un dominio que nuestro ordenador no sabe interpretar; para ello añadimos la dirección ip a nuestro archivo local /etc/hosts además del dominio al que nos redirige stocker.htb.

Echando un rápido vistazo a la página web, no se ve nada que destaque; con la herramienta gobuster veamos si hay algún subdominio:

1
 gobuster vhost -u stocker.htb -w /usr/share/SecLists/Discovery/DNS/subdomains-top1million-110000.txt


Añadimos el subdominio de la imagen al fichero de hosts y accedemos a él para ver un panel de autenticación para acceder a los recursos de la plataforma.

Intentar algún bypass simple no es efectivo; interceptando la petición desde nuestro dispositivo con BurpSuite podemos cambiar el contenido de la aplicación de “url-encoded” a “json” sin recibir ningún error del estilo “Internal Server Error”; esto me hace pensar que por detrás se esté haciendo algún tipo de petición a una base de datos.

Saltando el panel de autenticación

Haciendo varias pruebas encontré una manera de saltarme el panel.A continuación se puede ver una forma de aprovechar esto jugando con los valores json:

¿Qué estamos haciendo realmente? Según la documentación de MongoDB $ne selects the document where the value of the field is not equal tothe specified value es decir, estamos seleccionando todos los valores distintos al que hemos puesto incluido los valores de autenticación correctos . Usando este valor que se interpreta internamente como un tipo de dato BSON, podemos acceder como usuario registrado a la plataforma.

Obteniendo credenciales ssh

Nos encontramos ante una especie de tienda, donde seleccionamos los objetos para comprar, realizamos la compra y obtenemos un pdf a modo de factura. Interceptando la petición de compra podemos alterar el contenido de este pdf.

Mirando los metadatos del fichero, este está generado con chromium ¿podremos ver el contenido de un fichero abusando de esto y gracias a un iframe?La respuesta es que sí, podemos:

Obtenemos el usuario “Angoose”. Tras buscar en varios ficheros insatisfactoriamente se me ocurrió buscar ficheros “js” que contuvieran la configuración del usuario para el inicio de sesión de este; probé con varios hasta dar con el “index.js” que contenía:

Probando el usuario y la contraseña en ssh ganamos acceso.

Escalada de privilegios

Una vez hemos ganado acceso tenemos permisos para ejecutar como root sin contraseña el comando “node” acompañado de cierta ruta usando el comodín asterisco. Gracias a este comodín podemos ejecutar realmente el fichero que queramos porque el comodín se puede sustituir por cero o más ocurrencias de cualquier caracter. Creamos el siguiente scrip y obtenemos la flag de root:

1
2
3
4
5
6
const fs = require("fs"), filename = "/root/root.txt";

fs.readFile(filename, 'utf-8', (error,data) => {
  if (error) throw error;
  console.log("ROOT FLAG: ", data);
})
Tema Stack diseñado por Jimmy