Description
A Python script decrypts flag.txt.enc after checking a password. The password is plainly stored inside the code-use it to reveal the flag.
Open patchme.flag.py and note the password hard-coded inside the function (e.g., `ak98-=90adfjhgj321sleuth9000`).
Run `python3 patchme.flag.py`, enter the password, and the script prints the flag.
python3 patchme.flag.pySolution
- Step 1Read the function`f` stores the password in clear text. Nothing needs to be patched; just use that string when prompted.
Learn more
Hardcoded secrets are credentials, passwords, or keys embedded directly in source code. This is a critically common vulnerability - developers sometimes store secrets in code for convenience during development, then accidentally ship those files.
The challenge title "PatchMe" implies you would need to modify the script to bypass the check, but reading the source reveals there's nothing to patch at all. The password is stored in plain sight inside a Python function. Tools like
grep,strings, or even a simple text editor are all you need.In real security assessments, hunting for hardcoded credentials in source code is a standard step. Tools like truffleHog, gitleaks, and semgrep automate this across entire repositories and git history. Secrets committed to git remain retrievable even after deletion via
git log.The reason hardcoded secrets persist is partly cultural: during development it's faster to put a password directly in the code than set up a proper secrets management system. Once hardcoded, the secret often gets checked into version control and then propagates - into build artifacts, container images, deployed binaries, and third-party audit logs. By the time someone realizes it's there, rotating the secret requires tracking down every location it was copied to.
Pre-commit hooks are the most effective automated prevention. Tools like detect-secretsscan each diff before it is committed and block any commit containing high-entropy strings or known secret patterns (AWS access key prefixes, private key headers, connection strings). Integrating this check into CI/CD pipelines as well ensures that secrets don't slip through even if the pre-commit hook is bypassed locally.
- Step 2Get the flagRun the script alongside flag.txt.enc, enter the password, and copy the picoCTF output.
Learn more
The script uses the password to decrypt
flag.txt.enc- a file that has been encrypted, likely with a symmetric cipher like AES. This is a legitimate decryption workflow; the flaw is that both the key and the ciphertext are distributed together.This pattern mirrors real-world mistakes where developers encrypt sensitive files but bundle the decryption key alongside them - in the same repository, Docker image, or binary. Encryption only provides security when the key is kept separate from the ciphertext.
The lesson: encryption protects data in transit or at rest, but only if key management is done correctly. Symmetric keys should live in environment variables, secret managers (AWS Secrets Manager, HashiCorp Vault), or hardware security modules - never in code.
An alternative approach to this challenge - consistent with its "PatchMe" title - is to modify the Python script directly. You could replace the password comparison with a no-op (
if True:), patch the condition to always return True, or simply call the decryption function directly with any argument. This patching technique is used in real-world software cracking and license bypass scenarios, and understanding it is a core reverse engineering skill even though it wasn't necessary here.For compiled binaries (rather than Python scripts), binary patching means modifying the actual bytes of the executable. A common technique is to locate the conditional jump instruction (
JZfor "jump if zero",JNZfor "jump if not zero") that guards the password check and flip it to its complement - or replace it with aNOP(no operation, opcode0x90) to make the check unconditional. Tools like radare2 and Binary Ninja support interactive binary patching with visual feedback.
Flag
picoCTF{p47ch1ng_l1f3_h4ck_f01e...}
This is a reminder to never ship secrets in client-side code-anyone can read them.