jueves, 26 de julio de 2018

Auditando una librería en 16 horas

Hace unos días en el trabajo me asignaron una tarea donde tenía que auditar una librería, la funcionalidad de la librería era poder leer diferentes formatos de documentos (PDF, WORD, TXT, etc) y estaba programada en C#.

Como nunca había hecho algo del estilo no sabía como comenzar, por eso estoy escribiendo este post, por si alguien tiene algún caso como el mío que pueda servirle como una guía.

Al ser una librería y no ser una aplicación o algo parecido no podemos trabajar sobre un entorno real, por lo que lo que tenemos que hacer es una serie de recomendaciones que los futuros programadores puedan usar para no tener fallos de seguridad al hacer sus aplicaciones sobre esta librería, y para esto vamos a partir de la base de que no crean ningún filtro y todo lo harán tal cual funcionan las funciones en las librerías.

Además de esto, esta auditoria tenía un poco de prisa, y la librería era bastante grande, por lo que en lugar de poder leer todo el código tuve que hacer como una especie de Checklist de las cosas que eran importantes de mirar. Vamos a pensar las cosas que podrían provocar una posible vulnerabilidad.


  • ¿El código está ofuscado? Esto es lo primero que pensé, ya que al ser C# este código es legible, y el hecho de que no esté ofuscado facilitaría mucho la tarea de un posible atacante para ¿?encontrar vulnerabilidades en una aplicación que estuviese programada con esta librería.
  • ¿Tiene algún Buffer Overflow? Bueno este punto lo descarté debido a que la librería esta programada en .NET, el cual hace una eficiente gestión de la memoria, y para provocar aquí un Buffer Overflow habría que hacerlo con esta intención.
  • ¿Cómo actúa la funcionalidad de guardar ficheros? Es importante saber si sobrescribe ficheros o deja guardarlos con cualquier extensión.
  • ¿Cómo actúa la funcionalidad de cargar ficheros? Igual que en el anterior es importante conoces si hace algún filtro por extensión, además pensé que tal vez al detectar que se carga un fichero ".docx" ejecutara los macros.
  • ¿Tiene alguna función de cifrado? En caso de que si habría que ver si estas funciones son seguras o están ya desfasadas.
Una vez hecha nuestra lista de posibles fallos de seguridad nos vamos a poner manos a la obra.


Ofuscación del código

Al estar programado en C# decompilarlo es algo sencillo, lo único que hay que hacer es usar alguna herramienta como DotPeek.

Una vez decompilado el código pude ver que tenía una ofuscación muy pobre, algunas funciones tenían un nombre extraño, pero el código dentro de estas funciones no tenía ningún tipo de ofuscación, por lo que el código era totalmente legible.

Funcionalidad de guardar ficheros

Una vez tenemos el código perfectamente legible lo primero que hice fue buscar la funcionalidad encargada de guarda ficheros, en este caso era "Save()", estaba dentro de una clase donde se guardaba toda la información de dicho Documento y se le pasaba por parámetro el path y el nombre del fichero para guardarlo.

Dentro de esta función detectaba a través de la extensión el tipo de documento, y al no detectar que fuera ni PDF ni WORD lo guardaba en texto plano y sin ningún filtro de extensión.

En caso de que la aplicación funcionara por HTTP, deberían aplicar un filtro de extensiones para evitar una subida arbitraria de ficheros, yo creé una pequeña POC para mostrar esto.


Además de esto pude comprobar que la sobrescribía ficheros sin ningún tipo de validación, por lo que depende de la aplicación podría derivar en una elevación de privilegios.

Imaginemos esta situación:

  1. Nos encontramos con tres usuarios, dos de ellos son administradores y otro es usuario sin privilegios.
  2. Hemos conseguido acceso al servidor con el usuario sin privilegios, sin embargo la aplicación se encuentra abierta con privilegios de administrado.
  3. El otro usuario administrador tiene un programa en el registro de Windows el cual se inicia al iniciar sesión.
En este caso tendríamos la posibilidad de sobrescribir el programa del otro usuario administrador y sobrescribirlo por malware obteniendo así una elevación de privilegios.



Funcionalidad de cargar ficheros

La función que se encargaba de esto era "Load()" y, aunque en ningún momento les hacía caso a las macros de un fichero de WORD (lo cuál me dio mucha pena), tampoco aplicaba ningún filtro de extensiones.

El peligro en este caso reside en que, en el caso de que hicieran una aplicación funcionando por HTTP, podrían obtener información privilegiada, algo así como si fuera un LFI.

Aquí prepare una pequeña POC mostrando que con esta función sin ningún tipo de filtro podría obtenerse el código del PHP que habíamos subido con la funcionalidad de guardar ficheros.


Funcionalidades de cifrado

Funcionalidades que se encargasen de cifrar solo encontré una rebuscando entre el código, sin embargo los algoritmos que se encargaban de esto ya estaban desfasados.

Encontré un estandar llamado FIPS 197, que advierte de los peligros del uso de RC4 al encriptar PDFs, en lugar de este algoritmo recomienda usar AES con claves de cifrado de 128 bits.

En el código de la librería solo se permitía el uso de RC4 con dos tipos distintos de claves.


Hasta aquí es todo lo que encontré yo, también es verdad que tuve poco tiempo para realizar la auditoria. Espero que este post le sirva a alguien que se encuentre un caso parecido en un futuro.

Saluti.

ai pocas fotoh por temah de confidensialidad

No hay comentarios: