Page cover

💣Vulnerabilidades Web en Aplicaciones de Cliente Pesado

Las aplicaciones de cliente pesado con una arquitectura de tres niveles tienen una ventaja de seguridad sobre las que tienen una arquitectura de dos niveles, ya que impiden que el usuario final se comunique directamente con el servidor de base de datos. Sin embargo, las aplicaciones de tres niveles pueden ser susceptibles a ataques específicos de la web, como Inyecciones SQL o el Path Traversal

Durante las pruebas de penetración, es habitual que alguien se encuentre con una aplicación cliente pesada que se conecta a un servidor para comunicarse con la base de datos. El siguiente escenario demuestra un caso en el que el pentester encontró los siguientes archivos mientras enumeraba un servidor FTP con acceso anonymous.

  • fatty-client.jar

  • note.txt

  • note2.txt

  • note3.txt

La lectura del contenido de todos los archivos de texto revela que:

  • Se ha reconfigurado un servidor para que se ejecute en el puerto 1337 en lugar de 8000.

  • Esta podría ser una arquitectura de cliente pesado/liviano donde la aplicación cliente aún necesita actualizarse para usar el nuevo puerto.

  • La aplicación cliente se basa en Java 8.

  • Las credenciales de inicio de sesión para iniciar sesión en la aplicación cliente son qtc / clarabibi.

Ejecutaremos el archivo fatty-client.jar haciendo doble clic sobre él. Una vez iniciada la aplicación, podremos iniciar sesión con las credenciales qtc / clarabibi.

errar

Esto no se ha realizado correctamente y se muestra el mensaje Connection Error!. Probablemente esto se deba a que el puerto que apunta a los servidores debe actualizarse de 8000 a 1337. Capturemos y analicemos el tráfico de red mediante Wireshark para confirmarlo. Una vez que se inicia Wireshark, hacemos clic en Login una vez más.

Tiburón de cables

A continuación se muestra un ejemplo de cómo abordar las solicitudes DNS de las aplicaciones a su favor. Verifique el contenido del archivo C:\Windows\System32\drivers\etc\hosts donde la IP 172.16.17.114 apunta a fatty.htb y server.fatty.htb

El cliente intenta conectarse al subdominio server.fatty.htb. Iniciemos un CMD como administrador y agreguemos la siguiente entrada al archivo hosts.

Al inspeccionar nuevamente el tráfico se revela que el cliente está intentando conectarse al puerto 8000.

puerto

Se trata de un archivo Java fatty-client.jar, y su contenido se puede extraer haciendo clic derecho sobre él y seleccionando Extract files.

Ejecutemos PowerShell como administrador, naveguemos al directorio extraído y usemos el comando Select-String para buscar todos los archivos del puerto 8000.

Hay una coincidencia en beans.xml. Este es un archivo Spring de configuración que contiene metadatos de configuración. Leamos su contenido.

Editemos la línea y establezcamos el puerto en 1337. Leyendo atentamente el contenido, también notamos que el valor del secret es clarabibiclarabibiclarabibi. La ejecución de la aplicación editada fallará debido a una discrepancia en el resumen SHA-256. El JAR está firmado, validando los hashes SHA-256 de cada archivo antes de ejecutarlo. Estos hashes están presentes en el archivo META-INF/MANIFEST.MF.

Quitemos los hashes META-INF/MANIFEST.MF y eliminemos los archivos 1.RSA y 1.SF del directorio META-INF. La modificación de MANIFEST.MF debe terminar con una nueva línea.

Podemos actualizar y ejecutar el archivo fatty-client.jar emitiendo los siguientes comandos.

Luego hacemos doble clic sobre el archivo fatty-client-new.jar para iniciarlo e intentamos iniciar sesión con las credenciales qtc / clarabibi.

acceso

Esta vez nos da el mensaje Login Successful!.


Foothold

Al hacer clic en Profile-> Whoami se revela que el usuario qtc tiene asignado el rol user.

perfil1

Al hacer clic en ServerStatus, nos damos cuenta que no podemos hacer clic en ninguna opción.

estado

Esto implica que puede haber otro usuario con mayores privilegios que esté autorizado a utilizar esta función. Al hacer clic en FileBrowser-> Notes.txt se muestra el archivo security.txt. Al hacer clic en la opción Open en la parte inferior de la ventana se muestra el siguiente contenido.

seguridad

Esta nota nos informa que aún quedan algunos problemas críticos por solucionar en la aplicación. Navegando hasta la opción FileBrowser-> se nos muestra el archivo dave.txt que contiene información interesante. Podemos leer su contenido haciendo clic en la opción Open que se encuentra en la parte inferior de la ventana.

David

El mensaje de Dave dice que todos los usuarios admin se eliminaron de la base de datos. También hace referencia a un tiempo de espera implementado en el procedimiento de inicio de sesión para mitigar los ataques de inyección SQL basados ​​en el tiempo.


Path Traversal

Como podemos leer archivos, intentemos un ataque de path traversal proporcionando la siguiente carga útil en el campo y haciendo clic en el botón Open.

contraseña

El servidor filtra el carácter / de la entrada. Descompilamos la aplicación usando JD-GUIarrow-up-right , arrastrando y soltando el fatty-client-new.jar en el jd-gui.

jdgui

Guardamos el código fuente presionando la opción Save All Sources en jdgui. Descomprimimos el archivo fatty-client-new.jar.src.zip haciendo clic derecho y seleccionando Extract files. El archivo fatty-client-new.jar.src/htb/fatty/client/methods/Invoker.java maneja las características de la aplicación. Al leer su contenido se revela el siguiente código.

La función showFiles toma un argumento para el nombre de la carpeta y luego envía los datos al servidor mediante la llamada sendAndRecv(). El archivo fatty-client-new.jar.src/htb/fatty/client/gui/ClientGuiTest.java establece la opción de carpeta. Leamos su contenido.

Podemos reemplazar el nombre de la carpeta configs por lo siguiente (..).

A continuación, compilamos el archivo ClientGuiTest.Java.

Esto genera varios archivos de clase. Vamos a crear una nueva carpeta y extraer el contenido de fatty-client.jar en ella.

Navegamos hasta el directorio raw y descomprimimos fatty-client-new-2.jar haciendo clic derecho y seleccionando Extract Here. Sobrescribimos los archivos existentes htb/fatty/client/gui/*.class con archivos de clase actualizados.

Finalmente, construimos el nuevo archivo JAR.

Iniciamos sesión en la aplicación y navegamos a FileBrowser-> Config.

atravesar

Esto se ha realizado correctamente. Ahora podemos ver el contenido del directorio configs/../. Los archivos fatty-server.jar y start.sh parecen interesantes. Al enumerar el contenido del archivo start.sh, se ve que fatty-server.jar se está ejecutando dentro de un contenedor Docker de Alpine.

comenzar

Podemos modificar función la open en fatty-client-new.jar.src/htb/fatty/client/methods/Invoker.java para descargar el archivo fatty-server.jar de la siguiente manera.

Reconstruímos el archivo JAR siguiendo los mismos pasos e iniciamos sesión nuevamente en la aplicación. Luego, navegamos hasta FileBrowser-> Config, agregamos el nombre fatty-server.jar en el campo de entrada y hacemos clic en el botón Open.

descargar

El archivo fatty-server.jar se ha descargado correctamente en nuestro escritorio y podemos comenzar el examen.


Inyección SQL

Al descompilar el archivo fatty-server.jar usando JD-GUI, se revela el archivo htb/fatty/server/database/FattyDbSession.class que contiene una función checkLogin() que maneja la funcionalidad de inicio de sesión. Esta función recupera los detalles del usuario en función del nombre de usuario proporcionado. Luego, compara la contraseña recuperada con la contraseña proporcionada.

Veamos cómo la aplicación cliente envía credenciales al servidor. El botón de inicio de sesión crea el nuevo objeto ClientGuiTest.this.user para la clase User. A continuación, llama a las funciones setUsername()y setPassword()con los valores de nombre de usuario y contraseña correspondientes. Los valores que se devuelven de estas funciones se envían al servidor.

código de inicio de sesión

Revisemos las funciones setUsername() y setPassword()de htb/fatty/shared/resources/user.java.

El nombre de usuario se acepta sin modificaciones, pero la contraseña se cambia al formato que se muestra a continuación.

También observamos que el nombre de usuario no está desinfectado y se usa directamente en la consulta SQL, lo que lo hace vulnerable a la inyección SQL.

La función checkLogin de htb/fatty/server/database/FattyDbSession.class escribe la excepción SQL en un archivo de registro.

Al iniciar sesión en la aplicación con el nombre de usuario qtc' para validar la vulnerabilidad de inyección SQL, se revela un error de sintaxis. Para ver el error, debemos editar el código en el archivo fatty-client-new.jar.src/htb/fatty/client/gui/ClientGuiTest.java de la siguiente manera.

Al enumerar el contenido del archivo error-log.txt aparece el siguiente mensaje.

error

Esto confirma que el campo de nombre de usuario es vulnerable a inyecciones SQL. Sin embargo, los intentos de inicio de sesión con payloads como ' or '1'='1 en ambos campos fallan. Suponiendo que el nombre de usuario en el formulario de inicio de sesión es ' or '1'='1, el servidor procesará el nombre de usuario como se muestra a continuación.

La consulta anterior se ejecuta correctamente y devuelve el primer registro de la base de datos. A continuación, el servidor crea un nuevo objeto de usuario con los resultados obtenidos.

Luego compara la contraseña de usuario recién creada con la contraseña proporcionada por el usuario.

Luego, la función produce el siguiente valor newUser.getPassword().

El hash de la contraseña proporcionada por el usuario user.getPassword()se calcula de la siguiente manera.

Aunque el hash enviado al servidor por el cliente no coincide con el de la base de datos y la comparación de contraseñas falla, la inyección SQL sigue siendo posible mediante consultas UNION. Consideremos el siguiente ejemplo.

Es posible crear entradas falsas utilizando el operador SELECT. Ingresemos un nombre de usuario no válido para crear una nueva entrada de usuario.

De manera similar, la inyección en el campo username se puede aprovechar para crear una entrada de usuario falsa.

De esta manera, se puede controlar la contraseña y el rol asignado. El siguiente fragmento de código envía la contraseña en texto plano ingresada en el formulario. Modifiquemos el código de htb/fatty/shared/resources/User.java para enviar la contraseña tal como está desde la aplicación cliente.

Ahora podemos reconstruir el archivo JAR e intentar iniciar sesión utilizando el payload abc' UNION SELECT 1,'abc','a@b.com','abc','admin en el campo username y el texto aleatorio abc en el campo password.

derivación

El servidor eventualmente procesará la siguiente consulta.

La primera consulta de selección falla, mientras que la segunda devuelve resultados de usuario válidos con el rol admin y la contraseña abc. La contraseña enviada al servidor también es abc, lo que da como resultado una comparación de contraseñas exitosa y la aplicación nos permite iniciar sesión como el usuario admin.

administración

Caso práctico

¿Cuál es la dirección IP de la interfaz eth0 en la pestaña ServerStatus -> Ipconfig en la aplicación fatty-client?

Escaneo de puertos

Vamos un puerto 21 FTP abierto. Vamos a descargarnos todos los archivos

FTP Download

Encontramos 3 archivos interesantes, vamos a descargarlos.

La lectura del contenido de todos los archivos de texto revela que:

  • Se ha reconfigurado un servidor para que se ejecute en el puerto 1337 en lugar de 8000.

  • Esta podría ser una arquitectura de cliente pesado/liviano donde la aplicación cliente aún necesita actualizarse para usar el nuevo puerto.

  • La aplicación cliente se basa en Java 8.

  • Las credenciales de inicio de sesión para iniciar sesión en la aplicación cliente son qtc / clarabibi.

Edición del ejecutable

Vamos a extraer fatty-client.jar:

Ahora buscamos las líneas que contengan el puerto 8000:

Editamos el archivo beans.xml en la línea del puerto 8000 y establecemos el puerto en 1337

Quitamos los hashes del archivo META-INF/MANIFEST.MF y eliminemos los archivos 1.RSA y 1.SF del directorio META-INF. La modificación de MANIFEST.MF debe terminar con una nueva línea.

Podemos actualizar y ejecutar el archivo fatty-client.jar emitiendo los siguientes comandos.

Luego hacemos doble clic sobre el archivo fatty-client-new.jar para iniciarlo e intentamos iniciar sesión con las credenciales qtc / clarabibi.

La ejecutamos de nuevo y tenemos un login successfull:

Explotación

No podemos acceder a la pestaña Ipconfig en Server Status, que es el objetivo del caso práctico, por lo que tendremos que intentar desbloquear esa funcionalidad:

Vamos a decompilar la aplicación con jd-gui. Lo guardamos en la ruta C:\Apps

Inyección SQL

1. Modificar el código del cliente para desactivar el hashing de contraseñas:

  • Archivo: htb/fatty/shared/resources/User.java

  • Cambios necesarios:


2. Recompilar y reconstruir el JAR modificado (desde C:\Apps):


3. Explotar la inyección SQL:

Payload de nombre de usuario:

Contraseña: abc (texto plano, sin hashing).

Vemos que se han desabloqueado todas las funcionalidades porque somos admin, y conseguimos acceder a la pestaña de Ipconfig:

Última actualización