ShaktiCTF 2025 Write-up
Full write-up of completed challenges in ShaktiCTF 2025 by AppleTree, covering Misc, OSINT, Rev, and Web categories.
ShaktiCTF 2025 Write-up
Author: AppleTree
Team: APISec Avengers
Event Date: July 25–26, 2025
Platform: ShaktiCTF 2025
Flag Format: shaktictf{...}
✅ Completed Challenges Overview
Challenge Name | Category | Points | Status | Difficulty |
---|---|---|---|---|
Welcome Flag | Misc | 100 | ✅ | Beginner |
water water everywhere | Misc | 100 | ✅ | Unrated |
gooGOOgaaGAA | Rev | 100 | ✅ | Unrated |
OpenSesame | Rev | 100 | ✅ | Unrated |
Hooman | Web | 100 | ✅ | Unrated |
Brain Games | Web | 100 | ✅ | Unrated |
Total Personal Score: 600 points
Total Team Score: 1100 points
Final Rank: 127th of 554 total teams
Welcome Flag
Category: Misc
Points: 100
Difficulty: Beginner
Flag: shaktictf{c0ngratulations_y0u_h4ve_f0und_it!!!}
Description
The challenge served as an onboarding exercise to familiarize participants with the event Discord server.
Steps Taken
- Joined the event Discord server
- Checked channel names, pinned messages, announcements
- Found organizer message in
#announcements
with text hidden in pipe blocks - Copying message to a plaintext editor revealed the flag
water water everywhere
Category: Misc (tagged OSINT)
Points: 100
Difficulty: Unrated
Flag: shaktiCTF{vellayani_lake}
Description
˚⊱🪷⊰˚
- Replace all spaces with underscore
- no caps inside shaktiCTF{random_lake}
Author: ._switch_
Steps Taken
- Observed palm trees, lotus pads, tropical climate
- Hypothesized Kerala or southern India
- Searched Google Images for
"kerala lake with lotus"
- Matched to Vellayani Lake, Kerala
- Verified via Google Maps and travel photography
gooGOOgaaGAA
Category: Rev
Points: 100
Difficulty: Unrated
Flag: shaktictf{b4byR3v_1s_cut3}
Description
Solve this babyrev challenge first ^-^
Steps Taken
- Observed
gaga()
XOR function (renamed for manual analysis) with key"IWANTMOMOS"
- Re-applied XOR to encrypted list to recover flag
1
2
3
4
5
6
7
def gaga_decrypt(encrypted, key):
return ''.join(chr(ord(encrypted[i]) ^ ord(key[i % len(key)])) for i in range(len(encrypted)))
key = "IWANTMOMOS"
encrypted = [':','?',' ','%',' ','$',',','9',')','(','+','c','#','7','\x06','~','9','\x12','~',' ','\x16','4','4',':','g','0']
flag = gaga_decrypt(encrypted, key)
print(flag)
OpenSesame
Category: Rev
Points: 100
Difficulty: Unrated
Flag: shaktictf{Hii1i1i1ii_^_^__3243242_3nj0y_r3v_^_}
Description
You discover the secret treasure in a thieves’ den, what might the magic password be?
-y0urk4rma
Steps Taken
- Decompiled in Ghidra
- Reversed rotations and XOR sequences seeded by fixed constants
- Reconstructed ASCII characters from processed integers
Hooman
Category: Web
Points: 100
Difficulty: Unrated
Flag: shaktictf{n0on3_l1k3s_5ar4h}
Description
Try your best to prove being a Hooman!
Author: ._switch_
Steps Taken
Review the Source Code
We are given the Flask app source code
app.py
. Key behaviors:- On
/login
, a JWT is generated withare_you_hooman: False
- The JWT is signed with
HS256
and the secret'Youcanneverhavethis'
- The
/hooman
route only allows access ifare_you_hooman: True
- When decoding the JWT: ```python decoded = jwt.decode(token, key=None, options={“verify_signature”: False})
- On
Forge a JWT We can now forge a JWT without knowing the real secret. There are two approaches:
Use jwt.io directly
Use Python’s jwt.encode (PyJWT) — though some environments block HS256 without a key.
To make it easy, I used jwt.io via archive.org, since newer versions of the tool enforce recommended requirements.
Set the Cookie Once we get the JWT token from jwt.io, we set it in our browser’s cookies.
In DevTools (Chrome or Edge):
- Go to Application > Cookies
- Find the domain
- Set a cookie named token to the forged JWT
Reload the page.
Brain Games
Category: Web
Points: 100
Difficulty: Unrated
Flag: shaktictf{n0on3_l1k3s_5ar4h}
Description
🎮🧑💻
Author: ._switch_
Steps Taken
- Inputs like
help
returned MD5 hash → confirmed command injection (though intended?) - Spaces,
/
,cat
,ls
blocked; ;
,dir
allowed- Enumerated environment and listed files using:
1
dir;
- Used
${IFS}
to bypass space filter - Found partial flag in
user.txt
; hint pointed to/usr/local/flag
1
head${IFS}user.txt
- Used
${HOME:0:1}
to bypass/
filter - Read final part of flag:
1
head${IFS}${HOME:0:1}usr${HOME:0:1}local${HOME:0:1}flag;
- Combined flag parts for final flag
Takeaways
- Misc & OSINT: Geolocation from visual cues and hidden messages in Discord are common quick wins
- Reversing: Simple XOR and layered rotation/XOR patterns remain CTF staples
- Web: JWT signature bypass and blacklist command injection are classic but valuable vulnerabilities to understand
Note: AI-assisted editing was used only for grammar, formatting, and consistency. All opinions are my own based on official OffSec documentation.