
Script zur Automatisierung der Linux-Speichererfassung und -analyse
Ein Skript zum Auslesen des Linux-Arbeitsspeichers und Erstellen von Volatility(TM)-Profilen. Hal Pomeranz ([email protected]), 2020-02-01
„Wenn ich weiter gesehen habe, dann nur, weil ich auf den Schultern von Giganten stehe.“ ~ Isaac Newton
Viele Menschen verdienen Dank dafür, dass dieses kleine Werkzeug möglich wurde:
– Die guten Leute von Microsoft, die AVML verfügbar gemacht haben
– Joe Sylve für seine Arbeit an LiME
– Das gesamte Volatility(TM)-Entwicklungsteam für ihre fortlaufende Arbeit. Besonders erwähnen möchte ich Andrew Case, der mir während der Entwicklung meines Tools eine Reihe lästiger Fragen beantwortet hat.
– David Anderson für seine fortlaufende Unterstützung von libdwarf und dwarfdump
– Matt Suiche von MoonSols. Als ich mein Tool zusammenstellte, lautete mein Designziel: „Mach es so einfach zu bedienen wie DumpIt“ (wenn Sie Windows-Arbeitsspeicher erfassen müssen, kenne ich kein einfacheres Werkzeug). Danke für die Inspiration, Matt!
– Leute, die mit Ideen und Code zur Verbesserung des Tools beigetragen haben:
Julien – Alternative Ausgabe-/Build-Verzeichnisse und Fall-ID-Labels,
Abbruch, wenn nicht als Root ausgeführt
Jonathon Poling – ähnliche Ideen wie Julien
Jeff Bryner – Erstellung von Volatilityrc-Dateien für jeden Capture
Die Gemeinschaft ist durch all diese Bemühungen besser geworden. Ich habe mich entschlossen, mein Tool unter der Creative Commons „Attribution“-Lizenz (CC BY) verfügbar zu machen, um es so weit wie möglich zu verbreiten.
Um Linux-Arbeitsspeicher zu analysieren, müssen Sie ihn zunächst erfassen können. AVML funktioniert hervorragend, aber wenn Ihr System weder /proc/kcore noch /dev/crash hat, benötigen Sie Joe Sylves Linux Memory Extractor (LiME). Sie benötigen jedoch ein LiME-Modul, das für den Kernel des Systems kompiliert wurde, auf dem Sie den RAM erfassen möchten.
Volatility(TM) ist hervorragend geeignet, um Linux-Arbeitsspeicherabbilder zu analysieren. Es benötigt jedoch ein Profil, das zum System passt, auf dem der Arbeitsspeicher erfasst wurde. Die Erstellung eines Profils bedeutet, ein C-Programm auf dem entsprechenden System zu kompilieren und dwarfdump zu verwenden, um die Adressen wichtiger Kernel-Datenstrukturen zu erhalten. Außerdem benötigen Sie eine Kopie der System.map-Datei aus dem /boot-Verzeichnis.
Wenn Sie zufällig ein Duplikat Ihres Zielsystems besitzen, können Sie das Volatility(TM)-Profil auf dem Klon erstellen und ggf. LiME bauen, um den Arbeitsspeicher des Ziels zu erfassen und zu analysieren. Aber es gibt viele Situationen, in denen ein Duplikat des Zielsystems nicht verfügbar ist. Daher müssen Sie Ihr Volatility(TM)-Profil und LiME möglicherweise auf dem Zielrechner selbst erstellen.
Und das ist nichts für schwache Nerven. Es sind zahlreiche Schritte und einige recht systemnahe Linux-Befehle erforderlich. Mein Ziel war es, ein Paket zu erstellen, das (von einem Experten) auf einem USB-Stick installiert und an Außendienstmitarbeiter verteilt werden kann. Der Benutzer des USB-Sticks sollte in der Lage sein, den Stick einzustecken, einen einzigen Befehl auszuführen und erfolgreich ein Arbeitsspeicherabbild des Zielrechners sowie ein funktionierendes Volatility(TM)-Profil zu erlangen. Das Ergebnis ist mein lmg (Linux Memory Grabber)-Skript.
Wenn Sie auf forensische Reinheit Wert legen, ist dies wahrscheinlich nicht das richtige Werkzeug für Sie. Lassen Sie uns einige Wege besprechen, auf denen mein Tool mit dem Zielsystem interagiert:
Wechselmedien – Das Tool ist für die Ausführung von einem tragbaren USB-Gerät (z. B. einem USB-Stick) konzipiert. Sie stecken ein beschreibbares Gerät in Ihr Zielsystem, das möglicherweise von böswilligen Benutzern oder Malware auf dem System angegriffen werden kann. Das Einstecken des Geräts verändert den Systemzustand (z. B. durch Log-Einträge, mtab-Einträge usw.). Wenn das Gerät nicht automatisch vom Betriebssystem eingehängt wird, muss der Benutzer das Gerät manuell über eine Root-Shell einhängen.
Kompilierung – Die Erstellung eines Volatility(TM)-Profils erfordert das Kompilieren von Code auf dem Zielrechner. Gleiches gilt für den Bau von LiME, wenn AVML nicht funktioniert. Daher werden gcc ausgeführt, Header-Dateien gelesen, Bibliotheken gelinkt usw. lmg versucht, die Auswirkungen auf das Dateisystem des Zielrechners zu minimieren, indem TMPDIR auf ein Verzeichnis auf dem USB-Gerät gesetzt wird, von dem lmg ausgeführt wird. Das bedeutet, dass vom Compiler erstellte Zwischendateien auf den USB-Stick und nicht auf das lokale Dateisystem des Zielrechners geschrieben werden.
Abhängigkeiten – Um Kernel-Code unter Linux zu kompilieren, benötigt der Zielrechner eine funktionierende Entwicklungsumgebung mit gcc, make usw. sowie alle entsprechenden Include-Dateien und Shared Libraries. Insbesondere müssen die Kernel-Header-Dateien auf dem lokalen Rechner vorhanden sein. Diese Abhängigkeiten sind auf dem Zielrechner möglicherweise nicht gegeben. In diesem Fall steht der Benutzer vor der Wahl, die entsprechenden Abhängigkeiten zu installieren (falls möglich) oder kein Volatility(TM)-Profil für das System erstellen zu können.
Malware – lmg verwendet /bin/bash, gcc, zip und eine Reihe anderer Programme vom Zielrechner. Wenn das System kompromittiert wurde, sind die von lmg verwendeten Anwendungen möglicherweise nicht vertrauenswürdig. Eine vollständigere Lösung wäre, eine sichere Ausführungsumgebung für lmg auf dem tragbaren USB-Gerät zu schaffen, was jedoch über den Rahmen dieses ersten Proof of Concept hinausging.
Arbeitsspeicher – Alle ausgeführten Befehle führen dazu, dass sich der Arbeitsspeicher des Zielsystems ändert. Das Erfassen von RAM erzeugt immer Artefakte, aber in diesem Fall gibt es neben dem RAM-Dumper umfangreiche Kompilierungs-, Dateisystemzugriffe usw.
Ungeachtet dessen ist lmg ein sehr praktisches Werkzeug, um weniger erfahrenen Mitarbeitern zu ermöglichen, nützliche Arbeitsspeicher-Analysedaten von Zielsystemen zu erfassen.
Beachten Sie, dass lmg, wenn AVML fehlschlägt, nach einem bereits vorhandenen LiME-Modul auf dem USB-Gerät sucht, das zur Kernel-Version und Prozessorarchitektur des Zielrechners passt. Wenn ein solches gefunden wird, führt lmg keine erneute Kompilierung durch. Ebenso können Sie festlegen, dass lmg kein Volatility(TM)-Profil für das Ziel erstellt, um die Auswirkungen auf das Zielsystem zu minimieren.
lmg verwendet relative Pfadnamen beim Aufruf von Programmen wie gcc und zip. Wenn Sie diese Programme von einem anderen Medium ausführen möchten, aktualisieren Sie einfach $PATH entsprechend, bevor Sie lmg ausführen.
Bereiten Sie zunächst einen USB-Stick gemäß den Anweisungen im mit lmg gelieferten INSTALL-Dokument vor.
Wenn Sie RAM erfassen möchten, stecken Sie den USB-Stick in Ihr Zielsystem. Auf den meisten Linux-Systemen werden neue USB-Geräte automatisch unter /media eingehängt. Nehmen wir an, Ihr Gerät landet unter /media/LMG.
Führen Sie nun als Root „/media/LMG/lmg“ aus. Dies ist der interaktive Modus, und der Benutzer wird vor dem Bau eines LiME-Moduls für das System und/oder der Erstellung eines Volatility(TM)-Profils zur Bestätigung aufgefordert. Wenn Sie nicht aufgefordert werden möchten, verwenden Sie „/media/LMG/lmg -y“.
Alles andere ist automatisiert. Nachdem das Skript gelaufen ist, haben Sie ein neues Verzeichnis auf dem USB-Stick mit dem Namen
„.../capture/-YYYY-MM-DD_hh.mm.ss“
lmg unterstützt eine Option -c zur Angabe eines Fall-ID-Verzeichnisnamens, der anstelle des Standardverzeichnisses „-YYYY-MM-DD_hh.mm.ss“ verwendet wird.
Unabhängig vom verwendeten Verzeichnisnamen enthält das Verzeichnis:
-YYYY-MM-DD_hh.mm.ss-memory.lime – der RAM-Capture -YYYY-MM-DD_hh.mm.ss-profile.zip – Volatility(TM)-Profil -YYYY-MM-DD_hh.mm.ss-bash – Kopie von /bin/bash des Zielrechners volatilityrc – prototypische Volatility-Konfigurationsdatei
Die Datei volatilityrc definiert die entsprechenden Speicherorte für den erfassten Arbeitsspeicher und das Plugin. Siehe das ANWENDUNGSBEISPIEL unten zur Verwendung dieser Datei.
Die Kopie von /bin/bash ist hilfreich, um die Adresse der Shell-Verlaufs-Datenstruktur im Arbeitsspeicher von Bash-Prozessen im Arbeitsspeicher-Capture zu bestimmen. Weitere Details zur Verwendung dieser ausführbaren Datei finden Sie unter https://github.com/volatilityfoundation/volatility/wiki/Linux-Command-Reference#linux_bash (oder siehe das ANWENDUNGSBEISPIEL unten).
Beachten Sie, dass es Zeiten geben kann, in denen Sie keine Daten auf das Medium schreiben möchten, von dem Sie lmg ausführen – zum Beispiel, wenn sich die lmg-Werkzeuge auf einem schreibgeschützten Medium wie einer DVD-ROM befinden. lmg unterstützt eine Option -d zur Angabe eines anderen Ausgabeverzeichnisses. Standardmäßig erfolgt die gesamte Kompilierung im Zielverzeichnis, aber der Benutzer kann mit -B ein alternatives Kompilierungsverzeichnis angeben.
Hier ein Beispiel für die Verwendung des lmg-Tools, einschließlich der direkten Nutzung von Volatility(TM) vom USB-Stick zur Analyse des erfassten Abbilds. Auf meinem Testrechner befand sich der USB-Stick unter /dev/sdb und wurde von meinem Betriebssystem nicht automatisch eingehängt. Daher habe ich alles manuell durchgeführt.
[root@localhost ~]$ sudo -s [sudo] password for lab: [root@localhost lab]# mkdir -p /mnt/usb [root@localhost lab]# mount /dev/sdb1 /mnt/usb
[root@localhost lab]# /mnt/usb/lmg -y AVML is /mnt/usb/avml/avml-x86_64 Dumping memory in "lime" format to /mnt/usb/capture/localhost.localdomain-2020-02-01_08.16.55 This could take a while...Done! Grabbing a copy of /bin/bash...Done! Writing volatilityrc to /mnt/usb/capture/localhost.localdomain-2020-02-01_08.16.55...Done! make -C //lib/modules/4.18.0-147.3.1.el8_1.x86_64/build M="/mnt/usb/volatility-master/tools/linux" clean make[1]: Entering directory '/usr/src/kernels/4.18.0-147.3.1.el8_1.x86_64' make[1]: Leaving directory '/usr/src/kernels/4.18.0-147.3.1.el8_1.x86_64' rm -f module.dwarf make -C //lib/modules/4.18.0-147.3.1.el8_1.x86_64/build CONFIG_DEBUG_INFO=y M="/mnt/usb/volatility-master/tools/linux" modules make[1]: Entering directory '/usr/src/kernels/4.18.0-147.3.1.el8_1.x86_64' CC [M] /mnt/usb/volatility-master/tools/linux/module.o Building modules, stage 2. MODPOST 1 modules WARNING: modpost: missing MODULE_LICENSE() in /mnt/usb/volatility-master/tools/linux/module.o see include/linux/module.h for more information CC /mnt/usb/volatility-master/tools/linux/module.mod.o LD [M] /mnt/usb/volatility-master/tools/linux/module.ko make[1]: Leaving directory '/usr/src/kernels/4.18.0-147.3.1.el8_1.x86_64' dwarfdump -di module.ko > module.dwarf make -C //lib/modules/4.18.0-147.3.1.el8_1.x86_64/build M="/mnt/usb/volatility-master/tools/linux" clean make[1]: Entering directory '/usr/src/kernels/4.18.0-147.3.1.el8_1.x86_64' CLEAN /mnt/usb/volatility-master/tools/linux/.tmp_versions CLEAN /mnt/usb/volatility-master/tools/linux/Module.symvers make[1]: Leaving directory '/usr/src/kernels/4.18.0-147.3.1.el8_1.x86_64' adding: module.dwarf (deflated 90%) adding: boot/System.map-4.18.0-147.3.1.el8_1.x86_64 (deflated 79%)
[root@localhost lab]# cd /mnt/usb/capture/localhost.localdomain-2020-02-01_08.16.55 [root@localhost localhost.localdomain-2020-02-01_08.16.55]# ls localhost.localdomain-2020-02-01_08.16.55-bash localhost.localdomain-2020-02-01_08.16.55-memory.lime localhost.localdomain-2020-02-01_08.16.55-profile.zip volatilityrc [root@localhost localhost.localdomain-2020-02-01_08.16.55]# ../../volatility-master/vol.py --conf-file=volatilityrc linux_banner Volatility Foundation Volatility Framework 2.6.1 Linux version 4.18.0-147.3.1.el8_1.x86_64 ([email protected]) (gcc version 8.3.1 20190507 (Red Hat 8.3.1-4) (GCC)) #1 SMP Fri Jan 3 23:55:26 UTC 2020
[root@localhost localhost.localdomain-2020-02-01_08.16.55]# gdb localhost.localdomain-2020-02-01_08.16.55-bash GNU gdb (GDB) Red Hat Enterprise Linux 8.2-6.el8_0 Copyright (C) 2018 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-redhat-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: http://www.gnu.org/software/gdb/bugs/. Find the GDB manual and other documentation resources online at: http://www.gnu.org/software/gdb/documentation/.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from localhost.localdomain-2020-02-01_08.16.55-bash...Missing separate debuginfo for /mnt/usb/capture/localhost.localdomain-2020-02-01_08.16.55/localhost.localdomain-2020-02-01_08.16.55-bash
Try: dnf --enablerepo='debug' install /usr/lib/debug/.build-id/b6/858d77c486b7b596f22956149bbc9f8058d98d.debug
Reading symbols from .gnu_debugdata for /mnt/usb/capture/localhost.localdomain-2020-02-01_08.16.55/localhost.localdomain-2020-02-01_08.16.55-bash...(no debugging symbols found)...done.
(no debugging symbols found)...done.
(gdb) disass history_list
Dump of assembler code for function history_list:
0x00000000000ccea0 <+0>: endbr64
0x00000000000ccea4 <+4>: mov 0x24b09d(%rip),%rax # 0x317f48
0x00000000000cceab <+11>: retq
End of assembler dump.
(gdb) quit
[root@localhost localhost.localdomain-2020-02-01_08.16.55]# ../../volatility-master/vol.py --conf-file=volatilityrc linux_bash -H 0x317f48
Volatility Foundation Volatility Framework 2.6.1
Pid Name Command Time Command
13822 bash 2020-01-30 20:25:39 UTC+0000 uname -a 13822 bash 2020-01-30 20:25:39 UTC+0000 ls 13822 bash 2020-01-30 20:25:39 UTC+0000 sudo -s 13822 bash 2020-01-30 20:25:39 UTC+0000 fg [... more output not shown ...]