WebDecode picoCTF 2024 Solution

Published: April 3, 2024

Description

Do you know how to use the web inspector? Start searching here to find the flag

Browser only

Open the challenge URL in your browser and enable DevTools (Ctrl+Shift+I).

Navigate to the About section where the hint lives.

Solution

Want to try it yourself first?

The guided walkthrough reveals hints one step at a time.

Walk me through it
  1. Step 1
    Inspect the element
    Observation
    I noticed the challenge prompt specifically said to use the web inspector, which suggested that the flag was not visible on the rendered page but was instead hidden somewhere in the raw DOM, such as inside a non-standard HTML attribute.
    The challenge prompt says use the web inspector. Open DevTools (F12), focus the Elements panel, and scan the source for unusual attributes. The About section carries a non-standard attribute named notify_true holding a Base64 blob.
    Learn more

    Custom HTML attributes (anything not in the HTML spec) appear in the page source and DevTools but are invisible to casual readers. Developers occasionally hide data this way as a quick way to embed values without displaying them. Scanning DevTools for unusual attribute names is a standard reconnaissance step on any web challenge.

    HTML data attributes (the official way to embed custom data) use the prefix data-, e.g., data-user-id="42". Non-prefixed custom attributes like notify_true still work in browsers but are technically invalid HTML5. Either way, any value stored there is fully accessible to anyone who views the page source: not a secure storage location.

    • Right-click any element and choose Inspect to jump directly to that element in the DevTools Elements panel.
    • Use Ctrl+F inside the Elements panel to search for notify or base64 patterns across the full DOM.
    • document.querySelector('[notify_true]').getAttribute('notify_true') in the Console tab also extracts the value programmatically.
  2. Step 2
    Decode the blob
    Observation
    I noticed the notify_true attribute held the string cGljb0NURnt3ZWJfc3VjYzNzc2Z1bGx5X2QzYzBkZWRfMDJjZGNiNTl9, whose alphanumeric-plus-equals character set and length being a multiple of 4 are the hallmarks of Base64 encoding, which suggested piping it through base64 -d to recover the flag.
    Pipe the attribute value into base64 -d. Quick sanity check first: the prefix cGljb0NUR decodes to picoCT, so any picoCTF flag base64-encodes to a string starting with that prefix.
    bash
    echo cGljb0NUR | base64 -d
    bash
    echo cGljb0NURnt3ZWJfc3VjYzNzc2Z1bGx5X2QzYzBkZWRfMDJjZGNiNTl9 | base64 -d

    Expected output

    picoCTF{web_succ3ssfully_d3c0ded_...}
    If base64 -d errors with "invalid input", the blob probably has stray newlines or whitespace from the copy. Strip them first:
    echo "<blob>" | tr -d '\n ' | base64 -d
    What didn't work first

    Tried: Trying to decode the blob using base64 -D (uppercase D) on Linux

    On Linux, base64 uses -d for decode; the uppercase -D flag is a macOS-ism and on Linux it is either unrecognized or silently ignored, producing no output. Use base64 -d (lowercase) on Linux and base64 -D on macOS.

    Tried: Pasting the blob into a hex-to-ASCII converter instead of a Base64 decoder

    The notify_true value contains characters like G, j, b, and 0 that are not valid hex digits, so a hex decoder will throw an 'invalid character' error immediately. The character set (A-Z, a-z, 0-9, +, /, =) and the length being a multiple of 4 both identify this as Base64, not hex.

    Learn more

    Base64 is an encoding scheme that represents binary data using only 64 ASCII-safe characters (A-Z, a-z, 0-9, +, /). It was originally designed to safely transmit binary data over channels that only support text, such as email. It is not encryption: there is no key, and anyone who sees the encoded string can decode it instantly. See the CTF encodings reference, the Burp Suite Decoder shortcut for one-keystroke stacked decodings, and the web bug patterns post for more places this shows up.

    You can recognize base64 by its characteristics: the character set is limited to alphanumerics plus + and /, the string length is always a multiple of 4 (padded with = signs), and the encoded length is about 33% larger than the original.

    Common places developers accidentally leave base64-encoded secrets: HTML attributes, JavaScript variables, URL parameters, HTTP response headers, and API responses. Security researchers routinely grep for base64-like strings when reviewing web application source code.

Interactive tools
  • Base64 & Base32 DecoderDecode Base64 and Base32 strings with auto-detection. Multi-layer mode unwraps nested encodings automatically.
Alternate Solution

Once you copy the Base64 string from the HTML attribute, decode it in one click with the Base64 Decoder on this site. Paste the value and the flag is shown immediately, no terminal or CyberChef needed.

Flag

Reveal flag

picoCTF{web_succ3ssfully_d3c0ded_02c...}

Decoding the notify_true attribute reveals the flag above.

Key takeaway

Browser DevTools expose the full DOM including non-standard HTML attributes that never render to the user, making them a poor hiding spot for secrets. Base64 encoding provides no confidentiality because it is a public, reversible transformation with no key; anyone who finds the encoded value can decode it instantly. Security researchers routinely scan page source, network traffic, and JavaScript bundles for base64-like strings as a standard recon step in web application assessments.

Related reading

Want more picoCTF 2024 writeups?

Tools used in this challenge

What to try next