Description
This vault uses Base64 and URL encoding for the password. Decode the layers to find the flag.
Setup
Download the Java source file and inspect it.
wget <url>/VaultDoor5.javaSolution
Want to try it yourself first?
The guided walkthrough reveals hints one step at a time.
Step 1
Read the Java source and identify the encoding chainObservationI noticed the challenge description mentioned both Base64 and URL encoding, which suggested the Java source's checkPassword method would apply these two layers in a specific order that I needed to trace before attempting any reversal.Open VaultDoor5.java. The checkPassword method applies URL encoding and Base64 encoding to the input, then compares it to a stored string. To reverse this: the stored string is Base64-decoded first, then URL-decoded, to recover the password.bashcat VaultDoor5.javaWhat didn't work first
Tried: Trying to crack the stored string as if it were a hash using a tool like hashcat or john.
Hashcat and john expect a hashed value and require a dictionary or brute-force attack. The stored string here is not a hash - it is a layered encoding. Encodings are deterministic and reversible without any key, so running a cracker produces no result and wastes time. The correct approach is to recognize Base64 padding (trailing '=' characters and a 64-character alphabet) and apply a simple decode.
Tried: Looking only at the import statements for clues and missing the actual encoding order inside checkPassword.
Imports tell you which libraries are available, but the checkPassword method body determines the order in which URL encoding and Base64 encoding are applied to the input. Reversing in the wrong order (URL-decode first, then Base64-decode) produces garbled output. Always trace the data flow through the method logic to establish the exact sequence before reversing.
Learn more
Base64 encodes binary data as printable ASCII characters (A-Z, a-z, 0-9, +, /). It inflates the data by 33% and is reversible without a key.
URL encoding (percent encoding) replaces special characters with a percent sign followed by their hex code (e.g., space becomes %20). This ensures text can be safely embedded in URLs.
These are encodings, not encryption - they provide zero confidentiality. Anyone who recognizes the encoding chain can reverse it instantly.
Step 2
Reverse the encoding chainObservationI noticed the stored string in VaultDoor5.java had Base64 padding characters and that checkPassword applied URL encoding before Base64 encoding, which suggested I needed to reverse those layers in opposite order using Python's base64.b64decode followed by urllib.parse.unquote.Extract the stored encoded string from the Java source. First Base64-decode the stored string, then URL-decode the result to recover the password.bash# Base64-decode then URL-decode the stored string:pythonpython3 -c "import urllib.parse, base64; s = '<paste stored string>'; print(urllib.parse.unquote(base64.b64decode(s).decode()))"What didn't work first
Tried: Applying URL-decode first and Base64-decode second (reversing the reversal order).
urllib.parse.unquote on a raw Base64 string mostly passes it through unchanged because Base64 characters are URL-safe, but then base64.b64decode fails or returns gibberish because the input was never a URL-encoded Base64 string. The stored string was produced by URL-encoding first and then Base64-encoding, so to reverse it you must Base64-decode first and URL-decode second - exactly the opposite of the encoding order.
Tried: Using the command-line tool base64 -d on the stored string and piping to python -c urllib.parse.unquote separately, then wrapping the result in picoCTF{} by hand.
base64 -d can decode the first layer correctly, but the decoded output may contain percent-encoded sequences that a naive print or echo will not interpret as URL escape codes. If the percent signs are not properly unquoted, the resulting password looks like raw percent-escaped text rather than clean ASCII, and the vault door will reject it. Using Python's urllib.parse.unquote in one pipeline ensures both layers are decoded cleanly before the flag is assembled.
Learn more
Python's
urllib.parse.unquote()performs URL decoding.base64.b64decode()performs Base64 decoding. Chain them in the reverse order of the encoding (Base64-decode first, then URL-decode) to recover the plaintext.
Interactive tools
- Strings ExtractorPull printable text from any binary, library, or image. ASCII and UTF-16 detection, configurable minimum length, flag-like highlight, no command line needed.
- Hex ViewerView text or raw hex bytes as a xxd-style hex dump with byte offset, hex columns, and ASCII sidebar. Highlights printable characters and null bytes.
- Base64 & Base32 DecoderDecode Base64 and Base32 strings with auto-detection. Multi-layer mode unwraps nested encodings automatically.
Alternate Solution
Use the Base64 Decoder on this site to reverse the Base64 layer after manually URL-decoding the stored string.
Flag
Reveal flag
picoCTF{c0nv3rt1ng_fr0m_ba5e_64_...}
The password went through URL encoding then Base64 encoding before storage - reverse by Base64-decoding then URL-decoding.