Linux Rootkits
Transcrição
Linux Rootkits
Lehrstuhl Netzarchitekturen und Netzdienste Institut für Informatik Technische Universität München Linux Rootkits Referent: Clemens Paul Betreuer: Simon Stauber / Holger Kinkelin 12.04.2013 Linux Rootkits 1 Agenda Einführung User-Mode-Rootkits Kernel-Mode-Rootkits Patchen des Kernels durch die Devices /dev/mem und /dev/kmem Loadable Kernel Module (LKM) System-Call Allgemeines Hooking-Methoden Auslesen der Adresse der System-Call-Table Funktionalität und Demo eines selbst entwickelten Rootkits Detektion von Rootkits Zusammenfassung Linux Rootkits 2 Einführung Definition nach Raúl Siles Peláez: „[…] a rootkit is a tool or set of tools used by an intruder to hide itself ‘masking the fact that the system has been compromised‘ and to keep or reobtain ‘administrator-level (privileged) access‘ inside a system.“ [1, p. 8] Root-Zugriff Voraussetzung Typische Funktionalitäten: Stealth – Spuren des Angreifers verbergen Backdoor – somit kann ein Angreifer wieder auf das System zugreifen Sniffer – abhören von Systemkomponenten (z.B. Netzwerk, Keylogger) Dient nun häufig dazu Schadprogramme (Malware) unbemerkt einzuschleusen und auszuführen Einteilung von Rootkits: User-Mode-Rootkits Kernel-Mode-Rootkits Linux Rootkits 3 User-Mode-Rootkits Infizieren das Betriebssystem außerhalb des Kernels laufen in Ring 3 der Unix Ring-Terminologie Ebene mit niedrigsten Zugriffsrechten Ersetzen spezifische Systemkomponenten laufende Prozesse verbergen durch Ersetzen von ps, top etc. Netzwerkverbindungen verbergen durch Ersetzen von netstat, ss etc. Nachteil für Angreifer zu viele Binärdateien ersetzen, die betriebssystemspezifisch sind Erkennung und Vorbeugung einfacher als bei Kernel-Mode-Rootkits Beispiele: Login, T0rnkit, LRK (The Linux Rootkit) Linux Rootkits 4 Kernel-Mode-Rootkits Bieten alle Features von User-Mode-Rootkits auf tieferer Ebene an laufen in Ring 0 der Unix Ring-Terminologie höchste Rechte Applikationen verwenden System-Calls, um mit dem Kernel zu kommunizieren Modifizieren von System-Calls getdents64 System-Call, um Dateien zu verbergen Verbergen von Malware Verschiedene Möglichkeiten um Kernel zu manipulieren: Patchen des laufenden Kernels Schadcode in den Kernel laden Linux Rootkits /dev/mem und /dev/kmem Loadable Kernel Module (LKM) 5 Kernel-Mode-Rootkits – /dev/(k)mem /dev/mem Device – physikalischer Speicher /dev/kmem Device – virtueller Speicher wird von Kernel genutzt Für den Zugriff können die APIs read(), write(), mmap() verwendet werden Super User Control Kit („SuckIT“) Verändert die originale System-Call-Table (SCT) nicht Integritätsprüfung OK Erstellt Kopie der SCT, diese Kopie wird manipuliert Funktionen: Prozesse, Dateien, Netzwerk-Sockets verbergen, sniffen von TTYs Linux Rootkits 6 Kernel-Mode-Rootkits – Loadable Kernel Module (1) Kernel-Module erweitern die Funktionalität des Kernels z.B. Gerätetreiber lsmod Modul anzeigen insmod Modul laden rmmod Modul entladen #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> // used by every module // used by KERNEL_ALERT // used by macros static int init(void) { printk(KERN_ALERT "Hello\n"); return 0; } static void exit(void) { printk(KERN_ALERT "Goodbye\n"); } module_init(init); module_exit(exit); Linux Rootkits 7 Kernel-Mode-Rootkits – Loadable Kernel Module (2) Hauptproblem von LKM wird nach Neustart nicht geladen Ändern von Boot-Scripts durch Integritätsprüfung leicht feststellbar Zwei Methoden, um Neustart zu überstehen: Ein anderes laufendes LKM infizieren Kernel-Image des Systems patchen Beispiele für LKM-Rootkits: „adore“, „adore-ng“ – von „Stealth“ entwickelt „knark“ – von „Creed“ entwickelt Linux Rootkits 8 System-Call – Allgemeines (1) System-Call wird von Applikationen verwendet, um mit dem Kernel zu kommunizieren Beispiele für System-Calls: sys_read sys_write sys_fork Linux Rootkits um Key-Logger zu implementieren 9 System-Call – Allgemeines (2) Linux Rootkits 10 System-Call – Allgemeines (3) – IDT Interrupt-Descriptor-Table (IDT) – verbindet Interrupt- und ExceptionVector mit den jeweiligen Adressen der Handler Maximal 256 Einträge Jeder Eintrag ist eine 8 Byte große Adresse IDT Register (IDTR) spezifiziert Base-Adresse und Limit der IDT die Speicherstelle der IDT ist beliebig IDT wird mit Assembler-Instruktion lidt (Load IDT) initialisiert Linux Rootkits 11 System-Call – Hooking Methoden – IDT/SCT Hooken Angriffsszenario für IDT: Angriffsszenario für SCT: Erstellen einer neuen InterruptDescriptor-Table Erstellen einer neuen System-CallTable Umleiten des Pointers des IDTRs von originaler IDT auf kopierte IDT Umleiten des Pointers der IDT von originaler SCT auf kopierte SCT Manipulieren der kopierten IDT Manipulieren der kopierten SCT Integrität der original Tabelle bleibt erhalten Linux Rootkits 12 System-Call – Hooking Methoden – SCH Hooken (1) Vor dem Hooking: Linux Rootkits 13 System-Call – Hooking Methoden – SCH Hooken (2) Nach dem Hooking: Linux Rootkits 14 System-Call – Auslesen der SCT Adresse Statisch: Dynamisch: Aus Datei „/boot/System.mapKernel-Version“ Brute-Force-Scan des Kernel-Speichers zwischen 0xc0000000 und 0xd0000000 (32-Bit Architektur) Vergleiche Speicher mit exportiertem System-Call (z.B. sys_close) static unsigned long** find_syscall_table(void) { unsigned long **sctable; unsigned long i; for(i = 0xc0000000; i < 0xd0000000; i++) { sctable = (unsigned long **)i; if (sctable[__NR_close] == (unsigned long *) sys_close) { return &sctable[0]; } } return NULL; } Linux Rootkits 15 Funktionalität eines Rootkits – File Hiding Hooken des getdents64 System-Call Erstellen eines neuen System-Call-Handlers Anpassen der System-Call-Table Linux Rootkits 16 Funktionalität eines Rootkits – Process Hiding Programme wie ps verwenden die Liste all-tasks Der Task-Scheduler des Kernels verwendet die Liste run-list Angriff: löschen der Prozesse aus der Liste all-tasks Linux Rootkits 17 Funktionalität eines Rootkits – Module Hiding Module werden in zwei Listen gespeichert: /proc/modules – von lsmod verwendet list_del_init(struct list_head*entry) entfernen durch die Funktion /sys/module/ – Verzeichnis, das alle Module anzeigt Funktion kobject_del(struct kobject *kobj) Linux Rootkits entfernen durch die 18 Funktionalität eines Rootkits – Demo Linux Rootkits 19 Detektion von Rootkits Schwierig ein Rootkit von einem infizierten System aus zu entdecken Zwei Ansätze zur Detektion von Rootkits Das Rootkit selbst entdecken Das Verhalten des Rootkits entdecken „LynxSecure 5.2“ – verwendet Virtualisierungstechnologie um Rootkits in Echtzeit zu entdecken Linux Rootkits 20 Zusammenfassung Rootkits können Spuren von sich und von anderer Malware verbergen Rootkits werden in User-Mode- und Kernel-Mode-Rootkits unterteilt Rootkits verwenden häufig System-Calls als Angriffsquelle Linux Rootkits 21 Linux Rootkits 22 Literaturreferenzen [1] Silez Peláez, R., Linux kernel rootkits: protecting the system's "Ring-Zero". SANS Institute, 2004. [2] Quade, J., Kernel Rootkits and Countermeasures. http://www.linuxmagazine.com/Online/Features/Kernel-Rootkits-and-Countermeasures. Aufgerufen am 24. März 2013. Linux Rootkits 23 Backup (1) – Lesen von /dev/kmem Code-Beispiel zeigt wie von /dev/kmem gelesen wird /* read from virtual memory */ int read_kmem(off_t offset, void* buf, size_t count) { int fd; int n; fd = open("/dev/kmem", O_RDONLY); // open device if (fd < 0) { perror("open /dev/kmem failed"); return -1; } lseek(fd, offset, SEEK_SET); // jump to the given offset n = read(fd, buf, count); // read from the device if (n != count) perror("/dev/kmem read failed"); else printf("/dev/kmem read buf = %ld\n", *(unsigned long *)buf); close(fd); return n; } Linux Rootkits 24 Backup (2) – IDT Struktur des IDTR Registers struct idtr { uint16_t limit; uint32_t base; //! size of the interrupt descriptor table (idt) //! base address of idt }; Code-Beispiel, das zeigt wie man die IDT Adresse erhält uint32_t idt_table; __asm__(" sidt %0" : "=m"( idtr )); idt_table = idtr.base; funktioniert bei VMs nicht Linux Rootkits 25 Backup (3) – Privilege Escalation Kopieren der Credentials des Init-Prozesses in den Prozess, der RootRechte erhalten soll durch Datenstruktur Erhalten der notwendigen Datenstruktur (struct task_struct) der Prozesse durch Hilfsfunktion Linux Rootkits 26 Backup (4) - Ausblick „LynxSecure 5.2“ verwendet Virtualisierungstechnologie, um Rootkits und Bootkits in Echtzeit zu erkennen Es gibt nur wenige Programme zum Aufspüren und Entfernen von Rootkits Bootkits kommen zum Einsatz bevor der Kernel geladen wird BIOS-Bootkit diente als Angriff im Jahr 2011 Smartphones dienen als weitere Angriffsquelle Linux Rootkits 27