Challenge Info

Spoiler
Illumination hands you a Discord bot’s project folder and asks you to recover a secret token that isn’t sitting in the current source anymore.

Artifacts Provided

  • Illumination.JS/ — a Discord bot’s project folder, including a .git directory.

No remote instance, no interaction — just a git repository to dig through.

Analysis

Recon — the bot’s source

ls -la on the artifact immediately shows a .git folder — this is a git repository, not just a bare source dump, so its history is fair game.

bot.js is a small Discord bot built on discord.js and the Philips Hue API — it logs in by base64-decoding a token pulled straight from config.json:

1
2
3
var config = JSON.parse(fs.readFileSync("./config.json"));
...
client.login(Buffer.from(config.token, 'base64').toString('ascii')) //Login with secret token

But the current config.json on disk doesn’t hold a real token:

1
2
3
4
5
6
7
{
	"token": "Replace me with token when in use! Security Risk!",
	"prefix": "~",
	"lightNum": "1337",
	"username": "UmVkIEhlcnJpbmcsIHJlYWQgdGhlIEpTIGNhcmVmdWxseQ==",
	"host": "127.0.0.1"
}

That placeholder string obviously isn’t valid base64 either — so the real token has to be sitting somewhere in the project’s history instead.

Solution — walking the git log

1
git log
commit edc5aabf933f6bb161ceca6cf7d0d2160ce333ec (HEAD -> master)
    Added some whitespace for readability!

commit 47241a47f62ada864ec74bd6dedc4d33f4374699
    Thanks to contributors, I removed the unique token as it was a security risk. Thanks for reporting responsibly!

commit ddc606f8fa05c363ea4de20f31834e97dd527381
    Added some more comments for the lovely contributors! Thanks for helping out!

commit 335d6cfe3cdc25b89cae81c50ffb957b86bf5a4a
    Moving to Git, first time using it. First Commit!

The commit message on 47241a47f62ada864ec74bd6dedc4d33f4374699 gives it away — that’s the one that swapped the real token out for the placeholder. git show on it prints the diff directly:

1
git show 47241a47f62ada864ec74bd6dedc4d33f4374699
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
diff --git a/config.json b/config.json
index 316dc21..6735aa6 100644
--- a/config.json
+++ b/config.json
@@ -1,6 +1,6 @@
 {
-	"token": "SFRCe3YzcnNpMG5fYzBudHIwbF9hbV9JX3JpZ2h0P30=",
+	"token": "Replace me with token when in use! Security Risk!",
 	"prefix": "~",
 	"lightNum": "1337",
 	"username": "UmVkIEhlcnJpbmcsIHJlYWQgdGhlIEpTIGNhcmVmdWxseQ==",

Same value shows up just as easily by going straight to the repo’s root instead — git show 335d6cfe3cdc25b89cae81c50ffb957b86bf5a4a (the very first commit) dumps the original config.json in full, token included, since that’s the commit that added the file before anyone thought to strip it.

Either way, the recovered string is SFRCe3YzcnNpMG5fYzBudHIwbF9hbV9JX3JpZ2h0P30= — base64-decode it and it is the flag:

1
echo "SFRCe3YzcnNpMG5fYzBudHIwbF9hbV9JX3JpZ2h0P30=" | base64 -d
Spoiler
HTB{v3rsi0n_c0ntr0l_am_I_right?}

Full chain

Illumination.JS/ (git repo)
  └─ bot.js — logs in via base64(config.token)
      └─ config.json (HEAD) — token replaced with a placeholder string
          └─ git log — flags the commit that removed it
              └─ git show <commit> — diff/full-file reveals the original base64 token
                  └─ base64-decode → FLAG
Tip
git commit/push doesn’t unsend anything — deleting a secret from the working tree just adds a new commit on top of it; the blob is still sitting in .git/objects, reachable from any earlier ref. Anyone who clones the repo (or just runs git log/git show against it) can walk straight back to it. The only real fix once a secret lands in history is revocation, not a follow-up commit.