Dylan's Blog

2020 Flare-On Challenge 3 Writeup: Wednesday

Category: CTF

Challenge 3 - Wednesday

Description

Be the wednesday. Unlike challenge 1, you probably won’t be able to beat this game the old fashined way. Read the README.txt file, it is very important.

Download - wednesday.7z

Contents

Tools Used

Solution

Intro

tl;dr: Patch the collision detection and let the game run.

The challenge zip contains a bunch of DLL’s, a data folder with subfolders that contain files related to fonts, grpahics, and music. We’re also provided a README.txt and the challenge executable, mydude.exe. I check out the README.txt since the description mentions it.

README

The README tells us to “BE THE WEDNESDAY” and an odd piece of text, “S M T DUDE T F S”. (More on this later).

So it looks like I just have to focus on mydude.exe and not worry about all the other files.

Initial Analysis

Running mydude.exe brings us to a start screen with basic controls. Clicking DUDE starts the game.

StartScreen

Gameplay

After playing the game for a bit, I found that just dodging the blocks isn’t enough, you need to either duck or jump, depending on the label of the blocks. I’ve labelled the different blocks and the correct moves below:

You might have noticed the pattern here and also from the odd text in the README, the frog is the “Wednesday” and the block represent the days of the week, so we just need to ensure “Wednesday” is in the correct position, as described by the blocks. (Ducking under Sunday, Monday, Tuesday and Jumping over Thursday, Friday, Saturday.)

Taking a look at the graphics folder also gives us hints to the correct moves, given by the file names for the different block PNGs. (down_0, down_1, up_0, up_1, etc.)

GraphicsAssets

Exploring in Ghidra

Feeling satisfied with my initial analysis, I open the file in Ghidra to see if I can find the score required to win the game. After some digging, I come across the following snippet:

  if ((piVar2 != (int *)0x0) && (*piVar2 == 0x128)) {
    @sceneeq___HC7o4hYar8OQigU09cNyehg@8
              (_game__7aozTrKmb7lwLeRmW9a9cs9cQ,_winScene__eVaCVkG1QBiYVChMxpMGBQ);
  }

Here I assume piVar2 is the current score and it needs to equal 0x128 or 296 to set the “winScene”.

At this point I decide to patch the collision detection.

Patching Collision Detection

After more digging, I found where the ducking collision detection happens. I simply patch the assembly and changed JS to JMP, doing this allows you to run through blocks that you would normally have to duck under.

PrePatchDuckCollision
Unpatched ducking collision

PostPatchDuckCollision
Patched ducking collision

Once patched, I save the patched binary and run the game, confirming that I can successfully run through blocks that I would normally have to duck under and still have my score increment.

I repeat this process for patching the jumping collision detection. Here I patched JZ to JNZ, allowing you to run through blocks that you’d have to jump over.

PostPatchJumpCollision
Patched jumping collision

Saving the fully patched binary, I run the patched-binary and wait until the score hits 296.

Flag

Once the score hits 296, the win screen is displayed, along with the flag.

Flag

Flag: 1t_i5_wEdn3sd4y_mY_Dud3s@flare-on.com