Aunque la mona se vista de seda… ¿Mona se queda?

Solemos asociar que el llevar a cabo ataques contra entidades que consideramos seguras sólo puede ser realizado por atacantes altamente especializados y con profundos conocimientos sobre la temática. Aunque suele ser la norma, esto no siempre es así, y para ejemplo, la noticia que saltaba este verano de dos chicos que, movidos por el famoso juego ‘Pokemon Go’, llegaron a introducirse en una zona de seguridad de un cuartel de la Guardia Civil de Las rozas en Madrid. Muchas veces no son necesarios unos amplios conocimientos técnicos, sino más bien dar en el clavo con ciertas técnicas o ideas medianamente diferentes que se nos ocurran.

En esta entrada vamos a comprobar cómo se comportan diferentes motores «antivirus» (AV) ante amenazas ya conocidas por ellos mismos pero que se encuentran empaquetadas por un software que creen conocer. No se busca hacer una comparativa de antivirus, sino analizar cómo se comportan y concienciar sobre la fe ciega que muchas veces se pone en ellos.

Para la creación del packer, en lugar de construir uno propio desde 0, lo que nos daría bastante ventaja pero complicaría su creación, se ha utilizado uno de los más famosos no por su poder de ocultación, sino por lo extendido de su uso y porque su código es libre, UPX. Los motores antivirus deberían ser capaces casi de ver ‘a través’ del empaquetamiento. Para las pruebas y modificaciones que presentamos se ha utilizado versión 3.91 de UPX.

Antes de modificar el código fuente de UPX, es necesario estudiarlo ya que aun tratándose de un packer archi-conocido y de fácil extracción, no por ello lo es su código. UPX permite empaquetar diferentes formatos de ejecutables de distintas plataformas, cada formato con sus propias características únicas. Además, pueden aplicarse distintos tipos de compresión a cada muestra. Se trata de un código maduro y muy modularizado. Para crear nuestro UPX modificado tenemos que decidir qué tipo de modificación realizar y dónde. Las pruebas las vamos a llevar a cabo con ejecutables del formato PE32 ya que son los que, por cuestiones obvias e históricas, se encuentran mejor y más profundamente estudiados. Sólo nos centraremos en los códigos fuente implicados en su procesamiento, compresión y, no nos olvidemos, descompresión.

Pueden realizarse cientos de distintas modificaciones al empaquetador. Sin embargo, para simplificar el estudio en lugar de, por ejemplo, modificar alguno de los algoritmos de compresión, hemos optado por aplicar la «apenas conocida» operación de OR exclusivo (XOR) antes de proceder a la compresión. Navegando por el código que hemos descargado vamos a buscar el punto donde se comprime la información. Comprobamos que las modificaciones necesarias han de ser realizadas en el archivo ‘packer.cpp’, que es el encargado, para todos los formatos de ejecutables, de empaquetar y desempaquetar la muestra. El código que hemos añadido es básicamente un bucle que aplica el OR exclusivo usando el valor ‘0xA5’ a todo el buffer antes de ser comprimido. De esta manera el resto del código del programa pensará que éste es el código original y nos evitaremos problemas con las diferentes comprobaciones de integridad que realiza UPX. El código añadido se encuentra comprendido entre las líneas 188 y 199.


Tenemos ya nuestra propia versión de UPX que antes de comprimir el ejecutable aplica XOR sobre él. Los ejecutables que intenten ser descomprimidos con otras versiones de UPX (UPX permite extraer/desempaquetar el ejecutable original) generarán un ejecutable no funcional ya que no aplican la operación de ‘unXOR‘ para obtener el código en él escondido. De igual manera, si intentamos ejecutar este programa empaquetado, no funcionará tampoco, ya que no le hemos «enseñado» a descifrarse antes de la ejecución para liberar la posible amenaza que podría encontrarse dentro de él.

El siguiente paso es incluir en los ejecutables empaquetados el código ensamblador encargado de revertir el XOR aplicado antes de la compresión. En este caso hay que realizar el XOR después del proceso de descompresión. Sin entrar en detalles de cómo genera internamente UPX el cargador del programa, tenemos que modificar el archivo ‘src/stub/src/i386-win32.pe.S’. A continuación, se muestra el código ensamblador que ha sido añadido. En él cargamos los valores que necesitamos, como la dirección de memoria donde se encuentra la información a la que se le ha aplicado XOR y el tamaño de ésta. Con un bucle, la recorremos y volvemos a operar con XOR para obtener el contenido original.

img2
Con todos los ingredientes listos, procedemos a compilar y tenemos ya nuestro propio packer recién salido del horno. Realizamos las pruebas pertinentes para comprobar que el cargador modificado en ensamblador vuelve a recuperar el ejecutable original y ya estamos listos para empezar a jugar.

Para las pruebas hemos ido a una base de datos de malware gratuita y hemos descargado varias muestras de forma aleatoria para comprobar si con nuestro UPX modificado conseguimos hacer cambiar de opinión a algún motor antivirus. Veamos el resultado de realizar estas modificaciones mínimas a las cuales no les hemos aplicado ninguna técnica sucia para dificultar el análisis del código.

Los hashes SHA256 de las muestras con las que se han realizado las pruebas son los siguientes:

229624322c5265096cfbb5b683c1ca38896d6a2c38d340fee4cecb04b419b6ef
26b4699a7b9eeb16e76305d843d4ab05e94d43f3201436927e13b3ebafa90739
2b4a12a28309d51d6ba30d420792a41ae2de0c7a758e5d2249deae4a5959793a
40271c351f8f3117b3b6926cd4156dba612ce09e3844053c040de3490ac10d72
55b6f3283ba4f5ee61cf1e118b151e432055d004f1d85ef28b9ef678f4d824f2
5ce0fa2f79d7095ffacd8ca6effc37c72311b9b135439e8095887d2fe02fcb06
7a48e376fbef8573bd2cbc4c388b359a6106729e2073405af7727d3287d90dec
883ec8f4371547d297895632d59ccd2e50ad1826f6cc47d09873390a53393344
94c12b0de0e28a5c88d9b3242793f1d1cd4ff4a86a4bce991e68f3d2e04c56a6
c88df5b1f9c743f12c6f44324a79183bdb4e2a3babc2274773e989ba264a6e02
c8ef9bcd32f99f64666dad94e2cc6cf12926391f4e9c13bb68831215128916c6
d965e50cb93b74b1840da63c1d50f4316459fe7e92ec135d8cec0f486c364c44
dfeddef030ee62d4a26aa4a1033f8264e4be8e8fec1295cae911eb6a45b45a5b

Veamos qué ocurre cuando empaquetamos estas muestras con nuestro UPX modificado. Se muestra el número de motores antivirus que detectan la muestra:

img3
Se observa que la aplicación de nuestro UPX modificado produce unos resultados, en general, bastante buenos, pero… ¿Y si no hubiéramos querido rompernos la cabeza modificando un packer ya existente? ¿Y si empaquetamos las muestras directamente usando la versión original de UPX? ¿Caerán en saco roto nuestras esperanzas de vestir a la mona de seda con el mínimo esfuerzo? Veamos:

img4
Vemos que en general se mantiene la tendencia a reducir el número de detecciones conforme más se oculta la muestra. La aplicación de UPX a una muestra puede llegar a reducir hasta más de un 80% el número de detecciones como en el caso de ‘883ec8f4.exe’. Llegando al 90% con la versión UPX+XOR. Por otro lado, en el menor de los casos, se observa que el hecho de aplicar un packer a una muestra puede llegar a hacer que sea incluso más detectada la muestra, véanse las detecciones de ‘dfeddef0.exe’.

Dando una vuelta a estas últimas muestras en las que el número de detecciones aumenta al aplicar nuestro packer… ¿Y si somos malpensados? Supongamos que hay algunos AV que, por el simple hecho de detectar «algo raro», directamente marquen la muestra como sospechosa. Comparemos entonces si las detecciones cambian por el mero hecho de utilizar un packer. Hemos realizado las mismas pruebas con 5 programas legítimos: Ccleaner, VLC, Procmon (SysInternal), Calc y Firefox.

img6
La gran mayoría de motores de análisis no muestran ningún cambio de opinión con respecto al software legítimo empaquetado. En todos los casos ha habido al menos un motor que ha levantado la mano al analizarlo, motor paranoico que difiere entre muestras, no se repite siempre el mismo. Veamos el peor de los casos en el que un ejecutable legítimo ha sido detectado por 4 motores:

img5
Entre las diversas pruebas llevadas a cabo, también se probó a usar las distintas opciones de compresión que ofrece UPX (la versión sin modificar). ¿Existiría alguna diferencia notable entre comprimir la muestra más rápido (ejecutable más grande) y con más calidad (muestra resultante más pequeña)? En general, no hay una diferencia significativa entre usar un método de compresión u otro, aunque si en lugar de usar el algoritmo rápido, se opta por el de mayor ratio de compresión, se puede llegar a despistar a un par de motores.

Para finalizar, es importante también analizar estos datos con una perspectiva temporal. Poco antes de la publicación de la entrada del blog, se volvieron a reanalizar las muestras y los datos obtenidos son bastante reveladores. Por ejemplo, la muestra ‘c8ef9bcd.exe’ que pasó de 30 a 6 detecciones con nuestro UPX modificado, 5 días después del primer análisis pasa de reducir su detección (No UPX contra UPX+XOR) de 42 a 23 firmas AV. En este caso, lo que más llama la atención es que casi se cuadriplica el número de motores que detectan la versión empaquetada con nuestro packer personalizado. Los creadores de malware tienen claro que, una vez expuesta su amenaza, no va a permanecer sin detectar de por vida, lo importante es esa ventana de tiempo en la que puede moverse sin levantar muchas sospechas. Este ejemplo es igualmente extrapolable a las listas negras de dominios para bloquear, por ejemplo, ransomware. Los creadores del ransomware saben que se exponen a gran cantidad de ojos pero lo que cuenta para ellos son las infecciones exitosas que consiguen en las primeras horas desde que se lanzan los ataques. Es curioso cómo en el primer análisis de esta muestra, donde se observan firmas con nombres muy genéricos, de los pocos AV que detectan la muestra con UPX+XOR, varios de ellos no habían sido capaces de detectar la muestra original sin empaquetar.

Sin embargo, otra muestra de las reanalizadas (‘883ec8f4.exe’) que pasó de 21 a 2 detecciones con el UPX+XOR, no ha sufrido ningún tipo de cambio en prácticamente una semana. Buscando las razones del porqué no había habido a penas movimiento, encontramos que se trata de una amenaza aparecida hace 3 años. No se trata de una muestra ‘caliente’, y lo más seguro es que tenga ya su C&C totalmente desactivado. Esto me trae a la cabeza el dilema actual sobre la rotación de reglas de detección de amenazas. ¿Y si llega alguien ahora y comienza a usar esta muestra con este empaquetador modificado y registra el dominio de C&C de la muestra?

Para finalizar esta entrada, y a modo de cierre, recordar que no existe la herramienta 100% efectiva. No tenemos que confiarnos de que poseer instalado un antivirus en el sistema va a protegernos ante cualquier amenaza. Aun siendo una herramienta útil en muchos casos, siguen existiendo formas de reducir, de forma temporal, su efectividad. Hemos de conocer nuestras herramientas y ser críticos con su uso. Para ejemplo, las detecciones antivirus de la herramienta NetCat, totalmente legítima, detectada por prácticamente la mitad de los motores de VirusTotal.