04.03.2013

Gozi goes 64bit

Gozi goes 64bit Malware

Export Address Table Hooking

Jede Programmbibliothek (DLL) enthält eine Tabelle der bereitgestellten Programmierschnittstellen, die sogenannte Export Address Table (EAT). Die Tabelle enthält eine Liste mit der Zuordnung von Schnittstellennamen zu Schnittstellenadressen. Beim Hooking werden nun in der Liste Schnittstellenadressen manipuliert, so dass eine Schnittstelle plötzlich auf Programmcode des Trojaners zeigt, der Man-in-the-Browser-Funktionalität bereitstellt.

In 64bit-Prozessen funktioniert diese Methode allerdings nicht ohne Weiteres. Denn bei der EAT handelt es sich auch in 64bit-Prozessen um eine Tabelle mit 32bit-Adressen, relativ zum Beginn der Programmbibliothek. Mit einem Abstand von 32bit kann ein Trojaner in einem 64bit-Adressraums aber nicht sicherstellen, auf seinen eigenen Programmcode verweisen zu können.

Inline Hooking

Die ersten Programminstruktionen der Zielfunktionen selbst werden manipuliert. Zielfunktionen sind die Funktionen, die gehooked werden sollen, in diesem Fall die SSL Funktion. Hierbei macht sich Malware zu Nutze, dass die Windows-Programmierschnittstellen in 32bit-Prozessen immer mit denselben fünf Bytes beginnen:

8B FF           mov edi,edi
55              push ebp
8B EC           mov ebp,esp

Bei der ersten Instruktion (mov edi, edi) handelt es sich um einen sogenannten hot-patch point, der insbesondere zum (legitimen) Hooking von Funktionen gedacht ist. Die nächsten beiden Instruktionen dienen dazu, den stack frame einer Funktion vorzubereiten.

In 64bit-Bibliotheken gibt es allerdings keine festen fünf Bytes zum Beginn einer Funktion. Deshalb müsste zum Inline Hooking von 64bit-Bibliotheken der Bytecode mit einem sogenannten Disassembler analysiert werden. Dabei handelt es sich allerdings um einen ausgesprochen aufwändigen und fehleranfälligen Prozess

 

Gozi muss mit Hybrid-Technik arbeiten

Auf Grund der benannten Schwierigkeiten verwendet Gozi eine Art Hybrid dieser beiden Technologien. Zuerst sucht sich Gozi eine unbenutzte Speicherregion am Ende des ausführbaren Codes der Bibliothek. Eine unbenutzte Speicherregion ist dort praktisch immer vorhanden, da Windows Speicher in feste Blöcke aufteilt („Alignment“). Wenn der letzte Speicherblock also nicht zufällig gänzlich ausgenutzt wird, wird der Rest mit Füllbytes belegt („Padding“). Um nicht, wie beim Inline Hooking, direkt den Bytecode einer Funktion manipulieren zu müssen, schreibt Gozi eigene Sprunginstruktionen in diese Füllbytes. Diese Technologie nennt sich auch „Code Caving“.

 

IE64 Hooking

Um Man-in-the-Browser-Funktionalität zu implementieren, wird üblicherweise eine Technologie namens Hooking verwendet. Dabei werden Aufrufe von Programmierschnittstellen von Netzwerkbibliotheken (IE: WININET.DLL) an Programmcode des Trojaners umgeleitet, um SSL-verschlüsselten Netzwerkverkehr im unverschlüsselten Zustand manipulieren zu können.
Es gab zwar bereits zuvor einige Trojaner, die unter 64bit-Betriebssystemen lauffähig waren, selbst innerhalb dieser konnten bisher aber nur 32bit-Browser attackiert werden. Dies liegt mitunter daran, dass Hooking in 64bit-Prozessen extrem komplex ist. Klassisch gibt es vor allem zwei Hooking Methoden:

Gozi startet zunächst mit EAT Hooking

Die Schnittstellenadressen in der EAT werden nun so manipuliert, dass sie auf die zugehörigen Sprunginstruktionen in der „Code Cave“ zeigen. Da sich die „Code Cave“ noch innerhalb der Bibliothek befindet, sind für die Zeiger auf diese noch keine 64bit-Abstände erforderlich. In diesem Rahmen ist EAT Hooking also problemlos möglich. Erst die Sprungbefehle innerhalb der „Code Cave“, wo ausreichend Platz vorhanden ist, können auch Sprünge mit 64bit-Abständen realisieren.

Chrome Hooking

In Google Chrome gibt es – im Vergleich zum Internet Explorer oder zu Firefox – einen entscheidenden Unterschied für die Implementierung von Hooks. Chrome benutzt zwar sogar dieselbe Bibliothek wie Firefox (nspr4), diese wird allerdings nicht als dynamische Bibliothek (DLL) sondern statisch, direkt in den Code von Chrome, eingebunden. Allerdings gibt es in Chrome eine interne Tabelle, die die Funktionen für eingehenden (ssl_Read) und ausgehenden (ssl_Write) SSL-verschlüsselten Netzwerkverkehr enthält:

static const PRIOMethods ssl_methods = {
    PR_DESC_LAYERED,
    ssl_Close,           	/* close        */
    ssl_Read,            	/* read         */
    ssl_Write,           	/* write        */
    ssl_Available,       	/* available    */
    ssl_Available64,     	/* available64  */
    ssl_FSync,           	/* fsync        */
    ssl_Seek,            	/* seek         */
    ssl_Seek64,          	/* seek64       */
    ssl_FileInfo,        	/* fileInfo     */
    ssl_FileInfo64,      	/* fileInfo64   */
    ssl_WriteV,          	/* writev       */
    ssl_Connect,         	/* connect      */
    ssl_Accept,          	/* accept       */
    ssl_Bind,            	/* bind         */
    ssl_Listen,          	/* listen       */
    ssl_Shutdown,        	/* shutdown     */
    ssl_Recv,            	/* recv         */
    ssl_Send,            	/* send         */
    ssl_RecvFrom,        	/* recvfrom     */
    ssl_SendTo,          	/* sendto       */
    ssl_Poll,            	/* poll         */
    PR_EmulateAcceptRead,	/* acceptread   */
    ssl_TransmitFile,    	/* transmitfile */
    ssl_GetSockName,     	/* getsockname  */
    ssl_GetPeerName,     	/* getpeername  */
    NULL,                	/* getsockopt   OBSOLETE */
    NULL,                	/* setsockopt   OBSOLETE */
    NULL,                	/* getsocketoption   */
    NULL,                	/* setsocketoption   */
    PR_EmulateSendFile, 	/* Send a (partial) file with header/trailer*/
    NULL,                	/* reserved for future use */
    NULL,                	/* reserved for future use */
    NULL,                	/* reserved for future use */
    NULL,                	/* reserved for future use */
    NULL                 	/* reserved for future use */
};

Alle Funktionen in Chrome, die verschlüsselten SSL-Netzwerkverkehr behandeln, lesen die Adressen der entsprechenden Funktionen aus dieser Tabelle aus. Gozi verwendet deshalb eine Technologie namens Function Table Hooking, d.h. diese Tabelle wird so manipuliert, dass zuerst der Code von Gozi ausgeführt wird (hier: mspaperf.dll):

Diese Methode ist insbesondere dann interessant, wenn man sich die Unterschiede zu klassischen Hooking-Varianten vor Augen führt. Bei klassischen Varianten werden Daten in Speicherblöcken überschrieben, die normalerweise nicht schreibbar sind (Code-Sektion und EAT). Deshalb müssen Speicherberechtigungen verändert werden, was relativ einfach erkannt werden kann. Auch nach dem Setzen der Hooks kann die Datei im Speicher mit der Datei auf der Festplatte verglichen werden, um durch Hooks modifizierten Speicher zu finden. Beim Function Table Hooking befinden sich die überschriebenen Funktionszeiger allerdings in der Datensektion der Binärdatei des Browsers. Deshalb müssen keine Speicherberechtigungen verändert werden. Außerdem enthält die Datensektion immer dynamisch veränderbare Daten, so dass eine Veränderung für sich genommen nicht verdächtig ist, Im Gegensatz zur Manipulation der Code-Sektion und der EAT.

Function Table Hooking ist somit deutlich schwerer zu erkennen als die klassische Varianten EAT Hooking und Inline Hooking.

 

Schutz durch G DATA BankGuard

Die kommende G DATA Security-Generation 2014 enthält eine verbesserte BankGuard-Technologie für sicheres Online-Banking. Mit ihr werden zusätzlich sowohl Chrome, als auch die 64bit-Version des Internet Explorers geschützt.

Mehr Informationen zu dieser verbesserten G DATA Technologie und der neuen Produktgeneration erfahren Sie auf und nach der CeBIT 2013!


Für Forscherkollegen: Die SHA256 des Samples lautet e388d31e6fde7bdf1f395c29e158c24bb0a87829c6f19511de46e4ef6e054ce0


Artikel teilen

Wichtige IT-Security-News per E-Mail

  • Aktuelle IT-Gefahren
  • Schutz-Tipps für Privatkunden
  • 15 % Willkommensgutschein