Passer au contenu principal

Rule Breaker 1

🛡️ Writeup – 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

    Descriptif.png?raw=true


    🔍 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
                        Option / Argument Description 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
                                Élément Description -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
                                      Élément Description -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