Dylan's Blog

2022 Flare-On 9 Challenge 2: Pixel Poker

Category: CTF

Challenge 2 - Pixel Poker

Description

I said you wouldn’t win that last one. I lied. The last challenge was basically a captcha. Now the real work begins. Shall we play another game?

Download (password: flare) - 02_PixelPoker.7z

Contents

Tools Used

Solution

Intro

In this challenge, we’re given two files:

readme.txt has the following text:

Welcome to PixelPoker ^_^, the pixel game that’s sweeping the nation!

Your goal is simple: find the correct pixel and click it

Good luck!

Sounds pretty straight forward, let’s see.

Initial Analysis

Running the exe brings up the following window, we have 10 tries to click on the right pixel. The coordinates of the pixel we hover over is shown in the title bar along with the number of tries taken.

Gamescreen

Failing to click the right pixel in 10 clicks, gives the following game over message and quits the game.

Gameover

Finding Bitmaps

Opening the file in CFF Explorer, we find 2 bitmaps, 129.bmp and 133.bmp under Resources.

CFF Explorer

XOR Time

Whenever we come across two images in a CTF that look like noise, we should always try to XOR them together.

First, I extract the images from the exe with the following:

7z x PixelPoker.exe .rsrc/ICON

Next, I use some ImageMagick magic to do the XOR:

convert 129.bmp 133.bmp -fx "(((255*u)&(255*(1-v)))|((255*(1-u))&(255*v)))/255" output

Credits to this answer on Stack Overflow for the ImageMagick one-liner and this answer on Unix Stack Exchange for extracting the images.

Flag

Luckily our hunch was correct and the final image contains the flag. I’m guessing this worked because both images were encrypted with the same key.

Flag

Flag: w1nN3r_W!NneR_cHick3n_d1nNer@flare-on.com

Alternate Solution

I feel like I cheated on this challenge, so I decided to revist it and try actually reversing.

Static Analysis

Opening up the binary in Ghidra, we can search for the Game Over string Womp womp... :(, Please play again!. This string is used once in the following code:

Pixel Check

This code looks interesting, so let’s dive into the decompiled code and get an idea of what it’s doing.

Decompiled Code

The program first checks if we used up all 10 tries and if we did, displays the Game Over message and quits. Otherwise, it increments the counter and then checks to see if uVar8 and uVar6 are equal to some computed values. (I’m guessing that this is where it checks to see if we selected the right pixel).

Dynamic Analysis

Instead of trying to figure out the exact coordinates, I decide to just patch the jumps after each comparison that checks the coordinates.

The two jumps I’m interested in patching are the JNZ shown below.

Jumps

We open the binary in x64dbg and flip the jumps at addresses 00401486 and 0040149D, changing them from JNE -> JE. (Quick note, x64dbg shows the JNZ as JNE, but as far as we’re concerned, they’re the same.)

Patched Binary

Now we can click any pixel and it should give us the flag.

Clean Flag