Description
We intercepted a suspicious file from a system, but instead of the password itself, it only contains its SHA-1 hash. Using OSINT techniques, you are provided with personal details about the target. Generate a custom password list and recover the original password by matching its hash. Download: userinfo.txt , hash.txt , and check_password.py .
Download userinfo.txt, hash.txt, and check_password.py.
Read userinfo.txt to understand the target's personal details.
cat userinfo.txtcat hash.txtcat check_password.pySolution
Walk me through it- Step 1Profile the targetRead userinfo.txt carefully. It contains personal details like name, birthdate, favourite things, pet names, or other information people commonly use in passwords.bash
cat userinfo.txtLearn more
Password profiling is an OSINT (Open Source Intelligence) technique used in penetration testing and red team engagements. Instead of brute-forcing all possible passwords, you generate a targeted wordlist based on information specific to the target: their name, birthday, spouse's name, pet's name, favourite sports team, employer, and common patterns like appending birth years or "123" suffixes.
Research shows that people overwhelmingly choose passwords based on memorable personal information. A 2019 study found that over 50% of users choose passwords containing their name or birthdate. Attackers who know a target's personal details can often crack their password with a few hundred candidates, whereas a brute-force attack against the same password might take millions of years.
In real engagements, profiling information comes from LinkedIn profiles, social media, company websites, and data breaches. This challenge simulates receiving that information in a file - in practice, gathering it requires careful OSINT research using tools like Maltego, SpiderFoot, or manual social media enumeration.
- Step 2Generate a custom wordlist and crack the SHA-1Parse the personal details out of userinfo.txt programmatically, mash them together with common suffixes/leet variants, and check each candidate against the target hash from hash.txt. No external tools required.python
python3 << 'EOF' import hashlib, itertools, re # Load the target hash directly from disk - don't paste it in. target_hash = open("hash.txt").read().strip().lower() # Parse userinfo.txt as "Field: value" lines, normalising keys. info = {} for line in open("userinfo.txt"): if ":" in line: k, v = line.split(":", 1) info[k.strip().lower()] = v.strip() # Pull out anything that looks useful. Don't hardcode names. name = info.get("name", "").split()[0] if info.get("name") else "" lastname = info.get("name", "").split()[-1] if info.get("name") else "" birth = re.search(r"\d{4}", info.get("dob", info.get("birthday", ""))) birth = birth.group(0) if birth else "" pet = info.get("pet", info.get("pet name", "")) bases = {name, lastname, birth, pet, name + lastname, name + birth, lastname + birth, pet + birth} bases = {b for b in bases if b} suffixes = ["", "!", "1", "123", "@1", "2024", "2025", "."] leet = str.maketrans("aeios", "@3105") for base in bases: variants = {base, base.lower(), base.upper(), base.capitalize(), base.lower().translate(leet)} for v in variants: for s in suffixes: cand = v + s if hashlib.sha1(cand.encode()).hexdigest() == target_hash: print("Found:", cand) raise SystemExit print("No match - widen the suffix list or add more bases.") EOFLearn more
SHA-1 is a cryptographic hash function that produces a 160-bit (40 hex character) digest. It is no longer considered secure for digital signatures (broken in 2017 by Google's SHAttered attack), but understanding it is important because it's still found in older systems and CTF challenges. SHA-1's main weakness for password storage is that it's fast: a GPU can compute billions of SHA-1 hashes per second, making dictionary attacks trivial.
The correct tool for password hashing is a purpose-built slow hash function like bcrypt, scrypt, Argon2, or PBKDF2 with a high iteration count. These deliberately take milliseconds to compute, making dictionary attacks tens of thousands of times slower. They also include a salt (a random value mixed into the hash) to prevent pre-computed rainbow table attacks. For a deeper tour of the cracking workflow see Hash cracking for CTF; for the Python idioms used in the loop above see Python for CTF.
- Step 3Run check_password.py with the found passwordOnce you have the correct password, run check_password.py to confirm and retrieve the flag.python
python3 check_password.py FOUND_PASSWORDLearn more
Hash cracking fundamentally works by preimage attack: given a hash H, find any input m such that hash(m) = H. For targeted attacks like this, you compute hash(candidate) for each candidate in your wordlist and compare against the target hash. This is conceptually simple but the quality of the wordlist determines success.
From a defensive standpoint, this challenge illustrates why password complexity rules alone are insufficient. "Fluffy123!" satisfies most complexity requirements (upper, lower, number, special character, 9+ characters) but is trivially cracked by any attacker who knows your pet's name. Password managers generating random strings are the correct solution because they make password profiling attacks impossible.
Flag
picoCTF{p4ssw0rd_pr0f1l3r_...}
Generate a targeted wordlist from the victim's personal details and crack their SHA-1 hashed password.