Grundlagen


[ Seminar Linux, WWW, Java und Internet ] ... [ Thema Sicherheit unter Linux ] ... [ Einleitung ] ... [ Absicherung von Diensten ] ...

Übersicht: Grundlagen


Sicherheitskonzepte

Für einen Einzelplatzrechner gibt es drei verschiedene Sicherheitskonzepte:

Keine Sicherheit: Die einfachste Variante sollte lieber nicht gewählt werden.
Alles, was nicht explizit verboten ist, ist erlaubt.
Alles, was nicht explizit erlaubt ist, ist verboten.

In letzter Zeit hat sich die letzte Regel durchgesetzt, damit die Lücken in einem System überschaubar bleiben

weiter

Dienste deaktivieren

Dienste, wie z.B. www oder ftp, stellen die Grundlage eines Linux-Systems dar, ebenso aber auch die Hauptangriffsfläche für Einbrecher. Alle Dienste, die nicht zwingend benötigt werden, sollten deaktiviert werden. Dies gilt auch für unbekannte Dienste.

Dienste laufen entweder eigenständig als Daemons (httpd, sshd) oder werden vom sogenannten Super-Daemon (inetd) auf Anfrage gestartet. Die Konfigurationsdatei /etc/inetd.conf enthält eine Liste der aktiven Dienste. Alle nicht nicht benötigten Dienste müssen hier auskommentiert werden. Um die Änderungen zu übernehmen, erhält der inetd mit killall -HUP inetd das Signal SIGHUP.

Die eigenständigen Dienste müssen jeweils einzeln deaktiviert werden. Der Befehl netstat -a | grep LISTEN zeigt mögliche Kandidaten an.

weiter

TCP Wrapper

Ein einfacher Mechanismus zum Beschränken der Dienste sind die sogenannten TCP Wrapper. Der inetd ruft anstelle des eigentlichen Dienstes das Programm tcpd auf. Dieses prüft anhand der Dateien /etc/hosts.allow und /etc/hosts.deny, ob der Remote-Rechner überhaupt den Dienst anfordern darf. Fällt die Prüfung positiv aus, so wird der Dienst für den Remote-Rechner gestartet, andernfalls nicht.

Mehr Infos hierzu finden sich unter man 5 hosts_access.

Diese Methode ist zwar sehr praktisch für die vom inetd gestarteten Dienste, sie schützt jedoch nicht bei eigenständig laufenden Diensten.


weiter

Informationen verbergen

"Was ich nicht weiß, macht mich nicht heiß"


Aus Sicht des Angreifers stellt sich das zu erbeutende Zielsystem zuerst als Blackbox dar. Der erste Schritt ist die Anwendung eines sogenannten Portscanners, der das Dienstangebot des Servers analysiert. Von vielen Dienstanbietern wird dies schon als Bedrohung angesehen, da ein Scan der erste Schritt eines Einbruches sein kann.

Als nächstes muss bestimmt werden, um welches Betriebsystem es sich handelt. Um dem Angreifer dies so schwer wie möglich zu machen, sollte die Geschwätzigkeit der Dienste etwas gezügelt werden. So lässt sich durch Ändern der Dateien /etc/issue bzw. /etc/issue.net die Login-Meldung so einstellen, dass sie weder das Betriebsystem noch die Kernel-Version ausgibt.

Einer der Lieblingsdienste für Einbrecher ist der Fingerdienst. Der Standard-Fingerdienst stellt wertvolle Informationen über lokale Benutzer zur Verfügung. So kann beispielsweise ermittelt werden, wie oft der Superuser Root anwesend ist, oder welche Accounts selten verwendet werden.

Ein häfig ausgenutztes Sicherheitsloch ist der FTP-User: Mit dem Finger-Befehl kann überprüft werden, ob dessen Home-Verzeichnis mit den FTP-Root-Verzeichnis übereinstimmt. Ist dies der Fall und ist der FTP-Dienst schwach abgesichert, lassen sich beliebige Nicht-Root-Dateien per Email zuschicken (.forward).
Der Fingerdienst sollte entweder deaktiviert werden oder durch eine harmlosere Variante ersetzt werden.

(bsp.: /usr/local/andre/windpocke_finger)

weiter

Updates installieren

Mit der häufigste Grund, warum ein bis vor kurzem noch sicheres Linux-System ausgebeutet werden kann, ist, dass ein sogenannter Exploit gefunden wurde. Mit diesem ist es möglich - oft als Remotelösung - auf einem Rechner Root-Rechte zu erlangen. Zwar dauert es manchmal nur wenige Stunden, bis ein Patch herauskommt, aber installiert wird dieser teilweise erst Monate später, wenn der Administrator Zeit hat, sein Linux-System auf den neuesten Stand zu bringen. Ein gefundenes Fressen für "Script-Kiddies", die den Exploit-Code gerne und vielfach ausprobieren.

Bei jeder Linux-Distribution gibt es auch eine Security-Mailingliste, der man unbedingt beitreten sollte, möchte man über aktuelle Sicherheitslöcher informiert werden.

Die Mitteilungen der SuSE-Mailinglisten haben nur wenige Stunden Latenz-Zeit.

weiter

Passwörter

Die Sicherheit eines Linux-Systems steht und fällt mit der Qualität der Passwörter. Lassen sie sich leicht erraten oder sind sie zu kurz, lassen sie sich mit nur geringem Aufwand knacken.

Ein Beispiel für ein Crack-Programm ist john. Leichte Passwörter werden in nur wenigen Sekunden erraten.
Mit diesem Programm sollte von Zeit zu Zeit die Qualität der Passwörter abgeklopft werden.


Funktionsweise des aktuellen Linux-Passwort-Systems


Pluggable Authentication Module (PAM)

Noch besser ist allerdings, das Standard-Passwort-System durch PAM zu ersetzen. Dies ist bei SuSE-Linux ab der Version 6.2 integriert, benötigt allerdings noch etwas Feintuning. Eine Nachrüstung ist schwierig, da sämtliche Dienste, die Authentifizierung verwenden, neu compiliert werden müssen.

Funktionsweise PAM



Konfiguration von PAM

PAM lässt sich auf zwei Arten konfigurieren, hier wird allerdings nur die Verzeichnismethode beschrieben, da sie verbreiteter ist und flexibler.

Das Konfiguration-Verzeichnis ist /etc/pam.d. Hier befindet sich für jeden Dienst genau eine Konfigurationsdatei, z.B. passwd.

Der Aufbau ist folgender:

module-type        control-flag   module-path   arguments
module-type        control-flag   module-path   arguments
othermodule-type   control-flag   module-path   arguments
othermodule-type   control-flag   module-path   arguments

module-type (vereinfacht)

control-flag (vereinfacht)

arguments (unvollständig)

Ob ein Programm PAM-Funktionalität besitzt. lässt sich auf eine unschöne, aber einfache Art mit ldd appname herausfinden. Taucht libpam.so in der Liste auf, so benutzt die Applikation PAM zur Authentifizierung.

Leider ist PAM bei der Standardinstallation etwas zu einfach konfiguriert und bietet eine Fülle an Schlupflöchern. Folgende Anpassungen sollten durchgeführt werden:

passwd
password  required pam_cracklib.so  minlen=8
password  required pam_pwdb.so      use_authtok md5
Hiermit wird die minimale Passwortlänge auf 8 Zeichen gesetzt und der MD5-Hash aktiviert. Nun sind lange Passwörter kein Problem mehr. Alle neu eingegebenen Passwörter werden md5-codiert. Mit Hilfe des cracklib-Moduls lassen sich neue Passwörter sofort bei Eingabe auf Unsicherheiten checken, wie z.B. Benutzername, emanreztuneB, einfache lexikalische Wörter, Tastaturzeichenfolgen wie QWERTZ, Ähnlichkeit dem alten Passwort, Groß/Klein-Schreibung vorhanden, ...

other
auth     required       /lib/security/pam_warn.so
auth     required       /lib/security/pam_deny.so
account  required       /lib/security/pam_warn.so
account  required       /lib/security/pam_deny.so
password required       /lib/security/pam_warn.so
password required       /lib/security/pam_deny.so
session  required       /lib/security/pam_warn.so
session  required       /lib/security/pam_deny.so
Findet sich für eine Applikation keine passende Konfiguration, wird other gewählt. Dieses gewährt im Normalfalle jedem den Zutritt. Durch Änderung wie oben, scheitern diese mit Vermerk im Syslog.

Vorsicht! Falsche Konfiguration kann das System total unbrauchbar machen!

weiter

Arbeiten als Root

Ist zwar ein bekannter alter Hut, soll hier aber der Vollständigkeit nicht unerwähnt bleiben. Nicht nur, dass aus Versehen große Ungeschicke passieren können. Es lässt sich genauso wenig abschätzen, wie sicher das gerade unter root-Rechten ausgeführte Programm ist, oder ob es sich dabei vielleicht sogar um ein trojanisches Pferd handelt.

weiter

suid root und sudo

Die innere Sicherheit von Linux ruht in seinem Dateisystem. Fast alles wird als Datei (normale Dateien, Devices, Prozesse, Sockets, ...) abgebildet. Und jede Datei besitzt die bekannte Berechtigungsmaske:

-rwxr-x--- root root Dateiname
SUUUGGGOOO        
Ist das x-Bit für den entsprechenden Benutzer gesetzt, darf das Programm unter der Benutzer-ID des Aufrufers ausgeführt werden.

Etwas unbekannter ist jedoch das sogenannte s-Bit. Ist es gesetzt, so wird das Programm entweder mit der ID des Besitzers oder der ID der Gruppe gestartet.

-rwsr-xr-x root root Programm1
-rwxr-S--- root root Programm2
Programm1 läuft immer mit den Rechten des Root-Benutzers. Programm2 läuft immer mit den Rechten der Root-Gruppe. Ironischerweise sollte sich durch Anwendung des s-Bits die Sicherheit erhöhen, da sich Root dann nicht mehr persönlich anzumelden braucht. Und nur spezielle vertrauenswürdige Programme dürfen dann von jedem unter Root-Rechten ausgeführt werden. Doch leider gibt es viel zu viele dieser Programme. Eine Auflistung gibt der folgende Befehl wieder:

find / -type f \( -perm +4000 -o -perm +2000 \) -print

Die angezeigten Programme sollten sehr argwöhnisch betrachtet werden. Ganz sicher wird in den nächsten 6 Monaten mindestens eins dieser Programme eine Geheimtür zum System öffnen können. Bleibt nur zu hoffen, dass es keiner ausnutzt.

(Anm.: Die meisten Programme laufen nicht fehlerfrei, wenn nicht-suid root)

Das Programm-Paket sudo bietet die Möglichkeit, in einer einzigen Datei festzuhalten, wer wann von wo was als wer ausführen darf. Darauf möchte ich hier aber nicht eingehen... Mehr gibts unter man sudoers zu sehen.

weiter

Verschlüsselung

Verschlüsselung schützt private Daten in ungeschützten Medien vor neugierigen Augen. Rein prinzipiell sollte man sich darüber im Klaren sein, was ungeschützte Medien sind.

Zum Verschlüsseln von Dateien eignet sich das Programm PGP wunderbar. Mit pgpk -g lassen sich die für die Benutzung notwendigen Schlüssel generieren. Anschließend kann mit pgp -c xxx und pgp xxx.pgp private Daten unlesbar gemacht werden.

Netzwerkverbindungen aller Art können mit dem Programm-Paket ssh gesichert werden. So ist ein sicheres Telnet ebenso möglich wie auch eine sichere WWW-Verbindung mittels Port-Forwarding. Dateien können mit dem Befehl scp verschlüsselt übertragen werden: Eine Art FTP-Ersatz.


Ganze Dateisysteme können mit dem Cryptographic Filesystem (CFS) verschlüsselt werden. Dies spart das Codieren von Hand, im allgemeinen Arbeiten treten jedoch mehr oder weniger starke Performance-Probleme auf.

weiter

Buffer Overflow

Eine der beliebtesten Einbruchsmethoden ist der sogenannte Buffer Overflow. Programme, die sich diese Buffer Overflows zu Nutze machen, nennt man Exploits. Davon wiederum gibt es Varianten, die nur lokal auf einem System arbeiten, allerdings kommen auch viele Remote-Exploits in der freien Wildbahn vor.

Der Ablauf ist immer derselbe:
Ein unsauber programmierter Dienst benutzt folgenden Unterprogrammaufruf:

   void parse(char *arg) {
     char param[1024];
     int  localdata;

     strcpy(param,arg);
     .../...
     return;
   }
Dieser grobe Schnitzer erlaubt es, dass der Inhalt von arg den Stack nach oben hin vollschreiben kann. Hierbei wird die Rücksprungadresse der aufrufenden Routine überschrieben und eigener Exploit-Code kann auf dem Stack ausgeführt werden. (Zeichnung)

Der Stack wird so manipuliert, dass er folgendes Aussehen hat:

bottom of  DDDDDDDDEEEEEEEEEEEE  EEEE  FFFF  FFFF     top of
memory     89ABCDEF0123456789AB  CDEF  0123  4567     memory
           buffer                sfp   ret   *arg    

<------   [JJSSSSSSSSSSSSSSCCss][ssss][0xD8][0x01]
           ^|^             ^|            |
           |||_____________||____________| (1)
       (2)  ||_____________||
             |______________| (3)
top of                                                bottom of
stack                                                 stack

In ret wird ein Zeiger auf die Funktion abgelegt, welche parse ausführt.

Ein passendes Assembler-Beispiel könnte etwa so aussehen:


        jmp    0x26                     # 2 bytes
        popl   %esi                     # 1 byte
        movl   %esi,0x8(%esi)           # 3 bytes
        movb   $0x0,0x7(%esi)           # 4 bytes
        movl   $0x0,0xc(%esi)           # 7 bytes
        movl   $0xb,%eax                # 5 bytes
        movl   %esi,%ebx                # 2 bytes
        leal   0x8(%esi),%ecx           # 3 bytes
        leal   0xc(%esi),%edx           # 3 bytes
        int    $0x80                    # 2 bytes
        movl   $0x1, %eax               # 5 bytes
        movl   $0x0, %ebx               # 5 bytes
        int    $0x80                    # 2 bytes
        call   -0x2b                    # 5 bytes
        .string \"/bin/sh\"             # 8 bytes


Dieses Assembler-Programm holt sich zuerst den Offset für den Shell-String und fügt an dessen Ende eine "\0" an, gefolgt von einem Zeiger auf diesen String, dieser wiederum gefolgt von einem NULL-Zeiger. Anschließend wird die Funktion execve mit den entsprechenden Parametern in ebx, ecx und edx aufgerufen. Dieser Auruf startet die angegebene Shell.
Nach dem Aufruf von execve terminiert das Programm mit einem Rückgabecode von 0.

Beispiel: qpopper2.2 auf zwergpinselaffe.fh-wedel.de



weiter

Sniffen / Sniffer entlarven

Unter Sniffen versteht man das Abhorchen des Netzwerkverkehrs mit einem speziellen Programm. Dieses veranlasst Netzwerkkarte, sämtliche Pakete anzunehmen. Diese können dann mehr oder weniger anschaulich auf dem Bildschirm dargestellt werden.

Da es viele Protokolle gibt, bei denen man sich mit Klartext-Passwörtern authentifizieren muss, ist Sniffen in (ungeswitchten) Netzwerken sehr effizient beim Herausfiltern von Passwörtern. Beispiel:

./sniffit -s 195.37.84.217 -nax | grep -i "p a s s"

Sniffer können aber auch entlarvt werden. (Demonstration schwierig)

arp -s hostname 00:ba:d0:c0:ef:ee
ping hostname
Wenn hostname auf den Ping antwortet, dann "snifft" dieser...

weiter

Hijacken von Verbindungen

Unter dem Hijacken von Verbindungen versteht man das eingreifen in bereits bestehende (telnet-)Verbindungen. So lassen sich Befehle einschummeln oder die Sitzung ganz übernehmen. Ein Programm, welches dies erledigt, ist das bekannte Juggernaut.

Weniger bekannt ist, dass auch SSH-Verbindungen geklaut werden können. Wenn sich ein dritter Rechner im selben Netz befindet, so kann dieser zu Beginn der Verbindung als "Man in the Middle" fungieren und alle Daten mitlesen.

weiter

Kernel absichern

Der Linux-Kernel ist die Basis jedes Linux-Systems. Ebenso werden alle primären Netzwerkfunktionalitäten über den Kernel abgebildet. Bei seiner Erstellung lässt sich einstellen, ob er als Router mit Paketfilterung dienen soll oder nicht. Ist diese Option aktiviert, so ist mit entsprechenden Tools im Betrieb der Netzwerkverkehr abhören. Um zu vermeiden, dass dies in feindlicher Absicht geschieht, sollte auf einem Nicht-Router-System diese Option deaktiviert werden.

weiter

Shell Accounts

In einem Linux-System befinden sich meist ein große Anzahl eingetragener Benutzer. Aber längst nicht alle Benutzer existieren auch tatsächlich. Um zu gewährleisten, dass nicht einer dieser unbenutzten Accounts (beispielsweise vom Benutzer Ftp) füt einen Einbruch herhalten muss, sollte in der Datei /etc/passwd bei allen unbenutzen Benutzer die Shell auf /bin/false gesetzt werden.

nach oben
[ Seminar Linux, WWW, Java und Internet ] ... [ Thema Sicherheit unter Linux ] ... [ Einleitung ] ... [ Absicherung von Diensten ] ...