Writeup: I Want Pie 🩸 (NahamCon CTF 2025)
Writeup: I Want Pie 🩸 (NahamCon CTF 2025)
The NahamCon CTF 2025 has wrapped up, and honestly, it was a super interesting and fun experience. We tackled some technical challenges, but this one stood out because I managed to solve it first and got the First Blood.
It was a MISC challenge, Medium difficulty, and I’ll quickly walk you through how I solved it.
Challenge Overview
As soon as you landed on the page, you got the classic CTF home template vibe. But there was also a little poem that definitely hinted at what we had to do next:
1 | If I eat one more piece of pie, I'll die! |
Initial Analysis
1. While inspecting the page, I spotted a few key details
The clever wordplay in “pie(t)”
The very specific line: As long executing that piece of pie prints out
flag, oh my
2. In the HTML source code
- The hint “print ascii… probably” in the animated text:
1 | <span class="typed" data-typed-items="print ascii... probably"></span> |
- The reference to “most colorful pie” in the paragraph:
1 | <p>Mmmmm does my CPU ever like pie. And with the most colorful pie, we can...</p> |
- The upload form accepted .png images only:
1 | <form action="/run" method="post" class="php-email-form"> |
All these clues pointed me straight to a programming language called PIET.
What is PIET?
Piet is an esoteric programming language where programs are represented as “bitmaps” — images, basically. It’s a wild mix of art and code.
One of its quirks is that it only uses 20 specific colors, and the execution flows based on how the brightness and hue change between color blocks.
Basically, the “CPU eats the image like pie,” which ties directly back to the name of the challenge: I Want Pie.
For more info: https://en.wikipedia.org/wiki/Piet_(programming_language)
Solving the Challenge
1️⃣ First attempt: a basic .png file
When you see an upload form, your mind races with possibilities. But the key was to figure out how it actually worked. So I just uploaded a sample.png and got this response:
1 | Error: This is prooobably not pie my CPU can eat. I like ppm pie. |
That’s when I realized that the server didn’t want a PNG file at all — it was expecting a PPM file, not PNG like I initially thought.
2️⃣ Second attempt: converting to PPM
On my second try, I converted my PNG to PPM using an online converter. But that just gave me another error:
1 | 500 INTERNAL SERVER ERROR |
At that point, it was clear: my Piet program wasn’t valid. I needed to find a real, working Piet code.
3️⃣ Finding valid examples
I started digging for functional Piet examples. I found this awesome gallery:
https://www.bertnase.de/npiet/picture.html
I grabbed a “Hello World” program that actually worked, and when I uploaded it to the challenge, I got:
1 | Executing bytes, stdout: Hello, world! |
Nice! All that was left was to tweak it to print something that would actually get me the flag.
4️⃣ Using an automatic Piet generator
After wasting some time on random online editors, I knew I needed to automate it. I found an old GitHub repo from about 9 years ago. Shoutout and link: https://github.com/sebbeobe/piet_message_generator
This Python script takes any text input and spits out Piet code that prints it. Fun fact: if the input is short enough, it even makes a picture of Platon reading a book about Piet.
1 | git clone https://github.com/sebbeobe/piet_message_generator.git |
5️⃣ Cracking the challenge by going back to the poem
Like with any challenge, I tried a bunch of stuff, but here it was all about paying attention and going back to the start. Even though the poem said “prints out flag, oh my
“, it wasn’t instantly obvious that this exact phrase was the only valid output.
I only confirmed it when I uploaded the “Hello, world!” Piet and saw it worked but didn’t give me the flag. That’s when I realized the server was comparing the program’s output directly to “flag, oh my”. So if I wanted the challenge to give me the flag, I had to make a Piet program that printed exactly that, with no extra characters.
And sure enough, that’s where the script I found earlier came in handy. After generating a new image with piet_gen.py that printed flag, oh my
, I uploaded it and snagged the flag.. along with the First Blood: