Conferencia DEFCON 17. ¡Ríete de tus virus! Parte 1

Michael: Doy la bienvenida a todos, soy Michael Lai, este es Matthew Richard, puedes llamarlo Matt o Richard, porque tiene dos nombres, pero no importa.

Matt: El tema de nuestra conversación de hoy es el ridículo del malware, y eso es exactamente lo que estamos tratando de hacer.



Entonces, no todos los que escriben el código lo hacen bien, la gente comete muchos errores. Y no todos los que usan el virus lo hacen bien. También hay personas que fracasan en ambos casos. Así que siéntate más cómodamente, relájate y escucha, tal vez esta información te sea útil.

Por si acaso, incluimos material técnico factual en la presentación para que al menos aprenda algo si la conversación no le parece divertida. Observo que esta es solo nuestra opinión, que puede no coincidir con la opinión de nuestros empleadores.

Michael: La primera historia se llama "Cariño, reduje la entropía". Ella habla sobre cómo el autor de Silent Banker, un algoritmo de cifrado muy complejo, olvidó crear entropía usando PRNG, un generador de números pseudoaleatorios. En la diapositiva, verá un fragmento de código Zeus de septiembre de 2007 en el que PRNG se utiliza para evitar la detección basada en hash. La generación consiste en iniciar esta variable global llamada ddTickCount: primero, la coloca en el registro EAX, desde donde se llama a la función por primera vez. Luego se verifica si el valor de la función es igual a cero, y si no es igual, se llama a TickCount para generar SEED, es decir, para iniciar un número pseudoaleatorio, utilizando el comando GetTickCount.



No nos sorprendió ver las similitudes con este código en el archivo binario Silent Banker de febrero de 2008. Utiliza PRNG para generar nombres de archivo temporales. Aquí, también, existe la misma variable global ddTickCount, que verifica si hay un cero, y si es así, se inicia un número pseudoaleatorio usando GetTickCount. Primero, antes de ver msvsrt rand, el generador de números pseudoaleatorios utilizado por la función rand () de la biblioteca de Microsoft C Runtime Windows, pensé que había una conexión entre el autor Zeus y el autor de Silent Banker, solo basado en números HEX codificados en un archivo binario . Pero, de hecho, ambos estaban vinculados estáticamente a msvsrt.

Ahora llegamos a la receta para el desastre. Este es un fragmento de código de la versión de Silent Banker de julio de 2008, lanzado unos meses después de la versión de febrero.



Actualizaron su código y publicaron una nueva versión de Silent Banker, que era significativamente diferente de lo que vimos anteriormente. En este programa, PRNG se utiliza para generar una clave de cifrado. Aquí ya no verá que una variable global llamada CurrentSeed se verifica para determinar la igualdad a cero y se genera un número pseudoaleatorio dependiendo de esto, simplemente se usa en este código.



Es posible que en algún lugar del archivo binario, incluso antes de este lugar, el valor de esta variable global se genere en forma de algún tipo de número. Así que paso a desmontar este código y ver si el valor CurrentSeed se usa en otra parte del programa antes de usarlo en esta función rand (). Verá que inicialmente dd comienza desde cero, y comprobaremos las referencias cruzadas a esta variable.



En la columna T, el valor w significa que solo hay una operación válida para esta variable global en todo el archivo binario: esta es la función rand misma. Repasaré estas cosas con fluidez porque ya se mencionaron en la DefCon del año pasado. En la diapositiva "Receta para el desastre", la línea Seed the PRNG, o "Initiation of a Pseudo Random Number Generator", se muestra en gris para indicar que el autor de Silent Banker no hizo esta iniciación.



El siguiente paso es que generan una clave de 16 bytes, haciendo 1000 llamadas del sistema a la función MyRand (). Luego, a partir de una clave de 16 bytes, generan un número de 8 bytes, la clave, usando una fórmula específica.

Después de eso, generan otro número de 8 bytes para crear una clave secundaria a partir del primer número de 8 bytes, le agregan un valor arbitrario desde el archivo de configuración INI y obtienen una clave terciaria, que también es un número de 8 bytes. Finalmente, utilizan una función matemática de precisión arbitraria para convertir una clave de 8 bytes en una de 32 bytes.

Después de eso, cifran los datos robados, como la contraseña del usuario, utilizando la clave original de 16 bytes. Pero no pasan este número de "16" bytes a "su" atacante con los datos robados, porque enviar la clave junto con el mensaje cifrado no es una buena idea. En cambio, el autor de Silent Banker coloca un número de 32 bytes dentro de los datos robados y lo envía al destinatario, quien debería tener un programa que convierta ese número nuevamente a la clave original de 16 bytes. Sin embargo, no tenemos este programa!

La siguiente diapositiva muestra una receta sobre cómo usar este desastre con el número 1, la falta de un generador de PRNG, para su ventaja.



Para empezar, equiparamos el valor de PRNG a cero. Podemos automatizar los siguientes cuatro pasos utilizando un script de Python para el depurador, porque tenemos una fórmula que calcula una clave de 16 bytes, una clave de 8 bytes, la siguiente clave de 8 bytes y una clave de 32 bytes. Esta fórmula no está en el código C, pero la tenemos porque tenemos una copia del archivo binario Silent Banker en el que existe.

Le mostraré una demostración de cómo funciona este script de Python. Tenemos un buen escenario: aquí tengo Silent Banker y un depurador independiente al que estoy conectado, así como Internet Explorer, en el que se ejecuta Silent Banker. Noté cuatro características que generan claves de cifrado. Incluyo este script de Python que se muestra en la diapositiva anterior, que invoco con el comando bang keygen. Puede ver que el depurador simplemente "pierde" estas pocas funciones que quiero realizar para esta demostración 5 veces. Pero en la vida real, realizamos esta acción 5.000 veces para obtener un conjunto de claves más grande.

En el panel de registro, puede ver que para cada iteración del bucle, se emite una clave primaria de 16 bytes, que luego se asocia con una clave de 32 bytes. Al mismo tiempo que el script imprime información en el registro, también se crea un archivo de texto en el disco, que incluye pares de claves relacionadas de 16 y 32 bytes. Es solo un archivo HEX hexadecimal, por lo que podemos usar nuestro script Python para procesar este archivo, también tenemos un directorio de registro que recuperamos del nodo robado de comando y control.



En la parte superior, verá varios certificados de claves privadas cifradas, y debajo de ellos hay varios archivos de texto que contienen datos cifrados. Simplemente podemos ejecutar el programa y buscar dentro de estos archivos de texto extrayendo esta clave de 32 bytes y la clave original de 16 bytes asociada a ella.

Tan pronto como el programa encuentra una clave de 16 bytes, descifra la información que contiene y la presenta en forma de archivo de texto. Verá este archivo en la pantalla y es imposible leerlo.



Pero luego tenemos un montón de archivos temporales .tmp legibles, desde donde podemos obtener esta información y devolverla a los propietarios "legítimos". Silent Banker hizo todo el trabajo duro para proteger la información en vano porque olvidaron iniciar un generador de números pseudoaleatorio.



Ahora mostraré la mejor parte de lo anterior: esta es la función Silent Banker, que llamé Why_Not_Use_This (¿Por qué no usarla?).



De hecho, dentro de su propio programa, tienen la función GetCursorPos (determinar la posición del cursor) para generar entropía, que se puede utilizar para iniciar PRNG, y podemos verificar si hay referencias cruzadas a esta función dentro del programa.



Vemos que se usa en 10-15 otros lugares en el código. Por lo tanto, resulta que los autores de Silent Banker no olvidaron insertar un generador de números pseudoaleatorios en el programa, simplemente olvidaron ejecutar esta función en el proceso de cifrado utilizando el operador de llamada.



La siguiente diapositiva se llama "Eso se escapó ..." y muestra cómo funcionaría este programa si el autor no hubiera olvidado nada.



La siguiente historia, titulada "DES o no DES", trata sobre un autor de malware que ni siquiera sabe cómo usar correctamente la interfaz de programación de Windows o no sabe cuál es el tamaño máximo de la clave DES. Como resultado, debido al tamaño no válido de esta clave, su troyano se usa por defecto con el operador lógico xor.

Entonces, para la función de interfaz del programa CryptDeriveKey, los dos bytes bajos del parámetro dwFlags, banderas que establecen cómo se verá la URL resultante, determinan el tamaño de su clave de cifrado.



Entonces, si los bytes bajos son 0080, entonces la clave de cifrado que solicitamos será una clave RC4 de 128 bits. Es lo mismo que dispararte en el pie, y te mostraré por qué.



En la diapositiva, verá una línea con el tamaño incorrecto de la clave dwFlags de 128 bits: 800000 y una línea con el valor incorrecto de MSCryptoAPI. Te mostraré el desmontaje de esta cosa. Verá una función llamada "inicialización del subsistema de cifrado": el troyano llama al contexto cifrado y luego crea un contenedor para el hash MD5, después de lo cual crea un hash MD5 de la contraseña codificada en el archivo binario e intenta usar la salida de esta función hash para crear una clave DES de 128 bits. Sin embargo, no se crea ninguna clave en este caso, porque no existe una clave DES de 128 bits.



Si alguna de estas funciones API falla, salta a este lugar, que marqué en amarillo, y muestra un mensaje de que no se puede recibir la clave. Y este lugar está aquí, donde mueve el valor que está en ebp y en ese momento es 0, es decir, directamente en este valor booleano bUseMSCryptoAPI.

Veamos qué efecto causa esto durante la ejecución del programa. Seguiremos este elemento de la estructura del código para ver dónde más se usa en el programa y cuán diferente se comporta esta exposición de troyanos cuando la función es verdadera y cuando la herida es falsa.



Vemos que el valor lógico se verifica en la función que llamé cifrar datos, "cifrado de datos", y si es cierto, se trata de este bloque, donde se usan el cifrado DES y CryptEncrypt MSAPI.



Sin embargo, si este valor es 0, y como sabemos, siempre será temprano cero, la función va a este bloque, que por defecto es xor.



Tenía curiosidad sobre en qué momento el autor del programa malicioso decidió hacer una copia de seguridad de todo esto. Tal vez la gente lo estaba empujando desde arriba, por lo que se vio obligado a deshacerse del malware, pero en el último minuto se dio cuenta de que su DES no funcionaba, por lo que usó xor para la grabación de respaldo. En general, fue bastante divertido, ¡así que la moraleja de esta historia es hacer siempre copias de seguridad!

La siguiente historia se llama "¿Qué has hecho con qué?". Traté de encontrar un término que describiera cómo funciona el cifrado del troyano Coreflood, y decidí llamarlo "cifrado dependiente de la ubicación". En resumen, los autores de este troyano inventaron un nuevo método de cifrado. Pensé, ¿tal vez alguien ya escribió un artículo sobre esto y debería ser "google"? Google me dio un enlace a un sitio de patentes de los EE. UU. Donde alguien presentó una patente por "encriptación dependiente de la ubicación". Este esquema es bastante confuso, por lo que tomará mucho tiempo estudiarlo. Así es como funciona: le estoy enviando un mensaje encriptado, y para descifrarlo y leerlo, debe tomar un dispositivo GPS e ir a un punto con la latitud y longitud indicadas por mí. Por lo general, el cifrado es un compromiso entre la seguridad y la usabilidad, pero no hay uno ni el otro en este método.



Esto definitivamente no es seguro y requiere que vayas a donde el remitente señala para leer el mensaje. Matt bromeó diciendo que si estás luchando en línea por correo electrónico y realmente quieres deshacerte de alguien, envíale un mensaje cifrado que pueda leer en algún lugar de Irak, y ya no tendrás problemas con él.

¿Cómo se usa este método en el troyano Coreflood? La diapositiva muestra un fragmento de código del que se deduce que después de que el troyano ha robado la información del usuario, la cifra y la escribe en el disco para que el troyano pueda recibir esta información y cargar comandos y controles en su sitio web.

Esta función se llama SetFilePointer (establece el puntero del archivo) y su valor de retorno es dWord, que indica el desplazamiento en el archivo en el que se estableció el puntero si se superó. Luego, la función toma el número de bytes para encriptar nNumberOfBitesToWrite y lo mueve al registro ecx. Luego toma el puntero de datos para el cifrado y lo mueve al registro edx.



Después de eso, se utiliza el operador xor, que coloca cada byte en el búfer al y ah, lo que significa bytes de nivel bajo y alto devueltos por SetFilePointer. Por lo tanto, la clave de cifrado en este esquema es el desplazamiento en el archivo en el que existen los datos. ¡Esto es simplemente asombroso!

La siguiente diapositiva se llama "Cómo restablecer un volcado de memoria". Representa el programa dumpCore que acabo de escribir, que acaba de salir. Puede descargarlo, hay todo el código fuente. Este programa lo ayudará si la computadora está infectada con el virus Coreflood, que por alguna razón no pudo acceder al servidor de comando y control para descargar los datos robados. Por lo tanto, puede obtener estos archivos que guardó en el disco y descifrarlos utilizando mi programa para averiguar qué le fue robado, por ejemplo, si necesita informar al cliente al respecto.

Los registros de los datos robados están rodeados en rojo en la diapositiva.



Lo que sigue siendo interesante en Coreflood: aunque tiene un algoritmo de cifrado bastante débil, todavía trata de transferir toda la información robada sobre la configuración de la computadora de la víctima, toda la información objetivo de los bancos y cooperativas de crédito, y así sucesivamente. Entonces, otra forma de eliminar un volcado de núcleo se llama "Cómo eliminar un volcado de núcleo utilizando Wireshark". Wireshark es un programa que analiza el tráfico de red Ethernet o el flujo de datos TCP.



La siguiente diapositiva muestra cómo funciona Coreflood. Estos son archivos DLL que se ingresan en Explorer e Internet Explorer. Modifican el registro, requieren un reinicio de la aplicación, pero no requieren un reinicio del sistema. Hay varias formas de inyectar estos dlls en un proceso.



Importante para los piratas informáticos que desean invadir el virus sin darse cuenta es cómo ingresa el virus en la computadora del usuario: requiere un reinicio del sistema para que el malware tenga efecto, o es suficiente para que el usuario simplemente reinicie la aplicación, en este caso Explorer.

¡Y ahora está tranquilo para que nadie pueda escuchar!



Este es el código que reconstruimos utilizando ingeniería inversa. Esto muestra cómo Coreflood cierra manualmente Explorer para que los cambios surtan efecto de inmediato. Probablemente esté familiarizado con lo que sucede cuando el Explorer falla en la computadora: la barra de tareas desaparece, las ventanas de todas las aplicaciones abiertas, todos los íconos en el escritorio desaparecen, y luego, uno por uno, comienzan a regresar a su lugar.

Los autores de Coreflood obviamente sabían sobre esto, por lo que colocaron una llamada al sistema en este lugar para establecer el modo de error "correcto" del conductor justo antes de la llamada de OpenProcess.

¿Qué hace la función SetErrorMode? Evita una falla específica de las notificaciones enviadas al sistema que crean una pequeña ventana emergente y envían un mensaje de error que llevó a la finalización de la aplicación. Todo lo que hicieron con este mensaje de error fue evitar que una ventana emergente apareciera ante el usuario antes de que Explorer fallara. Dígame qué le parece más sospechoso al usuario: una pequeña ventana emergente acompañada por la desaparición de todo lo que aparece en la pantalla y luego reaparece, o la desaparición y aparición de todo sin ningún mensaje de error. Escuché que dijiste: "ambos eventos".

La siguiente diapositiva la llamé "Con brazos y piernas, pero sin cabeza". Coreflood, cuando se carga como un dll, no aparece en la lista de módulos cargados. Él asigna un poco de memoria en el montón y se copia a sí mismo en este lugar del montón; lo puse en un marco rojo.



Luego elimina su encabezado PE, por lo que si se encuentra con una computadora infectada con este troyano, diga: "mi próximo paso debería ser volcar este archivo ejecutable y subirlo a la IDA para su análisis", pero es muy difícil volcar el archivo ejecutable, si no hay su encabezado PE. Entonces, cuando Coreflood llama a aloc virtual, define el indicador de memoria de arriba a abajo, lo que hace que el sistema devuelva la dirección más alta, no la más baja, disponible. Esto permite que el troyano oculte las comillas de apertura / cierre en un área de memoria más alta del modo de usuario entre otros dlls del sistema. Por lo tanto, la próxima demostración que llamé "Cómo inutilizar todo lo que está oculto".



Cuando te encuentras con algo como Coreflood que usa sigilo, y no hay herramientas listas para trabajar con tales virus, debes crear el tuyo propio.
Si está familiarizado con el desempaquetado, usar un depurador es común para usted. Especialmente si no hay un desempacador automático, ya que este no es un algoritmo común. En este caso, puede usar el depurador para ir al punto de entrada original y luego eliminar el volcado del troyano usando ProcDump u otra utilidad. PE Import Reconstructor, , , .

, . . Volatility, Internet Explorer . , Coreflood, , . , 7FF81000.



, HEX , Coreflood. , , . .

, , Coreflood, Volatility . , ID Internet Explorer. , , PID 1732. Malfind, , , , . VAD , , . , .



, , 7FF81000. , Fix IAT, PID 1732 Internet Explorer , Coreflood.

dll, Internet Explorer, , RBA , , .

, 7FF81000, , . , PE . , Import Reconstructor: , , . Fix IAT , PE modify viewer , .



21:15

DEFCON 17. ! Parte 2


Gracias por quedarte con nosotros. ¿Te gustan nuestros artículos? ¿Quieres ver más materiales interesantes? Apóyenos haciendo un pedido o recomendándolo a sus amigos, un descuento del 30% para los usuarios de Habr en un análogo único de servidores de nivel de entrada que inventamos para usted: toda la verdad sobre VPS (KVM) E5-2650 v4 (6 núcleos) 10GB DDR4 240GB SSD 1Gbps de $ 20 o cómo dividir el servidor? (las opciones están disponibles con RAID1 y RAID10, hasta 24 núcleos y hasta 40GB DDR4).

VPS (KVM) E5-2650 v4 (6 núcleos) 10GB DDR4 240GB SSD 1Gbps hasta diciembre de forma gratuita al pagar por un período de seis meses, puede ordenar aquí .

Dell R730xd 2 veces más barato? Solo tenemos 2 x Intel Dodeca-Core Xeon E5-2650v4 128GB DDR4 6x480GB SSD 1Gbps 100 TV desde $ 249 en los Países Bajos y los EE. UU. Lea sobre Cómo construir un edificio de infraestructura. clase utilizando servidores Dell R730xd E5-2650 v4 que cuestan 9,000 euros por un centavo?

Source: https://habr.com/ru/post/es428858/


All Articles