Description
The password is encoded as chr() calls in the source. Decode it to run the script.
Setup
Download level2.py and level2.flag.txt.enc from the challenge page.
Solution
- Step 1Find the encoded password in the sourceOpen level2.py and locate the password comparison. Instead of a plaintext string, the password is built from chr() calls: chr(0x34) + chr(0x65) + chr(0x63) + chr(0x39).
Learn more
Code obfuscation is the practice of making source code harder to read and understand without changing what it does. Using
chr()calls instead of literal characters is a very basic form of obfuscation -- the password is technically "hidden" from a casual glance, but anyone who knows Python can reconstruct it instantly by evaluating the expression.This technique is sometimes used by malware authors or by developers who mistakenly believe it provides security. It does not. Obfuscation only raises the bar slightly; it does not prevent a determined analyst from recovering the secret. The terms security through obscurity describe the (incorrect) belief that hiding implementation details is a substitute for real cryptographic security.
Reading hex values in source code is a skill worth developing. Common ASCII hex values you will encounter frequently:
0x41–0x5A-- uppercase A through Z0x61–0x7A-- lowercase a through z0x30–0x39-- digits 0 through 90x7B/0x7D-- curly braces{}(appear in every picoCTF flag!)
- Step 2Decode the chr() expressionEvaluate the expression in Python to recover the plaintext password.python3 -c "print(chr(0x34)+chr(0x65)+chr(0x63)+chr(0x39))"# Output: 4ec9
Learn more
Python's
chr()function converts an integer to a Unicode character. Its inverse,ord(), converts a character back to its integer code point. Together they form the bridge between numeric representations (used in memory and encodings) and human-readable text.Using
python3 -cto evaluate arbitrary expressions is a quick and powerful technique for decoding obfuscated values during CTF challenges. You can paste the exact expression from the source code and wrap it inprint()to immediately see the decoded result -- no file creation or script editing required.More advanced obfuscation techniques include base64 encoding, XOR encoding, and multi-layer encoding chains. Each layer adds complexity but can still be peeled back with the right tools or by running the decoding logic itself.
- Step 3Run the script with the decoded passwordExecute level2.py and enter 4ec9 when prompted. The flag is printed.python3 level2.py# Enter password: 4ec9
Learn more
This challenge illustrates an important point about static analysis -- examining code without running it. By reading the source and mentally (or programmatically) evaluating the
chr()expression, you recovered the password without ever interacting with the script's password prompt. Static analysis is often faster and safer than running unknown code.In real security assessments, static analysis is used to audit code for vulnerabilities, recover hardcoded secrets, and understand malware behavior without executing potentially dangerous code. Tools like
strings,Ghidra, andIDA Proextend this capability to compiled binaries where the source code is not available.
Flag
picoCTF{...}
chr() obfuscation is a trivial encoding -- evaluating the expression in Python immediately reveals the literal string, providing no real protection.