Windows Rootkits 2005, Teil 2
Der erste Artikel dieser Serie beschäftigte sich mit aktuellen Rootkit-Techniken. Dieser Teil geht einen Schritt weiter und konzentriert sich auf kommende, innovative Techniken. Der dritte und letzte Artikel dreht sich um verschiedene Methoden, Rootkits aufzuspüren, und den vorbeugenden Schutz.
Die in diesem Artikel vorgestellten Methoden präsentierten wir in unserer Konzeptstudie Shadow Walker auf der Black Hat 2005. Sie ermöglichen es einem Angreifer, sowohl bekannten als auch unbekannten Schadcode vor einem Security-Scanner zu verstecken, indem sie dessen Speicherzugriffe auf Hardware-Ebene kontrollieren. Die Implikationen sind umso alarmierender, weil diese Technik nicht auf Rootkits beschränkt ist, sondern für alle Formen von Schadsoftware von Würmern bis hin zu Spyware anwendbar ist.
Persistente versus speicherbasierte Rootkits
Verallgemeinert gibt es zwei Typen von Rootkits: persistente Rootkits und speicherbasierte. Der primäre Unterschied ist die Lebensdauer des Rootkits auf einer infizierten Maschine. Persistente Rootkits überleben einen Neustart des Systems, während speicherbasierte dies nicht tun. Um einen Neustart zu überstehen, müssen zwei Voraussetzungen erfüllt sein. Erstens muss das Rootkit seinen Code irgendwo auf dem System permanent speichern können -- etwa auf der Festplatte. Zweitens muss es sich so in die Boot-Sequenz des Systems einklinken, dass es von der Platte geladen und ausgeführt wird.
Anders als persistente Rootkits versuchen das die speicherbasierten gar nicht erst. Ihr Code existiert nur im flüchtigen Speicher und sie können verdeckt durch einen Exploit installiert werden. So agieren sie heimlicher als ihre persistenten Geschwister und sind mit forensischen Methoden schwerer aufzuspüren. Auch wenn ihre Unfähigkeit, einen Neustart zu überleben, ihre Nützlichkeit stark einschränkt, bleiben doch Server-Systeme oft für Tage, Wochen oder Monate online. Und in der Praxis kann es dem Angreifer wichtiger sein, nicht aufgespürt werden zu können, als auszuschließen, dass er ein infiziertes System verliert.
Ein Rootkit verstecken
Rootkit-Autoren haben eine Reihe raffinierter Methoden entwickelt, die Anwesenheit ihres Rootkits auf einem System zu verbergen. Sie reichen von diversen Hooking-Tricks bis hin zur direkten Manipulation von Kernel-Objekten (DKOM). Doch auch die ausgefeiltesten Rootkits wie FU haben ein inhärentes Problem [1]. Sie sind zwar Meister darin, den Ausführunsgsablauf zu kontrollieren, aber sie weisen bisher kaum Fähigkeiten auf, zu kontrollieren, wie Applikationen den Speicher sehen. Somit müssen solche Rootkits zwei Dinge gewährleisten, wenn sie unbemerkt bleiben wollen: Sie müssen ihren eigenen ausführbaren Code verstecken und die von ihnen durchgeführten Veränderungen im Speicher verbergen – also beispielsweise die Hooks.
Ohne diese Fähigkeiten sind auch die ausgefeiltesten, veröffentlichten Kernel-Rootkits "stehende Ziele" für primitive Signatur-Scans im Speicher wie sie Antiviren-Programme seit 20 Jahren einsetzen. Darüber hinaus müssen persistente Rootkits ihren Code auf dem nichtflüchtigen Speichermedium und auch den Eintrag in der Boot-Sequenz des Systems verstecken. In diesem Artikel beschäftigen wir uns mit den ersten beiden Aspekten und ignorieren den dritten, was faktisch die Diskussion auf speicherbasierte Rootkits begrenzt.
Das Problem, Code und/oder Änderungen im Speicher zu verstecken, erinnert daran, wie die ersten Virenschreiber versuchten, ihren Code im Dateisystem zu verstecken. Sie reagierten auf die ersten signaturbasierten Virenscanner, indem sie polymorphe und metamorphe Viren entwickelten. Polymorphismus versucht das äußerliche Erscheinungsbild eines Code-Blocks zu modifizieren, ohne seine Funktion zu ändern. Als einfaches Analogon kann man Synonyme betrachten -- also verschiedene Wörter mit exakt der gleichen Bedeutung. Ein polymorpher Virus ersetzt Befehle (Wörter) durch andere Opcodes (Synonymen), die exakt die gleiche Funktion haben. Damit ändert sich das "Aussehen" des Virus und er ist immun gegen einfache musterbasierte Erkennung.
Nur sehr wenige veröffentlichte Rootkits haben nennenswerte Anstrengungen unternommen, polymorphe Techniken der Viren einzubauen. Obwohl Polymorphismus durchaus effektiv sein kann, um Code vor Signatur-Scans zu verbergen, hilft er wenig, um die Änderungen zu verbergen, die ein Rootkit an existierendem Binärcode in anderen Systemkomponenten vornimmt. Anders gesagt bleiben gekaperte Systemkomponenten anfällig für Integritäts-Checks im Speicher. Eine bessere Lösung ist es folglich, nicht den Rootkit-Code selbst zu ändern, sondern das, was andere Systemkomponenten von ihm "sehen".
In den folgenden Absätzen zeigen wir, wie die aktuelle Architektur es erlaubt, die virtuelle Speicherverwaltung so zu unterwandern, dass ein nicht-polymorphes Kernel-Mode-Rootkit die lesenden Speicherzugriffe des Betriebssystems und anderer Prozesse kontrollieren kann. Zunächst liefern wir dazu einen Überblick über die Architektur des virtuellen Speichers. Danach schildern wir, wie die Konzeptstudie Shadow Walker das Speichersubssystem unterwandert, um ausgeführten Code vor einem Security-Scanner zu verbergen. Und schließlich diskutieren wir die Implikationen dieser Technik sowohl für Security-Profis als auch Hacker.
WEITER GEHT ES HIER