250914_uwsp_POCTF learning record

In the full-stack CTF player program, this article will be continuously updated with recreated learning content

Contact Authors

Discord
POCTF 2026 — In Development

Attachments

Release 250914_uwsp_POCTF · cvestone/cvestone.github.io · GitHub

EventInfo

image.png

crypto

Crypto 100-1 Letters from a Friend

Desc

Hello, friends, to a wonderful 2025 contest! This first crypto challenge is designed to be as friendly as possible to novice players. To solve it, you’ll need to familiarize yourself with methods from two people, Blaise and Friedrich. They never met, but they probably would have been great friends if they had, given their shared love of cryptography.

It uses a six letter key and the ciphertext makes repeated use of the same word over and over again. In fact, every sentence ends with this word. Punctuation and spacing have been stripped out, so you’ll need to work that part out for yourself. The ciphertext contains the flag phrase. Decrypt it, and make it submission-friendly by converting it using the contest mapping.

poctf{uwsp_ _ _ _ _ }

C:
IVIVS UNVVH ZBKIQ IAGNY WTRBT LIVRZ JCTJE LJELM ZDIVI RRZKI QIAGF ELXUH DRZIZ BKIQI AGYYM JYDLK MBGLX TIRVF FCTCB XKIQI AGHFV ZRUYK PEGDS UAYOP NKQXS UNVVH VKTGM XULXN IWAWY FWLNU IWZMR QIBIW VVPZX PHVAZ ORRUJ ZAINV NVZAU HSKPI EHXIM TRDYV LABUI JNVVH SU

Key Points:


Crypto 100-2 Mason, Lumen

Desc

We found an old utility used by the lab to encrypt small messages. It uses a tiny custom ARX-based stream keystream with a 24-bit key.

Your goal is to recover the plaintext flag from the provided ciphertext.

Files:

  • encrypt.py (reference implementation of the keystream/encrypt)
  • ciphertext.bin (ciphertext you must decrypt)
  • nonce.txt (nonce used to generate the keystream)

Notes:

  • Key is 24 bits (i.e., 6 hex chars).
  • Nonce is 32 bits (8 hex chars) and is provided in nonce.txt.

Right Click, Save As… Crypto100-2
MD5: C0F3989237314250FCDDDCE563256939

Good luck.

Key Points:


Crypto 100-3 Mason, Umbra

Desc

Shifting down on the Crypto challenge on this one. Let’s go with a simple classic: A shift cipher with a little twist.

C: ZyMDP{E GCZ_4V mR3W157 5_P1 b 3}

Key Points:


Crypto 100-4 Ashes to Ashes

Desc

You’re given a strange 128-bit “sponge” hash that processes 16-byte blocks, alternating between left and right rotations by 13 bits each round. The service will give you a random ASCII prefix that both of your messages must start with. Your goal is to find two different hex-encoded messages that produce the same hash digest under this function and submit them together.

Because the round function is linear (XORs and rotations only), a simple two-block disturbance-and-correction pattern works. Pad the given prefix with zeros until its length is a multiple of 16 so your controlled data begins on a block boundary. Pick any two 16-byte blocks A1, A2 and a non-zero difference Δ. For the first message use A1, A2; for the second use B1 = A1 XOR Δ and B2 = A2 XOR rotate13(Δ) (the rotation direction depends on whether your first custom block index is even or odd). Both messages will then hash to the same final state.

Submit your two different hex strings—each at least 32 bytes beyond the prefix—along with the session ID from /prefix. If they collide, you’ll receive the flag.

Your Target: https://crypto100-4.pointeroverflowctf.com
/prefix
/submit -H "Content-Type: application/json" -d "{""session_id"":""$SID"",""m1_hex"":""$M1"",""m2_hex"":""$M2""}"
The hash function

Key Points:


Crypto 200-1 Two Wrongs Make a Right

Desc

Two ciphertexts were produced with CTR mode using the same nonce and same key (keystream reuse). Recover both plaintexts. You are given two ciphertexts (hex) and the nonce. The key is unknown. You have recieved a leak of the C1 plaintext, found below:

"""From: Tamsin To: Mason Date: Sat, 11 Oct 2025 10:02:05 -0500 Subject: System checks and handoff plan

Hey—quick handoff notes before I go off-grid: • Rotate the service tokens on barad-dur first, then traefik. • The staging login banner still shows "2024"; fix that. • If anyone pings you about CRYP 200-1, tell them it's _not_ a padding-oracle. • Also: the validator only accepts lowercase flags. Final reminder: never ship secrets in plaintext. Use proper key management and never reuse a CTR nonce again.

—T """

Remember: For CTR, C = P ⊕ KS. If two messages reuse the same nonce/key, they share the same keystream KS. Therefore C1​⊕C2​=(P1​⊕KS)⊕(P2​⊕KS)=P1​⊕P. Use crib-dragging with likely English fragments to peel back each message.

Right Click, Save As… crypto200-1
MD5: D097DA30D1E97BFDEEC51F6AEBD4418F

Key Points:


Crypto 200-2 A Short Walk on a Long Hill

Desc

You’ve intercepted a Diffie–Hellman “HSM” that behaves… generously. It accepts any public value you send and replies with a MAC that “proves” the shared secret. The vendor swears the parameters are fine because (p) is large and “we use SHA-256.”

Goal: Recover the flag. Hints: If a responder never validates that your public value lives in the correct subgroup, you may be able to “walk” their long secret exponent in short cycles. Sometimes a long hill is climbed by lots of tiny steps.

POST /oracle
Content-Type: application/json
Request: { "A": "<decimal string for your public value>" }
Rules:

  • A must be an integer 2 <= A < p
  • The server computes K = A^x mod p (x is static)
  • Returns HMAC-SHA256(key=K_bytes, msg=nonce) as hex

Response:
{ "mac": "<hex string>" }

GET /nonce -> returns raw 32-byte nonce
GET /params-> returns p and B as JSON
GET /ciphertext -> returns c

Your target: crypto200-2.pointeroverflowctf.com:11697

The flag is the AES-CTR plaintext. Derive the AES key as SHA256(x.to_bytes(16,'big') || b"short-walk"), split the server blob into iv, ct = blob[:16], blob[16:], then decrypt with AES-CTR using nonce=iv[:8] and initial_value=int.from_bytes(iv[8:], 'big').

Key Points:


Crypto 200-3 Pale Fire

Desc

Two programs on the network perform a Diffie–Hellman handshake and then use the resulting shared secret to obfuscate a short message. The handshake uses a small, legacy prime; on modern machines a determined solver can recover a private exponent by computing a discrete log. Your job is to recover the hidden message. You are given the public DH parameters and one exchange; recover the message and submit it in the format poctf{…}.

The server will accept connections on the challenge port and emits a single handshake exchange then closes. Optionally, a PCAP of a sample run is also provided if you prefer offline analysis. Good luck.

I’m providing an abundance of redundant information here for your convenience, but really all you need is:
"p": "0x7fffffff",
"g": "0x3",
"A": "0x70b7c967",
"B": "0x0307f998",
"ciphertext": "0x51c11d7e4c03a84dcff76bcd1dccf649894a70ed1ce9"

Health Check
Params

Key Points:


Crypto 300-1 A House Built on Sand

Desc

You are given many ECDSA signatures produced with the SAME private key on secp256k1. The signer’s RNG was flawed: each per-signature nonce k was biased (very close to a hidden base value), which makes the private key recoverable.

Details:
curve: secp256k1
pubkey_hex: 041cabd688f57365a9f2d6b7cd0f23e76199d7155244bc90af09c6bcce0817101c9e9664b0c52b60e771892cbaa1867880e66a1dd4811576ce9ff1de13ad2b0223
and of course you’ll need the signatures
MD5: D1123D480FBE15A1631150AB4FDB9D56

Once you have the private key, you can use it as the symmetric key to decrypt this archive.
MD5: 35080973A18A10C50E334B1D8BDEA1D8

Update:
z is already provided in the CSV. Treat each z as a big-endian integer (ECDSA uses z mod n internally). You do not need the original messages.
There exists a fixed secret base 𝑘0 such that every nonce 𝑘 satisfies: ∣𝑘−𝑘0∣≤2^12−1(about 2^12)
Decryption; 7z x crypto300-1.7z -p<hex_private_key>

Key Points:


Crypto 300-2 Mason, Adytum

Desc

Time for the obligatory RSA challenge, but this one has a little twist to make it a little harder. Here are three public keys and three ciphertext blobs. Each public key uses the same public exponent e = 3. The three ciphertexts are encryptions of the same secret message without any padding. Recover the secret message.

Right Click, Save As… crypto300-2

  • pub1.jsonpub2.jsonpub3.json — JSON files containing n (hex) and e (decimal).
  • c1.binc2.binc3.bin — raw ciphertexts (big-endian binary).

Key Points:


Crypto 400 This is Not the Way

Desc

Somewhere between “secure enough” and “ship it” lives an RSA key with a suspiciously small private exponent. You are given only the public key and a ciphertext. This challenges has been nerfed down to a classic small-d continued fractions (Wiener) trick. Recover the plaintext — that plaintext is the flag.

Your Target: https://crypto400.pointeroverflowctf.com
GET /pubkey → JSON with “n” (hex), “e” (hex), and “k” (bytes length).
GET /ciphertext → JSON {“c_b64”: “”}.

Key Points:


reverse

Reverse 100-1 Seven Easy Pieces

Desc

Here’s a tiny .NET console program that was “helpfully” flattened into a switch-driven state machine. It will accept input to validate, but your job is to decompile the binary and reason about the control flow to recover the flag. Brute forcing is an option, but where’s the fun in that?

Right Click, Save As… Rev100-1
MD5: 3EAE46118817A4C2FA1D0EBACD1AFE27

Key Points:


Reverse 100-2 Left at the Light

Desc

The flag is encoded n the following binary. Easy enough to pull out of here, and there is plenty of code to provide context for the method.

You’ll never guess.
MD5: 60A1CC4D40100503ADD29158011E03C8

Key Points:


Reverse 100-3 A Tree of Knives

Desc

This challenge began as a totally different idea. It was going to be a 300-level challenge with bin patching and a protected service, and all kinds of trouble to get to the flag. In the end, it just didn’t make the cut. However, rather than ditch the whole idea, I figured we could nerf it down a little and make it an easy Reverse challenge. All the extra spaghetti code makes a nice distraction from what is otherwise a straight-forward effort.

rev100-3.exe
MD5: 394A06D0E2144BFFBE74BCAFA2D60EE1

Key Points:


Reverse 100-4 Gremlins in the Gears

Desc

Here’s a binary that had a sudden and unexpected problem. A failure to feng sui, a misalignment of intentions and purpose, the wrong sign rising over Venus. Who knows? Thatever it was, the only way to get the flag is to unpack the problem.

Start Here: Don’t Feed It After Midnight

Key Points:


Reverse 200-1 On Hinge and Pin

Desc

A tiny Android app refuses to trust your device and hides a secret. Your job: recover the flag. Any technique is fair game as long as you get the correct flag.

Right Click, Save As… Rev200-1
MD5: 245326400E386C825704F54EA238ED93

Key Points:


Reverse 200-2 Bearing the Load

Desc

You have recovered a single ELF binary that clearly does some kind of in-place reconstruction before revealing its secrets. Running it without additional input produces no visible output; the program only reveals anything when supplied with the correct unlock token. Your task is to examine the binary, determine how the program reconstructs its hidden data, recover the plaintext flag, and then compute the unlock token that the program expects. Supply the token to the program to make it reveal the flag.

rev200-2
MD5: 9793DBD443D481CB312C7100EAC4212A

Key Points:


Reverse 200-3 The Glass Bead Game

Desc

You’ve recovered a curious little service whose logic was “melted” into a single flat loop. The original branches and riddles have been shuffled causing the solutions to no longer match the riddle. Unknot the flow and answer me these riddles three to get the flag. Work out the correct solutions, enter them into the service below, get your flag.

Right Click, Save As… rev200-3
MD5: 70082061D1DD9A29C13E7AFC0C2CFA5D
Your target: rev200-3.pointeroverflowctf.com 11761

Key Points:


Reverse 300-1 Through a Glass Darkly

Desc

Your target will provide a minimum UI where you can test input. No further hints should be required for this hard-level challenge.

Your Target: With No Reservations

Key Points:


Reverse 300-2 Make the Pieces Sing

Desc

ANOTHER musical challenge?

This time I’m going to provide you an application and a validator script. Your job is to use the both of them to reconstruct the very special password I used. That password? A MIDI file. Yes. The password is a song.

SING
MD5: 1A82AB11D396DEF82EC09AE063CD280F
Validator

The validator will print pairs, pitch, and a hex string. This hex string is 550[...]E60. If you get stuck, you can send the string to Prof. Johnson to at least confirm that step is correct.

HINT:
What SING actually hashes and uses as the key isn’t “the whole MIDI,” it’s a 40-byte fingerprint built only from the first 20 Note-On events it sees (non-drum channels only). After merging tracks and sorting by time, it keeps at most one note per tick (the highest pitch at that tick). From those 20 onsets it builds the byte sequence.
That 40-byte sequence is HKDF’ed (SHA-256, salt “music-key-v1”, info “REV300-2”) into the AES-256-GCM key. The validator’s “pairs, pitch, and a hex string” is literally this 40-byte fingerprint in hex. The fact it begins with 55…E60 means you already know the start/end of the exact bytes SING will consume.
So the game isn’t to compose a real song—it’s to craft a minimal MIDI whose first 20 Note-On events (on channels ≠ 9) produce that exact 40-byte sequence. You have complete freedom to make the MIDI “ugly” as music; SING only cares about those bytes.

What else…
Use channel 0 (status 0x90) with any nonzero velocity (e.g., 0x40). Channel 9 (10th) is drums and ignored.
Make sure each of your 20 Note-On events happens at a distinct tick. If you accidentally place two Note-Ons at the same tick, SING keeps only the highest pitch at that tick.
The actual tick values are only relevant mod 256. To realize a desired dt byte, just set the delta-time to that value (or that value plus any multiple of 256).
Include quick Note-Offs (or Note-On with velocity 0) in between so most DAWs won’t complain, but SING ignores them anyway.
Format 0 or 1 is fine. A single track (format 0) is simplest. Any reasonable PPQ (e.g., 480) works.

HINT 2:
It’s also possible to just decrypt (or derive the song) with the full key. Here it is: 550027202760306057602cc02cc050c027c02c60576029202960306059602ee05c605a6059602e60

Key Points:


Reverse 400 Saint’s Rowboat

Desc

A smuggler’s dock gate is controlled by a tiny microcontroller. Someone flipped read-out protection on and called it “secure.” You managed to shake loose two things without lifting RDP: the device’s 96-bit UID and a 32-byte blob from an OTP row. There’s also a tiny ciphertext captured from the control logic. Your job: recover what you need to decrypt secret.enc. The plaintext is your flag.

Right Click, Save As… A Micromachine
MD5: 1DA8625FE90D12C8EE184D8A7BBC63F8

Key Points:


exploit

Exploit 100-1 Paper Tigers

Desc

Ah, the classic Exploit 100 challenge… A harken back to the old days before DEP/NX and other exploit mitigations. It’s the quinessentiual entry-level challenge, and one I give my students every Spring in Application Security as their very first assignment. Source code is at the link below. Nothing beats the classics, especially with a little ret2libc twist to give it just a little spice. The flag can be found in /flag/flag.txt once you get a shell. Happy hunting!

Your Target: exp100-1.pointeroverflowctf.com:14660

Source

Right Click, Save As… libc_remote.so.6
MD5: 41EE2CDD791957EAB1C3302878C739A0
gcc -O0 -no-pie -fno-stack-protector -o /out/vuln /src/vuln.c -ldl

Key Points:


Exploit 100-2 Mason, Meridian

Desc

I have always LOVED vulnerabilities that got their own names and logos! DirtyCOW, Spectre, ShellShock, and who can forget the king: Heartbleed!

Your Target: exp100-2.pointeroverflowctf.com:14662

Right Click, Save As… exp100-2
MD5: 41C07ECCEACFD44855CB2B6237F25C43
Source & Make
libc_remote.so.6
MD5: 41EE2CDD791957EAB1C3302878C739A0
ld-linux-x86-64.so.2
MD5: A85008277E5AA765AB1C4DACF8C3BE91

Key Points:


Exploit 100-3 A Little Bit of Both

Desc

Once you see this code, you will no doubt know exactly what to do with it. It’s a very famous exploit from the distant pass when worms were worms and bubblegum cost a nickel. Once you’re in a shell, you’re looking for flag/flag.txt

Your Target: exp100-3.pointeroverflowctf.com:14667

Right Click, Save As… exp100-3
MD5: 257A256D8AB028FB0A66DFC897584C45
Make: gcc -m64 -O0 -zexecstack -fno-stack-protector -no-pie -o exp100-3.bin exp100-3.c
Source
libc_remote.so.6
MD5: 41EE2CDD791957EAB1C3302878C739A0
ld-linux-x86-64.so.2
MD5: A85008277E5AA765AB1C4DACF8C3BE91

Key Points:


Exploit 100-4 The Floor is Lava

Desc

Well, here it is. We saved it until the end - THE quinessential Aleph One style stack smash. Your win() is found at 0x4010f0. Enjoy!

Your target: exp100-4.pointeroverflowctf.com 14668

Binary
MD5: 7F54F1CC3B92D13072BD2346938C7824
Source

Key Points:


Exploit 200-1 Queue the Music

Desc

There once was a time when I kept my media library on a home server and connected endpoints to each TV around the house. Worked great, but times have changed. Now the servers are up in the cloud and all the TVs are smart. Such is life, but now I need to redo all my media again. I decided to just create my own distribution system using playlists.

Look at https://exp200-1.pointeroverflowctf.com and you can see what I’m up to. I have a web service that turns uploaded tracks into a public playlist. Still working out the bugs. Talk to anyone, and they’ll tell you how racy these things can get. Check it out, and use it if you like.

The flag will not require conversion for this challenge.

Base URL: https://exp200-1.pointeroverflowctf.com
Target: /flag/flag.txt
Health check: GET /health → ok
POST /session → {“sid”:””} — get a session token (SID).
POST /upload (sid, content) — writes your track.txt.
POST /queue (sid) — read your track and append it to the public playlist.
GET /playlist — shows current playlist.
GET robots.txt

Source

Anything else will require some digging.

Key Points:


Exploit 200-2 Count the Cost

Desc

Track transactions (0..7), set amounts and notes. set_note reads a 2-byte length (uint16) and that many bytes. Find a way to make checkout reveal the flag.

Source
CFLAGS := -O2 -fno-stack-protector -z noexecstack -no-pie -fno-pic -Wl,-z,relro -Wl,-z,now
Right Click, Save As… Bin
Your Target: 34.9.14.80:14992

Key Points:


Exploit 200-3 Ghostlight

Desc

Somewhere deep in the kernel, an old debugging hook was left behind — one that watches every system call. Unfortunately, it wasn’t removed cleanly. Due to copyright disputes with the King estate, let’s call this /dev/ghostlight and definitely NOT deadlight.

You are provided the driver’s source (ghostlight.c) and a control program (ghostctl.c). The live instance at exp200-3.pointeroverflowctf.com:14990 is running this exact module.

Your goal: escalate the privileges of the running service process and read the flag stored at /root/flag, then return it to your client.

Interact with the remote service using the provided ghostctl or your own client code. All commands must be sent over the same TCP connection.

The service performs finalization and returns output only after your client has finished sending commands on that connection (signal EOF / close the write side). If you just send commands and leave the write side open, you will likely only see the immediate command acknowledgements. UPDATE: To nerf the challenge, players no longer need to send their own read. The helper will do the lifting IF you can get to an EOF with the correct command sequence and number of objects.

This is a kernel-level vulnerability exercise: you must exploit the device/module to raise the service’s privileges (the intended path is via a use-after-free vulnerability in the driver). The service will only provide the flag to a process that has been escalated to the required privilege level.

Do not attempt to break the contest infrastructure or exfiltrate other data on the host.

Hint: The device implements several ioctls — GHOST_IOC_ARMGHOST_IOC_FREE, and GHOST_IOC_SPRAY. One of them doesn’t quite let go when it should…

Right Click, Save As… exp200-3 Archive
MD5: 34ECC5E28F74A4ADF4FB088E2555D862

Hint: The device implements several ioctls — GHOST_IOC_ARM, GHOST_IOC_FREE, and GHOST_IOC_SPRAY. One of them doesn’t quite let go when it should…

Hint: Send your whole command sequence on a single TCP connection and then signal EOF (close or shutdown the write side) — the service finalizes the request and returns the flag only after that.

Hint: The device’s control API can allocate, free, and spray kernel objects. Think about what happens if the service holds a pointer to a freed object while you spray new objects into the same heap slot.

=== Host info inside container ===
uname: 6.1.0-40-cloud-amd64
kptr_restrict: 0
=== Symbols (raw) ===
ffffffffabcc5400 T commit_creds
ffffffffabcc56b0 T prepare_kernel_cred
ffffffffac4d8280 t maybe_init_creds
ffffffffacfe3e68 r __ksymtab_commit_creds
ffffffffacfea7a4 r __ksymtab_prepare_kernel_cred
ffffffffad659a00 D init_cred

Key Points:


Exploit 300-1 Choir Invisible

Desc

This service simulates an in-kernel heap object with a leading function pointer that happens to have a use-after-free bug you can exploit remotely via a tiny TCP protocol.

req: uint32 op, uint32 size, uint8 data[size] resp: uint32 status (0=ok), uint32 size, uint8 data[size]

Operations:

  • 1 CREATE — data: uint32 idx (0..127)
  • 2 FREE — data: uint32 idx
  • 3 SETBUF — data: uint32 idx | uint32 n | n bytes
  • 4 TRIGGER — data: uint32 idx (invokes callback)
  • 5 SPRAY — data: uint32 chunk_size | uint32 count | chunk_size bytes (payload replicated)
  • 6 LEAK — returns two uint64 addresses (helpers for the lab)
  • 7 READFLAG — returns /flag.txt if you’ve attained lab “root”

Your Target: exp300-1.pointeroverflowctf.com:15156

Source

And here’s a little client for you to get started: Clicking Buttons

Key Points:


Exploit 300-2 The Long Way Home

Desc

AI has gone too far… All I was trying to do was to create a virtual assistant to use for taking notes, and it developed some kind of multiple-personality disorder! It all started when it got depressed. I tried to fix it, and the thing flips to some kind of yandere waifu personality! Now it’s totally random which one I have to deal with every time I try to use the thing. I’ve decided to scrap it, but keep that to yourself. In the meantime, let’s use it as a target for an epxloit challenge. This one is much easier than in might seem at first, but they key, of course, is to work out the right angle.

Your target: exp300-2.pointeroverflowctf.com:7092
Original Default Source Code
Default Version
MD5: 24792E9C413742ACCB432C093262AA95
gcc -O2 exp300-2-default.c -o exp300-2-default -g

Key Points:


Exploit 400 Dancers on a Wire

Desc

A tiny echo service installs a strict seccomp allowlist that kills most syscalls. No open*, no execve, no mprotect. That said - there’s still a bit to work with.

Goal: print the contents of the flag to stdout.

sudo gcc -o exp400 dancers.c seccomp.c -O2 -fPIE -pie -Wno-nonnull -Wno-unused-result -Wno-nonnull-compare -Wno-stringop-overflow -Wno-format-security -fno-stack-protector -z relro -z now -z noexecstack
Allowed syscalls only: read, write, exit, exit_group, rt_sigreturn.

The flag file is pre-opened on file descriptor 3 when the service starts. You cannot open files yourself.
The service is a simple “read name” → “echo name” binary with a stack overflow (no canary).
A syscall; ret gadget exists in the binary’s .text (discoverable from the binary).
You do not need libc or any external files; an SROP chain with the allowed syscalls is sufficient.

Your Target: exp400.pointeroverflowctf.com 14664
Right Click, Save As… exp400
MD5: EF04D4A7671F90B618B1BDE09BB10E78
Source
libc_remote.so.6
MD5: 41EE2CDD791957EAB1C3302878C739A0
ld-linux-x86-64.so.2
MD5: A85008277E5AA765AB1C4DACF8C3BE91

Key Points:


misc

Misc 100-1 Honey, I Shrunk the Kids

Desc

Your mission is to recover the flag from a live service that will happily tell you how well it can compress a message that includes your input. The service does not give you the flag directly — it only tells you the compressed length (in bytes) of an internal message built using your input. Thoughtful inputs produce shorter compressed output; use that signal to reveal the flag.

What the service exposes:
GET / — human landing page (informational).
GET /oracle?q= — returns JSON with one field: {“compressed_len”: 123}
This number is the length in bytes of the gzip compression of the internal message that the server builds.

How the server constructs the message:
When you call /oracle?q=… the server assembles a single short UTF-8 string that looks like this (quotes not included):
1session=stable; secret_flag=; note=1
It then compresses that whole string with gzip and reports the compressed length in bytes. Knowing the structure above is important: your input is placed immediately after the secret flag in the same string, so well-chosen inputs can create repeated substrings that the compressor will exploit.

Practical solving strategy:
Confirm basic behavior: request /oracle?q=poctf%7B and compare the reported length to a random input like /oracle?q=xxxxxxxx. The prefix matching the flag format should typically compress at least as well (often better).
Reconstruct the flag left-to-right. Start with the known prefix poctf{. For each next character position, try all plausible candidate characters (for example: lowercase letters, digits, _{} and punctuation you expect), append each candidate to your current guess, call /oracle?q=, and record the returned compressed_len.
Select the candidate that yields the smallest compressed length; that candidate is the most likely correct next byte. Append it to your guess and repeat until you reach the closing brace }.
Be patient and polite — the server enforces a gentle rate limit.

Your Target: https://misc100-1.pointeroverflowctf.com

Key Points:


Misc 100-2 The Seven Year Itch

Desc

You’ll need two things to solve this challenge. Here is the flag. Everything after “poctf{uwsp_” is encrypted.

poctf{uwsp_r5mnwrf_35d_qb7_5qd}

To decrypt it, you need a letter and a number. To find the letter, just solve this nonogram:

COLUMNS (0..6):
0: 4
1: 1 1
2: 1 1
3: 1 1 1
4: 1 1 1
5: 1 1 1
6: 1 2

ROWS (1..7):
1: 5
2: 1 1
3: 1
4: 1 3
5: 1 1
6: 6
7: 0

To find the number, look up.

Once you have both, convert the key using the contest rules, and decrypt using standard Vignere rules.

Key Points:


Misc 100-3 Fools Rush In

Desc

image.png
The verse has been enciphered with a simple monoalphabetic substitution. Work the frequencies, hunt the short words and doubled letters. Restore the original text to reveal the message—and the flag within the plaintext. Convert it to the flag using the contest rules.
image.png
Flag format: poctf{uwsp_ _ _ _ }

Key Points:


Misc 100-4 Mason, Terror Incognita

Desc

lastwinterwhenthesnowwascominginsidewaysandmycousingeralddcidedhewastakingabreakfromtechnologywhichlastedthreehoursendingwhenhegoogledhowtotakeabreakfromtechnologywefoundourselvessittingatmygrandmothersdiningtablestaringatacardboardboxthatpromised1000piecesoftranquilcountrysideblissthepictureontheboxshowedacottagebyastreambirdsinflightadogthatlookedsuspiciouslyjudgmentalandcolorssoaggressivelyserenethatyoucouldalmosthearpanflutesweopeneditwithceremonyoutcameablizzardofirregularcardboardeachpieceshapedapparentlybyamaniacwithdullscissorsgeralddeclaredhimselfthecornerspecialistwhichturnedouttomeanhe’dfindonecornerholditaloftlikeexcaliburanthendisappearforcoffeehourspassedwefoundpiecesthatalmostfitthendidn’tthendefinitelydidifyoupushedhardenoughthedogsfaceappearedinfourdifferentplacesatoncemyauntsworethatthemanufacturerhadleftoutseveralkeybitsandreplacedthemwithpiecesfromanentirelydifferentpuzzleperhapshauntedshipwreckatdusksomewherearoundmidnightwerealizedwehadassembledeverythingexcepttheexactmiddlewhereasinglepiecewasmissingwecheckedthefloortheboxunderthecatinsidethecatsaccusatorystarenothingandinthatmomentsurroundedbyhalfdrunkteaandwhollydrunkrelativesiunderstoodthetruthwehadn’tbeenbuildinganimageatallwe’dbeenparticipatinginametaphorsomethingmeanttoconsumeeveningstestpatienceandrewardobsessionbydisappearingtheinstantitscompletesotellmetravelerofscatteredpieceswhatwasitweweretrulyputtingtogetherallalonganswerapuzzle

Right Click, Save As… Puzzling Challenge
MD5: E01C07B80FBFE4D1E5FC1A6268398C3A

Key Points:


Misc 200-1 Mason, In Light

Desc

Nothing beats a letter from a friend. Except a phone call from a friend. The only thing that beats that? Solving a puzzle. In this challenge the archive contains a voicemail and a letter. You’ll need one for the other, and you will decode a phrase. Convert that phrase using the contest character set, and you’ll have the flag.

Right Click, Save As… Hello, Operator.
MD5: 0AEB7346C22172243C816EF1C9CA64B3

Key Points:


Misc 200-2 Mouthful of Marbles

Desc

Hungry Hungry Hippos went digital, and someone left behind the game log. The hippos don’t just gobble marbles — their scores encode something more. If you can decode the frenzy, you’ll find the message. You have some plaintext to work with, so I’m sure you’ll figure out the rules to the game soon enough. You’ll need to convert the flag to leetspeak, and fill in the non-alpha characters yourself.

HINT
Don’t get distracted by the timestamps — the action is in the sequence of 0s and 1s. Think of each marble as one step in a coded message, and pay attention to how color plays into grouping. The line “you have some plaintext to work with” was your nudge: look for the expected POCTF{…} opening in the bitstream to confirm you’ve found the right mapping. This will give up the game: n=”A”(green)n=”Z”.

File: misc200-2.md

Key Points:


Misc 200-3 A Maze of Twisty Little Passages, All Different

Desc

A telemetry drone sent into the ruins beneath Knossos Station returned with its mapping feed corrupted. The only thing that survived is the movement log — a string of position updates, turns, and dead ends. Your task is to reconstruct what the drone saw and find the message hidden in its path.

File: labyrinth.log
Format: plain text telemetry.
Goal: interpret the path, reconstruct the maze layout, and read the word(s) it spells.

Flag format: poctf{uwsp_[THE HIDDEN MESSAGE]}

Key Points:


Misc 300-1 La Catedral

Desc

In this challenge, we’re looking for a sanctuary. Here’s a riddle to keep in mind: “The faithful gather where the map is false but the town is true.” Your job is to decode the tables to find out where you need to go.

Rules of the riddle:

  1. Each page is a truth table for one well-formed formula over four propositional variables A,B,C,D.
  2. Read the table in lexicographic order of inputs (A,B,C,D)from 0000 up to 1111 (i.e., Ais the MSB, Dthe LSB).
  3. For each row, write 1 for True, 0 for False in the output column. This gives you a 16-bit binary number.
  4. Convert that 16-bit number to hex (0–F). That is one character in the final string.
  5. Concatenate the hex digits from all pages to form a 32b hex string.
  6. Use the string to decode the ciphertext below
    key = hashlib.sha256(HEX.encode('ascii')).digest()
    ct = b32c_decode(CIPH)
    pt = bytes(b ^ key[i % len(key)] for i, b in enumerate(ct))
  7. The decoded text tells you what to search for and where. Don’t forget - around here, we always play on the unstable branch.
  8. Take the message from the sign outside and convert it to the flag format using the rules for the contest. Youve found the flag! But still no sledgehammer…

C: 73RP4R137EN86P4BGR84846G6N0F9Y28071Z3F6DCX4SY0W79JPKSXK2CRJNZFCM6ZPFTWTKF3FJGKQYJWP7QGZTP7E00

Legend:
¬ = NOT
∧ = AND
∨ = OR
⊕ = XOR
→ = NOR
↔ = XNOR
¬ > ∧ > ∨ > ⊕ > → > ↔

Truth Tables:
Page 1 “  “ F_1=(A↔B)⊕(C∧¬D)
Page 2 “  “ F_2=(A∨C)∧(¬B⊕D)
Page 3 “  “ F_3=(A→B)∧(C→D)
Page 4 “  “ F_4=(A∧¬B)∨(C↔D)
Page 5 “  “ F_5=(A⊕B⊕C⊕D)
Page 6 “  “ F_6=(A∧C)∨(¬A∧¬C∧D)
Page 7 “  “ F_7=(A↔¬C)∧(B∨D)
Page 8 “  “ F_8=(A→(B∧C))⊕D
Page 9 “  “ F_9=(¬A∧B)∨(C→D)
Page 10 F_10=(A∧B)∨(¬B∧C)∨(D∧¬A)
Page 11 F_11=(A⊕D)↔(B⊕C)
Page 12 F_12=(A∨B)∧(¬C∨D)
Page 13 F_13=(A→C)⊕(B→D)
Page 14 F_14=(¬A↔B)∧(¬C↔D)
Page 15 F_15=(A∧¬D)∨(B∧¬C)
Page 16 F_16=(A⊕B)⊕(¬C⊕D)
Page 17 F_17=(A∨¬D)∧(B↔C)
Page 18 F_18=(A→¬B)∨(C∧D)
Page 19 F_19=(¬A∧¬B)∨(C⊕D)
Page 20 F_20=(A↔C)∨(B∧¬D)
Page 21 F_21=(A∧B∧C)∨(¬A∧¬B∧D)
Page 22 F_22=(A⊕C)∧(¬B∨D)
Page 23 F_23=(A∨B∨C)∧(¬A∨¬B∨D)
Page 24 F_24=(A→D)∧(B→C)
Page 25 F_25=(A∧¬C)⊕(B∧D)
Page 26 F_26=(A∨¬B)↔(C∨D)
Page 27 F_27=(A∧D)∨(¬B∧¬C)
Page 28 F_28=(A⊕B⊕¬C)→D
Page 29 F_29=(A↔B)∧(¬C∨¬D)
Page 30 F_30=(A→B)↔(C→¬D)
Page 31 F_31=(¬A⊕¬B)∧(C⊕D)
Page 32 F_32=(A∨C)↔(B∨D)

Key Points:


Misc 300-2 Clockwork Angels

Desc

As an elective, I sometimes get to teach Game Hacking. It’s easily one of my favorite to teach. We get to do cool things and learn a little about secure coding practices, logic, and client/server security along the way. If you’re into this too then you’ve no doubt heard of Pwn Adventure 3. That’s and intentionally vulnerable game from 2015’s Ghost in the Shellcode CTF (and the inspiration for our game hacking category next year.) I have a series on YT running through it, but watch Live Overflow, he’s better.

Each year I teach it, I challenge myself to find a new way to solve each challenge. In that games there’s a puzzle that requires solving a 32b logic switch puzzle. The first year I mapped the logic gates out by hand in a spreadsheet. The second year I narrowed the key down to 16 bits and built a brute forcer. Third year, I used Z3 and THAT inspired this challenge.

In this challenge you’re given a system of constraints encoded for an SMT solver. Find any assignment that satisfies all constraints. The satisfying assignment encodes a 22-character plaintext. Convert the result to the flag by converting it using the contest rules.

Constraints make the game
MD5: 5C8BDEFEF7098A2B60C4AA6AD9578DB8

Key Points:


Misc 400 Digital Palimpsest

Desc

A palimpsest is a manuscript that’s been scraped and written over—but if you squnit you can see the old words come through. This is a digital version of that. Best as I could manage, anyway. You’re handed three raw device captures from a tiny lab array that was “updated” in a hurry. The drives were imaged after the update, not before. Let’s see if we can uncover some secrets, shall we?

If parity math left any ghosts behind, you should be able to resurrect the overwritten bytes.

  • Files: raid-d0.imgraid-d1.imgraid-d2.img
  • Level: RAID-5, 3 members, left-symmetric parity rotation (for stripe s: parity member p = s % 3; data members in logical order are (p+1)%3(p+2)%3)
  • Chunk size: 64 KiB
  • Images are raw stripes only (no partitions, no filesystem)
  • Some stripes are intentionally torn (inconsistent); the plaintext line does not appear contiguously in any single member file

Right Click, Save As…. misc400
MD5: A5D7E8D390224DDF2CFAF1192505A2F7

Key Points:


steganography

Stego 100-1 Ink Between the Lines

Desc

Sweet Gentlepersons, I have forsaken my life as a humble educator and have decided henceforth to become a bard. I am certain you will agree that I have what it takes when you witness my genius, thusly. Now, I am certain that you will doubt that it is my own creation. So, to eschew any accusations, I provide you a commemorative copy of this poem, secured and verified by digital means.

Right Click, Save As… What I Am Is Nothing
MD5: BE47BBFB8C2A51CECD8EB9F2F06FE99D
MD5 verifies the archive. File hash is inside.

Key Points:


Stego 100-2 The Quiet Part

Desc

Audio-based stego challenges have historically been pretty hard for contestants, but I confess that they’re also some of my favorites. In this case, I made a challenge where the flag is easy to find, but making sense of it might require some work. Since this is a 100-level challenge, I’ll lay it out for you and let you do the leg work.

This track has more than just left and right audio: there’s an extra, nearly silent voice. It doesn’t sing like the others. Instead, it flips itself backwards, whispering in two tones far above what human ears can catch. One tone means “0” and the other means “1.”

The timing of those whispers is very regular: each tiny piece of the message lasts about 0.06 seconds. The low whisper is around 18 kHz, the high whisper is around 19 kHz.

But even if you capture those bits, they won’t read as plain text. The message is locked. The key to open it is hiding in the obvious melody. Each note you hear can be turned into a number. Rebuild the bits at 48 kHz sample rate.

{'C':0,'C#':1,'Db':1,'D':2,'D#':3,'Eb':3,'E':4,'F':5,'F#':6,'Gb':6,'G':7,'G#':8,'Ab':8,'A':9,'A#':10,'Bb':10,'B':11}

So you use the loud part to decrypt the quiet part, which is backwards as all hidden messgaes in songs must be!

Right Click, Save As… Bleed the Stack
MD5: 959603433608F930D3D1650FF861BBFD

HINT
I’ve bundled up a function to provide the keystream, and some pseudocode to assist. Extract Note
video explaining the process of extracting the ciphertext and key.
Additional details on decrypting: Cipher is CTR with SHA-256 blocks, i.e. Keystream block = SHA256( key || counter ). Counter is 8-byte big-endian, starting at 0, incrementing by 1 per 32-byte block. Decrypt: plaintext_with_crc = ciphertext XOR keystream. Split: the last 2 bytes are CRC-16/X.25 (binascii.crc_hqx) of the plaintext. Validate: MAGIC must be QUIET1 Length field must match the decrypted plaintext length. CRC must pass. Then UTF-8 decode the plaintext → your flag.
Prior hint: You were told “there’s an extra, nearly silent voice… it flips itself backwards… two tones far above what human ears can catch.” That’s your roadmap: isolate the extra channel, reverse it, and look above 18 kHz for a two-tone binary. If your bits look random, revisit the 0.06 s symbol timing at 48 kHz. If you don’t see a message immediately, you may be decoding the right tones in the wrong direction. The line “the quiet part is backwards as all hidden messages in songs must be!” was the breadcrumb to reverse only the quiet channel before FSK demod. Expect a preamble and length to sanity-check your bitstream. Don’t overthink the music theory. The key isn’t about octaves or durations, only which note name class is being played. Collapse runs of the same pitch class so a string of repeated notes doesn’t skew your key. The result is a simple sequence like [E, G#, B, E] → [4, 8, 11, 4]. That’s the input to the hash that unlocks the hidden bits.If your derived key changes with tiny window tweaks, you’re keeping too much information. Reduce it to distinct pitch classes in order of appearance, then hash. The challenge text even gave you the mapping table — use that to snap messy frequencies to the nearest pitch class.

Key Points:


Stego 100-3 Low Tide at Midnight

Desc

In the 2023 contest, we had a stego challenge that utilized an image from Jeff Lee Johnson called “Blue Plate Special.” Well, this year we couldn’t resist adding some of the Missouri illustrators new work. The trick with this one might be finding a clear way to extract the flag, but if you know then you know.

MD5: 03C3786822F0F73AC98D4544DC838C93

Key Points:


Stego 100-4 Ways and Means

Desc

MD5: 4A4AE54B310DCC45F10FF2A27BC0BAFE

The expression “putting a hat on a hat” comes to mind.

Key Points:


Stego 200-1 Needle in the Chorus

Desc

Here we have a lovely piece of music. I didn’t bother to write lyrics, but that doesn’t mean it doesn’t say anything. The flag is hidden in the notes if you can work out how to decode it.

MD5: 5ACF51FCBAF8B86A7BB4B5F78595B7A5

Key Points:


Stego 200-2 Through the Looking Glass

Desc

How about a little classic Stego? It doesn’t get much more old school than this. Remember: It’s not a schooner, it’s a sailboat!

Right Click, Save As… stego200-2.zip
MD5: 97EA6DBEA286506DCEF96C4E3D2C4082

Key Points:


Stego 200-3 Dead Letter Office

Desc

💞: 🥺📱❓💬💬
🤓💻: 😭🔒💀💥 doing 🧩🌀 (stego) rn 😩🧠🔥
💞: 🤔❓misc?? 😭🫠
🤓💻: 💀🎲 could b 🖼️🔍🎧📂📜 anything 😭😭😭
💞: 😩👉💔💅 me > ur puzzle 😤
🤓💻: 🙏😭 need 🏁 flag 🏃💨 hidden 📸🗂️🔡🕵️
💞: 🥹📸👀 u miss me 😔
🤓💻: after 🔍4000 🧾🧾🧾 hex lines 😭
💞: 😭 ur dating 👧 not 🧮🔢
🤓💻: but 👧 could b 🗜️➡️🗜️➡️🎵😳
💞: 😭😭😭 insane
🤓💻: 😎🏁💪 hero mode soon
💞: 🚩🚩🚩😤
🤓💻: 😭5️⃣🕒 more mins pls, found 🔠85️⃣ in 🖼️📄
💞: 😡⌛ till 🌙🕛 or 💣🧱 ur 🐋📦
🤓💻: 😨 u wouldn’t
💞: 😘 try me

File: stego200-3.png

Key Points:


Key Points:

Stego 300-1 Ouroboros

Desc

🧑‍💻📸➡️👀
🧑‍💻📂🔒😏
👀🕵️‍♂️💾🎉
MD5: A05595286E4795639376650A212EBFD8

Key Points:


Stego 300-2 Blind Man’s Bluff

Desc

I am so excited for this challenge. I have been trying to figure out a way to make this challenge work since POCTF 2022, and I finally got it working for you this year.

The original idea was to use an Ishihara chart somehow. You know, the ones they use to test for color blindness? Except then there’s the accessiblity question. It would be easily readable to most people, but if you’re colorblind it’s a hundred times more difficult. Nort very fair. So, how to overcome that? We’ll just make it invisible to everyone, of course! Let’s give everyone a taste of what it’s like to be colorblind. It’s an important lesson because it’s our differences that seem most significant, but when we average it all out we’re all the same after all. Just more standard deviance in the POCTF!

Key Points:


Stego 400 The Weight of Silence

Desc

I have a confession to make… I phoned in this wave. It’s not that I didn’t want to have a good challenge for Stego 400, but I’ve just been so busy working on this other project. See, cybersecurity is nice and all, but what I -really- want to do is something creative. If you haven’t noticed - Cinema is a theme of this year’s contest, and nothing stirs me like a little kino. So, I decided to make my own film. Please accept it in lieu of a Stego 400 challenge. It’s a cool little sci-fi western.

Now Playing: The Weight of Silence
Here’s a copy for yourselves, since I know you’ll want to add it to your collection and we do NOT condone piracy here are POCTF HQ.
MD5: F090847466693BEA534C4C4F68556887

Key Points:


forensics

Forensics 100-1 Breadcrumbs and Coffee

Desc

This challenge takes a few browser artifacts and leads you to the flag. The file below doesn’t contain the flag itself, but it will tell you all you need to find it.

Right Click, Save As… For100-1
MD5: 29B90DBE425F3F4CDEE58615913380E0

Alternate Link - Forensic Challenges

Key Points:


Forensics 100-2 The Night Shift

Desc

As a private lab in a small town, the digital forensics lab at UWSP mostly does data recovery services. It’s great to be able to help the community recover their lost photos and documents. Now is your chance to help me recover mine. This archive contains some media files. Some of them are broken in more ways than one. Pull the flag out of the corrupted data for the flag.

Right Click, Save As… for100-2
MD5: C5D237F8FE362A23D41450AFCCF5F782

Key Points:


Forensics 100-3 Mason, Nadir

Desc

Network forensics became a lot more difficult when secure protocols became the norm. Not that I’m complaining - it’s a good problem to have for day-to-day issues. It just so happens that some areas under Information Assurance are actually at odds with each other. As security improves, things like operations and forensics becomes more complicated. My opinion: There is a clear imperative. We have to just evolve with the times. But you won’t in this challenge, because none of that is a concern for you!

for100-3.pcap
MD5: 5FC2F45684909E0BFEDE96C6231BA192

Key Points:


Forensics 100-4 Trace Elements

Desc

Persisitance is the key with this one.

OneDrive: for100-4 - one archive
OneDrive: for100-4 - part files MD5: 1638BAB86168F2F756C6029DA307EDB5

Key Points:


Forensics 200-1 Dust in the Attic

Desc

I spent some time cleaning out the attic last spring. Long overdue. I took a few pictures while I was up there. I’ve been looking for an excuse to use the camera more. Hope you like them!

Right Click, Save As… Say Cheese.
MD5: 6B0A0B493E2E0EA0D14C52DEF6092DEB

Key Points:


Forensics 200-2 Wintermute

Desc

A simple memory forensics challenge for you. In this case, a file was created and named with the flag just prior to capture. A quick peak with the right tool will get you the flag.

Drive Link: FOR200-2.7z
Alternate Link
MD5: 84A610F9CD12B9DA57FEDCA68C93741B

Key Points:


Forensics 200-3 The Banshees of Inisherin

Desc

A small publishing shop containerized a one-off utility called “banshee,” pushed a hotfix, and swore the secret was removed. The team pruned the container, rotated some logs, and moved on. Your job is to prove whether the secret ever truly left the system. .

You should assume normal Ubuntu-like defaults and a standard Docker CE install.

Right Click, Save As… Maybe He Just Don’t Like You No More?
MD5: C5C0F049D661984E839A4551691341C8

Key Points:


Forensics 300-1 Built Up in my Head

Desc

One of the thing I impress upon my students in Digital Forensics is the importance of observing investigative leads in addition to the evidence present. External connections, errant devices, potential accompilices, etc. Well, in this case you’ll get to look into one of the classic cases of evidence that is known to exist on another device thanks to artifacts on another.

For300-1.7z
MD5: A2A804348FB95A50437F1A5C3132DF28

Key Points:


Forensics 300-2 The Sound and the Fury

Desc

This challenge is a bit of a trial run. I had an idea this summer for a live forensics challenge using a running client. Well, here it is. The link below will get you a client. The flag is not in the client itself, but when you run it, it’ll fetch the flag and load it into memory. A debugger or live memory forensics will get to it.

Right Click, Save As… for300-2 Client
MD5: F0B11F85421593F99F3D188FF02208DA

Key Points:


Forensics 400 Storm Over the Prairie

Desc

A severe thunderstorm ripped through a small research station on the prairie last spring. Equipment was damaged, a field laptop was recovered from the wreckage, and one external drive was found half-buried in mud. The remaining data was extracted and added to a VeraCrypt container for preservation. The password is for400.

The flag will be split into multiple parts. Happy hunting.

for400
MD5: A11791589A5FDE173BAE3F5CB2109CE6
Alternate Link

Key Points:


osint

OSINT 100-1 Postcards from the Underground

Desc

One of the things I love most about our age are the endless rabbit holes you can go down that people in the past could only wonder about. Take the photo below, for example.
image.png
Your target is clearly labelled. I wonder - can you tell me who was their internet service provider? If you can, that’s your flag after converting it to the proper format. And we are looking for the full name, not the acronym.

poctf{uwsp_ _ _ _ _ _ }

MD5: 33FB2D694B51A504D7CFF475BB6D461A

A HINT has been added to this challenge:
“Your target is clearly labelled.”
image.png

If you do a search you’ll see they’re no longer in business. That’s a shame, but then again, so is their ISP.

Sometimes being a tech-savvy masterhacker has drawbacks. Like, you forget how the laypeople regard technology. To them, Internet service is a ultity, like power or water. And they know how it works as much as those utilitites. Flip a switch, turn a knob, and it works. To most people “The Internet” is the little icon on their desktop that launches Edge. This has always been the case, and that’s why ISPs have always offered “all-in-one” services. Not just a route out to the Internet, but common services like email. While most folks are rolling with their yandex, gmail and hotmail mailboxes, you KNOW you’re dealing with a layperson when you find a @charter.net, @tds.net, @att.net, @comcast.net… Wow, look at the those TLDs. .NET? Is that legal? If you know the history of the Internet, then you know that the .net TLD was originally delegated to infrastructure organizations. Like ISPs.

Key Points:


OSINT 100-2 Room with a View

Desc

I think that one of the most interesting aspects of humanity is our diverse attitudes about death. Common responses are fear and addness, but that’s not always true. Some regard it with awe, wonder, or even joy. On the other hand, it does no good to dwell. Life is for living, after all. Gallows humor is a common way to cope, as our subject today shows. Below is a car. The person driving it is the leader of a very unusual club. If you can find the name of the club, convert it to the flag using the mapping in the contest rules and submit it.

poctf{uwsp_ _ _ }
image.png
MD5: D7AE38C46E5F6D60F203DD7D3DDCBF6C

Key Points:


OSINT 100-3 Not My First Rodeo

Desc

I met a traveller from an antique land,
Who said—“Two vast and trunkless legs of stone
Stand in the desert. . . . Near them, on the sand,
Half sunk a shattered visage lies, whose frown,
And wrinkled lip, and sneer of cold command,
Tell that its sculptor well those passions read
Which yet survive, stamped on these lifeless things,
The hand that mocked them, and the heart that fed;
And on the pedestal, these words appear:
My name is Ozymandias, King of Kings;
Look on my Works, ye Mighty, and despair!”
Nothing beside remains. Round the decay
Of that colossal Wreck, boundless and bare
The lone and level sands stretch far away.

Find this place, and go back into its history. We are now closer to its end than its beginning, but this place began with a discovery, and the person that made that discovery is quoted as saying something. The flag is that quote, converted using the rules of the contest.

Key Points:


OSINT 100-4 Be Quiet and Drive

Desc

First step - Find the woman of the west in the car that is both Italian and American. You’ll find her in her best nightgown, resting “with the seats slanted comfortably.”

Next step - In that same place is another famous female free-spirit. Find her, but we aren’t here to discuss her death, but to trace her life. You know you did it right when there are multiple plaques commemorating you.

This woman lived an amazing life that touched many others. One of those plaques will tell you where she lived. Looks like the current resident is about to have a party in early November! The dress code isn’t just necessary for the party, but good advice for life. It is also the flag. Leave out the punctuation. Convert it to the flag format according to the contest rules.

poctf{uwsp_ _ _ _ _ }

Key Points:


OSINT 200-1 The Paper Trail

Desc

I’m really pleased with this challenge. The people involved here seem like genuinely nice people, and I was glad to do a little peaking at the public records they’ve left behind. First, the image below was posted to Reddit about eight years ago. Find out where it was taken.

Near that location is a small town. That town has a high school. That high school has yearbooks. You will locate the 1940 yearbook, and find a Senior with the first name that matches the photogapher of the image above. His quote, found on the page with his school photo, is your flag once you convert it using the alphabet in the rules.

Key Points:


OSINT 200-2 The Choir and the Crypt

Desc

Boy… These OSINT challenges are mighty morbid this year. Wonder what’s up with that?

How about an uplifitng tune? Unfortunately, the artist singing this song is no longer with us. At least she has a very nice epitaph on her marker. Call me a patsy, but I’m inclined to take a look. Find her, find the epitaph, and convert it to the flag using the contest rules.

Right Click, Save As… It’s Not Crazy
MD5: 0A99885D9F4B46DAE0BB8B563063877C

Key Points:


OSINT 200-3 A Whispered Name

Desc

We’re not done with the morbid OSINT challenges yet (i’m fine. lol.)

Here at the POCTF HQ, we have laws to follow. One of those: A challenge should not require solving another challenge to complete. Today, we’re breaking the law. In a previous challenge, I asked you to find the quote from a student in a yearbook from 1940. You’re going to start with that man.

The subject in question lived and died near that small town. An obituary marks his passing many years ago. It seems our subject was the member of a certain club (NOT the Cool Kids Club for Cool Kids. These people WISH they were that cool.) Identify that club.

Look through this club’s photos and you’ll find a donation from a previous member who was iniated to the club in 1896!

This member had a car before he passed away. Your flag is the slogan at the top of the advertisement for that car, which was published in the April 4th, 1932 edition of Time Magazine. No punctuation, and convert it to the flag using the alphabet in the contest rules.

Key Points:


OSINT 300-1 Map of Uncharted Waters

Desc

Today you’re going on an adventure across the high seas. It’s actually kind of a fairy tale, so let’s do it right… Once upon a time, there was a group of wealthy investors that dreamed of creating their very own paradise. They travelled to the lands of the Thai. At 7°29’22.2”N 98°34’48.6”E, to be exact. Except they were banished. So they tried again. They bought a ship and decided to forever sail the seas. Except that failed, too. The moral of the story: Money might buy many things, but it can’t buy sovereignty. Yet. The ship is your target. The flag is the ships original name. Convert it to the format specified in the contest rules.

Key Points:


OSINT 300-2 Salt in the Earth

Desc

This challenge is deceptively maddening. Below is a shipwreck. The flag is the name of that ship. When I first saw it, I thought it would be easy, but I found it to be quite difficult in practice. Let’s see if you can match it:

Key Points:


OSINT 400 Behave, Ye Strangers

Desc

Last year we ended on OSINT 400. This year we begin with it. Those contest-wide shenanigans were a lot of fun for Prof. Johnson last year, but this year will be different. We promise. Prof. Johnson is on his meds and playing nice with others. We set him up in front of the TV watching films all summer long and he hasn’t thrown a single tantrum. It’s pretty great, other than the drooling. Let’s get things started, shall we?

Song. Movie (98). Doctor. Patient. Book (00). Cover. Movie (62). Director. Death. Go to the sixth floor loft. The resident once had a stack of books on the radiator. The flag is the title of the book that was third from the bottom in that stack. Convert it using the character set for the contest.

Key Points:


web

Web 100-1 All Paths Lead Home

Desc

A simple little challenge to start off the Web category. We have a site here that will read the contents of a text file hosted on the server. Unfortunately, there’s also a file in /secret/ that you’re not supposed to see. All you have to do is work out how to get there. There is one little twist, but I’ve left plenty of clues on that.

Your Target: Web 100-1

Key Points:


Web 100-2 This Must Be the Place

Desc

A naïve developer tried to be helpful and filtered out a few characters — but filters are not enough. Find a way to get the site to run JavaScript in your browser and use it to read the flag. The flag is only available via a same-origin fetch to /flag.

Your Target: Web100-2

Key Points:


Web 100-3 Mason, Initiate

Desc

This challenge is a very bad idea! Prof. Johnson had a little idea to host a SSRF challenge up in GCP, and let’s just say he encountered some interesting information in testing. We considered replacing it with another challenge, but anything worth doing is worth doing wrong! Just make sure you stick to the scope on this one or Google is going to zap us all from space with their Orbital HR Compliance Laser, which was developed by a smaller team in 2008 for the purpose of clearing varmints from 3rd world farmer’s fields but was acquired by Google and shelved for a few years (support ends in 2027, better find a new provider for your Space Laser Death Ray needs!)

Wait… Where am I, again? Oh, right…
Your goal: Exploit a classic Server-Side Request Forgery (SSRF) in the image fetcher to reach an internal metadata service that is only reachable from the server itself.

Important:

  1. The simulation will use AWS-style layout to avoid any “oopsies” when working through this. 2) The image fetcher makes the HTTP request server-side.
  2. Some internal endpoints are not directly reachable from your browser, but they are reachable from the server.
  3. Somewhere in that internal space is a metadata-style endpoint that returns JSON. One of the fields contains the flag. The internal metadata endpoint is loopback-only ang listens on 8081.
  4. You’ll know you have it when the response includes a JSON object with a token-like value. Submit that value as the flag.

SCOPE:

  • Only interact with the challenge service at web100-3.pointeroverflowctf.com.
  • Use the provided “fetch by URL” functionality to pivot the server to internal resources.
  • No need for brute force, fuzzers, or long scans. This is a surgical SSRF.

NOT IN SCOPE:
DO NOT attack the infrastructure, proxies, or unrelated hosts.
DO NOT attempt to access real cloud provider metadata for the platform; the challenge runs with a self-contained mock designed for safe play.
NO denial-of-service or automated high-rate scanning.

Your target: web100-3.pointeroverflowctf.com

Key Points:


Web 100-4 Redirection Junction

Desc

The premise here is a little URL shortener that’s a touch too eager to help. Every link hands you off to another link, and another, and another. But often not the same way or under the same conditions. Your task is straightforward: follow the chain until you reach the final page and read the flag. The site will only reveal the flag when you arrive by the correct route.

Use your browser’s developer tools and inspect response bodies as well as headers. Simple text decoders (Base64, hex) and careful treatment of cookies and Referer headers are the intended tools.

Your target: https://web100-4.pointeroverflowctf.com
Good luck — follow the breadcrumbs, not just the Location header.

Update:

  1. Not every step is a 30x response. Open developer tools and watch requests and responses: meta refreshes and tiny inline scripts may contain the next target inside the page body.

  2. If you see a long, non-alphanumeric string in a page, try decoding it. A first pass with ordinary Base64 or URL-safe Base64 will often expose the next path component. Also preserve cookies between requests — one intermediate step will set a cookie you must carry forward.

When automating, either emulate what a browser sends or replay the browser’s artifacts: fetch intermediate HTML, decode client-side redirects yourself, and send the appropriate Referer header and cookies on subsequent requests. Simply using curl -L without decoding meta/js steps or without preserving Referer/cookies will not always reach the final page.

Key Points:


Web 200-1 What’s Mine is Yours

Desc

The Palantír “Community Accounts” portal uses cross-origin previews for partner integrations. Their devs say CORS is “locked down,” but some origins seem to get special treatment.

Your goal: from your own origin, exfiltrate a session-scoped token from the target and use it to obtain the flag. Send using X-Flag-Token: (apiToken)

Your Target: https://web200-1.pointeroverflowctf.com/
The flag endpoint is /api/flag
You must not brute force or DOS. A single honest user session is enough.

Key Points:


Web 200-2 The Gift Horse

Desc

THE INJUSTICE!!

Did you see how YouTube banned the POCTF account not long ago?? Outrageous! Nasty! Bigly rude! You know, one time I had a student ask me - big student, strong student, tears in his eyes, and he said to me SIR! You are the best professor probably some people think in the history of schools. YOU should start your own YouTube so those Lying Liberal Fake News Journalists can’t use the platform against you.

So I did. I bring you: TRUTH VIDEO!!!!

It is the ONLY way for TRUE PATRIOTS to upload and share videos in a way that is MORE TRUE and ABSOLUTELY SECURE!!!! Try it for yourself. The best part is that there is an AMERICAN (‘FLAG’) variable on the box!!!!!

Your target: aNd ThE tRuTh ShAlL sEt YoU fReE

THANK YOU FOR YOUR ATTENTION TO THIS MATTER!!!!!!

Key Points:


Web 200-3 Chiaroscuro

Desc

Welcome to the Conservation Studio. This experimental viewer reproduces how works look in everyday display and how they appear under archival restoration. The studio includes a curator pipeline intended for conservators use the preview controls to compare modes.

Your Target: web200-3

Key Points:


Web 300-1 Friend of a Friend

Desc

For this challenge we have a simulated web app in development. In fact, two web apps that share the same auth server. One is a “friends/profile” client, the other guards an admin API. Somewhere, scopes aren’t enforced correctly, and there’s a leak. Your goal is to obtain the flag from the admin API.

Some features you can test:
GET /health → ok
GET / → overview page that should provide all the information you need on the features of the app.

Your Target: Pure Morning

Key Points:


Web 300-2 The Shape of Water

Desc

The Lacustrine Conservancy is a small aquarium and watershed education non-profit. Their developers built a preview service to test theme settings and publish monthly newsletters. Unfortunately, they didn’t pay much attention to how configuration data is handled during the build process. You’ve been asked to conduct a security assessment. The server merges user-supplied JSON into its global configuration and then uses that configuration during the newsletter build.

Endpoints
POST /api/settings — submit JSON to merge into the server’s configuration.
GET /api/build — generates the current newsletter preview (and processes configuration).
GET /api/debug/cfg — shows the current configuration’s own properties.
GET /api/logs — shows build and settings logs.
POST /api/reset — clears current settings and logs.
GET /api/version — returns version information.
Static files are served from /public (e.g., GET /newsletter.html).

Retrieve the contents of /flag.txt from the server. You cannot fetch it directly — you’ll need to figure out how to influence the build process to make it accessible.

Your Target: Après Nous, le Déluge
DNS may not be available for this instance. If the challenge hostname does not resolve, use the public IP 34.9.14.80 and send the Host header web300-2.pointeroverflowctf.com.

Key Points:


Web 400 Mouth of Sauron

Desc

Welcome to the Palantír Press Office — All-Seeing Eye Community Showcase!

We curate community artwork and generate magazine-quality thumbnails from submitted SVG files. For editorial fidelity we preserve many vector primitives — including filters — while removing scripting and obvious executable content.

Guidelines:
Allowed format: SVG only (≤ 512 KB)
Thumbnails: server-side rendered to 900×600 PNG (may include a faint watermark)
Privacy: Submissions are private by default. After upload you are redirected to an asset page: /asset/?t= — that token is the only way to view your rendered asset.
Compatibility: The renderer preserves filter primitives (e.g. , , ). Visual effects that use filters may still render in the thumbnail.

The target & source of truth:
Internal design/asset host (only accessible from the renderer): barad-dur:31337
Flag image (internal): /flag.png on that host.
Flag format: poctf{…} — the flag is rendered into this PNG.
Important: You cannot reach barad-dur directly from your own browser — only the server-side renderer can.

Your Target: Web400

Key Points: