Rating: 3.0

Square CTF 2018: C6 - gates of hell

## Description

C6 is a Linux based system. It was brought to Charvis by the very first
settlers. You found a USB drive with a copy of the executable.

Now, all you need to do is figure out the correct input to disable C6 through
its online interface.

## Solution

The only file provided with this challenge is a 32-bit Linux executable called
`gates_of_hell`. When run the executable doesn't seem to do anything. Running
the target under strace confirms this, as the only system call that the program
uses is `exit()`.

The online interface is located at `/cgi-bin/gates-of-hell.pl` on the server and
just displays

root@sqctf:~$ /bin/gates-of-hell

We figured out that if we add a query string to the URL it will be passed to the
program as a sequence of command line arguments. For example
`cgi-bin/gates-of-hell.pl?hello world` displays

root@sqctf:~$ /bin/gates-of-hell hello world

It looks like we will have to reverse the program and find a sequence of command
line arguments that will make it print the flag.

The target is very small (only 4 functions) and towards the end of the main
function we can see that it checks if ebx == 666. If the check succeeds, it will
print `flag is here on server\n-- Alok` and then exit, otherwise it will just

After some reversing we came up with the following pseudocode for the program:

unsigned char table[256] = { ... };

int main(int argc, char *argv[])
if (argc < 16)

unsigned int ebx = 37;

for (int i = 0; i < 16; i++) {
unsigned int x = atob(argv[i]);

if (!check_arg(x))
ebx = 0;

ebx *= table[x];

for (int j = 0; j < 256; j++) {
if (table[j] > 0)

if (ebx == 666)
write(1, flag, sizeof(flag));

where check_arg is a sequence of two x86 instructions,

aam 0x12
aad 0xf6

which set the sign flag if `x` meets certain conditions, and `atob` just
converts a string to an 8-bit unsigned integer.

To find the correct input we need to find the indices of 16 numbers in the table
whose product is 18 (= 666 / 37) while keeping in mind that every non-zero entry
in the table gets decremented by 1 at every iteration. These indices must also
pass `check_arg` otherwise ebx will be zeroed and we will not get the flag.

All we have to do now is dump the initial value of `table` and write a small
Python script to solve the challenge.

root@sqctf:~$ /bin/gates-of-hell 15 2 0 2 0 16 13 11 1 253 5 12 9 7 3 6

Original writeup (https://github.com/ctf-epfl/writeups/tree/master/square18/c6_gates_of_hell).