Carsten Willems Lehrstuhlworkshop Dagstuhl 29.6.2009
Transcription
Carsten Willems Lehrstuhlworkshop Dagstuhl 29.6.2009
„Analyse von Programmverhalten“ Carsten Willems Lehrstuhlworkshop Dagstuhl 29.6.2009 - 1.7.2009 Dienstag, 4. August 2009 v.01 Übersicht Motivation Grundlagen „Windows-Anwendungen“ von der Hochsprache zum Executable von der Datei zur Ausführung Systemaufrufe Verhaltensanalyse Dienstag, 4. August 2009 Motivation Dienstag, 4. August 2009 Motivation Häufige Frage: was macht ein Programm? meist unter dem Sicherheitsaspekt Einsatz von Closed Source Software Malware Desinfektion und Schadensminimierung Verhinderung von Infektion / Ausbreitung Trends verfolgen, Vorhersagen, Strafverfolgung Dienstag, 4. August 2009 Was macht ein Programm? „interne“ Datentransformationen Interaktion mit dem lokalen System Dateisystem, Registry, Prozesse, ... Interaktion mit der Außenwelt Kommunikation über das Netzwerk Dienstag, 4. August 2009 Was macht eine Malware? Beispiele für interessantes Programmverhalten: wie installiert sich die Malware für persistente Aktivität? welche Änderungen werden am System vorgenommen? welche Daten werden ausgelesen? mit welchen Hosts wird Kontakt aufgenommen? Dienstag, 4. August 2009 Verhaltensanalyse Um Programmverhalten zu erfahren Interaktion mit dem System beobachten dafür Systemaufrufe verfolgen wie kann das realisiert werden? ‣ Grundlagen eines Windows-Programms ‣ Systemaufrufe ‣ Verhaltensanalyse Dienstag, 4. August 2009 Grundlagen Dienstag, 4. August 2009 Windows-Anwendung Entwicklung normalerweise in Hochsprache C, C++, Java, Delphi, VB, ... Verwendung von Bibliotheken durch Compilieren und Linken ausführbares Programm erstellen Portable Executable Format (PE-Format) Dienstag, 4. August 2009 Bibliotheken Programmiersprache-Bibliotheken Hilfsfunktionen, Laufzeitsystem, ... Windows-Bibliotheken Systemdienste Drittanbieter-Bibliotheken z.B. für Grafik-/Netzwerkprogrammierung werden dynamisch oder statisch gelinkt Dienstag, 4. August 2009 Windows-Bibliotheken Linkung immer dynamisch => Dynamic Link Library (DLL) implizite Bindung ausführbares Programm enthält Informationen zu benötigten DLLs und Windows lädt diese automatisch bei Programmstart explizite Bindung Programm lädt DLL selber in den Speicher Dienstag, 4. August 2009 Bibliotheks-Funktionen DLLs exportieren Funktionen spezifiziert über das Export Directory exportierte Funktion = API Benutzer von DLLs importieren Funktionen spezifiziert über das Import Directory sowohl Anwendungen als auch DLLs selber können andere DLLs verwenden Dienstag, 4. August 2009 PE-Format - Anwendung Import Directory kernel32.dll Executable CreateFileA CreateFileW OpenMutexA ... DOS Header verkettete Liste der importierten DLLs und der daraus verwendeten Funktionen kein Export Directorty Dienstag, 4. August 2009 PE Header Import Directory Section 1 Import Adress Table (IAT) Export Directory Export Adress Table (EAT) ... Section n ... ntdll.dll NtCreateFile NopenFile NtClose ... PE-Format - DLL kernel32.dll Import Directory wie bei Anwendung DOS Header ntdll.dll PE Header Import Directory Import Adress Table (IAT) Section 1 Export Directorty Liste der exportierten Funktionen Dienstag, 4. August 2009 NtCreateFile NopenFile NtClose ... Export Directory Export Adress Table (EAT) ... Section n ... ActivateActCtx AddAtomA AddAtomW AddConsoleAliasA AddConsoleAliasW ... DependecyWalker Dienstag, 4. August 2009 LordPE Dienstag, 4. August 2009 IAT / EAT DLL zur Laufzeit in den Speicher geladen Adressen der exportierten Funktionen daher zur Compilezeit unbekannt Compiler richtet Platzhalter ein in DLL: Export Adress Table in Benutzer der DLL: Import Adress Table Windows-Loader füllt Tabellen beim Programmstart mit effektiven Adressen Dienstag, 4. August 2009 Windows-Loader wird zum Starten sämtlicher Windows-Prozesse (bis auf den System-prozess) verwendet CreateProcess, WinExec, ShellExecute, ... Aufgaben lädt Anwendung in den Speicher lädt implizit gelinkte DLLs füllt die EAT der DLLs füllt die IAT der Anwendung / DLLs Dienstag, 4. August 2009 Windows-Loader Virtual Memory Image der Anwendung in den Speicher mappen Images der implizit gelinkten DLLs mappen application.exe application.exe IAT EAT advapi32.dll IAT EAT kernel32.dll IAT EAT ntdll.dll IAT EAT advapi32.dll ntdll.dll kernel32.dll EAT der DLLs mit effektiven Adressen füllen IAT der Anwendung / DLLs mit Funktionsadressen der entsprechenden EAT füllen Dienstag, 4. August 2009 Aufruf via IAT 2 Möglichkeiten, je nach Compiler: JMP-Table mit IATReferenzen als Sprungziele CALL IAT Dienstag, 4. August 2009 GetProcAddress explizit gelinkte DLLs nicht via Windows-Loader es existiert keine IAT Funktionsadressen dynamisch ermitteln kernel32!GetProcAddress (immer implizit gelinkt) ntdll!LdrGetProcAddress manuelle Suche über Export Directory der DLL Dienstag, 4. August 2009 Systemaufrufe Dienstag, 4. August 2009 Kernelmodus vs. Usermodus CPU führt Code in verschiedenen Sicherheitsstufen ausführen: Ring 0 (hoch) bis Ring 3 (niedrig) Windows/Linux nur Ring 0 (Kernel-) und 3 (Usermodus) Usermodus keine privilegierten Operationen erlaubt nur Userspace-Speicher des aktuellen Prozesses sichtbar (untere 2 GB) Kernelmodus alles erlaubt (z.B. direkter HW-Zugriff) und sichtbar Dienstag, 4. August 2009 Betriebssystem Eine Aufgabe des OS: Dienste für Systeminteraktion anbieten dafür wird meist Hardwarezugriff benötigt Dateizugriff durch Lesen/Schreiben von Sektoren der Festplatte / USB-Stick / CD-Rom Netzwerkkommunikation durch Datenaustausch mit Netzwerkkarte (gemappter Speicher oder IO-Ports) Für viele Aufgaben muss daher kurzzeitig in den Kernelmodus umgeschaltet werden Dienstag, 4. August 2009 Systemaufrufe Zugriff auf OS-Dienste über Systemaufrufe Usermodus-APIs (für Anwendungen) Windows-DLLs verwenden wiederum oft Kernel-APIs Kernelmodus-APIs (für Treiber) ntoskrnl.exe, win32k.sys verwenden u.a. Gerätetreiber Dienstag, 4. August 2009 Systemaufruf - Diagramm Anwendung ruft Windows-API auf (DLL) unter Benutzung des IO Managers via IRP (Input Output Request Packet) verantwortliche(n) Treiber verwenden Dienstag, 4. August 2009 hardisk.sys IRP IRP CreateFile meistens dann Wechsel in den Kernelmodus => Kernel-Systemaufruf filesystem.sys kernel32.dll NtCreateFile API ruft weitere APIs auf application.exe IO manager ntdll.dll Usermode Sysenter ntoskrnl.exe Kernelmode Systemaufruf - detailliert application.exe IAT EAT .. call {kernel32!CreateFile} .. SSDT SST ntoskrnl kernel32.dll IAT ntoskrnl.exe EAT KiSystemService: .. call KiFastcallEntry .. => back to usermode CreateFileA: .. call {ntdll!NtCreateFile} .. SST win32k reserved reserved SST ntoskrnl service table ntdll.dll IAT KiFastCallEntry: .. lookup system service call systemservice .. ret EAT NtCreateFile: mov eax, 0x25 mov edx, &KiFastSystemCall call {ds:edx} retn 0x2c service limit argument table ST ntoskrnl NtCreateFile: .. KiFastSystemCall: mov edx, esp sysenter ret MSR NtCreateEventPair: .. .. NtCreateFile NtCreateEvtPair .. Usermode Dienstag, 4. August 2009 counter table Kernelmode Verhaltensanalyse Dienstag, 4. August 2009 Programmanalyse Erinnerung: was macht ein Programm? verschiedene Ansätze statische Codeanalyse Programmcode im Disassembler dynamische Codeanalyse Programmcode im Debugger während Ausführung Verhaltensanalyse Systeminteraktion beobachten Dienstag, 4. August 2009 Statische Codeanalyse Tools Disassembler (IDAPro) Decompiler (dede, VBDecompiler pro, ...) Nachteile sehr aufwendig Code obfuscation, Encryption, VM, Anti-RE keine dynamischen Werte Register- / Stack- / Heapinhalte, ... Dienstag, 4. August 2009 Dynamische Codeanalyse Tools Debugger (OllyDbg, WinDbg, ...) Nachteile sehr aufwendig ggfalls. nur ein Ausführungspfad Anti-Debug-Techniken Debugger-Erkennung, SEH, BP, malformed PE, ... Dienstag, 4. August 2009 Verhaltensanalyse Einzel-Tools (filemon, regmon, wireshark, ...) Komplett-Tools (CWSandbox, Anubis, Norman, ...) Nachteile nur ein Ausführungspfad zu erkennen zu umgehen Dienstag, 4. August 2009 Verhaltensanalyse - Ansätze von „innen“ mit Debugger Systemaufrufe beobachten von „außen“ Emulation (nur ein Teil des OS wird simuliert) VM (volle Systemsimulation, z.B. Hypervisor-Mode) von „mittendrin“ Modifikation des Executables oder des OS, um Systemaufrufe zu beobachten Dienstag, 4. August 2009 Analyse von innen Programm im Debugger ausführen, um Systemaufrufe zu verfolgen Einzelschritt: sehr, sehr langsam Software-Breakpoints: leicht zu erkennen/umgehen Hardware-Breakpoints: nur 4, ebenfalls zu erkennen Memory-Breakpoints: leicht zu erkennen/umgehen Dienstag, 4. August 2009 Analyse von außen Emulation z.B. in AV-Software leicht zu erkennen, da nur wenige APIs implementiert VM sehr aufwendig immer möglich: Erkennung via Timing / InstructionCount Dienstag, 4. August 2009 Analyse von „mittendrin“ Programm beobachten durch Modifikation des Executables leicht zu erkennen Problem mit polymorphen Code Modifikation des OS Usermode-/Kernelmode-Hooks vom OS angebotene Callbacks / Filter / Hooks Dienstag, 4. August 2009 Hooks Systemaufrufe abfangen und umleiten Usermode-Hooks leicht zu erkennen/umgehen leicht zu implementieren Kernelmode-Hooks aufwendig zu implementieren aus Usermode schwer zu entdecken/umgehen teilweise zu fein granular nicht alle Systemaufrufe landen im Kernel Dienstag, 4. August 2009 UM-Hooks - Möglichkeiten application.exe IAT EAT IAT EAT .. call {kernel32!CreateFile} .. kernel32.dll Modifikation der EAT und /oder IAT CreateFileA: .. call {ntdll!NtCreateFile} .. ntdll.dll IAT Gefahr: Adressen der DLL-Funktionen können ohne Verwendung der IAT / EAT lokalisiert werden EAT NtCreateFile: mov eax, 0x25 mov edx, &KiFastSystemCall call {ds:edx} retn 0x2c KiFastSystemCall: mov edx, esp sysenter ret MSR Usermode Dienstag, 4. August 2009 UM-Hooks Modifikation der EAT und oder IAT Aufruf der gehookten API wird umgeleitet Gefahr: DLL-Funktionen können dynamisch gesucht werden (ohne IAT / EAT) Inline-Hooks Code mit JMP zu Hookfunktion überschreiben erkennbar / umgehbar / modifizierbar Dienstag, 4. August 2009 Inline-Hooks mov edi, edi push ebp mov ebp, esp jmp hook mov edi, edi push ebp mov ebp, esp push ebp + 8 call 0x7c80e114 .. ret push ebp + 8 call 0x7c80e114 .. ret jmp remainder ret Unhooked function Hooked Function Trampoline .. call trampoline .. Hookfunction Funktionsprolog mit JMP zu Hookfunktion überschreiben überschriebene Operationen in Trampoline sichern Hookfunktion kann gehookte Funktion aufrufen Dienstag, 4. August 2009 Inline-Hooks Erkennung Erkennung über Dateivergleich, Checksumme, JMP suchen Gegenmaßnahme: TLB-Split / Desynchronize Read/Write greift auf anderen physikalischen Speicher zu als Execute, obwohl die selbe virtuelle Speicheradresse verwendet wird sehr kompliziert bisher nur Proof-Of-Concepts Dienstag, 4. August 2009 Inline-Hooks Umgehung Inline-Hooks können umgangen werden JMP-Operation wieder entfernen Usermode-Systemaufruf selber implementieren Kernelmode-Systemaufruf selber machen (sysenter) Windows-DLL kopieren, umbenennen, laden und aufrufen ... Dienstag, 4. August 2009 KM-Hooks - Möglichkeiten MSR KiSystemService SSDT KiFastCallEntry SST ntoskrnl ntoskrnl.exe KiSystemService: .. call KiFastcallEntry .. => back to usermode Service Table inline hook KiFastCallEntry: .. lookup system service call systemservice .. ret layered driver reserved SST ntoskrnl counter table service limit argument table ST ntoskrnl NtCreateFile: .. MSR ... NtCreateEventPair: .. .. NtCreateFile NtCreateEvtPair .. Kernelmode Dienstag, 4. August 2009 reserved service table Treiber modifizieren dispatcher hook SST win32k Future Work wie UM-Hooks installieren? Injection in neuen Prozess Injection in laufenden Prozess wie KM-Hooks installieren? Möglichkeiten Kernel-Treiber zu laden wie Logdaten extrahieren? IPC, Logging, UM<->KM-Kommunikation, ... Dienstag, 4. August 2009 Danke für die Aufmerksamkeit Dienstag, 4. August 2009