Plaid CTF 2018 - Plaid Adventures

Toshi Piazza

Challenge description:

It is pitch black.

You are likely to be eaten by a grue.

Hint: “You can find the yellow orb in the maze.”

Introduction

This was a (reasonably) fun challenge from Plaid CTF this year, and one of the only reversing challenges I got to do. Unfortunately we solved this challenge posthumously, and only solved it after we were given a hint on IRC after the CTF had ended.

First things first, the program files comprised a web-based interface for a MUD-type game. The game is surprisingly simple; we need to:

  1. Collect 4 colored orbs
  2. Collect the silver key
  3. Unlock a door
  4. Insert the 4 orbs into a statue

Afterwards we can touch each orb; after 48 tries a message pops up:o

The orbs darken for a second. It seems like the code wasn't accepted.

Looks like we need to touch the orbs in a certain order in order to get the flag.

Analysis

Digging through the program files, we notice a Plaid Adventure.gblorb file, which is of a known file format to file:

$ file Release/Plaid\ Adventure.gblorb 
Release/Plaid Adventure.gblorb: IFF data, Blorb Interactive Fiction with executable chunk

This is a well-known file format which contains bytecode commonly used for implementing games; the bytecode is for the glulx virtual machine. A decompiler for this file format can be found here.

The important bits we decompiled and subsequently cleaned up are shown below:

[ routine53995 local0 ;
  ...
    if (routine146071(10,local0,269) == 1) {
        TouchSphere(465371-->counter,0);
    }
    if (routine146071(10,local0,269) == 2) {
        TouchSphere(465371-->counter,1);
    }
    if (routine146071(10,local0,269) == 3) {
        TouchSphere(465371-->counter,2);
    }
    if (routine146071(10,local0,269) == 4) {
        TouchSphere(465371-->counter,3);
    }
    465371-->counter = 465371-->counter + 1;
    if (465371-->counter == 48) {
        if (CheckSpheres() == 1) {
            ...
            PrintFlag();
            ...
        } else {
            ...
        }
    }
    ...
    return 0;
];

[ TouchSphere …
...Read more

34C3CTF vim

Lense

Challenge description

Category: rev
Points: 215 (dynamic, calculated from solves)
Solves: 18

This is not compatible with emacs!

Tested with vim 7.4 on amd64 Ubuntu 16.04 (package vim 2:7.4.1689-3ubuntu1.2)

Difficulty: Easy

Preface

There are a lot of words here. If you looked at the challenge during the competition and just missed a few things, you might want to skip ahead to the high-level loop summary section.

Understanding the challenge file

Vim refresher

If you’re a complete Vim beginner, I recommend going through vimtutor. Just run it from a shell.

Here’s a list of every command that this challenge uses (all in normal mode):

  • h
  • j
  • k
  • l
  • ^
  • $
  • 0
  • G
  • f
  • F
  • t
  • Y
  • y
  • @
  • "
  • r (only after you get the flag)
  • d (only after you get the flag)

If you don’t know what some of them do, look them up in Vim’s help like: :help j or :h j. You might also be interested in the general concepts:

  • count (and the rest of notation or the whole intro.txt file)
  • registers
  • quote_quote
  • quote_alpha

and the command :registers for debugging. As an aside, the most common way I know to interact with registers is with q, which puts typed characters into the given register as a way to record macros. qx@x was a pattern I learned when I was a beginner, but I didn’t make the connection to registers for a long time.

Another thing to know is that @ execution will stop when a command fails to execute. For example, qx0hl@x will put 0hl in register "x and try to run it, but because 0h goes to the first character, h can’t move left and it will stop executing before moving right with l. I found this …

...Read more