Description
The provided Python script (bloat.flag.py) hides logic behind an array of printable characters before requesting a password to decrypt flag.txt.enc. Deobfuscate the script to recover the password, then run it to reveal the flag.
Setup
Download both bloat.flag.py and flag.txt.enc into the same working directory.
Read through the script to understand how the lookup table a[...] maps back to readable characters.
After uncovering the hard-coded password (happychance), run the script to decrypt the encrypted flag file.
wget https://artifacts.picoctf.net/c/103/bloat.flag.pywget https://artifacts.picoctf.net/c/103/flag.txt.encpython3 bloat.flag.pypython3 bloat.flag.py | tee output.txtsed -n '2p' output.txtSolution
Walk me through it- Step 1Understand the lookup tableEvery string literal is built from indices into one character array
a. Defineain a REPL and let Python evaluate the indexing for you.pythonpython3 -c " # Paste the obfuscated array exactly as it appears in bloat.flag.py a = ['h','a','p','y','c','n','e','...'] # Then walk one of the obfuscated index expressions, e.g.: print(''.join([a[i] for i in [0, 1, 2, 2, 3, 4, 5, 1, 6, 4, 7]])) "Learn more
The trick is "character-array string building": instead of
"happychance"the code writesa[i0] + a[i1] + a[i2] + .... At runtime the interpreter joins the same string; statically it's just integers. Definingain a REPL and running''.join([a[i] for i in [...]])on each obfuscated expression instantly reveals the plaintext.Don't run untrusted scripts on your host. Run inside a VM, container, or with
python3 -c "..."capturing only the print output. Real malware uses the same character-array, base64, and eval-chain patterns you see here. - Step 2Recover the passwordWalking the index expression for the credential variable spells
happychance. That string is whatflag.txt.encwas encrypted with.Learn more
Specifically, the script's password variable is assigned something like
password = a[i0] + a[i1] + .... Walking the index list against youraarray producesh-a-p-p-y-c-h-a-n-c-e. Because the array and the index sequence are both right there in the source, the obfuscation is purely cosmetic.Hardcoded credentials in source - even obfuscated ones - are a classic antipattern. Real systems store secrets outside source (environment variables, AWS Secrets Manager, HashiCorp Vault) or prompt the user at runtime and derive a key via PBKDF2/Argon2.
- Step 3Decrypt the flagRun the script with the recovered password, then verify the output starts with
picoCTF{before submitting.pythonpython3 bloat.flag.py | tee output.txtbash# enter: happychancebashsed -n '2p' output.txtbashgrep -oE 'picoCTF\{[^}]+\}' output.txtLearn more
Decryption is success when the output is well-formed: starts with
picoCTF{, ends with}, only printable ASCII inside. If the second line is binary garbage, the password is wrong or the script's decryption logic differs from what you reconstructed. Thegrep -oEregex is a robust alternative tosed -n '2p'when the output ordering shifts.teewrites stdin to both stdout and a file - useful when you want to see output live while also keeping a log. Combined with line-selection tools (sed,awk,grep), it beats copy-paste for any script that produces more than a couple of lines.
Flag
picoCTF{d30bfu5c4710n_f7w_b80...}
Never run opaque scripts blindly-printing the decoded payload first keeps you safe and shows the password immediately.