Beliebte Suchanfragen

Cloud Native

DevOps

IT-Security

Agile Methoden

Java

//

Aber ich habe doch ein Antivirusprogramm …

3.8.2022 | 7 Minuten Lesezeit

Antivirus- und EDR-Funktionsweise

In der Vergangenheit haben sich Antivirusprogramme auf das Entdecken und Beseitigen von schädlichen Dateien spezialisiert. Dabei überprüften sie das Dateisystem und Dateien während der Ausführung.

EDR-Software (Endpoint Detection and Response) hingegen betrachtete die Laufzeit von Programmen und analysierte Verhaltensmuster wie „post exploitation activities“ – also Aktionen, die durchgeführt wurden nachdem ein System bereits übernommen wurde, um Informationen zu sammeln oder sich lateral im Netzwerk weiter zu bewegen. Heute verschmilzen diese beiden Arten, sodass beide Systeme ebenfalls Aufgaben des jeweils anderen übernehmen.

Bei der Analyse von potenzieller Malware kommen verschiedene Methoden zum Einsatz.

Statische Analyse

Bei der statischen Analyse werden Dateien auf bekannte Signaturen untersucht. Signaturen können beispielsweise bekannte Byteketten, Strings oder Dateihashes sein. Werden diese Signaturen erkannt, wird die Datei als maliziös gekennzeichnet. Da diese Art der Analyse ausschließlich auf bekannten Signaturen basiert, eignen sich solche Systeme nicht zum Finden von neuen Bedrohungen.

Statische heuristische Analyse

Bei der statischen heuristischen Analyse wird das Verhalten von potenzieller Malware analysiert. Dabei werden beispielsweise Programme dekompiliert und mit Mustern von bekannter Malware verglichen. Ein Muster kann beispielsweise eine Menge an durchgeführten Syscalls in einer für Malware typischen Reihenfolge sein. Dieses Verfahren ermöglicht somit das Finden von Malware, dessen Signaturen bisher unbekannt sind. Dadurch, dass es allerdings auch nicht-schädliche Software geben kann, die ähnliche Muster verwenden (Antivirussoftware beispielsweise) sind heuristische Verfahren anfällig für falsch-positive Ergebnisse. Über eine Entropyanalyse, also die Gleichverteilung der unterschiedlichen Bytes innerhalb einer Datei, lässt sich zudem eine mögliche Verschlüsselung erkennen. Diese Analyse lässt sich allerdings auch einfach umgehen, indem beispielsweise Schadcode nicht in der ausführbaren Datei selber gespeichert wird, sondern dieser über das Netzwerk oder eine weitere Datei nachgeladen wird.

Dynamische Analyse

Bei dynamischen Analysen wird potenzielle Malware in einer virtuellen Umgebung ausgeführt und analysiert. In Kombination mit statischer und heuristischer Analyse kann auch Malware erkannt werden, die erst zur Laufzeit entschlüsselt wird. Dynamische Analysen sind aktuell die am häufigsten eingesetzten Verfahren. Leider können auch diese umgangen werden, indem beispielsweise eigene unbekannte Verschlüsselungsverfahren verwendet werden, oder die reguläre Ausführung des Scans unterbrochen wird. Eine Unterbrechung kann zum Beispiel einfach durch eine längere sleep-Anweisung oder das Allozieren sehr großer Speicherbereichen erreicht werden. Einige EDRs untersuchen lediglich den Hauptprozess einer Anwendung. Wenn die Malware sich selbst in einem child-Prozess erneut startet, hebelt das einige Scanner bereits aus.

Antivirus-Lifecycle

Um zu verstehen, wieso es trotz der oben genannten Methoden zur Malware-Analyse schwierig ist, sämtliche Malware zu erkennen, wird im kommenden Abschnitt betrachtet, wie AV- oder EDR-Software auf den Systemen funktionieren.

User- und Kernel Space

Antivirenprogramme „nisten“ sich in der Regel an zwei Stellen des Betriebssystems ein. Zum einen in Form eines Services im User-Space und zum Anderen in Form eines Treibers im Kernel-Space. Die Kernel-Komponenten (siehe minifilter driver ) monitoren Systemaktivitäten wie Festplatten- oder Netzwerkoperationen oder registrieren sogenannte Kernel-Callbacks, um über Events wie neue Prozesse informiert zu werden, wie neue Threads, Registry- oder Rechteänderungen. Die User-Space-Komponente dient zum Einen als Schnittstelle für die Kernel-Komponenten (zum Beispiel, um Ereignisse zu loggen) und zum Anderen zum Injizieren von Monitoring-DLLs (Dynamic-link library) in Prozesse. Wenn die EDR-Software beispielsweise einen neuen Prozess erkennt, wird eine Monitoring-DLL in diesen neuen Prozess injiziert. Das Programm „listdlls “ der Toolsammlung Sysinternals kann verwendet werden, um alle zu einem Prozess zugehörigen DLLs anzuzeigen.

Dieser Screenshot zeigt die injizierte BitDefender-DLL, atcuf64.dll welche von dem notepad-Prozess verwendet wird.

Diese DLL erlaubt es den EDR-Systemen, sogenannte hooks zu installieren, mit deren Hilfe Informationen über aufgerufene Funktionen geloggt werden können (welche Funktion, wann, welches Modul, welche Parameter etc.). Meistens werden diese hooks auf Funktionen der ntdll.dll installiert, da diese die letzte Userspace-DLL ist, die direkt mit dem Kernel-Interface kommuniziert.

Ein Beispiel für eine Funktion, die Malware häufig verwendet und EDRs als verdächtig einstufen können, ist SetWindowsHookExA . Diese Funktion erlaubt das Definieren von Callback-Funktionen, die zum Beispiel auf Tastatur- oder Mausevents reagieren. Damit lässt sich beispielsweise ein Keylogger implementieren, der sämtliche Tastatureingaben in einer Textdatei abspeichert oder in regelmäßigen Abständen Screenshots aufnimmt und an den Angreifer sendet. Da es sich allerdings um Standard-WinAPI-Funktionen handelt und demnach von vielen Programmen verwendet wird, ist diese Funktion alleine nicht ausreichend, um eine Anwendung als gefährlich einzustufen.

Dieser Abschnitt hat erklärt, wie sich Antivirenprogramme verhalten und welche Methoden sie verwenden, um Informationen zu sammeln. Im nächsten Abschnitt vergleichen wir nun, wie Malware funktioniert.

Beispielhafte Malware-Funktionsweise – “Classic DLL Injection”

Disclaimer: Hier werden keine neuen oder unbekannten Techniken beschrieben. Die Beispiele sind bekannt und es wird kein maliziöser Quelltext gezeigt, sondern lediglich ein Verfahren erläutert, wie Malware funktioniert.

Malware nutzt ähnliche Methoden wie Antivirenprogramme, um Schadcode auszuführen oder Hintertüren auf Systemen zu installieren. Ein klassisches Beispiel ist die DLL process injection-Methode. Hier wird eine DLL an einen existierenden oder neuen Prozess angehängt, um beispielsweise Schadcode auszuführen oder Hintertüren zu installieren. Um dieses Verfahren zu demonstrieren, wird im Folgenden ein sogenannter Loader programmiert, der anschließend eine DLL an einen Prozess anhängt und ausführt.

Loader

Die Aufgabe des Loaders ist das Nachladen und Ausführen von Schadcode. Dabei kommen oft verschiedene Methoden zum Entschlüsseln und zum Verstecken der Malware zum Einsatz. An dieser Stelle wird der Einsatz von dynamischen Analyseverfahren von EDR-Programmen essenziell. Das Nachladen, Entschlüsseln und Ausführen der Malware findet ausschließlich im Arbeitsspeicher statt, sodass die klassischen signaturbasierten Analysen nicht mehr funktionieren.

Das folgende Beispiel zeigt, wie ein einfacher Loader aussehen kann:

1int main(int argc, char *argv[]) {
2    HANDLE procHandle;
3    PVOID remoteBuffer;
4 
5    int processId = atoi(argv[1])
6    int s = strlen(argv[2])+1;
7    wchar_t dllPath[s];
8    size_t convertedChars = 0;
9    mbstowcs_s(&convertedChars, dllPath, s, argv[2], _TRUNCATE);
10 
11    printf("[X] Injecting DLL into process: %i\n", processId);
12    procHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, DWORD(processId));
13    remoteBuffer = VirtualAllocEx(procHandle, NULL, sizeof dllPath, MEM_COMMIT, PAGE_READWRITE);
14    WriteProcessMemory(procHandle, remoteBuffer, (LPVOID)dllPath, sizeof dllPath, NULL);
15    PTHREAD_START_ROUTINE threatStartRoutineAddress = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryW");
16    CreateRemoteThread(procHandle, NULL, 0, threatStartRoutineAddress, remoteBuffer, 0, NULL);
17    CloseHandle(procHandle);
18 
19    return 0;
20}

Über die Parameter processId und dllPath wird angegeben, welcher Prozess als Host verwendet und welche DLL injiziert werden soll. Nachdem der Prozess gefunden wurde (OpenProcess), wird ausreichend Speicher reserviert (VirtualAllocEx), um die DLL zu laden (WriteProcessMemory). Zum Ausführen wird die Funktion (LoadLibraryW) verwendet, indem die Addresse dieser Prozedur innerhalb der kernel32-Bibliothek gesucht und anschließend mit der geladenen DLL als Parameter (remoteBuffer) gestartet wird (CreateRemoteThread).

DLL-Beispiel

Nachfolgend wird der Sourcecode der kompilierten DLL dargestellt. Beim Anhängen der DLL an den Prozess wird lediglich eine MessageBox geöffnet. Bei Malware wäre an dieser Stelle komplexer Shellcode zu finden.

1BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
2{
3    switch (fdwReason)
4    {
5    case DLL_PROCESS_ATTACH:
6        OutputDebugString("DLL_PROCESS_ATTACH");
7        MessageBox(NULL, "Dll Attached", "TestDll.dll", MB_OK);;
8        break;
9    }
10    return TRUE;
11}

Analyse

Der folgende Screenshot zeigt die Ausführung des Programms. In diesem Setup wurde das Programm notepad gestartet, welches die Prozess ID (PID) 1244 zugewiesen bekommen hat. Der Loader wurde mit dieser PID und dem Pfad zur erzeugten DLL gestartet. Die DLL wird an den Prozess angehängt und die MessageBox erscheint.

Das Tool listdlls listet die genutzten DLLs des Prozesses auf und man kann erkennen, dass die TestDll erfolgreich injiziert wurde.

Zum Analysieren, wie unterschiedliche Antivirenprogramme auf Dateien reagieren, gibt es Online-Services wie virustotal oder antiscan.me. Der erzeugte Loader wurde lediglich von einem Antivirenprogramm als potenziell gefährlich eingestuft. Da an dieser Stelle tatsächlich kein echter Schadcode vorhanden ist, ist dieses Ergebnis wenig überraschend.

Nimmt man im Vergleich beispielsweise eine echte DLL, die eine Verbindung zu einem Angreifer aufbauen würde, sieht das Scanergebnis wie folgt aus:

An dieser Stelle beginnt die Herausforderung für Malware-Entwickler. Sie müssen den Schadcode so verändern oder verstecken, dass die verschiedenen ERDs ihn nicht erkennen.

Fazit

In diesem Beitrag wurde anhand eines Beispiels beschrieben, wie Antivirusprogramme funktionieren. Es wurde eine (primitive) Technik zum Verstecken von Malware beschrieben, die ähnliche Vorgehensweisen verwendet, wie sie auch von EDR-Software eingesetzt werden.

Aufgrund der Tatsache, dass sich sowohl Malware als auch EDR-Software ständig weiterentwickeln, ist es wichtig zu akzeptieren, dass EDR-Programme kein Allheilmittel sind. Insbesondere beim Auffinden von bekannter Schadsoftware oder Verhaltenssignaturen sind AV-Programme richtig und wichtig. Die Grenzen erkennt man allerdings schnell, wenn Schadcode beispielsweise kreativ versteckt wird und ausschließlich im Arbeitsspeicher zusammengesetzt und ausgeführt wird.

Software sollte als Hilfsmittel und als ein Teil des Sicherheitskonzeptes angesehen werden. Wichtiger als der Einsatz von Software ist allerdings das Bewusstsein wie Malware funktioniert, wo sie herkommen kann und wie man erkennt ob es sich um Schadcode handelt.

Deshalb:

  • Zugesandte Anhänge sollte immer hinterfragt werden.
    • Wer ist der Absender?
    • Was soll der Anhang beinhalten? (Passt der Inhalt zum Absender?)
    • Der Absender sollte kontaktiert werden, um die Authentizität der E-Mail zu klären, wenn man sich unsicher ist.
  • Unbekannte/gefundene Speichermedien sollten nicht genutzt werden.
  • Wenn der Arbeitsplatz verlassen wird, sollte der Rechner gesperrt werden.
  • Installierte Software sollte immer auf dem aktuellsten Stand gehalten werden.

Beitrag teilen

Gefällt mir

1

//

Weitere Artikel in diesem Themenbereich

Entdecke spannende weiterführende Themen und lass dich von der codecentric Welt inspirieren.

//

Gemeinsam bessere Projekte umsetzen.

Wir helfen deinem Unternehmen.

Du stehst vor einer großen IT-Herausforderung? Wir sorgen für eine maßgeschneiderte Unterstützung. Informiere dich jetzt.

Hilf uns, noch besser zu werden.

Wir sind immer auf der Suche nach neuen Talenten. Auch für dich ist die passende Stelle dabei.