Saturday 31 August 2013

ASIS CTF 2013 - Reverse 100 - RPS

Task:
Play Rock-Paper-Scissors game with dice! file

 In this task we probably have to win in some "winless" game, but that is not needed to get a flag. Let's go to the place in assembly where the flag is printed. Trying to find "ASIS" string won't tell the exact place where it is written to output. After digging in assembly you can find place where underscore character is printed. Also something is printed before underscore and a bit more is printed after underscore. That must be the flag.
As you might have noticed there is one block that prints 4 characters ("ASIS") and 8 blocks that print other part of the flag (Blocks are grouped by twos or threes). Each of these blocks uses 2 values from stack and one constant per block that is offset.

Let's assume that rbp - 0x174 stores index i and rbp - 0x340 is a pointer to the string. So the block of assembly does the following: it prints contents of the memory starting from the pointer str + 5 * ( i - 10) until 0x0 is found. Other code blocks do the same but with the different offset. So we need to find out contents of the rbp - 0x174 and rbp - 0x340. We are lucky because those values are almost not changed from the start of the program. Contents of the rbp - 0x340 not even changed after the stack initializing which is quite good for us. We need to find rbp - 0x174 by finding usage it is initially 1 and then before prompting for player input it is multiplied by 2. So to get a flag we set a breakpoint after it is multiplied (at the 0x401E6D) and examining stack. rbp - 0x340 contains string "ASIS". So we need to make i in  str + 5 * (i - 10)  have a value of 10 to let the first part of the flag be "ASIS". Using i=10 we can easily recover flag using gdb.
So the flag is "ASIS_e8a10c04d72b2f135dabe360c4bdd534"

No comments:

Post a Comment