292 words
1 minute
Bookmarklet - picoCTF Writeup

This picoCTF challenge gives us a page that hints at a browser-side trick. After opening the site, the most useful next step is to inspect the JavaScript behind the bookmarklet rather than interacting with the page blindly.

JavaScript bookmarklet source

The code shown in the page is a JavaScript bookmarklet, which means it is designed to run directly inside the browser. Instead of sending our input to a backend service, the page already contains the logic needed to recover the flag locally.

Understanding the Script#

The important variables are:

  • encryptedFlag: the encoded flag string.
  • key: the repeating key used during the transformation, which is picoctf.
  • decryptedFlag: an initially empty string that stores the recovered output.

The loop processes the encrypted string one character at a time:

for (var i = 0; i < encryptedFlag.length; i++)

For each character, the script:

  • Reads the numeric value of the encrypted character with encryptedFlag.charCodeAt(i).
  • Reads the numeric value of the matching key character with key.charCodeAt(i % key.length).
  • Repeats the key using modulo so it can be applied across the full ciphertext.

The core operation is:

(encryptedFlag_char - key_char + 256) % 256

This reverses the original transformation by subtracting the key character value from the encrypted character value, while keeping the result inside the byte range 0-255.

The resulting number is then turned back into a character:

String.fromCharCode(...)

At the end, the script displays the recovered flag with:

alert(decryptedFlag);

Solving the Challenge#

Since the full decryption logic is already present, we do not need to reimplement anything. The fastest solution is simply to copy the JavaScript and execute it in the browser console.

Flag revealed in browser console

Once the script runs, it reveals the flag in an alert box. The lesson here is simple: when a challenge uses client-side JavaScript, always inspect the code first because the secret or the decryption routine may already be exposed in the browser.