Linux-Interna mit Syscalltracker verfolgen

ArticleCategory:

KernelCorner

AuthorImage:[Here we need a little image from you]

[Photo of the Author]

TranslationInfo:[Author + translation history. mailto: or http://homepage]

original in en Mulyadi Santosa 

en to de Michael Weinrich

AboutTheAuthor:[A small biography about the author]

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.

Abstract:[Here you write a little summary]

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.

ArticleIllustration:[One image that will end up at the top of the article]

[Illustration]

ArticleBody:[The main part of the article]

Einleitung

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. :-)

Syscalltracker

(http://syscalltrack.sourceforge.net) ist eine Sammlung von Kernel-Modulen, die einem hilft, Systemaufrufe, die intern vom Linux-Kernel get�tigt werden, zu verfolgen. Wof�r ist das gut? Ganz allgemein benutzen wir es, um den Grund f�r ein Fehlverhalten des Systems zu verfolgen, das kaum durch gew�hnliche �berwachungs- und Debugging-Mechanismen zu l�sen ist. Hier ist ein einfaches Beispiel: Stell' Dir vor, Du hast eine Konfigurationsdatei namens inetd.conf im /etc-Verzeichnis (Grundkonfiguration f�r den INETd-D�mon). Du hast sie so konfiguriert, dass einige System-D�monen aktiviert und andere deaktiviert sind. Und dann startest Du inetd und erst einmal klappt alles wunderbar. Aber dann verschwindet /etc/inetd.conf pl�tzlich. Zum Gl�ck hast Du eine Sicherung und kannst die Datei schnell von einer aktuellen Sicherungskopie wiederherstellen. Dann startest Du das System erneut mit dieser Konfiguration. Dieses Mal hat irgendetwas neue Zeilen in die inetd.conf hinzugef�gt und einen Befehl zum Starten mysteri�ser D�monen hinzugef�gt. Nun wirst Du langsam verwirrt ... "Wer hat das getan?" "Ist dies durch einen D�mon geschehen, der selbst von inetd gestartet wurde?" "Gibt es hier einen Angriff und den Versuch, mein System zu kompromittieren?". Schnell scannst du mit "cat" das System-Protokoll und startest "top" und "ps", um nach ungew�hnlichen Prozessen oder Benutzern zu suchen, aber Du findest nichts dergleichen.

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.

Interessiert?

Dann kannst Du es ja mal versuchen. In diesem Artikel verwende ich RedHat Linux 7.3 als Basis-System. Gehe mit Deinem Browser zu http://syscalltrack.sourceforge.net und lade Dir das Paket von der Download-Seite. In diesem Artikel benutze ich syscalltrack-0.82.tar.gz, das ungef�hr 500kB gro� ist. Entpacke das Paket in ein Verzeichnis, beispielsweise /usr/src:

# 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 :-) )

Syscalltracker kompilieren

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:

  1. /lib/modules/2.4.18-3/syscalltrack-0.82/sct_rules.o

  2. /lib/modules/2.4.18-3/syscalltrack-0.82/sct_hijack.o



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………..>


Regeln

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 Beispielregel

rule
{
   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



Um alle geladenen Regeln zu l�schen, tippe:

# sct_config delete






Und schlie�lich kannst Du Syscalltracker aus dem Speicher l�schen, wenn Du es nicht mehr brauchst:

# sct_unload






Es besteht die M�glichkeit, dass dieser Befehl darin scheitert, Syscalltracker zu entladen und die Warnung "Device or resource busy" ausgibt. Wenn dies passiert, kann es sein, dass Syscalltracker gerade l�uft. Syscalltracker ist sicher f�r das System und es wird das laufende System nicht �ber die Ma�en beanspruchen (solange Du nicht gerade Tonnen von Regeln hinzuf�gst :-) ). Das Fazit: Lass Syscalltracker einfach auf dem Kernel sitzen und seine Arbeit tun. Wenn Du ihm genug Regeln gibst, kannst Du anfangen, Dein System n�her zu �berwachen.