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