Angriff auf die Domain-Controller-Datenbank (NTDS.DIT)
Inhaltsverzeichnis:
Wie versprochen beginnen wir mit der Analyse der einzelnen Phasen der Cyber Kill Chain des zuvor beschriebenen Angriffs. Heute werden wir einen der Angriffsvektoren auf die Unternehmensinfrastruktur überprüfen, den wir als zwei Phasen zählen können: «Action on Objectives» und «Reconnaissance». Unsere Ziele sind:
- Sich mit den erlangten Konten zu etablieren;
- Maximale Informationen über die Firma (E-Mail, Abteilungsnamen, Telefonnummern, Funktionstitel etc.) für weitere Angriffe zu erhalten oder sogar den Zugang zu ihrer Infrastruktur zu verkaufen.
SYSTEM und NTDS.DIT
Sobald die Angreifer im Firmennetzwerk sind, dringen sie in eines der „schmackhaftesten“ Stücke der ActiveDirectory-Informationen ein, nämlich die Dateien SYSTEM und NTDS.DIT. Diese Dateien sind Datenbanken, die alle Daten von ActiveDirectory enthalten. NTDS.DIT enthält Informationen über alle Benutzer in der Domäne, einschließlich Passwort-Hashes. Die SYSTEM-Datei wird benötigt, um Daten von der NTDS.DIT zu entschlüsseln.
Ich werde in diesem Artikel nicht auf die Methoden zur Hash-Beschaffung eingehen, da darüber bereits viele Artikel geschrieben wurden. Ich werde mich auf die Methode konzentrieren, die die Infrastrukturanfälligkeit durch Passwortoffenlegung zeigt (wenn LM-Hashes verfügbar sind) und die Automatisierung des Suchprozesses, der ihn extrem schnell macht.
Wir benötigen also nur LM- und NTLM-Hashes:Nach Erhalt der Hashes beginnen wir mit dem LM-Hash.
Zum LM-Hash
Einige Informationen über den LM-Hash.
Er basiert auf dem DES Blockchiffre und kann aufgrund zweier Schwachstellen in seiner Realisierung leicht für das Passwortcracking angegriffen werden. Erstens werden Passwörter, die länger als 7 Zeichen sind, in zwei Teile geteilt und jeder Teil wird separat gehasht, was es ermöglicht, jeden Teil separat anzugreifen. Zweitens werden alle Kleinbuchstaben in Großbuchstaben umgewandelt.
Also haben wir:
LM-Hash, der, wie wir bereits herausgefunden haben, aus zwei Teilen besteht.9196B21FEF3C8906AAD3B435B51404EE
AAD3B435B51404EE – dieser Hash stammt von einem leeren Passwort (eine solche Zahlenfolge bedeutet, dass eine Hälfte des Hashs ein leeres Passwort ist).
Wir folgern daraus, dass das Passwort aus weniger als sieben Zeichen besteht, weil der zweite Teil des Hashs mit dem leeren Zeichensatz übereinstimmt.
Nun zum Brute-Forcing des ersten Teils
Dazu verwenden wir hashcat, welches stark parallelisiertes GPU-Bruteforcingermöglicht. Verwenden Sie die folgenden Schlüssel:
-a => Attackenmodus
-m => Hash-Typ
?d = alle Ziffern (0–9).
?l = Kleinbuchstaben (a–z).
?u = Großbuchstaben (A–Z).
?s = Symbole.
Wir erhalten das Passwort in 24 Sekunden.
Jetzt ist NTLM an der Reihe
1BC10704ED604747D7D827FC7A43D555
Es ist viel einfacher, es zu brute-forcen, da wir die folgenden Informationen wissen:
- Welche Zeichen im Passwort verwendet werden;
- Die Reihenfolge dieser Zeichen.
Wir müssen nur überprüfen, ob ein Zeichen groß oder klein geschrieben ist.
Da wir einen LM-Hash haben, hat die gesamte Arbeit nur etwas mehr als 32 Sekunden gedauert.
Wir werden die Aufgabe weiter erschweren:
Angenommen, wir haben ein 14-stelliges Passwort mit dem dritten Schwierigkeitsgrad (klassisches Unternehmenspasswort):29355BC0D45C341B51ACD8D3923F7C21
Wir verwenden den gleichen Trick:Brute-force lieferte uns die erste Annäherung (Passwort in Großbuchstaben) in 31 Sekunden.
29355BC0D45C341B51ACD8D3923F7C21
Jetzt müssen wir nur noch
NTLM:E06E777CD11F495E9B9098B5576A4343
Die Erhöhung der Komplexität des Passworts sogar auf 14 Zeichen macht unsere Aufgabe nicht schwieriger – wenn wir einen LM-Hash haben, dauert das Knacken nur 40 Sekunden!Wir haben einen Hash verarbeitet. Wenn wir eine große Menge von Hashes verarbeiten müssten, wäre das Erstellen von Masken für jedes Passwort zu arbeitsintensiv. Deshalb habe ich ein Tool entwickelt, das für uns die nächste Arbeit übernimmt – ntlm_mask_gen.exe
(Sie können ihn hier herunterladen tut, MD5: c2a9dac79c51e14c84f35febd72d05ba
oder nehmen Sie Python-Code in Anhang 1) :
- Es bildet Wortlisten für jedes einzelne Passwort;
- Es bildet Masken für jedes einzelne Passwort inklusive der gebildeten Wortlisten;
- Es bildet eine einzige Datei mit Strings für jeden einzelnen Hash, Maske und Wortliste.
Alles, was Sie dann tun müssen, ist diese Datei auszuführen und zu beobachten, wie hashcat Passwörter in Sekunden geknackt werden.
Vorführung der beschriebenen Methodik
Lassen Sie uns ein weiteres Experiment durchführen, um die beschriebene Technik zu demonstrieren:
Wir verwenden 10 Passwörter mit 10 Zeichen, dem vierten Schwierigkeitsgrad mit den folgenden Einstellungen (traditionelle Anforderungen für technologische/administrative/systemische Konten aus der Unternehmenspasswortrichtlinie):
- Wir erstellen eine Datei mit Hashes
csv
:
- Dann erstellen wir eine Datei für unser Tool, das Wortlisten und Masken für uns generiert. Wir nehmen NTLM-Hash und Passwort zum Hacken von LM, zum Beispiel
test_ntlm_input.txt
:
- Unser Tool ausführen:Sofort erhalten wir eine Datei, die für die Passwortsuche durch Masken und automatisch gebildete Wortlisten bereit ist:
- Wir führen diese Datei aus und erhalten unsere Passwörter in 14 Sekunden:
Klarstellung
Wie Sie wissen, ist ab Version 2008 die Speicherung von LM-Hashes standardmäßig deaktiviert, aber im Falle einer Migration von Version 2003 (oder niedriger) bleiben Konten, die ihre Passwörter nach der Migration nicht geändert haben, mit dem LM-Hash in der Datenbank. In der Regel sind dies technologische Konten mit Passwörtern, die aus verschiedenen Gründen nicht geändert werden, zum Beispiel können sie das Abstürzen einiger kritischer Dienste verursachen usw. Solche Konten sind eine ernsthafte Bedrohung, da ihre Passwörter häufig «Niemals Ablaufen» sind, ihr Zugang nicht überwacht wird und sie häufig hohe Privilegien bis zum administrativen Zugang haben. Deshalb wird die Verwendung solcher Konten für Einbrüche am unauffälligsten sein.
Fazit
Es ist äußerst wichtig, auf Domänen zu verzichten, die auf 2003 oder niedriger basieren, und neuere Versionen zu verwenden. Im Falle einer Migration müssen Sie sicherstellen, dass alle Konten ihre Passwörter geändert haben und keine LM-Hashes mehr in der Datenbank vorhanden sind. Und noch ein Rat für Domain-Administratoren und Informationssicherheitsexperten: Arbeiten Sie proaktiv und brute-forcen Sie Ihre Passwörter mindestens vierteljährlich! Sie sollten den Zugriff auf AD kontrollieren, insbesondere Schattenoperationen mit SYSTEM- und NTDS.DIT-Dateien.
Ich hoffe, dieser Artikel wird für Informationssicherheitsexperten nützlich sein, die die beschriebenen Techniken als Argumente bei der Kommunikation mit IT-Spezialisten verwenden können. Oder er wird für Administratoren nützlich sein, um ein breiteres Verständnis für die mit Angriffen auf ActiveDirectory verbundenen Risiken zu erlangen.
Anhang 1
import math alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'exception = ' &%{}<>^|"'file_name = open('D:hashcatkd_input.new','r')main_len = len(file_name.readlines())file_name.close()file_name = open('D:hashcatkd_input.new','r')file_name_out = open('D:hashcatkd_input.cmd','w')hashes = []passwords = []masks = [[] for i in range(main_len)]dicts = []char_sets_count = 0char_sets = [[] for i in range(main_len)]ind_main = 0 ch1 = [] ch2 = [] ch3 = [] ch4 = []ch_sets = [ch1, ch2, ch3, ch4] def new_init(pass_letter): for ind_0 in range(4):ch_sets[ind_0] = [] return predict(pass_letter) def predict(new_password):pass_letter = '' for let in new_password: if let in alphabet and not (let in pass_letter):pass_letter += let return dict_generator(pass_letter) def dict_generator(pass_letter): global char_sets_count dict_new = ''pass_len = len(pass_letter) if pass_len < 4: for ind1 in range(pass_len):ch_sets[ind1].append(pass_letter[ind1])ch_sets[ind1].append(pass_letter[ind1].lower()) else:filler(pass_letter, spreader(pass_len)) for ind2 in range(4): if len(ch_sets[ind2]) > 0:dict_new += '-' + str(ind2+1) + ' ' + ''.join(ch_sets[ind2]) + ' 'char_sets[char_sets_count] = [ch_sets[0], ch_sets[1], ch_sets[2], ch_sets[3]]char_sets_count += 1 return dict_newdef spreader(letter_num):spread_counter = [0, 0, 0, 0] for ind3 in range(4):spread_counter[ind3] = int(math.ceil(letter_num/float(4-ind3)))letter_num -= spread_counter[ind3] return spread_counterdef filler(pass_letter, counter_letter):count_l = 0 for ind_ch in range(4): for ind_set in range(counter_letter[ind_ch]):ch_sets[ind_ch].append(pass_letter[count_l])ch_sets[ind_ch].append(pass_letter[count_l].lower())count_l += 1 def mask_generator(password,pwd_idx):mask_new = '' for pw_let in password: if pw_let in alphabet: for ind_array in range(4): if pw_let in char_sets[pwd_idx][ind_array]:mask_new += '?'+str(ind_array+1) elif pw_let in exception:mask_new += '?s' else:mask_new += pw_let masks[pwd_idx] = mask_new# ---------------------- Main -------------------------------- for line in file_name:hashes.append(line[:32])passwords.append(line[33:len(line)-1])dicts.append(new_init(passwords[ind_main]))ind_main += 1 for pwd_idx in range(len(passwords)):mask_generator(passwords[pwd_idx],pwd_idx) for index in range(len(hashes)):text = 'cudaHashcat64.exe -m 1000 -a 3 -o ntlm_tesult.hash ' + str(hashes[index]) + ' ' + str(dicts[index]) + ' ' + str(masks[index]) + 'n'file_name_out.write(text)file_name.close()file_name_out.close()