Mask attack od zera: jak Hashcat naprawdę generuje keyspace
Pierwszy błąd z Hashcatem popełniasz, zanim wciśniesz Enter: zakładasz, że on „łamie hasła". Nie łamie, tylko liczy hashe, a maski to sposób karmienia tego silnika. Pokażę Ci, jak naprawdę powstaje keyspace i jak przestać zgadywać, a zacząć liczyć.
Mask attack od zera: jak Hashcat naprawdę generuje keyspace
Materiał jest edukacyjny - kodeks karny już nie. Raz, dwa, trzy: CBZC i NASK patrzy.
Pierwszy błąd w pracy z Hashcatem pojawia się, zanim padnie jakiekolwiek polecenie. To przekonanie, że Hashcat „łamie hasła".
Nie.
Hashcat liczy funkcje skrótu. Reszta, czyli maski, reguły, wordlisty, to tylko różne sposoby karmienia tego samego silnika. Jeśli nie rozumiesz, jak ten silnik jest zbudowany, każdy kolejny atak będzie improwizacją. Czasem skuteczną. Częściej kosztowną (głównie czasowo) i mylącą, bo kończy się frustracją.
Hashcat jest narzędziem stricte inżynieryjnym. Jego architektura nie powstała po to, żeby było „łatwo", tylko żeby dało się przetworzyć absurdalne ilości danych w możliwie najprostszym modelu wykonania. To dlatego GPU nie jest dodatkiem, tylko fundamentem.
Co naprawdę dzieje się po uruchomieniu Hashcata
Z punktu widzenia programu każdy atak, niezależnie od trybu, składa się z tego samego pipeline'u: najpierw powstają kandydaci, potem są hashowani, na końcu porównywani z hashem docelowym.
I tu pada zdanie, które usłyszysz w co drugim tutorialu: „GPU tylko liczy hashe, kandydatów generuje CPU". To połowa prawdy. I akurat ta połowa, która wykłada ludzi przy maskach.
W rzeczywistości Hashcat dzieli każdy atak na dwie pętle. Base loop chodzi na CPU i produkuje słowa bazowe. Mod loop chodzi na GPU i to on dorabia z tych słów bazowych finalnych kandydatów, bezpośrednio na karcie. Ten mod loop to amplifier i to jest całe źródło przyspieszenia. Po co ten cyrk? Bo gdyby CPU miał wypychać przez PCI-E każdego kandydata z osobna, magistrala stałaby się wąskim gardłem, zanim GPU policzyłoby pierwszy hash. Więc CPU rzuca tylko zarodki, a GPU rozmnaża je u siebie.
Stąd wniosek, który wraca w całym artykule: jeśli base loop nie nakarmi GPU dostatecznie szerokim, równoległym strumieniem, karta się nudzi. A znudzone GPU to zafałszowany audyt, bo realna prędkość leci w dół o rzędy wielkości, mimo że maska teoretycznie „poszła".
Czym jest keyspace (i dlaczego to tylko mnożenie)
Keyspace to liczba wszystkich kandydatów, jakie dana maska potrafi wygenerować. Nic więcej, nic mniej. I co najważniejsze, liczy się go zwykłym mnożeniem: bierzesz rozmiar zbioru znaków na każdej pozycji maski i mnożysz przez siebie.
Maska to po prostu ciąg placeholderów, gdzie każdy placeholder opisuje, jakie znaki mogą stać na danej pozycji. Hasło o długości 8 znaków potrzebuje maski z 8 placeholderów.
Charsety, czyli alfabet maski
Wbudowane zbiory znaków, których używasz w masce:
-
?lto małe literyabcdefghijklmnopqrstuvwxyz(26 znaków) -
?uto wielkie literyABCDEFGHIJKLMNOPQRSTUVWXYZ(26) -
?dto cyfry0123456789(10) -
?sto znaki specjalne i spacja (33) -
?ato skrót na?l?u?d?s, czyli wszystkie drukowalne znaki ASCII (95) -
?hi?Hto hex małymi i wielkimi (0-9a-foraz0-9A-F) -
?bto wszystkie możliwe bajty0x00-0xff(256), przydatne przy binarnych formatach
Znak dosłowny wpisujesz po prostu wprost: maska ?u?l?l?l?l?l?d?d! ma na końcu twardy wykrzyknik. Jedyny wyjątek to dosłowny znak zapytania, który zapisujesz jako ??.
Jak policzyć keyspace maski ręcznie
Najlepiej na liczbach, bo dopiero wtedy widać skalę.
PIN, czyli ?d?d?d?d, to 10 do potęgi 4, równe 10 000 kandydatów. Złamiesz to szybciej, niż zdążysz zaparzyć kawę.
Sześć małych liter, ?l?l?l?l?l?l, to już 26 do potęgi 6, czyli 308 915 776, ponad 300 milionów kandydatów. I to tylko dla samych małych liter.
A teraz klasyk z korporacji, hasło typu „Wiosna2026!", czyli maska ?u?l?l?l?l?l?d?d?d?d?s:
26 × 26^5 × 10^4 × 33 ≈ 1,02 × 10^14
Grubo ponad sto bilionów kandydatów. Brzmi jak dużo, ale dla GPU liczącego NTLM to godziny, nie wieczność. I teraz najważniejsze: jeśli wiesz, że polityka i tak wymusza wykrzyknik na końcu, nie marnuj na niego całego ?s. Wbij dosłowne !:
?u?l?l?l?l?l?d?d?d?d! → 26 × 26^5 × 10^4 ≈ 3,09 × 10^12
Jeden znak zamieniony ze zmiennego na stały i keyspace spadł 33-krotnie. To jest cała dyscyplina mask attacku w jednym ruchu.
Mask attack w praktyce (-a 3)
Tryb maski to -a 3. Załóżmy, że masz plik z hashami NTLM:
hashcat -m 1000 -a 3 ntlm.txt ?u?l?l?l?l?l?d?d?d?d!
Rozbicie: -m 1000 to typ hasha (NTLM), -a 3 to tryb maski, a na końcu jedzie maska. Złamane hasła wpadają do potfile i wyciągniesz je przez --show. Status na ekranie pokaże Ci prędkość, postęp i szacowany czas, i właśnie ten czas jest Twoim sygnałem, czy maska ma sens, czy liczysz do końca świata.
Custom charsety (-1 -2 -3 -4)
Często nie wiesz, czy ktoś capitalizuje pierwszą literę, czy nie. Zamiast robić dwa ataki, definiujesz własny zbiór znaków flagą -1 i wołasz go w masce jako ?1:
hashcat -m 1000 -a 3 ntlm.txt -1 ?u?l ?1?l?l?l?l?l?d?d?d?d!
Pierwsza pozycja to teraz wielka albo mała litera. Masz cztery sloty: -1, -2, -3, -4 (albo pełne --custom-charset1 do 4). Zbiory możesz też trzymać w plikach .hcchr, gdzie znaki wpisujesz w pierwszej linii.
Zmienna długość: --increment
Maska ma sztywną długość. Jeśli chcesz przejechać zakres długości, dokładasz --increment i ograniczasz go widełkami:
hashcat -m 1000 -a 3 ntlm.txt --increment --increment-min 8 --increment-max 12 ?a?a?a?a?a?a?a?a?a?a?a?a
To przeleci długości od 8 do 12. Tylko ostrożnie z ?a, bo każdy kolejny ?a mnoży keyspace przez 95. Przy dwunastu pozycjach Hashcat policzy Ci czas zakończenia, który spokojnie wyląduje poza wszelkim sensem (o tym za chwilę).
.hcmask, czyli maski hurtem
Jednej maski nie da się rozciągnąć tak, żeby pokryła różne długości z różnymi układami znaków. Od tego są pliki .hcmask: jedna maska na linię, opcjonalnie z własnymi charsetami z przodu. Format to charset1,charset2,charset3,charset4,maska, gdzie charsety są opcjonalne.
Przykładowy plik /home/karolancx/masks/policy.hcmask:
?u?l?l?l?l?l?d?d?d?d! ?u?l?l?l?l?l?l?d?d?d?d! ?u?l,?1?l?l?l?l?l?d?d?d?d!
Trzecia linia definiuje lokalny charset ?1 jako wielka lub mała litera i używa go na pierwszej pozycji. Odpalasz to jednym strzałem:
hashcat -m 1000 -a 3 ntlm.txt /home/karolancx/masks/policy.hcmask
Hashcat przejedzie maski po kolei. To Twój sposób na zakodowanie całej polityki haseł firmy w jednym pliku.
Hybryda: wordlista plus maska (-a 6 i -a 7)
Najbardziej korporacyjny schemat świata to słowo plus rok plus znak. Pod to są dwa tryby hybrydowe. -a 6 to wordlista z maską doklejoną z prawej, -a 7 to maska z lewej i wordlista z prawej.
hashcat -m 1000 -a 6 ntlm.txt slowa.txt ?d?d?d?d
Bierze każde słowo z slowa.txt i dokleja cztery cyfry: „Wiosna2026", „NazwaFirmy2024" i tak dalej. Odwrotnie, gdy cyfry mają iść z przodu:
hashcat -m 1000 -a 7 ntlm.txt ?d?d?d?d slowa.txt
W realnym audycie hybryda z firmowym słownikiem bije czysty brute force na głowę, bo trafia w to, jak ludzie naprawdę budują hasła.
Dlaczego maska bije czysty brute force (i dlaczego --keyspace „kłamie")
Maska to brute force z dyscypliną. Nie testujesz wszystkiego, testujesz to, co realnie może być hasłem, i odcinasz keyspace, którego nikt nigdy nie wpisze.
I tu wracamy do architektury z początku, bo jest na to twardy dowód w samym narzędziu. Uruchom --keyspace na masce i porównaj z prawdziwą liczbą kombinacji:
hashcat --keyspace -a 3 ?a?a?a?a?a?a?a?a → 7 737 809 375 prawdziwa liczba kombinacji (95^8) → 6 634 204 312 890 625
Różnica o rzędy wielkości i to nie jest błąd. --keyspace raportuje rozmiar base loopa, czyli tej części, która chodzi na CPU i służy do rozdzielania pracy. Reszty Hashcat nie liczy, bo dorabia ją na GPU w mod loopie. To dokładnie ta sama architektura, o której mówiłam na samym początku, tylko widziana od strony liczników.
I jest jeszcze konsekwencja praktyczna, o której mało kto mówi. Hashcat zrównolegla generację po pierwszych dwóch, trzech znakach maski. Jeśli ustawisz je na sztywno, zabijasz prawie wszystkie równoległe generatory i GPU zostaje bez paliwa, przez co potrafi zwolnić nawet stukrotnie. Wniosek na warsztat: zmienność trzymaj po lewej stronie maski, a znane lub stałe fragmenty wrzucaj na prawo. To samo hasło, ten sam keyspace, a prędkość zupełnie inna.
Fun fact: jeśli kiedyś zobaczysz w polu szacowanego czasu „Next Big Bang", to nie literówka. Hashcat tak właśnie kwituje maski, których keyspace przekracza granice rozsądku (i jego liczników). To Twój sygnał, że pora wrócić do tej tabelki z mnożeniem i przyciąć maskę.
To jest cała robota z maskami. Nie zgadujesz, tylko liczysz keyspace, dobierasz charsety pod realną politykę i pilnujesz, żeby GPU miało co liczyć. Reszta to dyscyplina.
I oczywiście robisz to na hashach, które masz prawo crackować, czyli we własnym labie albo w ramach autoryzowanego audytu. Bo silnik silnikiem, ale kodeks karny liczy szybciej niż każde GPU ;)
Terminarz
Lista najbliższych webinariów
Zobacz inne wpisy
Wiedza i świadomość na temat aktualnych cyberzagrożeń to podstawa dobrej taktyki bezpieczeństwa. Chcesz być na bieżąco z wydarzeniami ze świata cybersecurity? A może szukasz wskazówek jak zapewnić wyższy poziom cyberbezpieczeństwa w swojej firmie? Chcesz poznać topowe rozwiązania? Dobrze trafiłeś.
Testy Socjotechniczne: Symulacje Phishingu
Sprawdź w kontrolowanych i bezpiecznych warunkach czy Twoi pracownicy są odporni na phishing i inne metody socjotechniczne. Obejmują one phishing e-mailowy, vishing (ataki telefoniczne) czy smishing (SMS), skupiając się na ludzkim czynniku w cyberbezpieczeństwie.
Testy Penetracyjne Sieci
Zapoznaj się z ofertą testy penetracyjnych sieci. Zabezpiecz infrastrukturę krytyczną przed atakami. Poznaj zagrożenia, podatności i luki. Na koniec otrzymasz szczegółowy raport z rekomendacjami.
Testy Penetracyjne Aplikacji
Testy penetracyjne aplikacji webowych to skuteczny sposób na ochronę stron internetowych, sklepów online i portali przed cyberatakami. Symulują ataki hakerskie, wykrywając luki w zabezpieczeniach, takie jak SQL Injection czy XSS, zanim wykorzystają je przestępcy.