BumbleCrypt
Ein vom Bumblebee inspirierter Crypter
Hintergrund
Der BumbleCrypt ist vom Crypter von Bumblebee inspiriert; im Fall von Bumblebee wird die Haupt-Bumblebee-DLL in den Speicher geladen und auf folgende Weise ausgeführt:
- Entschlüsselt die Payload und schreibt sie in den Heap
- Hookt drei NT-APIs – NtOpenFile, NtCreateSection und NtMapViewOfSection
- Ruft LoadLibraryW("gdiplus.dll") auf, was die Inline-Hooks auslöst, da die obigen drei APIs von LoadLibrary() zum Laden beliebiger Bibliotheken verwendet werden.
- Die Inline-Hooks und LoadLibrary selbst laden dann die Haupt-Bumblebee-DLL anstelle von "gdiplus.dll"
- Schließlich wird die Kontrolle an die exportierte Funktion "SetPath" der Haupt-Bumblebee-DLL übergeben.
Funktionsweise von BumbleCrypt
Bei der Analyse des Crypter von BumbleBee ist mir aufgefallen, dass die entschlüsselte DLL mit nur einem Inline-Hook auf "NtMapViewOfSection" geladen werden kann, anstatt der drei Inline-Hooks, die im Crypter von Bumblebee verwendet werden.
Als Ergebnis wurde "BumbleCrypt" entwickelt.
Der BumbleCrypt:
-
Der BumbleCrypt lädt zunächst eine verschlüsselte Ressource aus dem .rsrc-Abschnitt und entschlüsselt dann die endgültige DLL-Payload: verschlüsselte Ressource -> Base64-Dekodierung -> RC4-Entschlüsselung -> XOR-Entschlüsselung
-
Der Crypter nutzt den Heap, um die entschlüsselte DLL-Payload zu speichern, genau wie der Crypter von Bumblebee
-
Sobald die endgültige Payload entschlüsselt ist, hookt der BumbleCrypt die NT-API "NtMapViewOfSection", die zum Abbilden einer Ansicht des Abschnitts in den virtuellen Adressraum verwendet wird.
-
Dann ruft der BumbleCrypt LoadLibraryW("msimg32.dll") auf. Nun wollen wir verstehen, wie der Inline-Hook ausgelöst wird:
- LoadLibraryW() ruft zuerst NtOpenFile auf, um das Handle des als Argument übergebenen Moduls zu erhalten
- Dann erstellt es mit NtCreateSection ein Section-Objekt mit dem Handle des Moduls
- Sobald die Section erstellt wurde, ruft LoadLibrary NtMapViewOfSection auf, um die Ansicht einer Section in den Speicher abzubilden
- Hier wird unser Hook auf NtMapViewOfSection ausgelöst, wobei die Proxy-Funktion die folgenden Aktionen ausführt:
- Zuerst wird der Hook auf NtMapViewOfSection entfernt
- Erstellt eine Section der erforderlichen Größe mit NtCreateSection()
- Dann wird die Ansicht der erstellten Section mithilfe von NtMapViewOfSection (das zuvor enthookt wurde) in den virtuellen Adressraum abgebildet
- Schließlich bildet es die zuvor entschlüsselte endgültige DLL manuell an der Basisadresse der speicherabgebildeten Section ab und gibt dann NTSTATUS_SUCCESS an LoadLibraryW zurück und verlässt die Proxy-Funktion
- LoadLibraryW empfängt dann NTSTATUS_SUCCESS als Antwort auf NtMapViewOfSection sowie die Basisadresse der speicherabgebildeten Section, in der sich die entschlüsselte bösartige DLL im Speicher befindet. Darüber hinaus lädt LoadLibrary die DLL gemäß den Rückgabewerten; das Ergebnis ist, dass msimg32.dll in den geladenen Modulen sichtbar ist, aber auf die entschlüsselte Payload zeigt. Danach übergibt der Crypter die Kontrolle an die entschlüsselte DLL, indem er die exportierte Funktion "CallPath" ausführt.
-
Wenn wir uns nun den Screenshot der geladenen Module von BumbleCrypt ansehen, sehen wir, dass er die "msimg32.dll" enthält, aber die Basisadresse auf die entschlüsselte bösartige Payload zeigt.
Screenshot


PoC - BumbleCrypter

Vielen Dank! Ich hoffe, es hat euch gefallen =D
Ciao.
Ihr könnt mich auf Twitter kontaktieren, wenn ihr Feedback oder Kommentare habt.
Twitter: https://twitter.com/knight0x07
Hinweis
Nur für Bildungszwecke gedacht. Es ist ein persönliches Wochenendprojekt =)