Hintergrund Vor einiger Zeit half unser Projektteam Kunden bei der Lösung einiger Probleme im Bereich der Betriebssystemsicherheit und betraf dabei die drei wichtigsten Betriebssystemplattformen: Windows, Linux und macOS. Egal, um welches Betriebssystem es sich handelt, es handelt sich im Wesentlichen um Software. Wenn Software zum ersten Mal entwickelt wird, kann sie die Bedürfnisse der Benutzer nicht zu 100 % erfüllen. Dasselbe gilt auch für Betriebssysteme. Um die Bedürfnisse der Benutzer so weit wie möglich zu erfüllen, müssen einige Mechanismen bereitgestellt werden, mit denen Benutzer das Betriebssystem anpassen können. Natürlich gibt es neben einigen offiziellen Mechanismen auch schwarze Magie. Die Verwendung dieser schwarzen Magie wird nicht empfohlen, kann jedoch manchmal als Referenz verwendet werden, wenn bestimmte Geschäftsszenarien vorliegen. Allgemeine Abfang- und Filterfunktionen unter Linux Dieser Artikel konzentriert sich auf die häufigsten Abfangvorgänge auf der Linux-Plattform:
Dynamische Bibliotheksentführung Das Hijacking dynamischer Bibliotheken unter Linux basiert hauptsächlich auf der Umgebungsvariable LD_PRELOAD. Die Hauptfunktion dieser Umgebungsvariable besteht darin, die Ladereihenfolge dynamischer Bibliotheken zu ändern, sodass Benutzer dieselben Funktionen selektiv in verschiedene dynamische Bibliotheken laden können. Eine unsachgemäße Verwendung kann jedoch zu schwerwiegenden Sicherheitsproblemen führen. Wir können es verwenden, um andere dynamische Funktionen im Hauptprogramm und in der dynamischen Linkbibliothek zu laden, was uns die Möglichkeit bietet, schädlichen Code in die Programme anderer Personen einzuschleusen. Angenommen, es gibt die folgende Funktion zur Überprüfung von Benutzername und Passwort: #include <stdio.h> #include <string.h> #include <stdlib.h> int main(int argc, char **argv) { char passwd[] = "Passwort"; wenn (argc < 2) { printf("Ungültiges Argument!\n"); zurückkehren; } wenn (!strcmp(passwd, argv[1])) { printf("Richtiges Passwort!\n"); zurückkehren; } printf("Ungültiges Passwort!\n"); } Schreiben wir ein weiteres hookStrcmp-Programm, um sicherzustellen, dass der Vergleich immer korrekt ist. #include <stdio.h> int strcmp(const char *s1, const char *s2) { /* Gibt immer 0 zurück, was bedeutet, dass die beiden Zeichenfolgen gleich sind*/ gebe 0 zurück; } Wenn Sie die folgenden Befehle nacheinander ausführen, wird unser Hook-Programm zuerst ausgeführt. gcc -Wall -fPIC -shared -o hookStrcmp.so hookStrcmp.c exportiere LD_PRELOAD="./hookStrcmp.so" Als Ergebnis können wir feststellen, dass die von uns selbst geschriebene strcmp-Funktion zuerst aufgerufen wird. Dies ist die einfachste Form des Hijackings. Wenn Sie jedoch etwas wie geteuid/getuid/getgid hijacking und dafür sorgen, dass es 0 zurückgibt, ist dies gleichbedeutend mit der Preisgabe von Root-Berechtigungen. Aus Sicherheitsgründen ist die Umgebungsvariable LD_PRELOAD daher generell deaktiviert. Linux-Systemaufruf-Hijacking Kürzlich wurde festgestellt, dass der Kernel 4.4.0 über 513 Systemaufrufe enthält (von denen viele noch nie verwendet wurden). Der Zweck des System Call Hijacking besteht darin, die ursprünglichen Systemaufrufe im System zu ändern und durch unsere eigenen Programme zu ersetzen. Alle Systemaufrufe im Linux-Kernel werden in einem Kernel-Array namens sys_call_table abgelegt, und der Wert des Arrays stellt die Einstiegsadresse des Systemaufruf-Serviceprogramms dar. Der gesamte Systemaufrufprozess ist wie folgt: Wenn ein Systemaufruf im Benutzermodus initiiert wird, gelangt er über den 80-Soft-Interrupt in den Syscall-Handler und dann in die globale Systemaufruftabelle sys_call_table, um den spezifischen Systemaufruf zu finden. Wenn wir die Adresse in diesem Array in unsere eigene Programmadresse ändern, können wir einen Systemaufruf-Hijacking erreichen. Aus Sicherheitsgründen hat der Kernel jedoch einige Einschränkungen für diesen Vorgang vorgenommen:
Für die beiden oben genannten Probleme lauten die Lösungen wie folgt (es gibt mehr als eine Methode):
/* Seite beschreibbar machen */ int make_rw (vorzeichenlose lange Adresse) { vorzeichenlose int-Ebene; pte_t *pte = lookup_address(address, &level);//Suche die Seitentabellenadresse, in der sich die virtuelle Adresse befindet pte->pte |= _PAGE_RW;//Lege die Lese- und Schreibattribute der Seitentabelle fest return 0; } /* Seite schreibgeschützt machen */ int make_ro (vorzeichenlose lange Adresse) { vorzeichenlose int-Ebene; pte_t *pte = Suchadresse(Adresse, &Ebene); pte->pte &= ~_PAGE_RW; //Schreibgeschütztes Attribut festlegen return 0; } Beginnen Sie mit dem Ersetzen von Systemaufrufen Dieser Artikel implementiert den Systemaufruf, der dem Befehl ls entspricht. Die Systemaufrufnummer lautet _ NR _getdents. statische int syscall_init_module(void) { orig_getdents = sys_call_table[__NR_getdents]; make_rw((unsigned long)sys_call_table); //Seitenattribute ändernsys_call_table[__NR_getdents] = (unsigned long *)hacked_getdents; //Neue Systemaufrufadresse festlegenmake_ro((unsigned long)sys_call_table); gebe 0 zurück; } Wiederherstellung statisches void syscall_cleanup_module(void) { printk(KERN_ALERT "Modul-Systemaufruf entladen.\n"); make_rw((vorzeichenloses langes)sys_call_table); sys_call_table[__NR_getdents] = (vorzeichenloses langes *)orig_getdents; make_ro((vorzeichenloses langes)sys_call_table); } Verwenden Sie Makefile zum Kompilieren, fügen Sie das Kernelmodul mit insmod ein und führen Sie dann ls aus. Dadurch wird unser Systemaufruf eingegeben. Wir können bestimmte Dateien im Hook-Code löschen, und ls zeigt diese Dateien nicht an, aber diese Dateien sind weiterhin vorhanden. Gestapeltes Dateisystem Linux verwendet das virtuelle Dateisystem VFS, um bestimmte Festplattendateisysteme zu vereinheitlichen und zu abstrahieren, wodurch von oben nach unten ein stapelartiger IO-Stapel entsteht. Durch die Analyse des Kernel-Quellcodes wird am Beispiel eines Lesevorgangs der folgende von oben nach unten ausgeführte Prozess ausgeführt: Der Kernel verwendet viel objektorientierte Programmierung in Form der C-Sprache, also in Form von Funktionszeigern. Beispielsweise ist read die von vfs für Benutzer bereitgestellte Schnittstelle, und der spezifische Aufruf darunter ist die Leseoperation von ext2. Solange wir die verschiedenen von VFS bereitgestellten Schnittstellen implementieren, können wir ein Stapeldateisystem realisieren. Einige gestapelte Dateisysteme wurden in den Linux-Kernel integriert. Wenn Sie beispielsweise Ubuntu installieren, werden Sie aufgefordert, Ihr Home-Verzeichnis zu verschlüsseln. Dies ist eigentlich ein gestapeltes verschlüsseltes Dateisystem (eCryptfs). Das Prinzip ist wie folgt: Es ist ein Stapeldateisystem implementiert, was bedeutet, dass alle Lese- und Schreibvorgänge in unser Dateisystem gelangen, sodass wir alle Daten abrufen und einige Abfang- und Filtervorgänge durchführen können. Nachfolgend sehen Sie das einfachste Stack-Dateisystem, das ich implementiert habe. Es bietet die einfachste Möglichkeit zum Öffnen, Lesen und Schreiben von Dateien. Es ist klein, aber vollständig. https://github.com/wangzhangjun/wzjfs Inline-Hook Wir wissen, dass es für eine Funktion im Kernel unmöglich ist, alle ihre Funktionen in dieser Funktion zu implementieren, sie muss ihre untergeordneten Funktionen aufrufen. Wenn diese untergeordnete Funktion den gewünschten gefilterten Informationsinhalt erhalten kann, können wir den Offset der untergeordneten Funktion in der übergeordneten Funktion durch den Offset der neuen Funktion ersetzen. Auf diese Weise springt die übergeordnete Funktion, wenn sie die untergeordnete Funktion aufruft, zur neuen Funktion und führt in der neuen Funktion eine Filterung und Übernahme des Inhalts durch. Im Prinzip können Inline-Hooks also überall einhaken, wo Sie wollen. Bei Inline-Hooks gibt es zwei wichtige Probleme:
Zur ersten Frage: Sie müssen über einige Erfahrung mit Kernel-Quellcode verfügen. Für den Lesevorgang lautet der Quellcode beispielsweise wie folgt: Wenn hier der Lesesystemaufruf initiiert wird, wird sys read aufgerufen und die vfs-Lesefunktion wird in sys read aufgerufen. Die Parameter von vfs read enthalten die Informationen, die wir filtern müssen, sodass wir vfs_read als Hook-Punkt verwenden können. Zur zweiten Frage: Wie haken Sie ein? Hier sind zwei Methoden: Die erste Methode besteht darin, direkt eine binäre Ersetzung durchzuführen und den Operanden der Aufrufanweisung durch die Adresse der Hook-Funktion zu ersetzen. Die zweite Methode: der vom Linux-Kernel bereitgestellte Kprobes-Mechanismus. Das Prinzip besteht darin, den Maschinencode von int 3 (x86) am Hook-Punkt einzufügen, sodass die CPU, wenn sie hier ausgeführt wird, das Sig-Trap-Signal auslöst, und dann die benutzerdefinierte Hook-Funktion in die Rückruffunktion von Sig Trap einzufügen, um den Zweck des Auslösens der Hook-Funktion zu erreichen. Dies ist eigentlich das Prinzip des Debuggers. LSM LSM ist die Abkürzung für Linux Secrity Module, was so viel bedeutet wie Linux-Sicherheitsmodul. Es handelt sich um ein allgemeines Linux-Sicherheitsframework mit den Merkmalen hoher Effizienz, Einfachheit und Benutzerfreundlichkeit. Und so funktioniert es:
Die folgenden Arbeiten werden im Kernel ausgeführt:
Anwendbare Szenarien Die oben genannten Hook-Methoden haben unterschiedliche Anwendungsszenarien.
Zusammenfassen Aus Platzgründen wird in diesem Artikel nur die Abfangtechnologie unter Linux vorgestellt. Später werden wir die Gelegenheit haben, die Abfangtechnologie unter Windows und macOS zu besprechen. Tatsächlich sind ähnliche Audit-Hooks eine zwingende Anforderung in jedem System, nicht nur im Kernel. Wir können beobachten, dass immer mehr VMs und Runtimes, sogar viele Webkomponenten und Front-End-Anwendungen, flexiblere Hook-Methoden bereitstellen. Dies ist die gängigste Lösung unter den beiden großen Sicherheitstrends Transparenz und Echtzeitleistung. Das Obige ist der vollständige Inhalt dieses Artikels. Ich hoffe, dass der Inhalt dieses Artikels einen gewissen Lernwert für Ihr Studium oder Ihre Arbeit hat. Wenn Sie Fragen haben, können Sie eine Nachricht hinterlassen. Vielen Dank für Ihre Unterstützung von 123WORDPRESS.COM. Das könnte Sie auch interessieren:
|
<<: my.cnf-Parameterkonfiguration zur Optimierung der InnoDB-Engine-Leistung
>>: WeChat-Miniprogramme ermöglichen nahtloses Scrollen
Der gemeinsam genutzte Speicher von Nginx ist ein...
MySQL 5.7.9 Version sql_mode=only_full_group_by P...
Vorwort Aufgrund der schwachen Typisierung von JS...
Hintergrund Auf Mobilgeräten ist das Caching zwis...
Inhaltsverzeichnis 1. JavaScript ist Single-Threa...
Inhaltsverzeichnis 1. Reagieren.FC<> 2. Kla...
Zunächst können Sie den Unterschied zwischen den ...
Die Methoden zur Installation von Nginx und mehre...
Inhaltsverzeichnis Vorwort Option 1: Option 2: Op...
Legen Sie ein Hintergrundbild für die Tabelle fes...
eins. Zuerst müssen Sie es in eine Idee verpacken...
1. Kabellos Führen Sie PowerShell aus und geben S...
Inhaltsverzeichnis Hintergrund Zusammengesetzte I...
<table id=" <%=var1%>">, der...
Verwandte Artikel: Anfänger lernen einige HTML-Ta...