Bootkit-Analyse

Hallo allerseits! Im Zusammenhang mit dem Start des Kurses „Reverse Engineering“ haben wir eine geplante offene Stunde abgehalten. Der Bootkit-Betriebsalgorithmus wurde in verschiedenen Phasen des Ladevorgangs zerlegt.



Dozent - Arthur Pakulov , Virusanalyst bei Kaspersky Lab.

Der folgende Artikel ist eine Einführung und eine Textversion nur eines Teils der Lektion, die sich mit dem Bootkit-Installationsprogramm befasst. Eine detaillierte Analyse des Bootkits selbst finden Sie im Video.

Ein Bootkit ist ein bösartiges Programm, das Master Boot Record, den ersten Sektor der ersten physischen Festplatte oder des ersten Bootsektors, VBR, ändert. Programme dieser Art verfügen im Grunde genommen über eine Trojaner-Funktionalität und werden verwendet, um verborgene Aktionen im System auszuführen. In unserem Beispiel führt das Bootkit eine Privilegieneskalation auf die Prozessebene durch, deren Name mit einer Folge von Buchstaben beginnt: „inte“. Tatsächlich ist ein Bootkit ein Rootkit, das im 0-Schutzring zu funktionieren beginnt, der bereits gestartet wird, bevor das Betriebssystem geladen wird. Aus diesem Grund ist er für die Forschung von großem Interesse.

Um ein solches Programm zu entwickeln, reichen die üblichen Reverse Engineering-Kenntnisse nicht aus. Es reicht nicht aus, nur die Liste lesen zu können, sondern Sie müssen auch Dinge wie Prozessorarchitektur, Speicheradressierung usw. verstehen. Wir haben uns in einer offenen Lektion die wichtigsten Stellen des Bootkits angesehen.

Für die Arbeit wurde ein spezielles Beispiel für bootkit-xp.exe vorbereitet, das unter Windows XP funktioniert. Wir haben uns also nicht nur mit dem Bootkit befasst, sondern waren auch ein bisschen nostalgisch für dieses Betriebssystem. Im Allgemeinen wurde jedoch OS XP gewählt, um das Zurücksetzen zu vereinfachen, da XP eine gute Visualisierung ist und keine unnötigen Komplikationen auftreten. Nun, das Beispiel wurde speziell für dieses Betriebssystem geschrieben, gemessen am Code.

So sieht das Bootkit-Installationsprogramm aus :



Wenn Sie es sich nur ansehen, können Sie bestimmte Schlussfolgerungen ziehen. Beispielsweise ist sofort ersichtlich, dass diese Datei ein geringes Gewicht hat. Wenn Sie sich den Einstiegspunkt ansehen, sehen Sie, dass der Code einen Dateideskriptor mit dem Namen einer symbolischen Verknüpfung zur ersten physischen Festplatte - "PhysicalDrive0" - empfängt:



Um den Code besser verstehen zu können , haben wir auf IDA umgestellt . Es wird deutlich, dass für einen typischen Trojaner die verfügbare Funktionalität recht gering ist. Auch die Importtabelle ist verdächtig klein:



Ein solches Bild entsteht normalerweise bei der Analyse von verpackten Proben. In unserem Fall sieht die Datei jedoch nicht gepackt aus. Es stellt sich heraus, dass das Sample entweder von einem Protector / Cryptor abgedeckt wird und während seiner Arbeit die Adressen von Funktionen auf dynamische Weise erhält, wonach es das gewünschte Functional aufruft, oder dass alles in Ordnung ist und das Sample so ist, wie es ist.

Wir untersuchen den Code weiter.



Wie wir in HIEW gesehen haben, wird die CreateFileA- Funktion mit einem interessanten Argument als erstem Parameter aufgerufen. Hier ist es angebracht, sich an so etwas wie Kernelobjekte zu erinnern. Sie können nicht direkt vom Benutzermodus aus bearbeitet werden, sondern werden vom Kernel des Betriebssystems gesteuert. Im Benutzermodus kann ein Programm nur den Empfang / die Änderung des Status eines Kernelobjekts anfordern. Um dem System anzuzeigen, mit welchem ​​bestimmten Kernelobjekt das Programm arbeiten wird, muss das Handle des erforderlichen Kernelobjekts abgerufen werden. Wenn alle Prüfungen bestanden sind, sendet das Betriebssystem auf Anforderung des Eingangs das Handle des angeforderten OA an uns zurück. Und bereits mit handle können wir mit dem zugehörigen OA arbeiten.

In der obigen Abbildung wird daher mit CreateFile auf eine symbolische Verknüpfung zur ersten verbundenen physischen Festplatte zugegriffen. Wenn der Zugriff gewährt wird, können Sie mit einer solchen „Datei“ wie mit jeder anderen einfachen Datei arbeiten. Das heißt, die gesamte Festplatte wird als einzelne große Datei dargestellt.

Also lasst uns weitermachen. Handle ist zurück und wir befinden uns hier:



Was passiert als nächstes? Und dann liest die ReadFile- Funktion die ersten 0x200-Bytes. Und wir haben dort den allerersten Sektor der ersten physischen Festplatte.



Wie Sie vielleicht erraten haben, handelt es sich um den Master Boot Record (MBR). MBR besteht aus 3 Teilen: Codeteil, Partitionstabelle und Signatur. In einer normalen Situation liest das BIOS den MBR unter der Adresse 0: 0x7c00h in den Speicher und übergibt ihm die Kontrolle. Der Codeabschnitt des MBR wird also ausgeführt. Während der Ausführung analysiert es die Partitionstabelle, findet den Bootsektor und lädt ihn. Wenn der MBR bei einem Bootkit überschrieben wird, erhält sein Code nun die Kontrolle.

Ok, MBR wird gelesen und wie geht es weiter ? Und dann öffnet das Bootkit PhysicalDrive0 erneut, jedoch mit Schreibzugriffsmodus.



Als nächstes wird ein Zeiger auf den 600. Versatz gesetzt. Das heißt, der ursprüngliche Sektor wird gelesen und in den dritten Sektor kopiert .

Warum einen Sektor sichern? Dies ist natürlich notwendig, damit es in Zukunft benötigt wird.

Dann beginnt der Zyklus. Wenn man sich den Code ansieht, muss man natürlich auf Konstanten wie var_1C, 1BEh und andere achten . Gleichzeitig sollte die darüber befindliche MBR-Struktur im Speicher aktualisiert werden. Insbesondere interessieren wir uns für die Spalte „Offset“.



Der Lesepuffer des ersten Sektors befindet sich in lpBuffer . Dann wird 1BEh hinzugefügt, und der Zeiger springt an den Anfang der Partitionstabelle. Alle Daten von der Tabelle bis zum Ende des Sektors werden ab dem gleichen Offset - 1BE - in _markierte_Bytes eingefügt.



Das heißt, der zweite und dritte Teil des ursprünglichen MBR werden in _markierte_ Bytes eingefügt.

Was passiert als nächstes? Und dann setzt SetFilePointer den Zeiger auf den Anfang unserer „Datei“, das heißt auf den MBR.



Dann gibt es ein Schreiben (WriteFile), das _markierte_ Bytes bildet und Speicher freigibt . Damit endet die Funktionalität des Bootkit-Installationsprogramms.

Aber es wäre schön zu sehen, was genau im ersten Teil von _marked_bytes steht . Speichern Sie es dazu auf der Festplatte und analysieren Sie es. Das erste, was auffällt, ist eine Verringerung des Inhalts der Variablen um 2 bei 0x413.



Wenn Sie sich die technische Dokumentation ansehen, können Sie feststellen, dass die Variable bei 0X413 die Größe des physischen Speichers in Kilobyte enthält. Dementsprechend schneidet der Bootkit-Code zwei Kilobyte Speicher ab:



Um dies nicht weiter zu tun, wird davon ausgegangen, dass 2 Kilobyte weniger Speicher als zuvor vorhanden sind. Warum - ist noch nicht klar.

Als nächstes wird die physikalische Adresse mit einer bitweisen Linksverschiebung von 6 Bits auf das "Bit aus" -Speicherstück berechnet:



Eine Verschiebung von 6 führt zwei Aktionen gleichzeitig aus - konvertiert Kilobytes in Bytes (multipliziert den Wert der Variablen mit 2 ^ 10), um die physikalische Adresse des abgebissenen Speicherstücks zu erhalten, und extrahiert die Segmentnummer daraus, indem das Ergebnis durch 0x10 (2 ^ 4) dividiert wird.

Danach wird Ihr Körper über dieses Teil des Speichers kopiert, und da der Bootkit-Code im Teil "Bit off" ist, wird ihn niemand weiter stören . Darüber hinaus ändert keine Unterbrechung nicht, was in diesem Speicherbereich geschrieben ist. Wir können sagen, dass der Code für das System praktisch unsichtbar wird , als ob dort kein Speicher vorhanden wäre.

Dies ist nur der Anfang des Bootkits. Dann gibt es Interrupt-Interception, NTLDR-Signatur-Tracking, Modifikation des Betriebssystem-Kernel-Moduls usw.

Deshalb werden wir es nicht verderben, es ist besser, das Webinar bis zum Ende anzusehen , um nichts zu verpassen.

Source: https://habr.com/ru/post/de482086/


All Articles