Der letzte Teil der Tripwire-Serie befasst sich mit dem Schutz der Tripwire-Datenbank und der Datensicherung. Zudem stellt er ein kommandozeilenorientiertes Front-End vor, das weniger versierten Interessenten schnell zu einem Tripwire-Schutzschild verhilft.
Alle Anstrengungen aus der letzten Tripwire-Folge lassen noch einen für Hacker und Cracker idealen Angriffspunkt weitgehend schutzlos: die Referenz-Datenbank selbst. Sie ist aus Portabilitätsgründen als Ascii-Datei (siehe Abbildung 1) ausgeführt. Damit kann ein erfolgreicher Angreifer schon mit einem Texteditor Änderungen vornehmen und die Spuren seiner Manipulation verwischen.
Ohne ergänzende Maßnahmen bliebe der Tripwire-Schutz daher im Ergebnis löchrig: Es reicht, dass der Angreifer Root-Rechte erreicht. Eher unbefriedigend, zumal simple Stack-Buffer-Overflows bekanntlich zu den Schwächen von Unix zählen.
Am sichersten ist daher die Aufbewahrung der Referenz-Datenbank auf einem physikalisch gegen Schreibzugriffe geschützten Datenträger wie einer Diskette. Eine Partition read only zu mounten ist die schlechtere Variante. Auch eine Netzwerkverbindung zu einem sicheren Rechner mit wirksamer Zugangskontrolle kann die Referenz-Datenbank beherbergen. Es kann sogar sinnvoll sein, wichtige Inhalte auszudrucken. Das erleichtert die spätere Ursachenforschung und dient der Beweissicherung.
Die Konfigurationsdatei tw.config ist für Angreifer weit weniger attraktiv, ihre Manipulation wirkt sich nur auf den erzeugten Dateisystem-Schnappschuss aus. Ob der inhaltlichen Abweichung von der Referenz-Datenbank nun tatsächliche Veränderungen im Dateisystem zugrunde liegen oder die Folge einer manipulierten Konfiguration sind, ist für die Funktion unerheblich. Die zwangsläufig auftretenden Abweichungen von der Referenzdatenbank lösen in jedem Fall Alarm aus; die realen Veränderungen – so vorhanden – deckt der herbeieilende Administrator beim erneuten Integritätstest auf, diesmal mit restaurierter Konfiguration (Sicherheitskopie anfertigen!).
Der Datenbankschutz mit Siggen
Wenn die Größe der Datenbank ein Problem ist, was im Fall von Disketten selbst nach einer Komprimierung wahrscheinlich ist, bietet sich eine elegante Lösung mit dem bisher vernachlässigten Tripwire-Tool Siggen (Signatur Generator) an.
Mit siggen -7 tw.db_hostname kann vor jedem Integritätstest die aktuelle SHA-Signatur einer in DATADIR residierenden Referenz-Datenbank ermittelt werden. Stimmt sie mit dem auf Diskette gesicherten Original überein, darf der Administrator auf das problematische Einlesen von externen Medien wie Disketten oder Wechselplatten verzichten und mit einer Kopie im lokalen Dateisystem arbeiten.
Trotzdem: Um einer versehentlichen Löschung oder Beschädigung der Arbeitskopie vorzubeugen, ist es immer ratsam, nach jedem Update eine Sicherheitskopie zu ziehen und sicher zu verwahren.
Generell gilt: Das Datenbank-Handling darf nicht zu leger gehandhabt werden. Denn jede erfolgreiche Manipulation schreibt die bewirkte Veränderung aufgrund der Funktionsweise von Tripwire für alle Zeiten fest und handelt – so paradox das auch klingen mag – auf diese Weise im Interesse des Hackers.
Siggen kann auch die Unversehrtheit der potenziell gefährdeten Binaries sicherstellen, obwohl deren Manipulation des hohen Aufwands wegen unattraktiv ist. Das Leichtgewicht mit gerade 80 KByte gehört dann logischerweise mit auf die Diskette. Der Tripwire-Programmierer Kim empfiehlt, die gesamte Distribution – mit templateR versehen – als Eintrag in tw.config zu setzen. Das ist befremdlich, weil das mit der Datenbank nicht funktioniert: Die Signatur wird noch vor dem Überschreiben der alten Datenbank ermittelt, weshalb die Datenbank-Signatur in der Datenbank immer inkorrekt sein muss. Das heißt: Beim Integritätstest würde die Referenzdatenbank stets als changed ausgewiesen.
Auch beim Tripwire-Binary ergibt sich ein prinzipielles Problem im Falle einer Signatur-Überwachung: Eine veränderte Signatur würde ja offenbar auf ein fingiertes Binary hindeuten, das aus einem manipulierten Quelltext hergestellt wurde. Wenn andererseits tatsächlich die Möglichkeit zur Quelltext-Manipulation besteht, spielt die Signatur keine Rolle mehr, denn der Angreifer kann den Quelltext so abändern, dass Tripwire einen fingierten Integritätsbericht liefert, der das Binary als integer ausweist.
Abbildung 1: Die Referenz-Datenbank im Klartext |
# Generated by Tripwire, version 1.3.1 on Sat Oct 6 20:55:50 1999 @@dbaseversion 4 / 0 000zn0 40755 2 23 0 0 1024 0vtY05 0vFEK9 0vFEK9 0 0 0 0 0 0 0 0 0 0 /lost+found 0 000zn0 40755 11 2 0 0 12288 0vtY02 0uCWsv 0uCWsv 0 0 0 0 0 0 0 0 0 0 /etc 0 000zn0 40755 10201 27 0 0 4096 0vtY03 0vtWWY 0vtWWY 0 0 0 0 0 0 0 0 0 0 /etc/fstab 0 000zn0 100644 10789 1 0 0 586 0vtWwy 0v6kFw 0v6kFw 0 0 0 0 0 0 0 0 0 DqrnTXKyYyYj7GBaIt6Iz5TQLuB /etc/rc.config 0 000zn0 100600 10768 1 0 0 24183 0vtWWo 0vJr4Z 0vJr4Z 0 0 0 0 0 0 0 0 0 5VXnswXVg5LWNiDEV8tz90NYmEd /etc/passwd 12 000000 100644 10812 1 0 0 2040 0vtX:X 0up1tS 0up1tS 0 0 0 0 0 0 0 0 0 4DNdv:wwzqUO4KcpXDesO:fMsPf ... |
Kosmetik
Offenbar ist also der Umgang mit der Referenz-Datenbank ein etwas heikler Punkt bei der Administration von Tripwire. Die kommerzielle Version versucht diesen Widrigkeiten ähnlich wie beim (angestaubten) Konkurrenzprodukt ATP von vornherein durch generelle Chiffrierung per 1024bit-ElGamal/Triple-DES aus dem Wege zu gehen.
Jedes Update kann nur mit Kenntnis der gewählten Passphrase erfolgen, was aber die automatische Sicherheitsüberprüfung als Cronjob verkompliziert. Unabhängig davon, dass dieser Mechanismus nicht vor Zerstörung der Referenz-Datenbank durch Löschen schützt, was jede Chance auf Wiederherstellung des ursprünglichen Datenbestands verwirkt, scheint diese Neuerung auch noch aus einem anderen Grund problematisch:
Die Sicherheitspraxis im Homebanking zeigt, dass das Belauschen einer Passwort-Eingabe durch maßgeschneiderte Trojaner technisch möglich und darum ein ernstes Risiko ist. Eine physikalisch gegen Schreibzugriff geschützte Diskette hingegen setzt (bei aller technologischen Armseligkeit) immer die körperliche Anwesenheit des Hackers voraus, was eher selten gegeben ist.
Angreifers Neugier als effektives Frühwarnsystem
Eine unfaire, aber ungemein wirksame Maßnahme gegen Angreifer ist es, geeignete Köder im Dateisystem auszulegen, die als Indikatoren für fremde Aktivitäten fungieren. Dateien mit klangvollen Namen wie Kennwörter oder Gehaltsliste an exponierten Stellen platziert, geben geeignete Publikumsmagnete ab.
Da gerade hier Zugriffe infolge normaler Operation nicht zu erwarten sind, hat es endlich auch Sinn, den sensitiven Access Timestamp ( E+a, oder besser E+ac) zur Überwachung heranzuziehen. Die diesbezügliche Auswertung von Integritätsberichten muss deshalb nicht schwieriger werden. Da die entsprechenden Inkonsistenzen zuverlässig am Dateinamen erkennbar sind, lässt sich der Vorgang gut automatisieren. Das schließt zudem Flüchtigkeitsfehler aus und spart Zeit und Nerven.
Gleichzeitig ergibt sich ein wertvoller zusätzlicher Nutzen für den Anwender, nämlich die einmalige Gelegenheit, sofort auf das Wirken eines Eindringlings zu reagieren!
Die besondere Signalwirkung solcher Inkonsistenzen, die auf der Sonderrolle der ansonsten nutzlosen Attrappen beruht, müsste nur als Auslöser für eine automatische Gegenmaßnahme benutzt werden, die die Handlungsfreiheit des Hackers so lange einschränkt, bis der vom Angreifer gefundene Schleichweg zu den Systemressourcen beseitigt ist.
Auf Servern könnte das durch vorübergehendes Abschalten der Netzwerkdienste ( killproc -TERM /usr/sbin/inetd beziehungsweise init 1) oder einen raschen Wechsel in den Single User Mode ( init S) geschehen. Auch das Verstecken oder Löschen passwortgeschützten Datenmaterials oder das rasche Informieren der Sicherheitsabteilung wären nützliche Maßnahmen. Frühzeitiges Eingreifen kann die Ausfallzeit eines kompromittierten Rechners erheblich senken und somit bares Geld sparen (siehe dazu auch [1] oder [2]).
Diagnose und Redundanz?
Eine Fehlerquelle kann sich im Zusammenwirken mit Backup-Programmen ergeben: Beim Sichern bleibt die Access Timestamp st_atime nicht erhalten und die so erzeugten Schein-Inkonsistenzen blähen den Integritätsbericht unangenehm auf.
Den Eintrag durch das entsprechend konfigurierte Backup-Programm zurücksetzen hilft nicht, da das Schreiben auf die I-Node mit einer Aktualisierung des Inode Timestamp st_ctime quittiert würde. Gleiches passiert auch beim Gebrauch des Shell-Kommandos touch, etwa über touch –time=atime -t Zeit Datei.
Der Verzicht auf das betreffende Select-flag ist aus zwei Gründen unbefriedigend: Einmal rutschen unschöne Aktionen wie das Ändern von Zugriffsrechten (etwa root in user) leicht unter die Nachweisschwelle. Zum anderen böte sich Hackern die Gelegenheit, die Access Timestamp (bei Inkaufnahme einer Inode Timestamp-Verletzung) nachträglich manuell zurückzusetzen, um Lesezugriffe auf Systemdateien zu tarnen und damit einer Diagnose zu entziehen (siehe auch [3]).
Ein bequemer Ausweg aus diesem Dilemma steht theoretisch in Form des potenten Ext2fs-Tools Debugfs bereit, einem wenig bekannten Bestandteil des E2fsprogs-Pakets. Es repariert eigentlich Ext2-Dateisysteme und besitzt darum mächtige Befehle zur Manipulation einzelner I-Node-Einträge. Leider ist es im Einsatz sehr problematisch. Das unsachgemäße Überschreiben der I-Node führt nun mal zum irreversiblen Dateisystem-GAU. Von der Radikalkur
debugfs -R "modify_inode Datei" -w Partition
ist daher abzuraten. Von einer unkonventionellen, aber viel gefahrloseren Alternative ist später die Rede.
Der Tripwire-Programmierer Kim rät, das Vorhandensein eines Tripwire-Schutzschilds durch Wahl unverfänglicher Namen für benutzte Shell-Skripte (Achtung: Root-Rechte) und Verzeichnisse (etwa DESTDIR, DATADIR) zu verschleiern. Simpel, aber bei Tausenden von Dateien und Verzeichnissen nicht ohne Wirkung.
Die Umsetzung
Einige Bash-Skripte werden illustrieren, wie sich die vorgestellten zusätzlichen Maßnahmen praktisch realisieren lassen. Die vom Tripwire-Binary bekannte Funktionalität wird dabei um folgende Merkmale erweitert:
- vereinfachte Verwaltung mehrerer separater Konfigurationsvarianten,
- effektiver Datenbankschutz,
- Trojaner- und Köderdiagnose,
- konfigurierbarer Startmechanismus für eine optionale Notfallaktion,
- Tripwire-konforme Methode zur Datensicherung.
Bash-erfahrene Leser werden die Funktionsweise ohne Schwierigkeiten direkt im gut kommentierten Skript erfassen können. Hier die Beschreibung der wichtigsten Merkmale.
Abbildung 2: See, ein praktischer Filter für den Integritätsbericht |
1 #!/bin/bash
2 #
3 # Filter für den ASR-Integritätsbericht.
4 #
5
6 function info
7 {
8 echo -e `
9 SYNTAX: see [-c ext] tw.report
10
11 -c Wählt die Konfiguration "tw.config-ext" an.
12
13 see kennt die Schlüsselwörter FLAG (Trojaner) und BAIT (Köder).
14 ( [!/=] Objekt [Auswahlmaske] [#Kommentar [FLAG|BAIT[(Bem.)]]] )n'
15 }
16
17 source ${0%/*}/tw_conf
18
19 DATABASE=tw.db_$HOSTNAME
20 DBSIG=tw.db_sig
21
22 err_types=(added deleted changed detected touched)
23 # Auflösung.
24
25 list=/tmp/l.$$ ; buff=/tmp/b.$$
26
27 function set_entry
28 {
29 # Liest Pfade und zug. Hinweistexte.
30 unset -v entry rem ; declare -i i=0 ; h=$IFS ; IFS=${h:2:1}
31 for l in $(grep "#.*$1" $conf); do
32 entry[$i]=${l%% *}
33 if echo $l | grep -q "$1("; then
34 end=${l#*$1(} ; rem[$i]=${end%%)*}
35 fi
36 i=$((i+1))
37 done
38 IFS=$h
39 }
40
41 function set_index
42 {
43 # Merkt sich Treffer.
44 unset -v index
45 declare -i i=0 n=0
46 while [ -n "${entry[$i]}" ]; do
47 if eval ${1:+"!"} grep -q "${entry[$i]}$" $buff; then
48 index[$n]=$i ; n=$((n+1))
49 fi
50 i=$((i+1))
51 done
52 }
53
54 function delete
55 {
56 # Löscht überflüssige Zeilen.
57 str=${entry[*]} ; su_str="(${str// /|})"
58 eval cat ${str:+"| grep -v $su_str"}
59 }
60
61 function add
62 {
63 # Ergänzt ASR-Bericht.
64 cat
65 for i in ${index[*]}; do
66 top="$1${entry[$i]}"
67 [ "${rem[$i]}" ] && top="$top (${rem[$i]})"
68 echo "$top"
69 done
70 }
71
72 # Option?
73 conf="$DESTDIR/tw.config"
74 while getopts "c:h" opt; do
75 case $opt in
76 c) conf="$DESTDIR/tw.config-$OPTARG" ; shift 2;;
77 h) info ; exit 0;;
78 *) exit 1;;
79 esac
80 done
81
82 if ! [ -e $conf ]; then
83 echo "--> ${0##*/}: Keine gültige Konfiguration!"
84 exit 1
85 fi
86
87 cat $1 | tee $buff | sed `s/: /: /g' | {
88
89 # Trojaner?
90 set_entry FLAG
91 set_index if_not_found
92 delete | add "detected: ... "
93 } | {
94
95 # Köder?
96 set_entry BAIT
97 set_index
98 delete | add "touched: ... "
99 #} | {
100 #
101 # benutzerdefinierter Filter.
102
103 } | sed `/^$/d' | tee $list
104
105 # Statusbits setzen!
106 declare -i mask=2
107 for type in ${err_types[*]}; do
108 grep -q "^$type" $list && stat=$((stat | mask))
109 mask=$((mask <<!s>1))
110 done
111 rm -f $list $buff
112
113 exit $stat
114
115 # Statusbit: 7 6 5 4 3 2 1 0
116 # Bedeutung: - - touch. detec. chang. delet. added -
|
Das Skript Tw_init
Tw_init bildet die – aufmerksamen Lesern bekannte – Funktionalität des Tripwire-Kommandos tripwire –initialize nach. Das Skript sucht in DESTDIR nach gültigen Konfigurationsdateien (die Syntax ist tw.config beziehungsweise tw.config-ext) und erzeugt die passenden Datenbanken ( tw.db_hostname beziehungsweise tw.db_hostname-ext), die als Arbeitskopien im lokalen Dateisystem verbleiben sollen und daher gleich nach DATADIR verschoben werden.
Gleichzeitig werden Sicherheitskopien tw.db_hostname.gz und SHA-Signaturen tw.db_sig-ext erzeugt (Verzeichnisse BACKUPDIR beziehungsweise DBSIGDIR), die zur Löschprävention und Überwachung der Arbeitskopie notwendig sind. Es ist daher wichtig, dass beide Zielverzeichnisse nach erfolgter Initialisierung wieder effektiv gegen Schreibzugriffe geschützt werden.
Für die Dateinamensergänzung ext wird zweckmäßigerweise eine Bezeichnung gewählt, die gleich die angestrebte Funktion umschreibt. Praktisch ist eine Gliederung nach Verzeichnisnamen ( etc, sbin, …) oder Aufgaben ( admin, applic, data, …).
Das Skript See
See (Abbildung 2) ist die angekündigte Weiterentwicklung des im letzten Linux-Magazin vorgestellten Trojaner-Filters. Wichtigste Neuerung ist, dass zugehörige Pfadnamen nicht mehr von Hand ins Skript eingetragen werden müssen. Eine Erweiterung der tw.config-Syntax um die Schlüsselwörter FLAG für Trojaner und BAIT für Köder macht es nun möglich, alle relevanten Objekte schon in der Konfigurationsdatei selbst kenntlich zu machen.
See kennt die betreffenden Marker und extrahiert selbsttätig zugehörige Pfadangaben wie optionale Hinweistexte, die im Bedarfsfall im Integritätsbericht in Erscheinung treten (Anwahl der Konfiguration über see -c ext). Damit entfällt natürlich die ursprüngliche Bindung an eine bestimmte Konfigurationsdatei – der Filter wird also universell einsetzbar. Dieser Fortschritt kommt auch im später beschriebenen Cronjob-Wächter tw_check zur Geltung.
Der zweite Marker BAIT wurde notwendig, um neben der im letzten Artikel skizzierten Methode zur Trojaner-Früherkennung auch eine gesonderte Behandlung von solchen Inkonsistenzen zu ermöglichen, die auf angetastete Köderdateien zurückgehen.
Im Gegensatz zum traditionellen Fehlerkatalog ( added, changed, deleted) eines Tripwire-Berichts, der eher unspezifische Angaben zur Art der Veränderung selbst macht, sind diese beiden Fehlertypen verlässliche Indikatoren für Fremdeinwirkung. Daher liegt es nahe, noch die beiden zusätzlichen Fehlerkategorien detected und touched einzuführen. Schließlich wurde noch der Exit-Status des tripwire-Binaries um die neuen Kategorien (Bit 5 und 6) erweitert, damit sich die Pipeline tripwire –quiet | see in rufenden Shell-Skripten wie das Binary tripwire verhält.
Einem nachträglichen Einsatz von See in vorhandenen Skripten steht also nichts mehr im Wege. Die interne Ausführung als mehrstufige Pipeline macht es überdies einfach, den beiden eingebauten Filterstufen eigene zur Seite zu stellen.
Unser Skript See bietet damit eine Funktionalität, die man selbst in der kommerziellen Version von Tripwire vergeblich sucht. Dabei sind gerade Flüchtigkeitsfehler, die sich besonders leicht bei der manuellen Auswertung von Integritätsberichten einschleichen, ein nicht zu unterschätzendes Sicherheitsrisiko eines Filesystem-Integrity-Checkers.
Das Skript Tw_check
Tw_check beherbergt den eigentlichen Integritätstest. Das Shell-Skript (siehe Abbildung 3) ist daher in erster Linie für den Einsatz als Cronjob bestimmt, kann also das Kommando tripwire ersetzen. Jedem Integritätstest geht zunächst ein Datenbank-Check voraus, der als einfacher Hashwert-Vergleich mit tw.db_sig[-ext] ausgeführt ist.
Wenn sich die Arbeitskopie der Datenbank dabei als beschädigt herausstellt oder wenn ein Laufzeitfehler auftritt, terminiert das Skript vorzeitig (Status-Bits 7 und 1). Wie im Fall entdeckter Inkonsistenzen erfolgt dann eine Meldung an Root, die in knapper Form über den Testverlauf unterrichtet. Für eine spätere Auswertung werden sämtliche Aktivitäten außerdem in der separaten Datei REPORT hinterlegt, die am besten in dem Heimatverzeichnis des Administrators aufgehoben ist.
Das Tw_check-Skript stellt auch einen konfigurierbaren Startmechanismus für eine Notfallaktion zur Verfügung, deren Art der Anwender selbst festlegen kann. Die gleichnamige Shell-Funktion enthält für solche Situationen einige Beispiele für Standardfälle, die bei Bedarf entkommentiert werden müssen.
Es ist sinnvoll, die Startbedingungen gleichzeitig an mehrere Kriterien zu koppeln: den Schweregrad der ermittelten Inkonsistenzen, die spezielle Konfigurationsvariante und drittens auch das subjektive Empfinden des Anwenders.
Erreicht wurde das mit einer festen Rangordnung für die insgesamt sieben Fehlertypen err_types und eines zusätzlichen Schlüsselworts PRI. Es versetzt den Administrator in die Lage, für jede Konfigurationsvariante einen von den drei möglichen Prioritätsgraden low, medium oder high zu vergeben.
Das impliziert aber selbstverständlich, dass bei der Konfiguration nur solche Objekte zu einer Einheit zusammengefasst werden, die ungefähr die gleiche Bedeutung für die Systemsicherheit besitzen. In Unix-typischen Verzeichnisbäumen, die traditionell nach funktionalen Gesichtspunkten gegliedert sind, sollte das jedoch nicht schwer fallen. In Abbildung 4 ist am Beispiel eines fiktiven Testlaufs das Zusammenspiel der einzelnen Komponenten dargestellt.
Abbildung 3: Tw_check, der Cronjob-Wächter |
1 #!/bin/bash
2 #
3 # Shellscript zum Start von TRIPWIRE als Cron-Job.
4 #
5
6 function info
7 {
8 echo -e `
9 SYNTAX: tw_check [-c ext] [-i select-flag1,select-flag2,...]
10
11 -c Wählt die Konfiguration "tw.config-ext" an.
12 -i Diese Signaturen werden beim Testlauf ausgeblendet.
13
14 tw_check kennt das Schlüsselwort PRI. ( # [PRI(low|medium|high)] )n'
15 }
16
17 source ${0%/*}/tw_conf
18
19 DATABASE=tw.db_$HOSTNAME
20 DBSIG=tw.db_sig
21
22 err_types=("Dateien wurden hinzugefügt!" "Dateien wurden gelöscht!" "Dateien wurden verändert!" "Trojaner gefunden!" "Köder
23 angetastet!" "Datenbank beschädigt!" "Laufzeitfehler!") 24 # Fehlertypen...
25 declare -ia err_pri=(0 0 0 1 1 2 2)
26 # ...und zug. Prioritäten.
27 declare -i maxpri=2
28 # Arbeitspunkt für PRI-Marker
29
30 function Notfallaktion
31 {
32 # Einige Beispiele:
33 # report | mail -s "Hilfe!" sherlock@investigations.com # Nachricht an zust. Stelle
34 # killproc -TERM /usr/sbin/inetd # Netzwerkdienste einstellen
35 # init S # Single-User-Mode
36 # rm -f /home/norma/.gnupg/secring.gpg # PG-Schlüssel vernichten
37 # $DESTDIR/tw_service -c etc -b # Backup wichtiger Inhalte
38 return
39 }
40
41 function cf_pri
42 {
43 # Liefert PRI-Argument.
44 case $(grep "^#.*PRI(" | sed `s/.*PRI(//g;s/).*//g') in
45 low ) n=1;;
46 medium) n=2;;
47 high ) n=3;;
48 * ) n=0;;
49 esac
50 echo $n
51 } <$cf
52
53 function report
54 {
55 # Kurzinfo.
56 echo -e "--> $0: TRIPWIRE meldet Inkonsistenzen!n"
57 declare -i mask=2 i=0 max=0 stat=$1 ; IFS=''
58 for mess in ${err_types[*]}; do
59 if [ $((stat & mask)) != 0 ]; then
60 echo " - $mess"
61 [ ${err_pri[$i]} -gt $max ] && max=${err_pri[$i]}
62 fi
63 mask=$((mask << 1)) ; let i+=1
64 done
65 IFS=' ` ; echo
66 cat << EOF
67 Benutzer ......... $LOGNAME
68 Zeit ............. $local_time
69 Rechner .......... $HOSTNAME.$DOMAINNAME
70 Kommandozeile .... ${0##*/} $com_opt
71 Bericht .......... $REPORT
72 EOF
73 [ $((max + $(cf_pri))) -gt $maxpri ] && Notfallaktion
74 }
75
76 function add_mess
77 {
78 echo -e "$1n" >>$REPORT
79 }
80
81 # Optionen?
82 cf=$DESTDIR/tw.config ; db=$DATADIR/$DATABASE ; dbsig=$DBSIGDIR/$DBSIG ; com_opt=$*
83 while getopts "c:i:h" opt; do
84 case $opt in
85 c) ext="$OPTARG" ; cf="$cf-$ext" ; db="$db-$ext" ; dbsig="$dbsig-$ext"
86 tw_opt_1="cfgfile $cf dbfile $db" ; see_opt="-c $OPTARG";;
87 i) tw_opt_2="ignore ${OPTARG//,/ ignore }";;
88 h) info ; exit 0;;
89 *) exit 1;;
90 esac
91 done
92
93 if ! [ -e $cf ] || ! [ -e $db ] || ! [ -e $dbsig ]; then
94 echo "> ${0##*/}: Keine gültige Konfiguration!" ; exit 1
95 fi
96
97 local_time=$(date `+%a, %-d. %b %Y %H:%M:%S')
98
99 { echo "Folgende Veränderungen wurden von TRIPWIRE am $local_time erfasst:
100 -"
101 } >>$REPORT ; chmod 600 $REPORT
102
103 # Datenbank integer?
104 if [ "$(< $dbsig)" != "$($DESTDIR/siggen -7 $db)" ]; then
105 add_mess " - Datenbank ${db##*/} beschädigt - "
106 report 64 ; exit 64
107 fi
108
109 # Dateisystem integer?
110 $DESTDIR/tripwire quiet $tw_opt_1 $tw_opt_2 >$REPORT.new
111 if [ $? = 1 ]; then
112 # Laufzeitfehler.
113 rm -f $REPORT.new
114 add_mess ` - Laufzeitfehler - `
115 report 128 ; exit 1
116 fi
117 $DESTDIR/see $see_opt $REPORT.new >$REPORT.filt ; see_stat=$?
118 rm -f $REPORT.new
119 if [ $see_stat = 1 ]; then
120 # Laufzeitfehler.
121 rm -f $REPORT.filt
122 add_mess ` - Laufzeitfehler - `
123 report 128 ; exit 1
124 elif [ $((see_stat & 62)) = 0 ]; then
125 # Test ohne Befund.
126 rm -f $REPORT.filt
127 add_mess " - Bereich ${ext:-<HARDCODED>} ok - "
128 exit 0
129 else
130 # Inkonsistenzen.
131 { cat $REPORT.filt; echo; } >$REPORT && rm -f $REPORT.filt
132 report $see_stat ; exit $see_stat
133 fi
134
135 # Statusbit: 7 6 5 4 3 2 1 0
136 # Bedeutung: - datab. touch. detec. chang. delet. added -
|
Das Skript Tw_service
Tw_service, das letzte Shell-Skript, schließt die verbliebene Lücke: Datenbank-Wartung. Diese Aufgabe war bisher den Tripwire-Kommandos, tripwire –update und tripwire –interactive vorbehalten (Optionen -u und -i). Um die lästige Dekomprimierung zu umgehen, wird gleich die Arbeitskopie als Referenz verwandt. Dem eigentlichen Update ist deshalb auch hier ein Datenbank-Check vorgeschaltet. Das Procedere bei der Installation der neuen Datenbank ist dasselbe wie bei tw_init.
Daneben bietet tw_service eine interessante zusätzliche Funktionalität, die durch die beschriebene Backup-Problematik inspiriert ist und einen kleinen, aber feinen Mechanismus zur Datensicherung abgibt. Dass die Konfiguration eines Tripwire-Schutzschilds im Wesentlichen eine an Sicherheitsaspekten orientierte Gliederung des Datenvolumens darstellt und diese auch Voraussetzung für eine effektive Backup-Strategie ist, macht den Gedanken reizvoll, ein und dieselbe Konfiguration für beide Aufgaben zu nutzen.
Die Idee wurde mit Einführung des vierten und letzten Schlüsselworts BACKUP auch in die Tat umgesetzt. Zu sichernde Einträge – etwa die wichtigen Konfigurationsdateien unter /etc – müssen dazu gekennzeichnet werden:
[!|=] Objekt [Auswahlmaske] [#Kommentar [BACKUP]]
Der Aufwand für ein komplettes Systembackup reduziert sich so auf das Eintippen des kurzen Kommandos tw_service -b, wobei sich das komprimierte SVR4-Archiv tw.archives[-ext] .gz im gleichen Verzeichnis BACKUPDIR anlegt, das schon die Sicherheitskopien der einzelnen Datenbänke enthält.
Die kombinierte Nutzung einer einzigen Konfigurationsdatei schließt darüber hinaus Risiken aus, die durch die Sicherung manipulierten Datenmaterials entstehen – eine Gefahr, die beim unkoordinierten Einsatz eines Backup-Programms immer besteht. Dem eigentlichen Sicherungsprozess ist dazu einfach ein Integritätstest über tw_check vorgeschaltet, der einen sofortigen Abbruch erzwingt, wenn sich inhaltliche Überschneidungen zwischen Backup- und Berichtsvolumen ergeben.
Auf die gleiche Weise ist auch das eingangs beschriebene BackupProblem gelöst, das speziell solche Dateien betrifft, die eine st_atime-Kontrolle bedingen, zum Beispiel die Köderdateien. Dem eigentlichen Backup musste dazu lediglich noch ein Datenbank-Update nachgeschaltet werden, das vorher veränderte st_ atime-Stempel wieder auffrischt (mit dem Kommando tw_service -B).
Die Rückübertragung gesicherten Datenmaterials ins System ist ebenso einfach:
<b3>gzip -d -c Archiv | cpio -i
Zur Verdeutlichung noch ein kleines Konfigurationsbeispiel: Die beiden in DESTDIR untergebrachten Listen, also die tw.config-admin:
# PRI(high) /etc R # BACKUP /sbin R /boot R /root/Kennwörter E+ac # BAIT /root/.gnupg/secring.gpg R # BACKUP
und die tw.config-main:
# PRI(low) / R !/etc !/sbin !/boot !/root /tmp E
veranlassen mit den zugehörigen Crontab-Einträgen:
0 0-23 * * * root DESTDIR/tw_check -c admin 0 0 * * * root nice -n 10 DESTDIR/tw_check -c main
eine stündliche Überprüfung wichtigen Datenmaterials, die jeweils nur wenige Sekunden dauert.
Der weniger wichtige Datenrest hingegen wird nur dann bearbeitet, wenn die Systemlast niedrig ist, im Beispiel also zu später Stunde um null Uhr. PRI(high) stellt sicher, dass spätestens eine Stunde, nachdem der Köder angetastet wurde, eine Nachricht an Root geschickt und die festgelegte Notfallaktion gestartet wird.
Im main-Bereich dagegen passiert das nur dann, wenn ein Laufzeitfehler auftritt oder wenn sich die Arbeitskopie der zugehörigen Datenbank als beschädigt erweist. Zur Sicherung der gesamten Systemkonfiguration einschließlich des GNU-PG-Schlüsselbunds secring.gpg genügt das Kommando tw_service -c admin -b.
Abbildung 5 stellt den Bezug zum Tripwire-Instrumentarium her. Das neue Paket ist schnell installiert: Archiv nach DESTDIR kopieren, mit
tar xfz tw_ASR_1.3.1-shield.tar.gz
auspacken und in tw_conf an persönliche Bedürfnisse anpassen. Fertig!
Abbildung 5: Aus alt mach neu |
tripwire --initialize -> tw_init tripwire -> tw_check tripwire --update Pfad1 Pfad2 ... -> tw_service -u Pfad1,Pfad2,... tripwire --interactive -> tw_service -i Backup -> tw_service -b Backup & Update -> tw_service -B |
Fazit
Nach den bisherigen Erfahrungen von Anwendern aus unterschiedlichsten Bereichen ist Tripwire ein wirksames Instrument, das bei richtiger Handhabung die Integrität des Dateisystems sicherstellen kann.
Der im professionellen Bereich zu erwartende Nutzen steht zudem in einem guten Verhältnis zum Installations- und Wartungsaufwand. Ein wichtiger Punkt ist die Verfügbarkeit der Quelltexte. Ein Sicherheitstool ohne diesen Vorzug – de facto die Regel – ist eigentlich ein Widerspruch in sich (siehe [4]).
Ein Wermutstropfen bleibt: Für den erfolgreichen Einsatz sind neben der Vertrautheit mit der Wirkungsweise an sich auch gewisse Kenntnisse über Aufbau und Funktion Unix-artiger Dateisysteme gefordert. Hier ist auch der Grund dafür zu suchen, dass Tripwire bisher meist rein professionell eingesetzt wird.
Beim Kenntnisstand durchschnittlicher Linux-Anwender hat aber Tripwire das Zeug, die privat genutzten PCs zu erobern. Bewährte Appetitanreger wie grafische Front-Ends oder virtuelle Assistenten wären leicht in Tripwire integrierbar und eine sorgfältig präparierte Konfiguration könnte Bestandteil von Linux-Distributionen werden.
Natürlich ist Tripwire kein Allheilmittel, aber als wichtiger Bestandteil eines umfassenden Sicherheitskonzepts sollte es in keinem gut sortierten Werkzeugkasten fehlen. ( jk) n
Infos |
| [1] Notfallmaßnahmen am Unfallort: ftp://ftp.cert.dfn.de/pub/dfncert/tech_tips/root_compromise
[2] Practical UNIX & Internet Security by Simson Garfinkel & Gene Spafford 2nd Edition April 1996, ISBN: 1-56592-148-8 [3] Das Net-Backup-Problem: http://www.eng.auburn.edu/pub/mail-lists/veritas-users.Nov98 [4] Security Through Obscurity by Simson Garfinkel: http://www.wideopen.com/story/101.html |






