2022-01-23 by ams


Folgender Artikel ist dazu gedacht die eigene Umgebung für die man selbst verantwortlich ist sicherer zu gestalten.
Das folgende Audit ist nur mit Genehmigung der entsprechenden Stellen wie z.B. IT-Sicherheitsverantwortlicher durchzuführen und darf keinesfalls unerlaubt oder gar in fremden Umgebungen durchgeführt werden.

Alle Daten wie z.B. Orte, Namen, Passwörter in diesem Artikel sind fiktiv und wenn überhaupt nur andeutungsweise sehr weit an realen Beispielen angelehnt ohne Rückschlüsse zu ermöglichen und nicht die Geheimhaltung zu missachten.
Der Autor ist als Systemadministrator mit Schwerpunkt IT-Sicherheit in einem Unternehmen tätig und hat bereits u.a. diverse Erfahrungen mit Passwort-Audits in unterschiedlichen Umgebungen gesammelt.


Anmerkung:

Mein Ziel ist nicht eine bis ins letzte Detail ausführliche Anleitung zu erstellen.
Im Internet gibt es bereits viele Artikel zu diesen Themen.
Wenn man in seiner Suchmaschine die Schlagwörter eingibt die hier vielleicht nur kurz genannt, aber nicht weiter ausgeführt werden, sollte man fündig werden.
Genaue Beschreibung zu Parametern findet man z.B auch in den entsprechenden Manpages.

Mein Ziel ist es eher Admins zu motivieren, welche dies selbst auditieren möchten, weil vielleicht z.B.

  • nicht die Kosten für den letzten geplanten Pentest genehmigt wurden
  • noch nicht der letzte Webservice hinter einer WAF und mit Zweifaktorauthentifizierung aus irgendwelchen Gründen abgesichert ist
  • vor und/oder nach einer Awareness-Kampagne das Verständnis und der Erfolg dieser zu diesem Punkt geprüft werden soll

Vielleicht existiert auch schon eine gute sichere Passwort-Policy aber es werden durch das Audit Accounts aufgedeckt die zuvor schon existierten und z.B. den Haken ‘password never expires’ gesetzt haben.
Gerade bei Serviceaccounts erfahrungsgemäss ein Klassiker.

Vielleicht gibt es dem ein oder anderen Ideen die eigene Umgebung in der man schon eine Art Tunnelblick hat, diese durch eine andere Brille zu sehen.
Das Thema ‘Passwort’ ist ein kleines Puzzlestück in der gesamten Betrachtung der IT-Sicherheit im Unternehmen und es ist kein Allheilmittel wenn man ein schwaches Passwort durch ein starkes ersetzt.

Eigentlich ist das Thema ‘Passwort’ eh schon lange tot und wir betreiben hier nur Schadensbegrenzung.
Man möchte es einem Angreifer wo es geht schwierig machen - vor allem wenn der Aufwand verhältnismässig gering ist.

Wenn ein Angreifer z.B. über eine Kompromittierung eines Clients oder Servers Hashwerte von Passwörtern in die Finger bekommt, hat man vermutlich eh schon Probleme und man könnte sich über Pass-the-Hash und andere Dinge unterhalten.
Aber man möchte vielleicht auch das ein Offline-Knacken des Passwortes im zeitlichen Bereich von Jahren und nicht Minuten/Stunden/Tagen liegt, da vielleicht unsere User noch nicht genug Awareness erhalten haben und evtl. durch das Passwort Rückschlüsse auf andere Konten des Users möglich wären.

Wir sehen an Gründen scheitert es nicht.
Schreiten wir zur Tat!


Schritt 1: Extrahieren der Passworter aus dem Active Directory über den Domaincontroller (DC)

Wir melden uns als Domain-Administrator am Domain Controller (DC) an und öffnen ein Windows Powershell Fenster.
Mit folgendem Befehl exportieren wir eine Kopie der Active-Directory Datenbank nach c:\temp:

powershell "ntdsutil.exe 'ac i ntds' 'ifm' 'create full c:\tmp' q q"

Im Anschluss finden wir die ntds.dit Datei im Ordner ‘Active Directory’ sowie die System Hive Datei im Ordner ‘registry’.
Wir übertragen die Verzeichnisse in unser Kali Linux.

alt text

ACHTUNG:

Es ist selbsterklärend das diese Daten äußerst sensibel behandelt werden müssen und nicht in falsche Hände geraten sollten.
Empfehlungsansätze wäre z.B. Nutzung eines verschlüsselten Veracrypt-Containers zur Verwahrung/Übertragung der Daten und Festplattenverschlüsselung auf dem Gerät auf welchem das Kali Linux beheimatet ist.


Schritt 2: Extrahieren der Zugangsdaten

Nachdem wir im Kali einen neuen Ordner namens z.B. ‘pwaudit’ erstellt haben und dort die Daten abgelegt haben, öffnen wir ein Terminal.

alt text

Wir wechseln in den neuen Ordner und führen folgenden Befehl zum Extrahieren der Zugangsdaten aus:

impacket-secretsdump -ntds Active\ Directory/ntds.dit -system registry/SYSTEM -outputfile result local

Je nach Größe kann dies nun etwas dauern.

alt text

Nach Abschluss finden wir eine Datei ‘result.ntds’ welche nun alle Anmeldenamen und Hashwerte der Passwörter unserer Domäne beinhaltet.


Schritt 3: Knacken schwacher Passwörter mittels Wörterbuchattacken (Bruteforcing)

Kali Linux beinhaltet bereits mehrere einfache Wörterlisten.
Wir führen einen ersten Testlauf mit der bereits enthaltenen ‘rockyou’ Liste durch.
Diese muss erst noch entpackt werden falls noch nicht geschehen:

sudo gunzip /usr/share/wordlists/rockyou.txt.gz

Wer am Inhalt interessiert ist kann gerne einen Blick darauf werfen.

more /usr/share/wordlists/rockyou.txt

Bereits in dieser einfachen Liste sind nicht nur einfach Wörter wie aus dem Duden enthalten, sondern unterschiedlichste Kombinationen, Schreibweisen, Tastaturmuster, Zahlenkombinationen etc.

Wir verwenden für einen ersten einfachen Bruteforce-Angriff das Tool ‘hashcat’:

hashcat -a 0 -m 1000 --potfile-path POT.txt --username result.ntds /usr/share/wordlists/rockyou.txt

Falls Passwörter gefunden werden, findet eine Ausgabe im Terminal statt und sie werden in der Datei ‘POT.txt’ gespeichert.
Weitere Ausführungen von hashcat z.B. mit anderen Wörterlisten ergänzen das Potfile ‘POT.txt’ um weitere Funde.
Bereits gecrackte Hashes werden gespeichert und nicht erneut getestet.

alt text

Tipp: Falls jetzt schon bereits Passwörter gefunden werden, sollte man sich zeitnah Gedanken über die angewandte Passwort-Policy im Unternehmen machen. ;-)

Möchten wir die Usernamen zum gefundenen Passwort sehen müssen wir nach dem Lauf ein ‘–show’ mit angeben und können die Ausgabe bei Bedarf in eine Datei (z.B. ‘juwelen.txt’) umleiten:

hashcat -a 0 -m 1000 --potfile-path POT.txt --username result.ntds /usr/share/wordlists/rockyou.txt --show > juwelen.txt

Auch wenn die ‘rockyou.txt’ mehr als 14 Millionen Passwörter beinhaltet ist der Lauf relativ schnell durch.

Um die Trefferquote zu erhöhen suchen wir im Internet nach Wörterlisten mit mehr Inhalt, z.B. ‘crackstation wordlist’ und führen damit anstelle der rockyou.txt einen weiteren Lauf durch.
Mit über einer Milliarde Wörtern dauert der Vorgang schon länger.


Schritt 3.1: Erstellen einer eigener Wörterliste

Nun wissen wir wie wir eine einfache Wörterbuchattacke durchführen und wir haben evtl. schon einige schwache Passwörter gefunden.
Ein Angreifer würde jedoch eine eigene zugeschnittene Wörterliste auf das jeweilige Umfeld verwenden.
Quellen wären z.B. die Firmenwebseite parsen, Social-Media-Kanäle, Adressdaten (Orte, Straßen, Hausnummern, Vorwahlen, Telefonnummer) oder bereits geleakte Daten im Internet.

Um uns die Arbeit einer Recherche von Extern zu sparen ist auch ein LDAP-Export vergleichsweise praktikabel.
Der Fantasie sind hier keine Grenzen gesetzt und folgendes soll nur eine Idee sein um schnell an ein Wörterbuch mit Adressdaten etc. zu kommen.

Wir verwenden die Exchange Management Console und schreiben den Export nach ‘C:\temp\export.csv’.

Get-ADUser -Filter 'GivenName -like "*"' -Properties * | Select -Property DisplayName,GivenName,Surname,UserPrincipalName,Title,Department,Office,OfficePhone,MobilePhone,Fax,StreetAddress,City,State,PostalCode,Country | Export-CSV "C:\temp\export.csv" -NoTypeInformation -Encoding UTF8

Die Datei kopieren wir wieder in unser Verzeichnis im Kali Linux.
Der Export sollte in etwa ähnlich wie in der folgenden Ausgabe aussehen.
Im Beispiel zwei Zeilen fiktive Daten welche wir noch zum Wörterbuch formen müssen.

cat export.csv
"Meier, Erich","Erich","Meier","erich.meier@meinefirma.de","Lager","MF LG","Entenhausen",,,,"Kälberstraße 23","Entenhausen",,"54321","DE"
"Ostermüller, Christian","Christian","Ostermüller","christian.ostermueller@meinefirma.de","Einkauf","MF EK","Entenhausen",,,,"Kälberstraße 23","Entenhausen",,"54321","DE"

Es gibt mehrere Möglichkeiten und unterschiedliche Lieblingstools.
Als Freund des ‘awk’ nutze ich dieses exemplarisch direkt im Terminal für eine ‘Quick&Dirty Wörterliste’.
Als erstes würde ich den Separator ‘,’ nehmen und jedes Feld in eine eigene Zeile konvertieren.

awk -v RS=',' '1' export.csv > pwlist1.txt

Die Gänsefüsschen sollten weg und danach Leerzeilen entfernen.

cat pwlist1.txt | tr -d '"' > pwlist2.txt
awk 'NF > 0' pwlist2.txt > pwlist3.txt

Mal sehen…

cat pwlist3.txt
Meier
 Erich
Erich
Meier
erich.meier@meinefirma.de
Lager
MF LG
Entenhausen
Kälberstraße 23
Entenhausen
54321
DE
Ostermüller
 Christian
Christian
Ostermüller
christian.ostermueller@meinefirma.de
Einkauf
MF EK
Entenhausen
Kälberstraße 23
Entenhausen
54321
DE

Felder mit Leerzeichen und mehreren Strings in einzelne Zeilen konvertieren und nochmal Leerzeilen entfernen.

awk -v RS=' ' '1' pwlist3.txt > pwlist4.txt
awk 'NF > 0' pwlist4.txt > pwlist5.txt

Die Emailadressen sind evtl. brauchbarer wenn beim ‘@’ umgebrochen wird.

awk -v RS='@' '1' pwlist5.txt > pwlist6.txt

Doppelte Einträge brauchen wir natürlich nicht und entfernen diese für die finale Liste.

awk '!seen[$0]++' pwlist6.txt > mypwlist.txt

cat mypwlist.txt
Meier
Erich
erich.meier
meinefirma.de
Lager
MF
LG
Entenhausen
Kälberstraße
23
54321
DE
Ostermüller
Christian
christian.ostermueller
Einkauf
EK

Das sollte jetzt nach einer brauchbaren Wörterliste aussehen welche wir direkt testen.

hashcat -a 0 -m 1000 --potfile-path POT.txt --username result.ntds mypwlist.txt

Schritt 3.2: Erweitern einer benutzerdefinierten Wörterliste mit Begriffen und Datum

Um die Trefferquote weiter zu erhöhen wäre es noch zweckmässig die Wörterliste mit weiterem Inhalt zu füllen den auch ein externer Angreifer recherchieren würde.
Weitere Möglichkeiten sind z.B. regionale Vornamen.
Als Beispiel: Wenn das Unternehmen beispielsweise in Bayern sitzt, wären z.B. sämtliche bayerische Vornamen lohnenswert da diese wahrscheinlich weniger in allgemeinen Wörterlisten vorkommen.

Desweiteren würde ein Angreifer sicherlich auch Quellen wie z.B. ‘dnsdumpster’, ‘theHarvester’ oder einfach Suchmaschinen verwenden um spezifische Begriffe ausfindig zu machen.
Nehmen wir an wir finden via dnsdumpster Hostnamen die unwissentlich (oder auch wissentlich) öffentlich einsehbar sind wie z.B.

Fiktiv: router-muc-offc-01.meinefirma.de
Fiktiv: stor-ber-prod-01.meinefirma.de

Begriffe wie ‘muc’, ‘ber’ welche scheinbar für die Firmenlokation München und Berlin stehen, sowie interne Abkürzungen für Abteilungen wie Office oder Produktion sollten in unser Wörterbuch.

Als nächstes nehmen wir noch an unser Unternehmen vergibt Initial-Passwörter für User nach einem Schema und nicht zufällig.
Schlechte Idee.

Angenommen ein Angreifer erhält aus irgendwelchen Quellen das Vorgehen der Administration.
Der Leak könnte auf viele Arten passiert sein. Z.B. aus einer internen Doku, aus einem alten Passwortleak oder aus einer verlorengegangenen Email mit dem Initial-Passwort an den User etc.

Wir nehmen das fiktive Beispiel ‘initial-04052016’ an welches bekannt ist.

Dies gibt uns Anlass mit einem Pythonscript Wörterbuch mit ‘initial- < datum > ' zu Erstellen und für einen definierten Datumsbereich die Passwörter zu generieren.

Praktisch wäre es ebenso vorerst die Datumsfelder ohne Zusätze zu generieren und in den unterschiedlich verschiedenen Schreibweisen.
(ddmmyyyy / yyyymmdd / mmddyyyy / yyyy / …).
Dies können wir nämlich im nächsten Schritt 3.3 später gut gebrauchen.

Wir generieren mal großzügig ab Jahr 1950 mit unserem Pythonskript welches wir datumgen.py nennen.

i = 1

for jahr in range (1950,2023):
    for monat in range(1,13):
        for tag in range(1,32):

            #Jahr
            print(prefix + str(jahr))

            #Tag/Monat/Jahr
            print(prefix + "{:02d}".format(tag) + "{:02d}".format(monat) + str(jahr))

            #Jahr/Monat/Tag
            print(prefix + str(jahr) + "{:02d}".format(monat) + "{:02d}".format(tag))

            #Monat/Tag/Jahr
            print(prefix + "{:02d}".format(monat) + "{:02d}".format(tag) + str(jahr))

            i += 1

Mit unserem Lieblingseditor speichern wir das Skript im Ordner und vergeben noch das Recht das es auch ausgeführt werden darf:

chmod +x datumgen.py

Wir generieren eine erste Liste und leiten die Ausgabe in eine Datei datumwl.txt um.

python datumgen.py > datumwl.txt

Als nächstes erweitern wir unser Skript um einen eigenen Prefix ‘-’ vor dem Datum zu setzen und um eine mögliche Option im Datum bei Bedarf einen Separator einzufügen (z.B. “."), welche wir aber im Beispiel erstmal leer lassen.

separator = ""
prefix = "-"
i = 1

for jahr in range (1950,2023):
    for monat in range(1,13):
        for tag in range(1,32):

            #Jahr
            print(prefix + str(jahr))

            #Tag/Monat/Jahr
            print(prefix + "{:02d}".format(tag) + separator + "{:02d}".format(monat) + separator + str(jahr))

            #Jahr/Monat/Tag
            print(prefix + str(jahr) + separator + "{:02d}".format(monat) + separator + "{:02d}".format(tag))

            #Monat/Tag/Jahr
            print(prefix + "{:02d}".format(monat) + separator + "{:02d}".format(tag) + separator + str(jahr))

            i += 1

Um unsere datumwl.txt Wörterbuch nicht zu überschreiben sondern mit weiterem Inhalt zu ergänzen, starten wir die Ausgabe wie folgt:

python datumgen.py >> datumwl.txt

Angenommen ein Angreifer würde aus z.B. wie oben genannten Quellen die Information bekommen das ein (fiktives) Passwort z.B. ‘MUCprod-2016’ verwendet wurde.
Dies könnte zum Anlass genommen werden unser Skript etwas anzupassen und noch weitere Kombinationen zu generieren, um auch Dinge wie ‘BERoffc-yyyy’ abzudecken.

Nehmen wir an unser Unternehmen für welches wir das Audit durchführen hat noch weitere nationale Standorte auf der Firmenwebseite, wir nehmen natürlich sämtliche Begriffe und Abkürzungen mit auf.


Schritt 3.3: Da geht noch was. Kombinieren der Wörterlisten.

Hashcat kann u.a. auch Wörterlisten kombinieren. Mit der Option ‘-a 1’ und der Angabe zweier Wörterbuchdateien werden die Wörter miteinander kombiniert.
Im folgenden Befehl werden die Wörter der ‘rockyou’ auf der linken Seite des Passwortes und auf der rechten Seite die aus unserer eigenen Wörterliste verwendet.
Eine umgekehrte Angabe der Wörterlisten sollte deshalb ebenfalls durchgeführt werden.

hashcat -a 1 -m 1000 --potfile-path POT.txt --username result.ntds /usr/share/wordlists/rockyou.txt mypwlist.txt

alt text

Oder um auf das Beispiel im vorigen Schritt zurückzukommen, kombinieren wir eine mypwlist.txt mit unserer datumwl.txt was uns sicherlich Funde beschert wenn User Kombinationen von Wörtern mit Datum verwendet haben.

In vielen Fällen ergibt die doppelte Angabe derselben Wörterliste (also in Kombination mit sich selbst) noch Funde, da hybride Kennwörter (also ganze Wörter und Zahlen) verwendet werden.
Kombinationen wie z.B. Vorname/Nachname + Telefonnr./Postleitzahl werden dann in sekundenschnelle gefunden.

hashcat -a 1 -m 1000 --potfile-path POT.txt --userame result.ntds mypwlist.txt mypwlist.txt

Wer ein paar Tage Zeit und CPU Ressourcen mit sich bringt kann eine Kombination der ‘rockyou’ mit sich selbst (oder eine größere) probieren.
Cyberkriminelle scheuen sicherlich auch keine Zeit und Mühen wenn sie geleakte Hashes in die Finger bekommen und Offline bruteforcen.

Tipp: Wer den Vorgang pausieren möchte kann hashcat auch mit ‘c’ (checkpoint) beenden und beim nächsten Start mit ‘hashcat –restore’ an dieser Stelle weiter fortfahren.


…zum Ende

Wer sich noch tiefer mit hashcat Funktionen beschäftigen möchte, sollte sich die ‘rule-based attack’ ansehen.
Mit dieser sind u.a. ‘leetspeak’ Regeln möglich um z.B. ‘E’ durch ‘3’ oder ‘i’ durch ‘1’ etc. zu ersetzen.
Im Internet sind auch ‘wordlist generators’ für Passwörter zu finden.
Auch sogenannte ‘wordlist combinators’ welche mehreren Wörterlisten kombinieren und in eine neue Ausgabe schreiben.

Letzter Tipp:
Die bisher gefundenen Passwörter einsehen und prüfen ob diverse Muster zu erkennen sind.
Falls ein spezielles Kriterium erkannt wird, dieses wiederum in die eigene Passwortliste aufnehmen.

An dieser Stelle hoffe ich das ich zumindest ein paar Denkanstöße geben konnte.
Auch wenn es nur ist das jemand seine eigene Passwortwahl daraufhin optimiert.