# SEEN CTF 2025—Writeup

Welcome back to another writeup! 🚩 This time, I’ll be walking you through a detailed, step-by-step breakdown of how we tackled and solved the challenges from **SEEN CTF 2025**. In this writeup, I’ll not only share the exact methods and techniques we used, but also provide insights, thought processes, and alternative approaches that might help you in future competitions. Whether you’re a beginner looking to learn or a seasoned player comparing strategies, I hope this guide gives you both knowledge and inspiration for your own CTF journey!

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2F8ibEO1TmU8qGR37Yf3SN%2F528239986_730479733127848_8016910327756250971_n.jpg?alt=media&#x26;token=19f6507f-1610-4be7-99fb-7a1d8ad547ab" alt=""><figcaption></figcaption></figure>

**AUDITION**

Challenge Name #1: **first\_task**

In the challenge description, the term **`leash_protocol`** is emphasized, and within the provided game materials, there’s also a file with the same name. Opening this file in a text editor like Notepad shows that it’s technically readable, but the content appears messy and difficult to interpret. A practical approach here is to adjust or correct the file’s encoding to make the text more understandable.

Here's a Python script to automate this.

```python
import chardet

input_file = "leash_protocol"

# Detect encoding
with open(input_file, "rb") as f:
    raw = f.read()
    enc = chardet.detect(raw)["encoding"]

# Read and print
with open(input_file, "r", encoding=enc, errors="ignore") as f:
    text = f.read()

print(text)
```

Run the script and use grep for filtering.

`python3 utf-8_encoder.py | grep "SEEN"`

And here's the result

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FVe7k8JnCvpLIlbk9jDVT%2FScreenshot%20(23).png?alt=media&#x26;token=780976f4-42e2-486d-abfd-cdcdb1ba589d" alt=""><figcaption></figcaption></figure>

Challenge Name #2: **corp\_portal**

In the challenge description, we’re provided with a link to a login page. At first glance, it looks like a standard login form, but let’s take a closer look by inspecting it to understand what’s happening behind the scenes.

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FKt0szZl7YSWmR7aiybNe%2FScreenshot%20(24).png?alt=media&#x26;token=b338446e-9544-4fff-814b-5a7f114bae56" alt=""><figcaption></figcaption></figure>

While examining the source code, we notice that the credentials are hardcoded, and the password is written in a flag-like format. However, the expected flag format should be **`SEEN{}`**. To make sense of this, let’s attempt to decode it using common ciphers, such as the Caesar cipher.

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FgmtBYkQ4ZO9id9s8sZmZ%2FScreenshot%20(25).png?alt=media&#x26;token=f275e1e8-a0a3-4405-bf8d-9e8f2db367f3" alt=""><figcaption></figcaption></figure>

Challenge Name #3: **unsecured**

The challenge description indicates that our goal is to obtain some form of **Clearance**.

Looking at the source code, we can see that after a successful login, the page redirects to **dashboard.html**. Interestingly, we can bypass the login entirely and access **dashboard.html** directly by simply modifying the URL.

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2Fmi4D7LXVNDIGme6kLpwK%2FScreenshot%20(27).png?alt=media&#x26;token=7f203e56-084c-462e-ad5b-b5f56b58e886" alt=""><figcaption></figcaption></figure>

This is the **dashboard.html**, now let's take a look at the source code of this.

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FOJIcdtvmrG2gmLDRf5jk%2FScreenshot%20(28).png?alt=media&#x26;token=3876bd65-209a-4063-8117-7f9145b43cca" alt=""><figcaption></figcaption></figure>

At the end, you’ll notice that the dashboard links to another HTML page called **file.html**. Let’s take a closer look at it.

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FG22oAbn4XBNNKHrStmTv%2FScreenshot%20(29).png?alt=media&#x26;token=45e2d9c2-d4f7-4d2f-8533-5deea0bb0f99" alt=""><figcaption></figcaption></figure>

This is **file.html**, and as mentioned earlier, we need to find some kind of clearance. Here, we can see a file that matches the description—the **Clearance Documentation**. Let’s take a closer look.

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FqWxEXEpSeemHfk8BKUYv%2FScreenshot%20(30).png?alt=media&#x26;token=234a3f97-d058-4269-b1c9-cf5a6150596b" alt=""><figcaption></figcaption></figure>

You can use **Ctrl + F** for this but the flag is already obvious hehe.

Challenge Name #4: **company\_memo**

The challenge states that we need to locate a file named **quarterlybudgets.pdf** and inspect it. This one is straightforward—if we examine the list on **file.html**, we can see **Quarterly Budgets 2025**. Let’s go ahead and check it.

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FBML0olfONGKUtmkIRV0I%2FScreenshot%20(31).png?alt=media&#x26;token=57f93800-b199-45d3-a480-dc8f277977e8" alt=""><figcaption></figcaption></figure>

There's nothing useful at the contents of this PDF File, now let's check the metadata.

Here's the result

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2F7JzFoow8tGwW5Y5yGkD5%2FScreenshot%20(32).png?alt=media&#x26;token=6417b01c-d175-4d50-96d2-29aa86a8b938" alt=""><figcaption></figcaption></figure>

Challenge Name #5: **logging**

The challenge description mentions that there’s a log file in the same directory, but it’s not listed on **files.html**. So how can we locate it? One way is to enumerate the directory using Gobuster to find all files with the **`.log`** extension.

`gobuster dir -u https://zdvlg8fx0mugwaof.apollodon.tech -w wordlist.txt -t 50 -x log -k`&#x20;

Here's the result

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FbGjszg5fEyyyGSTgAx9L%2FScreenshot%20(34).png?alt=media&#x26;token=3f680cda-7dc9-4da9-9dd0-5e813a1ff7e1" alt=""><figcaption></figcaption></figure>

There it is, now let's check the `access.log` .

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FN3q8wGvUuvxVeTd0eDI4%2FScreenshot%20(35).png?alt=media&#x26;token=705040f8-5e93-40d8-9e85-9a94fbdfd2eb" alt=""><figcaption></figcaption></figure>

Challenge Name #6: **the\_name**

For this challenge, we’re provided with a link to a login page, which is indicated to be vulnerable to **SQL injection (SQLi)**. Let’s take a closer look.

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2F48vUxHpXOiKaZC2pjDYE%2FScreenshot%20(36).png?alt=media&#x26;token=d0885fca-5e6c-4e7c-8cd8-025223ae5566" alt=""><figcaption></figcaption></figure>

This is the login page, now let's do the classic 1=1 payload.

`' OR '1'='1`&#x20;

And it works!!!! We're in!

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2F3uUA0aiQH7YcyWNLhSLF%2FScreenshot%20(37).png?alt=media&#x26;token=35aa64d7-0bf7-4731-b1b3-21dc1dd35169" alt=""><figcaption></figcaption></figure>

Just do the same payload again xD..

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FZJA1bF5IU1iFMQHm74P6%2FScreenshot%20(38).png?alt=media&#x26;token=8a090ac3-65d7-4832-ac97-05dff2ab5540" alt=""><figcaption></figcaption></figure>

Challenge Name #7: **getaway**

In this challenge, the **corporate logo** is referenced, and we can find it listed on **file.html**. Let’s go ahead and take a closer look.

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2F25F8swYTJkSJt2FZH6zd%2FScreenshot%20(39).png?alt=media&#x26;token=a2232205-410f-4ad8-9482-3b2ca0fdb3b8" alt=""><figcaption></figcaption></figure>

And in the file.html, the title of this has this word inside a parenthesis "(High-Res)" So I wonder, what if we increase the resolution of this image.. We use Aperi'solve for this, and this is the result.

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2F7vyF9sbDE5MR4Nf3KQyf%2FScreenshot%20(40).png?alt=media&#x26;token=6a16fb48-47a5-4945-952f-a6b3d3e42a82" alt=""><figcaption></figcaption></figure>

**AXIOM CORP**

Challenge Name #8: **thorne's website**

In this challenge, we are presented with a webpage that requires a password. It’s specified that the verification happens entirely on the **client side**, which means tools like BurpSuite or ZAP won’t be effective. The flag is embedded in the frontend itself. Let’s take a closer look.

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2Fzk6aiBp8sM38TbVXeUnv%2FScreenshot%20(41).png?alt=media&#x26;token=5a512040-a861-4f87-bd74-35d1ca62d458" alt=""><figcaption></figcaption></figure>

This is the webpage, now let's check the source code.&#x20;

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FmK1soQfjJthW7Ei2OH7x%2FScreenshot%20(46).png?alt=media&#x26;token=d67259d2-8ee6-4c24-9248-a5a9b928faa3" alt=""><figcaption></figcaption></figure>

As you can see, this project is using **Next.js**. Let’s take a closer look at it.

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FjyHkZM2y4MHEBeSFyiE9%2FScreenshot%20(45).png?alt=media&#x26;token=670dc178-938e-48ab-9c6b-fc4f0bfcd32e" alt=""><figcaption></figcaption></figure>

I noticed a **Base64** encoded string here, now let's decode it. (**VGgwcm4zX1MzY3VyM19QQHN3**)

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FhE6oB0Y6cUvxEPYPtkLr%2FScreenshot%20(47).png?alt=media&#x26;token=48c9eb8e-6bf1-484e-979b-24dc3d580a0f" alt=""><figcaption></figcaption></figure>

Now let's enter this as a password.

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FWg8WDYYOLe00uqbC49SG%2FScreenshot%20(48).png?alt=media&#x26;token=0da49c4c-d7d4-44fd-b1c4-2c09b6be867c" alt=""><figcaption></figcaption></figure>

It works, but something is blocking us to get the flag, so let's check the source code again.&#x20;

```javascript
try {
    let s = await fetch("/api/".concat(btoa("notes")), {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ password: e })
    });
```

This line of JavaScript is making a **POST request** to an API endpoint. It first encodes the string `"notes"` in Base64 using `btoa()` and appends it to `"/api/"`. Then it sends a JSON payload containing a `password` field with the value `e`.

Now let's navigate to `/api/notes`  using curl.

`curl -X POST https://huilaumycqq3yrno154j36g65cf2fwm0.apollodon.tech/api/notes -H "Content-Type: application/json" -d '{"password": "Th0rn3_S3cur3_P@sw"}' | grep "SEEN"`

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FZ0xAe5WsygfUsiN1Lw3c%2FScreenshot%20(50).png?alt=media&#x26;token=4b6ddea8-3570-46c2-9f9d-920243997f1b" alt=""><figcaption></figcaption></figure>

Challenge Name #9: **network\_sniff**

We were provided with a pcap file named **traffic.pcap**. Before opening it in Wireshark, I ran `strings` combined with `grep` on the file, hoping to filter out and reveal the flag directly.

`strings traffic.pcap | grep "SEEN"`&#x20;

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FfsRptFp0OWVwOlIaDWAJ%2FScreenshot%20(51).png?alt=media&#x26;token=9593303c-cf3d-486d-8f75-f155279581ee" alt=""><figcaption></figcaption></figure>

Challenge Name #10: **the\_truth**

In this challenge, we’re given a zip file, and it’s noted that the password (or ciphertext) is encrypted using a **Vigenère cipher**.&#x20;

`vfffrqbumef`

In the challenge number 8, the key is mentioned as `cybernaut` so I decode and the plaintext is `thebadbatch` , but the problem is when I enter the bad batch, the plaintext is not the correct password.... So I entered the ciphertext instead as the password and it works. Weird.

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2F7rSAUD4OnPt1Eyd7B3N6%2FScreenshot%20(53).png?alt=media&#x26;token=c39a3407-63d2-4deb-9a6d-aea24b1fb90a" alt=""><figcaption></figcaption></figure>

Challenge Name #11: **daemon**

In this challenge, we’re given an executable file. Most people would immediately open it in **Ghidra** or try running the program. But in CTFs, it’s important not to overthink—challenges are often simpler than they seem. In this case, you can use the same `strings` and `grep` approach we applied to the pcap file earlier. Yes, it’s really that simple.

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FxqPRfZYhoUoMd3kYiqhn%2FScreenshot%20(54).png?alt=media&#x26;token=a85b1074-5268-4518-8543-6103096001c1" alt=""><figcaption></figcaption></figure>

**THE STELLAR SOVEREIGNTY**

Challenge Name #12: **loyalist**

In this challenge, we’re again provided with a **.pcap** file, and as usual, using `strings` combined with `grep` proves to be the most effective approach.

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FVkXiOQJys0nq5pSGDAFz%2FScreenshot%20(55).png?alt=media&#x26;token=737ea69b-e5f0-439d-ad3b-7df82759d8da" alt=""><figcaption></figcaption></figure>

Challenge Name #13: **gateway**

In this challenge, we are given a link for a webpage but CLI style, and it was asking for username and password and I enter the credentials we've got from loyalist.

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FKCH4yPdeJOeBm50XcWjX%2FScreenshot%20(58).png?alt=media&#x26;token=f7662107-ac2c-4105-a40e-fbba098b2997" alt=""><figcaption></figcaption></figure>

The core logic is this

```javascript
function checkCookieStatus() {
  const cookies = document.cookie.split(";");
  let bypassCookie = false;

  for (let i = 0; i < cookies.length; i++) {
    const cookie = cookies[i].trim().split("=");
    if (cookie[0] === "bypass" && cookie[1] === "true") {
      bypassCookie = true;
      break;
    }
  }
```

We will just use a bypass payload for this.&#x20;

`document.cookie = "bypass=true";`&#x20;

Just enter that to the console and refresh the page.

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2Ftl54fXU2vZqiyZ37yVw5%2FScreenshot%20(59).png?alt=media&#x26;token=f50dad0b-0c6f-4c81-a286-80daeb0fee4d" alt=""><figcaption></figcaption></figure>

Challenge Name #14: **prime\_bug**

Here we are given a ciphertext

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FwkKaLoWB2byIdJlPODpt%2FScreenshot%20(60).png?alt=media&#x26;token=4d459344-c1be-4350-93f3-64b6f5d6fede" alt=""><figcaption></figcaption></figure>

The main issue is that we have the values of p, q, and the private key, but we don’t yet have the decrypted number sequence. However, if we encrypt the correct decrypted sequence, it produces the same ciphertext. Looking back at the description, the word “sovereignty” catches our attention, and it turns out that the ciphertext corresponds to 11 characters — which is actually the decrypted text.

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FyHZhGaVuIS5MynJCCwSh%2FScreenshot%20(61).png?alt=media&#x26;token=dba7ac52-a1a2-4dbd-9286-80d4d291e980" alt=""><figcaption></figcaption></figure>

Challenge Name #15: **stellar\_redemption**

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FkbjLMq5JxpXUpFvEvs0i%2FScreenshot%20(62).png?alt=media&#x26;token=806f3ed9-a9bf-4d78-a344-c8ccd9e4048e" alt=""><figcaption></figcaption></figure>

The description mentioned that we needed to find some kind of kill switch or key. After carefully analyzing every detail, the URL “S33N2025” stood out. When we submitted this as the final flag, it worked perfectly!

Final Flag: **SEEN{S33N2025}**

I am proud to share that our efforts paid off — we secured **Top 1** and emerged as the **champions of SEEN CTF 2025**. This achievement would not have been possible without the exceptional dedication, skill, and support of my fellow members: **Brylle (ka1ro), Alisha (isha), Arvin (y3y), Matt (emoa),** and every single player who contributed, collaborated, and challenged us along the way. Your expertise, encouragement, and energy were invaluable in making this victory possible.

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FpibFAcW859tDzDm9SbeP%2FScreenshot%20(13).png?alt=media&#x26;token=fb623576-a59e-41f9-9753-06efb3e0aa64" alt=""><figcaption></figcaption></figure>

This competition was not just about ranking or accolades — it was about pushing the boundaries of our knowledge, sharpening our skills, and embracing the spirit of cybersecurity and ethical hacking. To all the participants, thank you for making SEEN CTF 2025 a truly unforgettable experience. Every challenge solved and every obstacle overcome has left a lasting impression, and I am inspired to continue striving for excellence in future competitions.
