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 -
-
-
-
-
-
-
-
-
-
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
Option / Argument Description hashcatLance le programme Hashcat -OActive l’optimisation des performances (ignore certaines règles trop complexes) -w 3Définit la charge de travail GPU : niveau 3 (élevé) -m 1400Spécifie le type de hash : 1400 = SHA-256-a 1Définit le mode d’attaque : 1 = attaque combinée (wordlist + wordlist)hash1.txtFichier contenant les hashes à casser -o cracked1.txtFichier de sortie où seront enregistrés les hashes cassés + mots de passe trouvés /tmp/rockyou.txtPremière wordlist utilisée dans l’attaque suffixes.txtDeuxiè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 2025Le 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
Élément Description -OActive l’optimisation des performances (peut ignorer certaines règles complexes) -w 3Définit une charge de travail GPU élevée (niveau 3 = rapide, mais intensif) -m 1400Spécifie le type de hash : SHA-256 -a 0Mode d’attaque : attaque par dictionnaire simple hash2.txtFichier contenant les hashes à casser -o cracked2.txtFichier de sortie : écrit les hashes cassés avec les mots de passe trouvés ./rockyou_typo.txtWordlist 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 validé!
-
-
-
-
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
Élément Description -OActive l’optimisation des performances (peut ignorer certaines règles complexes) -w 3Définit une charge de travail GPU élevée (niveau 3 = rapide, mais intensif) -m 1400Spécifie le type de hash : SHA-256 -a 0Mode d’attaque : attaque par dictionnaire simple hash3.txtFichier contenant les hashes à casser -o cracked3.txtFichier de sortie : écrit les hashes cassés avec les mots de passe trouvés ./rockyou_strict_leet.txtWordlist 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 2025Cette 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@bl3echo -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}

-
-
-
-
-
-