THCon 2021 CTF Write ups

4 minute read

The CTF was of a good standard, with an unusually high proportion of reverse and pwn challenges. I found it disappointing that there is no network nor forensic challenges. The challenges were nevertheless interesting, with a special mention for the challenge TUR-ROX-Z which was very beautiful and pleasant.

  • Flag format: THCon21{flag}
  • Team: Ra1sinTin3 (12th)

TUR-ROX-Z (248 pts)

First things first: appropriate music

Setup

After some basic internet searches, I have found that the given file was a kind of map file made for ZZT, a quite old videogame. So, I will need some tools to run the game with this map. A quick search on google gives me this, which look good, let’s install it:

$ git clone https://github.com/asiekierka/zeta.git
$ cd zeta/
$ make PLATFORM=unix-sdl

We also need the game itself which can be found here: https://museumofzzt.com/zzt. Now, we can launch the game:

$ cd build/unix-sdl
$ ./zeta86 THCON21Z.ZZT

zzt

Perfect ! So now, let’s look to the game. We have several panels where we can move around with our little character. One of them gives us a useful link: apocalyptech.com/games/zzt/manual/lang.html

panel

It is documentation for the in-game programming language, helpful to understand the third panel. Now let’s go to the map editor and see this third panel. The different dialogues tell us that we must find a combination that will allow us to validate the challenge. An NPC tells us whether or not our combination is right. More specifically, interacting with the NPC launches a script that checks that several flags are in place. These different flags are raised by the scripts associated with the counters under conditions that will have to be found.

The first thing I did was change the level to make all scripts accessible and make invisible walls visible:

3panel

We can now interact with the scripts to learn that a total of 4 flags are needed:

  • flag OK A1
  • flag OK A2
  • flag OK B1
  • flag OK C1

and several others must not be raised (fail flags). Finally, there are flags restricting the order in which the numbers are set up. In particular, line 1 (numbered lines from left to right) should not be touched after 2 and 5 must be adjusted before 6.

Green part

Now we need to study the script code. This is the longest part, although not very complicated. The six lines are grouped by two, and these groups are independent and each corresponds to one or more flags. Let’s start with the first two lines responsible for the A1 and A2 flags. The flags validation script is as follows:

@Checker12
  #end
  :lblMulti
    #set flagOkA1
    #zap lblMulti
    #send lblMulti
    ' "set OK A1"
  #end
  :lblMulti
  :lblMulti
  :lblMulti
  :lblMulti
  :lblMulti
  :lblMulti
    #set flagFailA
    ' "pwnz 2 zzzz"
    #send GlobCheck:lblBack12
  #end
  :lblMulti
    #set flagOkA2
    ' "gg  !"
    #send GlobCheck:lblBack12
  #end
  :lblMulti
  :lblMulti
    #set flagFailA
    ' "pwnz last"
    #send GlobCheck:lblBack12
#end

We see that we must call the label lblMulti twice without falling into the fails. For that the scripts of lines 1 and 2 have respectively two interesting commands: #zap and #restore which are call when we move the object. These commands allow us to delete and restore label in a file. We then understand that we will first have to move the line 1 object seven times then the line 2 object once to keep only the two labels that interest us. Since lblMulti is call during validation, once we have placed our objects, we are done for this first part.

Red part

The second part was much easier: in the map editor, we realize that there are invisible walls in the red rectangle. We also notice an invisible object that moves. By making all this visible, we can see that line 3 moves the object upwards and line 4 to the left. We make the object follow the path that emerges, and we see by looking at the scripts that the flag B is set.

lawless dgbB

Blue part

Last step also easy, the scripts evaluate, give and withdraw gems to the player:

@Line5
:touch
  #if blocked n then lblFailZ
  #give gems 1
  #if flag5Once then lblFailC
#end
  ...

@Line6
:touch
  #zap touch
  #set flag5Once
  #take gems 4 lblPoor
  ' "gems 4 taken"
#end
  ...

More precisely, the player must have exactly 4 gems. So it suffices to move the object line 5 4 times and the object line 6 twice to perform the requested operations. We can check that the last flag is set:

dgbC

We check that everything is good with the NPC, and voilĂ  !

end

So our flag is THCon21{Z824753}!

The challenge is very cool, and I invite you to try it, it is for me one of the best challenges of the CTF.