original in en Mulyadi Santosa
en to de Michael Weinrich
Mein Name ist Mulyadi Santosa. Ich lebe in Indonesien und arbeite als freiberuflicher Autor und Berater. Meine Interessen sind Clustering, Systemsicherheit und Netzwerke. Ich f�hre privat auch eine eigenen Firma im Cluster-Umfeld, die cost of the shelf Cluster verkauft. Mein Schwerpunkt liegt haupts�chlich auf OpenMosix und openSSI. In meiner Freizeit entspanne ich mich beim Lesen und Sport. Du kannst mir e-mail an die Adresse a_mulyadi@softhome schicken und mit mir diskutieren.
Manchmal m�chten wir unser Linux-System etwas genauer beobachten. Es gibt eine Menge Log-Programme, Einbruchs-Erkennungs-Werkzeuge, Integrit�tspr�fer und so weiter. Dieses Mal m�chte ich Euch mit einem Mechanismus bekannt machen, der Linux auf Kernel-Ebene �berwacht und mehr Betriebssicherheit und einen weiteren Umfang bietet.
Eines Tages verfolgte ich eine Diskussion �ber Clustering-Middleware auf einer Mailing-Liste. Auf einmal gab es einen Diskussionszweig, in dem eine System-Anomalit�t diskutiert wurde, die durch einen Kernel-Patch verursacht worden war. Und dann antwortete jemand, dass er versuchte, das Problem anhand der von der ersten Person genannten Schritte, zu reproduzieren. Diese Person benutzte ein Werkzeug namens Syscalltracker, das ihm half, das auftretende Problem festzumachen. Und ich selbst fragte mich "Was f�r ein Werkzeug ist dieses Syscalltracker? Was kann es leisten?" F�r einen Gelegenheitsnutzer wie mich, verursachte allein der Name "Syscalltracker" einen mysteri�sen Verdacht. :-)
Es gibt eine L�sung, um diese Art von Problem zu verfolgen. Keine 100% perfekte L�sung, aber wirksam genug, um die wichtigsten F�lle in den Griff zu bekommen. Sie basiert auf der Tatsache, dass jede Aktion und jeder Befehl, der durch die Shell, ein Anwenderprogramm oder einen D�mon ausgel�st wird (in anderen Worten: JEDER Prozess) einen oder mehrere interne Systemprozeduren ausf�hrt, die allgemein unter dem Namen system calls (Systemaufrufe) bekannt sind. Versuchst Du eine Datei zu l�schen? Dann rufst Du unlink auf. Du f�hrst ein Shell-Skript aus? Dann muss es exec() oder execute()aufrufen. Also wird praktisch jede Aktion in Bezug auf das System direkt als ein Systemaufruf interpretiert. Dieses ist die zugrundeliegende Idee, warum ein �berwachung auf Basis der Systemaufrufe eine so starke Waffe sein kann.
# tar xzvf syscalltrack-0.82.tar.gz
Und dann vergewissere Dich, dass Du die Quellen des Linux-Kernels in /usr/src hast.
# rpm -qa | grep -i kernel-source
oder
# ls -al /usr/src/linux-2.4
Wenn einer dieser Aufrufe ein negatives Ergebnis bringt, musst Du sie erst installieren. Sie sind auf der Redhat CD (#2):
# rpm -replacepkgs -Uvh /Pfad/zu/Deinem/RPM/kernel-source-2.4.18-3.i386.rpm
Achte darauf, dass Du Syscalltracker auf der Grundlager derselben Kernelversion (und anderer zus�tzlicher Patches), unter der Dein Linux-System gerade l�uft, installieren MUSST. Beispiel: Wenn Du einen Standard RedHat 7.3 Kernel verwendest, dann musst du sie mit den Kernel-Quellen von der RedHat CD kompilieren. Oder, wenn Du Deinen eigenen Linux Kernel verwenden willst, musst Du Syscalltracker mit den Quellen dieses Kernels kompilieren.
Neben dem Kernel Quellcode, brauchst Du noch die Kernel-Konfigurationsdatei, um die Syscalltracker-Installation zu bewerkstelligen. Versuch's mal mit dem Inhalt von /boot:
# ls -al config*
Wenn es eine Ausgabe wie 'config-2.4.18-3' gibt, dann musst Du diese Datei nach /usr/src/linux-2.4 kopieren. Benenne sie um in '.config'
# cp /boot/config-2.4.18-3 /usr/src /linux-2.4/.config
Wenn diese Datei aus irgendwelchen Gr�nden nicht in /boot steht, dann kannst Du sie aus dem Kernel-Quellverzeichnis kopieren. Sie liegt unter dem configs Verzeichnis. Du musst eine ausw�hlen, die zu Deinem gerade laufenden Kernel passt, also finde Deine laufende Version mit
# uname -a
heraus. Dies sollte Dir die Version Deines Kernels ausgeben. Du kannst es erraten. Nehmen wir an, die Ausgabe enth�lt "kernel-2.4.18-3-i386", dann musst Du die Datei kernel-2.4.18-3-i386.config kopieren.
# cd /usr/src/linux-2.4
# cp configs/kernel-2.4.18-3-i386.config ./.config
Nun musst Du folgendes laufen lassen:
#cd /usr/src/linux-2.4.18-3
# make mrproper
# make menuconfig
Nimm die Einstellungen, die Du brauchst vor und w�hle save/exit. Wenn Du einen selbstkompilierten Kernel verwendest, aber Deine alte Kernel-Konfigurationsdatei nicht mehr hast, dann musst Du vorsichtig die Einstellungen rekonstruieren, um k�nftige Probleme zu verhindern (ich hoffe, das ist nicht der Fall :-) )
Nun haben wir alle Anforderungen vorbereitet. Nun k�nnen wir mit dem Kompilieren von Syscalltracker beginnen:
# cd /usr/src/syscalltrack-0.82
# ./configure (or ./configure
-with-linux=/path/to/your/linux/kernel/source)
# make && make install
Wenn die Kompilation erfolgreich verlaufen ist, wirst Du zwei neue Module finden:
Dieses sind die Module, die f�r Deine System�berwachung verantwortlich sind. Der Autor selbst benutzt den Ausdruck system call hijacking (Systemaufruf-Entf�hrung), was bedeutet, dass der Systemaufruf unterbrochen wird und die vorgeschriebene Arbeit getan wird, bevor die eigentliche Prozedur ausgef�hrt wird. Als n�chstes musst Du die Module laden. Hierf�r gibt es ein vorgefertigtes Skript.
# sct_load (als root)
Stell' sicher, dass der Kernel die Module geladen hat, indem Du lsmod eingibst. Du solltest in etwa das folgende sehen:
Module Size Used by Not tainted sct_rules 257788 2 sct_hijack 110176 1 [sct_rules] <…..cut………..>
Herzlichen Gl�ckwunsch! Du hast die Module geladen und somit l�uft der Syscalltracker. Aber wir sind noch nicht fertig. Du musst nun Regeln schreiben, die der Syscalltracker braucht, um entsprechend arbeiten zu k�nnen. Lass' uns mit einer einfachen anfangen:
rule { syscall_name=unlink rule_name=unlink_rule1 action { type=LOG log_format {%comm : %params delete by %euid --> %suid} } when=before }
Jede Regel, die f�r Syscalltracker deklariert wird, beginnt mit dem reservierten Wort "rule", dem ein "{" folgt. Danach musst Du deklarieren, welchen Systemaufruf Du beobachten musst. Dies erfolgt mit dem Parameter "syscall_name". Es gibt eine Menge Systemaufrufe, aus denen Du w�hlen kannst. Um eine komplette Liste zu bekommen, schau in die Datei '/usr/local/lib/syscalltrack-0.82/syscalls.dat-2.4.18-3'. Manchmal ist es schwierig, die Bedeutung einiger Systemaufrufe zu erraten, aber es gibt auch leichte. F�r jetzt greife ich mal unlink heraus. Dieser Systemaufruf wird jedes Mal ausgef�hrt, wenn jemand oder etwas versucht, eine Datei zu l�schen. Ich denke, dies ist eine gute Wahl f�r den Anfang, die Idee ist es also, alle L�schvorg�nge, die auf Deinem System geschehen, zu �berwachen.
Dem Parameter "rule_name" muss der Name der Regel �bergeben werden. Dies ist ein frei w�hlbarer Eintrag, schreib' einfach einen leicht zu verstehenden Namen. Ich w�hle "unlink_rule1". In dem Abschnitt "action", musst Du eintragen, welche Aktion Syscalltracker ausf�hren soll, wenn es einen entsprechenden Systemaufruf gibt. Syscalltracker unterst�tzt verschiedene Aktionen, aber hier benutzen wir den Typ LOG. Diese Aktion wird eine Logdatei nach /dev/log schreiben. Laut TODO-Liste der Website gibt es Pl�ne, Systemaufrufe neu zu schreiben. Dies bedeutet, dass Du Systemaufrufparameter manipulieren und Deine eigenen Parameter einf�gen kannst. :-)
F�r die LOG Aktion musst Du ein Ausgabeformat definieren. Es gibt bereits eingebaute Makros, um eine umfassende Ausgabe zu erhalten
%ruleid -> Name der Regel, die den Systemaufruf betrifft %sid -> Identifikationsnummer des Systemaufrufs %sname -> Name des Systemaufrufs %params -> Parameter des Systemsaufrufs %pid -> ID des Prozesses, der den Systemaufruf t�tigt %uid -> Benutzerkennung, die den Systemaufruf ausf�hrt %euid -> effektive Benutzerkennung, die den Systemaufruf ausf�hrt %suid -> aufgezeichnete Benutzerkennung, die den Systemaufruf ausf�hrt %gid -> die Benutzergruppe, von der der Benutzer den Systemaufruf ausf�hrt %egid -> die effektive Benutzergruppe, von der der Benutzer den Systemaufruf ausf�hrt %sgid -> die aufgezeichnete Benutzergruppe, von der der Benutzer den Systemaufruf ausf�hrt %comm -> Name des Befehls, der den Systemaufruf ausf�hrt %retval -> R�ckgabewert des Systemaufrufs. Funktioniert nur f�r die LOG Aktionction mit dem Typ "after"
F�r dieses Beispiel habe ich das folgende geschrieben:
.log_format {%comm : %params delete by %euid --> %suid}
Dies bedeutet: "Ich m�chte jeden Befehl protokollieren, der den Systemaufruf names unlink ausf�hrt, und zwar mit der effektiven und der aufgezeichneten Benutzerkennung".
Beim Parameter when, k�nnen wir zwischen "before (vorher)" und "after (nachher)" w�hlen. Der Unterschied ist klar, wenn wir "before" verwenden, dann wird die Protokollierung ausgef�hrt, bevor der Systemaufruf ausgef�hrt wird. Wenn wir "after" w�hlen, dann findet die Protokollierung erst nach dem Ausf�hren des Systemaufrufs statt.
Die Regel wird mit "}" abgeschlossen. Diese ganze Regel kann in eine normale Textdatei geschrieben werden, lass sie uns zum Beispiel "try.conf" nennen und in /tmp speichern. Als n�chstes musst Du diese Regel in Syscalltracker einbinden.
# sct_config upload /tmp/try.conf
Wenn die Regel richtig geschrieben wurde, erh�ltst Du die Meldung "Successfully uploaded rules from file '/tmp/try.conf' ".
OK, alles hat geklappt. Nun kommt die Testphase. Wechsle auf die Konsole, zum Beispiel xterm innerhalb von xwindow. Auf einer Konsole beobachtest Du Systcalltrackers Protokoll:
# sctlog
Nun wirst Du bald eine Ausgabe als Ergebnis der Unterbrechung in der Ausf�hrung des Systemaufrufs sehen, wenn Deine Regel greift. Gib auf einer anderen Konsole etwas wie das folgende ein:
# cd /tmp # touch ./dummy # rm ./dummy
Beim Verwenden der oben genannten Regel, wirst Du nun diese Ausgabe auf sctlog sehen:
"rm" : "./dummy" delete by 0 --> 0
Von dieser Meldung kannst Du darauf schlie�en, das dieses passiert:
Der Befehl "rm" mit dem Parameter "./dummy f�hrt den Systemaufruf unlink() aus. Oder, in anderen Worten, wird rm benutzt, um eine Datei zu l�schen. Dieser Befehl verwendet eine effektive Benutzerkennung, die 0 (also Root) ist."
Hier folgt eine weitere Beispielregelrule { syscall_name = unlink rule_name = prevent_delete filter_expression {PARAMS[1]=="/etc/passwd" && UID == 0} action { type = FAIL error_code = -1 } when = before }
Dies ist unserem ersten Beispiel �hnlich, aber hier benutzen wir die FAIL Aktion. Exklusiv f�r FAIL m�ssen wir einen R�ckgabewert f�r den unterbrochenen Systemaufruf definieren. Hier benutze ich "-1" also "operation not permitted" (Ausf�hrung nicht erlaubt). Die komplette Liste dieser Nummern kann unter /usr/include/asm/errno.h eingesehen werden.
In der Zeile, die "filter expression" enth�lt, definiere ich eine Bedingung, unter der die �berpr�fung stattfindet, wenn der erste Parameter des Systemaufrufs "/etc/passwd" ist. Hierf�r brauchen wir die Variable PARAMS. Merke: Jeder Abschnitt hat seine eigenen geforderten Parameter. Diese �berpr�fung ist noch nicht perfekt, denn es k�nnte jemand etwas wie "cd /etc && rm -f ./passwd" benutzen. Aber f�r einen Anfang ist es okay. Wir pr�fen auch, ob die UID gleich 0, also root, ist.
F�ge diese Regel Deiner ersten hinzu und lade neu:
# sct_config delete # sct_config upload /tmp/try.conf
Achte darauf, dass die Reihenfolge der Regeln wichtig ist. Wenn Du "prevent_delete" vor "unlink_rule1" definierst, passiert folgendes: Wenn Du:
# rm -f /etc/passwd
eingibst, wird zuerst die Regel "prevent_delete" ausgef�hrt und die gesamte Aktion schl�gt fehl. Die Regel "unlink_rule1" wird ignoriert. Aber wenn Du die Reihenfolge vertauschst ("unlink_rule1" vor "prevent_delete") erh�ltst Du nur den Protokolleintrag, ohne die Aktion zu stoppen!
Es gibt einen weiteren Systemaufruf, dessen �berwachung interessant ist. Er hei�t ptrace. In "man ptrace" kannst Du lernen, dass dieser Systemaufruf verwendet wird, um die Ausf�hrung und Kontrolle der Ausf�hrung eines anderen Programms zu beobachten und zu steuern. In guten H�nden kann ptrace ein hilfreiches Werkzeug f�r debugging-Zwecke sein, aber in den falschen H�nden kann es dazu benutzt werden, um Sicherheitsl�cher zu analysieren und auszunutzen. Lass uns also eine Regel hinzuf�gen, es zu protokollieren.
Um dies zu tun, verwende eine Regel wie diese:
rule { syscall_name=ptrace rule_name=ptrace_rule1 action { type=LOG log_format {%comm : %params issued ptrace by %euid --> %suid} } when=before }
Beachte, dass wir prtrace als zu �berwachenden Systemaufruf definieren. Um dies zu testen, benutze das strace Programm. Lade zun�chst die oben genannte Regel in Syscalltracker und starte dann sctlog. Dann lasse strace gegen ls laufen, zum Beispiel so:
# strace /bin/ls
In sctlog solltest Du nun einige Zeilen, wie die folgenden bekommen:
"strace" : 3, 2019, 24, -1073748200 issued ptrace by 0 --> 0 "strace" : 24, 2019, 1, 0 issued ptrace by 0 --> 0 "strace" : 3, 2019, 44, -1073748200 issued ptrace by 0 --> 0 "strace" : 3, 2019, 24, -1073748200 issued ptrace by 0 --> 0 "strace" : 3, 2019, 0, -1073748216 issued ptrace by 0 --> 0 "strace" : 7, 2019, 1, 0 issued ptrace by 0 --> 0
F�r die, die bisher strace noch nicht kannten: Dies ist ein Werkzeug (und zwar ein m�chtiges), das Systemaufrufe verfolgt, die innerhalb einer ausf�hrbaren Datei get�tigt werden. Strace benutzt intern ptrace, um sich selbst in das Zielprogramm zu h�ngen, so dass dieses verfolgt werden kann. Tats�chlich sind strace und Syscalltracker das ideale Doppelpack f�r die �berwachung von System und Dateien, daher denke ich, dass es diese Erw�hnung wert ist. RedHat 7.378/9 haben es schon. Installiere einfach das RPM (hier f�r RedHat 7.3)
# rpm -Uvh /path/to/your/Redhat/RPM/strace-4.4-4.i386.rpm
Nun bist Du einen Schritt weiter bei der Diagnose Deines Systems. Syscalltracker gibt dem Nutzer Flexibili�t und Du kannst etwas �ber Systemaufrufe lernen. �brigens, wenn Du Dir die geladenen Regeln ansehen m�chtest, gib einfach das folgende ein:
# sct_config download
# sct_config delete
# sct_unload