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


🧪 É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 :

            1. Un symbole spécial (parmi !@#$%^&*)

            2. Un chiffre (de 0 à 9)

            3. 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
            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 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
                -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...

            • n 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}

                        Solved.png?raw=true