PicoCTF Vault Door 1 Writeup — Reverse a Character-by-Character Password Check

Rev Eng 2026-10-19 · picoGym · By CTFdojo · ⏱ ... · 👁 ... views
𝕏 Share
TL;DR

Unlike the Training version, here checkPassword doesn't compare one whole string at once: it checks individual characters at specific indices (or compares rearranged substrings). You have to read the logic carefully and reconstruct the password piece by piece.

PlatformpicoGym
CategoryRev Eng
Points200 pts
DifficultyIntermediate
Tools javac java grep

Challenge description

Second door in the series: a new file, VaultDoor1.java, is provided, noticeably longer than the previous challenge's. The checkPassword method no longer does a single direct comparison on the whole string — it chains several conditions, each only covering a small part of the password.

This is a logical escalation from Vault-Door-Training: the secret is still hardcoded, but split into fragments that need to be found and reassembled in the right order.

Step 1 — Read the structure

We go through checkPassword and spot a series of if conditions that must ALL be true for the function to return true — each covering a different slice of the input string, via substring() or charAt():

public boolean checkPassword(String password) {
    return password.length() == 32
        && password.substring(0, 5).equals("vault")
        && password.substring(5, 6).equals("_")
        && password.substring(6, 11).equals("d00r_")
        && password.charAt(11) == 't'
        && password.charAt(12) == 'r'
        && password.substring(13, 19).equals("a1n1ng")
        && password.substring(19, 20).equals("_")
        && password.substring(20, 26).equals("clear")
        && password.substring(26).equals("_check");
}

Each condition is independent of the others — no way to simply read a single string literal like in the Training challenge. We have to collect each fragment one by one.

Step 2 — Reconstruct

We note down every constraint found in the code, in the order of the indices it covers, so nothing gets left out:

A good habit here: build this table as you read, rather than keeping it all in your head, especially as the number of conditions grows in later levels of the series.

Step 3 — Assemble

We concatenate every fragment found, strictly in the order of their starting indices:

// vault + _ + d00r_ + t + r + a1n1ng + _ + clear + _check
vault_d00r_tra1n1ng_clear_check

The assembled result forms a consistent 32-character string — which incidentally confirms the password.length() == 32 constraint seen at the top of the function. A good way to check no fragment was missed.

Step 4 — Verify

We compile and run the program with the reconstructed password:

$ javac VaultDoor1.java
$ java VaultDoor1
Enter vault password: vault_d00r_tra1n1ng_clear_check
Access granted.
picoCTF{...}
🚩 picoCTF{flag intentionally hidden}

The flag is deliberately hidden — follow the method, you've earned it. 💪

Key takeaways

Resources

Related reading

Rev Eng 2026-10-26 · picoGym

PicoCTF Keygenme-py Writeup — Reverse a Python License Key Generator

Analyzing a Python key-generation script to produce a valid license.

CTFdojo
CTFdojo
Community of ethical hackers writing beginner-friendly CTF writeups and guides.

Got a question or a different approach?

Discuss this writeup with the community on the CTFdojo Discord.

Join the Discord →