Si no puedes confiar en tu software, ¿entonces en qué?

Durante los últimos años hemos escuchado con mayor frecuencia que el software ha sido blanco de ataques, el más reciente bajo el nombre de supply chain attack donde las aplicaciones han jugado un papel importante. Como ejemplo, se encuentra el incidente que sufrió FireEye en el que los atacantes lograron tener acceso a diferentes tipos de información, por medio del software Orion de SolarWinds.

El evento anterior, además de lo mediático, nos permite ver que el software es una de las últimas cosas que se busca proteger, y simplemente confiamos que quienes se encargan de construirlo, han pensado en la seguridad. Ciegamente creemos que se comportará como esperamos, y que no hará nada extraño sin que nosotros nos aseguremos de ello.

Este artículo se centrará en un ataque que se ha visto últimamente en diversos incidentes de seguridad: el uso de “reflection” en el desarrollo de las aplicaciones.  Reflection es una cualidad que los lenguajes de programación modernos como Java, Dot Net, PHP, Android, poseen desde hace varios años. Esta característica permite en tiempo de ejecución, tener acceso a los metadatos de métodos/atributos, así como invocar funcionalidades declaradas en un programa.

A primera instancia parece algo inofensivo, pero precisamente la posibilidad de mandar llamar a una función de nuestros programas desde un código ajeno a nuestra aplicación pudiera ya no parecerlo. Difícilmente será algo que no preocupe, que cualquier persona o programa pudiera estar invocando nuestra función de crear usuario, de cambiar contraseña, de efectuar trasferencias bancarias, o cualquier otra.

También esto agrega un problema a los equipos de monitoreo. Imaginemos el siguiente caso: Parece un día normal en su empresa del sector financiero, de pronto usted comienza a recibir llamadas de sus clientes que le indican que sus cuentas están registrando transferencias de dinero que ellos no realizaron. Al revisar con los equipos de monitoreo, no se identifica ninguna actividad sospechosa. Es más, los registros son normales y se posee evidencia de que las trasferencias se realizaron desde el portal Web con todas las autorizaciones provenientes del cliente (la aplicación), pero finalmente se dan cuenta que no hay una indicación de un usuario, sino que el propio software es el que está tomando la decisión de llevar a cabo las transferencias sin consentimiento o conocimiento de los clientes.

El caso anterior es un ejemplo de cómo un atacante empleando reflection, modificó la lógica de programación mientras el portal Web se encontraba “en ejecución”. En otras palabras, obligó a que el propio software hiciera lo que él le ordenaba, evadiendo todo el control de seguridad que se tenía implementado (WAF, IPS, Firewall, etc.). Así nadie podría sospechar de una actividad inusual de quien precisamente debía realizarla.

Identificar si una aplicación está utilizando reflection como parte de su lógica de negocio normal o si se emplea intencionalmente para algo malicioso es como “encontrar la aguja en un pajar”. Se necesita conocer prácticamente toda la aplicación, sus flujos de información y permisos. Esta información muchas veces no está documentada, incluso ni para los sistemas más críticos.

Una buena recomendación para ayudar a reducir el riesgo del uso de reflection de nuestro software de forma malintencionada, o incluso de otros recursos, es restringir los permisos para su uso, por ejemplo:

  • En Java, ejecutar las aplicaciones desde SecurityManager, el cual, a menos que explícitamente se declare, niega permisos para la aplicación y que pueda realizar acciones que interactúen con recursos del sistema como: lectura/escritura de archivos, Sockets y por supuesto el uso de reflection. Existen cerca de 20 permisos que se pueden otorgar o restringir.
  • Para PHP, se puede emplear la directiva disable_functions para deshabilitar la extensión reflection.
  • Para Android, evitar el uso del permiso ReflectPermission, o monitorear los Intent Reflection para identificar y realizar una acción ante un posible abuso de esa característica.
  • En Dot Net, restringir los permisos que el aplicativo utilizaría configurándolos en la clase PermissionSet.

Referencias:
https://docs.oracle.com/javase/7/docs/technotes/guides/security/permissions.html
https://developer.android.com/reference/java/lang/reflect/ReflectPermission
https://docs.oracle.com/javase/7/docs/api/java/lang/SecurityManager.html
https://www.php.net/manual/en/ini.core.php#ini.disable-functions
https://www.solarwinds.com/es/securityadvisory