Description
Our security team wrote a vault to protect our password. Can you defeat it? The Java source code is provided.
Setup
Download VaultDoorTraining.java from the challenge page.
Solution
Walk me through it- Step 1Read the checkPassword methodOpen VaultDoorTraining.java and locate the checkPassword() method. The password is hardcoded as a plain string literal - no encryption, no obfuscation. Reading that string directly gives you the flag contents.
Learn more
Hardcoded credentials - passwords, API keys, tokens, or secrets embedded directly in source code - are one of the most pervasive and dangerous security vulnerabilities in software. When source code is shared, leaked, decompiled from a binary, or checked into version control, every hardcoded secret in it is immediately exposed to anyone who reads it.
This is so common that major secret scanning tools exist specifically to detect it:
- GitHub Secret Scanning - automatically scans public repos for API keys and tokens
- truffleHog - scans git history for high-entropy strings and known secret patterns
- gitleaks - fast secret scanner for git repos and CI pipelines
- detect-secrets - Yelp's tool for preventing secrets from entering codebases
The correct pattern is to store secrets in environment variables or a secrets manager (like AWS Secrets Manager, HashiCorp Vault, or Doppler) and read them at runtime. The source code then contains no secrets, so reading it reveals nothing. This is CWE-798 (Use of Hard-coded Credentials) in the Common Weakness Enumeration and is included in every major security standard including OWASP and NIST.
In the context of this challenge series, the Vault Door challenges progressively introduce more sophisticated obfuscation techniques - but all of them share the same fundamental flaw: the password validation logic is visible in source code. No amount of obfuscation in application logic can substitute for proper cryptographic authentication design.
Decompiling Java makes this vulnerability especially acute. Java programs compile to bytecode (
.classfiles) that can be decompiled back to near-original source code using tools like CFR, Procyon, or Fernflower (built into IntelliJ IDEA). Unlike C/C++ compilation which loses variable names and high-level structure, Java decompilation often produces code indistinguishable from the original. This means even distributing a compiled Java JAR provides essentially no protection for hardcoded secrets - any attacker can decompile it in seconds.Obfuscation tools like ProGuard and DexGuard are commonly used for Android APKs to rename classes, methods, and fields to meaningless single-letter names (e.g., class
VaultDoorbecomes classa). This makes decompiled code harder to read but does not change its functionality. String encryption obfuscators go further by replacing string literals with calls to a decryption function - but the decryption key must be present in the binary, and the string values will still appear at runtime. Debuggers and decompilers that perform dynamic analysis or emulation recover the plaintext strings anyway.The correct authentication pattern: instead of comparing the user's input against a stored plaintext password, a secure system stores a salted cryptographic hash of the password (using bcrypt, Argon2, or scrypt). The input is hashed with the same salt and the hash values are compared - the original password is never stored. Even with full access to source code and the stored hash, an attacker cannot directly reverse the hash to get the password. This is the fundamental design principle behind password storage in every serious authentication system.
Flag
picoCTF{...}
Hardcoded credentials in source code are one of the most common and easily exploited vulnerabilities - always check for string literals in authentication logic.