BumbleCrypt
Un crypter inspirado en Bumblebee
Antecedentes
BumbleCrypt está inspirado en el crypter de Bumblebee. En el caso de Bumblebee, el DLL principal de Bumblebee se carga en la memoria y se ejecuta de la siguiente manera:
- Descifra y escribe el payload en el Heap
- Engancha tres NtApi's - NtOpenFile, NtCreateSection y NtMapViewOfSection
- Llama a LoadLibraryW("gdiplus.dll"), lo que dispara los inline hooks, ya que las tres API's anteriores son usadas por LoadLibrary() para cargar cualquier librería.
- Los inline hooks y el propio LoadLibrary cargan entonces el DLL principal de Bumblebee en lugar de "gdiplus.dll"
- Por último, el control se transfiere a la función exportada "SetPath" del DLL principal de Bumblebee
Funcionamiento de BumbleCrypt
Mientras analizaba el crypter de BumbleBee, me di cuenta de que el DLL descifrado podía cargarse con solo un inline hook en "NtMapViewOfSection" en lugar de los tres inline hooks utilizados en el crypter de Bumblebee.
Como resultado, se desarrolló "BumbleCrypt".
El BumbleCrypt:
-
BumbleCrypt primero carga un recurso cifrado de la sección .rsrc y luego descifra el payload final del DLL: res cifrado -> decodificación Base64 -> descifrado Rc4 -> descifrado xor
-
El crypter utiliza el Heap para almacenar el payload del DLL descifrado, igual que el crypter de Bumblebee
-
Una vez que el payload final está descifrado, BumbleCrypt engancha la NtApi "NtMapViewOfSection", que se utiliza para mapear una vista de la sección en el espacio de direcciones virtual.
-
Luego BumbleCrypt llama a LoadLibraryW("msimg32.dll"). Ahora entendamos cómo se dispara el inline hook:
- LoadLibraryW() primero llama a NtOpenFile para obtener el handle del módulo pasado como argumento
- Luego crea un objeto de sección con el handle del módulo usando NtCreateSection
- Ahora, una vez que la sección ha sido creada, LoadLibrary llama a NtMapViewOfSection para mapear la vista de una sección en la memoria
- Aquí se dispara nuestro hook en NtMapViewOfSection, donde la función proxy realiza las siguientes acciones:
- Primero quita el hook de NtMapViewOfSection
- Crea una sección del tamaño requerido usando NtCreateSection()
- Luego mapea la vista de la sección creada en el espacio de direcciones virtual usando NtMapViewOfSection (desenganchado previamente)
- Por último, mapea manualmente el DLL final previamente descifrado en la dirección base de la sección mapeada en memoria y luego devuelve NTSTATUS_SUCCESS a LoadLibraryW y sale de la función proxy
- LoadLibraryW recibe entonces NTSTATUS_SUCCESS como respuesta a NtMapViewOfSection y la dirección base de la sección mapeada en memoria donde se encuentra el DLL malicioso descifrado. Además, LoadLibrary carga el DLL según los valores de retorno; el resultado es que msimg32.dll puede verse en los módulos cargados, pero apunta al payload descifrado. Luego el crypter transfiere el control al DLL descifrado ejecutando la función exportada "CallPath".
-
Ahora, si observamos la captura de pantalla de los módulos cargados de BumbleCrypt, podemos ver que contiene "msimg32.dll", pero la dirección base apunta al payload malicioso descifrado.
Captura de pantalla


PoC - BumbleCrypter

¡Muchas gracias! Espero que te haya gustado =D
Ciao.
Puedes contactarme en Twitter si tienes algún comentario o sugerencia
Twitter: https://twitter.com/knight0x07
Nota
Solo con fines educativos. Es un proyecto personal de fin de semana =)