PW Crack 4

Published: April 2, 2026

Description

This time there are 100 candidate passwords. One of them hashes to the stored MD5 hash. Add a loop to test all 100.

Download level4.py -- it contains a list of 100 candidate passwords and a stored MD5 hash.

Solution

  1. Step 1Read the script structure
    Open level4.py. There's a list of 100 candidate passwords and a target hash. The script checks one password at a time -- modify it to loop through all of them.
    Learn more

    Scaling from 7 to 100 candidates makes manual testing impractical -- at 100 entries, you might still manage it manually, but the pattern clearly demands automation. This is a deliberate pedagogical progression: each pw-crack level increases the candidate pool until manual approaches are clearly infeasible, pushing you toward writing code.

    Understanding the script's structure before modifying it is essential. Locate:

    • Where the candidate list is defined
    • Where the stored hash is defined
    • Where the password is compared to the hash
    • Where the decryption function is called with the correct password

    This structural reading skill -- understanding how code flows before changing it -- is called code comprehension and is fundamental to both software development and security analysis. Never modify code you do not understand.

  2. Step 2Add a brute-force loop
    Write a loop that hashes each candidate with MD5 and compares to the stored hash. When a match is found, pass it to the decryption function to get the flag. The correct password is '607a'.
    python3 -c "import hashlib; candidates=['ee42','3a5f']; h='stored_hash'; [print(p) for p in candidates if hashlib.md5(p.encode()).hexdigest()==h]"
    Learn more

    This step introduces the concept of automating repetitive computation. The loop does exactly what you would do manually -- hash a candidate, compare it, move on -- but at computer speed. A Python loop can test 100 MD5 hashes in milliseconds.

    The list comprehension form [print(p) for p in candidates if hashlib.md5(p.encode()).hexdigest() == h] is a compact Python idiom that combines filtering and action in one line. It is functionally equivalent to a for loop with an if check inside -- choose whichever form you find more readable.

    In real-world password auditing, this same loop logic is the core of tools like John the Ripper and hashcat. The difference is that those tools add GPU acceleration, rule-based mutations (appending numbers, capitalizing letters), and support for hundreds of hash algorithms. The fundamental algorithm -- hash candidate, compare to target -- is unchanged.

  3. Step 3Run the modified script
    With the correct password found, the XOR decryption function unlocks and prints the flag.
    python3 level4.py
    Learn more

    The XOR decryption used in these pw-crack challenges is a simple symmetric cipher: the flag bytes are XORed with a key derived from the password. XOR has the property that applying it twice with the same key returns the original value -- (A XOR K) XOR K = A -- making encryption and decryption the same operation.

    While XOR is not secure on its own for real encryption (it is trivially breakable with known-plaintext attacks), it appears frequently in CTF challenges and in obfuscated malware as a lightweight way to obscure data. Recognizing XOR-based encoding and knowing how to reverse it is a valuable skill for reverse engineering challenges.

    The progression from pw-crack-1 through pw-crack-5 mirrors the real evolution of password security practices: plaintext storage, light obfuscation, small hash lookups, larger hash lookups, and finally full dictionary attacks. Each level requires a slightly more sophisticated approach.

Flag

picoCTF{...}

Testing 100 MD5 hashes takes milliseconds -- the same loop logic scales to millions of entries for real dictionary attacks.

More General Skills