Rule Breaker 1
Catégorie : Hash Cracking
Points : 500
Points obtenus : 50
Auteur : Suvoni
CTF : L3akCTF2025
Résolu par : Obso11337
Ce challenge a été résolu en 182ème position sur 258 solves
📝 Description

🔍 Analyse initiale
Il y a trois hashes à cracker.
Les mots de passe correspondant aux hashes se trouvent dans le dictionnaire rockyou.txt
Le format du flag est : L3AK{pass1_pass2_pass3}
Les hashes fournis sont :
5e09f66ae5c6b2f4038eba26dc8e22d8aeb54f624d1d3ed96551e900dac7cf0d
fb58c041b0059e8424ff1f8d2771fca9ab0f5dcdd10c48e7a67a9467aa8ebfa8
4ac53d04443e6786752ac78e2dc86f60a629e4639edacc6a5937146f3eacc30f
⚙️ Outils utilisés
Le dictionnaire de mots de passe "rockyou.txt" (https://github.com/brannondorsey/naive-hashcat/releases/download/data/rockyou.txt)
hashcat (https://hashcat.net/hashcat/)
sha256sum (https://www.gnu.org/)
python3 (https://www.python.org/)
🧪 Étapes de résolution
Hash 1 (5e09f66ae5c6b2f4038eba26dc8e22d8aeb54f624d1d3ed96551e900dac7cf0d)
Il faut ajouter 3 caractères à la fin dans cet ordre : un caractère spécial, un nombre et une majuscule
Test 1 : Ajout d'une règle de transformation à hashcat
Script pour générer toutes les règles possibles en respectant les 3 conditions :
#!/bin/bash
symbols='!@#$%^&*'
digits='0123456789'
letters='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
> suffixes.txt
# Boucles avec protection contre l'expansion des caractères spéciaux
while IFS= read -r s; do
while IFS= read -r d; do
while IFS= read -r l; do
echo "\$${s}\$${d}\$${l}" >> suffixes.txt
done <<< "$(echo "$letters" | fold -w1)"
done <<< "$(echo "$digits" | fold -w1)"
done <<< "$(echo "$symbols" | fold -w1)"
Ce script génère toutes les combinaisons possibles formées de :
Un symbole spécial (parmi !@#$%^&*)
Un chiffre (de 0 à 9)
Une lettre majuscule (de A à Z)
Et il les écrit dans un fichier nommé suffixes.txt
FICHIER
On lance hashcat pour tenter de cracker le hash :
hashcat -O -w 3 -m 1400 -a 1 hash1.txt -o cracked1.txt /tmp/rockyou.txt suffixes.txt
hashcat
Lance le programme Hashcat
-O
Active l’optimisation des performances (ignore certaines règles trop complexes)
-w 3
Définit la charge de travail GPU : niveau 3 (élevé)
-m 1400
Spécifie le type de hash : 1400 = SHA-256
-a 1
Définit le mode d’attaque : 1 = attaque combinée (wordlist + wordlist)
hash1.txt
Fichier contenant les hashes à casser
-o cracked1.txt
Fichier de sortie où seront enregistrés les hashes cassés + mots de passe trouvés
/tmp/rockyou.txt
Première wordlist utilisée dans l’attaque
suffixes.txt
Deuxième wordlist pour générer des combinaisons avec la première
Voici l'output de hashcat
hashcat (v6.2.6) starting
OpenCL API (OpenCL 3.0 PoCL 3.1+debian Linux, None+Asserts, RELOC, SPIR, LLVM 15.0.6, SLEEF, DISTRO, POCL_DEBUG) - Platform #1 [The pocl project]
============================================================================================================
Device #1: pthread-haswell-13th Gen Intel(R) Core(TM) i9-13900KF, 30986/62037 MB (8192 MB allocatable), 32MCU,
Minimum password length supported by kernel: 0
Maximum password length supported by kernel: 31
Dictionary cache hit:
Filename..: /tmp/rockyou.txt,
Passwords.: 14344384,
Bytes.....: 139921497,
Keyspace..: 14344384,
Dictionary cache hit:
Filename..: suffixes.txt,
Passwords.: 2080,
Bytes.....: 8320,
Keyspace..: 2080,
Hashes: 1 digests; 1 unique digests, 1 unique salts
Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates
...
Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 1400 (SHA2-256)
Hash.Target......: 5e09f66ae5c6b2f4038eba26dc8e22d8aeb54f624d1d3ed9655...c7cf0d
Time.Started.....: Sat Jul 12 16:57:39 2025 (37 secs)
Time.Estimated...: Sat Jul 12 16:58:16 2025 (0 secs)
Kernel.Feature...: Optimized Kernel
Guess.Base.......: File (/tmp/rockyou.txt), Left Side
Guess.Mod........: File (suffixes.txt), Right Side
Speed.#1.........: 420.3 MH/s (54.17ms) @ Accel:1024 Loops:1024 Thr:1 Vec:8
Recovered........: 1/1 (100.00%) Digests (total), 1/1 (100.00%) Digests (new)
Progress.........: 15609910944/29836318720 (52.32%)
Rejected.........: 2905760/15609910944 (0.02%)
Restore.Point....: 7472490/14344384 (52.09%)
Restore.Sub.#1...: Salt:0 Amplifier:1024-2048 Iteration:0-1024
Candidate.Engine.: Device Generator
Candidates.#1....: iankerry$9K -> hunie28*8T
Hardware.Mon.#1..: Temp: 93c Util: 88%
Started: Sat Jul 12 16:57:38 2025
Stopped: Sat Jul 12 16:58:18 2025
Le hash a été cracké!
On vérifie :
$ cat cracked1.txt
5e09f66ae5c6b2f4038eba26dc8e22d8aeb54f624d1d3ed96551e900dac7cf0d:hyepsi^4B
echo -n "hyepsi^4B" | sha256sum
5e09f66ae5c6b2f4038eba26dc8e22d8aeb54f624d1d3ed96551e900dac7cf0d -
Premier hash vaildé!
Hash 2 (fb58c041b0059e8424ff1f8d2771fca9ab0f5dcdd10c48e7a67a9467aa8ebfa8)
Une faute de frappe a été faite lors de la saisie du mot de passe. Il faut considérer une faute de frappe comme la suppression d’un seul caractère du mot de passe.
On doit tester chaque mot de rockyou.txt en le raccourcissant d’un caractère, à chaque position possible. Plutôt que de générer un fichier géant, on va utiliser un script Python :
#!/usr/bin/env python3
with open("/tmp/rockyou.txt", "r", encoding="latin-1") as f:
words = f.read().splitlines()
with open("rockyou_typo.txt", "w", encoding="latin-1") as out:
for word in words:
if len(word) > 1:
for i in range(len(word)):
variant = word[:i] + word[i+1:]
out.write(variant + "\n")
On lance hashcat pour tenter de cracker le hash :
hashcat -O -w 3 -m 1400 -a 0 hash2.txt -o cracked2.txt ./rockyou_typo.txt
-O
Active l’optimisation des performances (peut ignorer certaines règles complexes)
-w 3
Définit une charge de travail GPU élevée (niveau 3 = rapide, mais intensif)
-m 1400
Spécifie le type de hash : SHA-256
-a 0
Mode d’attaque : attaque par dictionnaire simple
hash2.txt
Fichier contenant les hashes à casser
-o cracked2.txt
Fichier de sortie : écrit les hashes cassés avec les mots de passe trouvés
./rockyou_typo.txt
Wordlist personnalisée contenant des mots avec une faute de frappe (1 caractère supprimé)
Voici l'output de hashcat:
hashcat (v6.2.6) starting
OpenCL API (OpenCL 3.0 PoCL 3.1+debian Linux, None+Asserts, RELOC, SPIR, LLVM 15.0.6, SLEEF, DISTRO, POCL_DEBUG) - Platform #1 [The pocl project]
==================================================================================================================================================
Device #1: pthread-haswell-13th Gen Intel(R) Core(TM) i9-13900KF, 30986/62037 MB (8192 MB allocatable), 32MCU,
Minimum password length supported by kernel: 0
Maximum password length supported by kernel: 31
Hashes: 1 digests; 1 unique digests, 1 unique salts
Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates
Rules: 1
Optimizers applied:
Optimized-Kernel,
Zero-Byte,
Precompute-Init,
Early-Skip,
Not-Salted,
Not-Iterated,
Single-Hash,
Single-Salt,
Raw-Hash,
Watchdog: Temperature abort trigger set to 90c
Host memory required for this attack: 8 MB
Dictionary cache built:
Filename..: ./rockyou_typo.txt,
Passwords.: 125574919,
Bytes.....: 1221106149,
Keyspace..: 125573586,
Runtime...: 3 secs,
[17:10]
Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 1400 (SHA2-256)
Hash.Target......: fb58c041b0059e8424ff1f8d2771fca9ab0f5dcdd10c48e7a67...8ebfa8
Time.Started.....: Sat Jul 12 17:10:00 2025 (1 sec)
Time.Estimated...: Sat Jul 12 17:10:01 2025 (0 secs)
Kernel.Feature...: Optimized Kernel
Guess.Base.......: File (./rockyou_typo.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........: 18013.5 kH/s (0.80ms) @ Accel:1024 Loops:1 Thr:1 Vec:8
Recovered........: 1/1 (100.00%) Digests (total), 1/1 (100.00%) Digests (new)
Progress.........: 9307522/125573586 (7.41%)
Rejected.........: 1410/9307522 (0.02%)
Restore.Point....: 9274754/125573586 (7.39%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:0-1
Candidate.Engine.: Device Generator
Candidates.#1....: thurma34 -> thecdez
Hardware.Mon.#1..: Temp: 71c Util: 0%
Started: Sat Jul 12 17:09:57 2025
Stopped: Sat Jul 12 17:10:02 2025
On vérifie :
$ cat cracked2.txt
fb58c041b0059e8424ff1f8d2771fca9ab0f5dcdd10c48e7a67a9467aa8ebfa8:thecowsaysmo
echo -n "thecowsaysmo" | sha256sum
fb58c041b0059e8424ff1f8d2771fca9ab0f5dcdd10c48e7a67a9467aa8ebfa8 -
Second hash vaildé!
Hash 3 (4ac53d04443e6786752ac78e2dc86f60a629e4639edacc6a5937146f3eacc30f)
Il faut modifier encore une fois le dictionnaire en leetifiant les voyelles
Script pour préparer le dictionnaire :
#!/usr/bin/env python3
from itertools import product
# Mapping des substitutions possibles,
leet_map = {
'a': ['4'],
'e': ['3'],
'i': ['1'],
'o': ['0']
}
def leetify_strict(word):
options = []
for c in word:
if c in leet_map:
options.append(leet_map[c]) # Seulement les leet substitutions
else:
options.append([c]) # Consonnes et autres caractères inchangés
return product(*options)
input_file = '/tmp/rockyou.txt'
output_file = 'rockyou_strict_leet.txt'
with open(input_file, 'r', encoding='latin-1') as infile, open(output_file, 'w', encoding='utf-8') as outfile:
seen = set()
for line in infile:
word = line.strip()
for variant in leetify_strict(word):
leet_word = ''.join(variant)
if leet_word not in seen:
seen.add(leet_word)
outfile.write(leet_word + '\n')
print("Fichier strictement leetifié généré : rockyou_strict_leet.txt")
On lance hashcat pour tenter de cracker le hash :
hashcat -O -m 1400 -a 0 -o cracked3.txt hash3.txt rockyou_strict_leet.txt
-O
Active l’optimisation des performances (peut ignorer certaines règles complexes)
-w 3
Définit une charge de travail GPU élevée (niveau 3 = rapide, mais intensif)
-m 1400
Spécifie le type de hash : SHA-256
-a 0
Mode d’attaque : attaque par dictionnaire simple
hash3.txt
Fichier contenant les hashes à casser
-o cracked3.txt
Fichier de sortie : écrit les hashes cassés avec les mots de passe trouvés
./rockyou_strict_leet.txt
Wordlist personnalisée contenant des mots avec une faute de frappe (1 caractère supprimé)
Non documenté : Hashcat n'a pas su cracker le hash.
On reprend le script remplaçant cette fois le 'a': ['4'] par 'a': ['@'] dans le mapping des substitutions
On lance à nouveau hashcat pour tenter de cracker le hash :
hashcat -O -m 1400 -a 0 -o cracked3.txt hash3.txt rockyou_strict_leet.txt
Voici l'output de hashcat:
OpenCL API (OpenCL 3.0 PoCL 3.1+debian Linux, None+Asserts, RELOC, SPIR, LLVM 15.0.6, SLEEF, DISTRO, POCL_DEBUG) - Platform #1 [The pocl project]
==========================================================================================================================
Device #1: pthread-haswell-13th Gen Intel(R) Core(TM) i9-13900KF, 30986/62037 MB (8192 MB allocatable), 32MCU,
Minimum password length supported by kernel: 0
Maximum password length supported by kernel: 31
Hashes: 1 digests; 1 unique digests, 1 unique salts
Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates
Rules: 1
Optimizers applied:
Optimized-Kernel,
Zero-Byte,
Precompute-Init,
Early-Skip,
Not-Salted,
Not-Iterated,
Single-Hash,
Single-Salt,
Raw-Hash,
Watchdog: Temperature abort trigger set to 90c
Host memory required for this attack: 87 MB
Dictionary cache built:
Filename..: rockyou_strict_leet.txt,
Passwords.: 14212481,
Bytes.....: 138965419,
Keyspace..: 14212463,
Runtime...: 0 secs,
NEW
[18:26]
Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 1400 (SHA2-256)
Hash.Target......: 4ac53d04443e6786752ac78e2dc86f60a629e4639edacc6a593...acc30f
Time.Started.....: Sat Jul 12 18:20:32 2025, (0 secs)
Time.Estimated...: Sat Jul 12 18:20:32 2025, (0 secs)
Kernel.Feature...: Optimized Kernel
Guess.Base.......: File (rockyou_strict_leet.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........: 13256.8 kH/s (6.81ms) @ Accel:1024 Loops:1 Thr:10 Vec:8
Recovered........: 1/1 (100.00%) Digests (total), 1/1 (100.00%) Digests (new)
Progress.........: 1310836/14212463 (9.22%)
Rejected.........: 116/1310836 (0.01%)
Restore.Point....: 983088/14212463 (6.92%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:0-1
Candidate.Engine.: Device Generator
Candidates.#1....: c@rl0v0n -> ryb@b3
Hardware.Mon.#1..: Temp: 72c Util: 15%
Started: Sat Jul 12 18:20:31 2025
Stopped: Sat Jul 12 18:20:34 2025
Cette fois le hash est cracké! Le petit malin qui a imaginé ce challenge a été vicieux et a utilisé @ au lieu de 4 et les autres voyelles étaient leetifiées avec des nombres...
On vérifie :
$ cat cracked3.txt
4ac53d04443e6786752ac78e2dc86f60a629e4639edacc6a5937146f3eacc30f:unf0rg1v@bl3
echo -n "unf0rg1v@bl3" | sha256sum
4ac53d04443e6786752ac78e2dc86f60a629e4639edacc6a5937146f3eacc30f -
Troisième hash vaildé!
🏁 Flag
A ce stade nous avons :
Hash1 = hyepsi^4B
Hash2 = thecowsaysmo
Hash3 = unf0rg1v@bl3
Il nous reste à reconstituer le mot de passe :
Flag format: L3AK{pass1_pass2_pass3}
Flag = L3AK{hyepsi^4B_thecowsaysmo_unf0rg1v@bl3}
IMAGE