X

JerseyCTF 2025: Encoded-Deception

Mar 31, 2025

author: @wxrth

Challenge Info:

Category: Web

TL;DR:

Poked around the website of a shady cyber-investigation agency, checked their JavaScript, and found a base64-encoded “Part 1” of a flag. Then sniffed out “Part 2” hidden in a response header from a PHP file. Decoded both parts, stitched ‘em together and boom got the full flag.

The Challenge (Solution):

The challenge gave us this website

http://encoded-deception.aws.jerseyctf.com/

Nothing seemed interactive on the surface. But the hint?

“Sometimes, secrets are buried in scripts…”

So I cracked open DevTools and went hunting.

Step 1 – Exploring:

Inside the Sources tab, under /assets/, there was a single JS file: casefiles.js.

function generateRandomHash(length) {
    let result = '';
    const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    for (let i = 0; i < length; i++) {
        result += characters.charAt(Math.floor(Math.random() * characters.length));
    }
    return result;
}

const hash1 = generateRandomHash(16);
const hash2 = generateRandomHash(24);

console.log("Initializing Black Hat Investigations system...");
console.log("User session ID:", hash1);
console.log("Verification key:", hash2);

const secretMessage = "UGFydCAxOiBqY3RmdntteXN0M3J5"; 
console.log("Nothing to see here... or is there?");

const fakeData = [
    "aGVsbG8gd29ybGQ=", 
    "ZGF0YXN0cmVhbQ==", 
    "U29tZXRoaW5nIHN1c3BpY2lvdXM="
];

function decodeFakeData(index) {
    return atob(fakeData[index]);
}

console.log("Processing encrypted logs...");
setTimeout(() => {
    console.log("Log entry:", decodeFakeData(Math.floor(Math.random() * fakeData.length)));
}, 2000);

async function fetchDummyData() {
    return fetch('/info.php');
}

fetchDummyData().then(response => console.log(response));

That secretMessage variable caught my eye:

const secretMessage = "UGFydCAxOiBqY3RmdntteXN0M3J5";

Looks like base64 so I copied it, opened up dcode, to check it out.

Sure enough, the output gave me:

Part 1: jctf{myst3ry

First half of the flag secured. Time to track down the second half.

Looking back at the script, I saw this:

fetch('/info.php');

Which meant there might be something interesting in the network traffic…

Step 2 – Inspecting /info.php:

I reloaded the page with DevTools → Network open, clicked on info.php, and sure enough in the Response Headers I found this:

HTTP/1.1 200 OK
Date: Mon, 31 Mar 2025 10:58:01 GMT
Server: Apache/2.4.62 (Amazon Linux)
Important: UGFydCAyOiBfMHAzcjR0MTBufQ==
Keep-Alive: timeout=5, max=99
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/plain;charset=UTF-8

Theres a header named "Important"

Important: UGFydCAyOiBfMHAzcjR0MTBuf

It looked like another base64 string just like earlier. So I copied it, headed back to dcode, and dropped it in.

Output:

Part 2: _0p3r4t10n}

Boom, second half of the flag successfully uncovered.

Step 3: Combineeeeeee!

Now with both pieces in hand:

🚩 Final flag: jctf{myst3ry_0p3r4t10n}