The Imaginary CTF 2025 – Certificate Write-up description “As a thank you for playing our CTF, we’re giving out participation certificates! Each one comes with a custom flag, but I bet you can’t get the flag belonging to Eth007!”
Most people visit the site and try to generate certificate and give up.

But most of them wouldn’t think to read the JavaScript code on the source page.
1. In the code The function makeFlag(name) is the key part:
function makeFlag(name){
const clean = name.trim() || "anon";
const h = customHash(clean);
return `ictf{${h}}`;
}
It trims the name. If empty, it uses “anon“. Then it computes a hash using customHash. The final flag is: ictf{hash}.
2. The customHash(str) function is:
function customHash(str){
let h = 1337;
for (let i=0;i<str.length;i++){
h = (h * 31 + str.charCodeAt(i)) ^ (h >>> 7);
h = h >>> 0; // force unsigned
}
return h.toString(16);
}
This part is a custom hash function — it processes each character and produces a hexadecimal string.
If you enter the Participant name”Eth007″, the code replaces it with “REDACTED” when rendering the preview:

This is just to trick users into thinking the flag is inaccessible.
But the hash algorithm is fully known in the Javascript.
So just by reading the JS, we can compute the flag without needing the site to tell us.
Step 2 – Python Script to get the flag – Imaginary CTF 2025
Here, customHash starts with h = 1337. For each character, it multiplies by 31, adds the character code, then XORs with a shifted version of h. The final result is converted to hexadecimal.
Python script you can use to compute the flag for Eth007:
def custom_hash(name):
h = 1337
for ch in name:
h = (h * 31 + ord(ch)) ^ (h >> 7)
h = h & 0xFFFFFFFF # Force unsigned 32-bit
return hex(h)[2:] # Convert to hexadecimal without '0x'
def make_flag(name):
clean = name.strip() or "anon"
h = custom_hash(clean)
return f"ictf{{{h}}}"
if __name__ == "__main__":
name = "Eth007"
flag = make_flag(name)
print("The flag is:", flag)
After running this script I got the flag:

By reading the Client-side JavaScript carefully can reveal hidden logic.









