Codehead's Corner
Random ramblings on hacking, coding, fighting with infrastructure and general tech
Internetwache CTF 2016 – File Checker – Reversing – 60 Points
Posted: 21 Feb 2016 at 23:00 by Codehead

Challenge:

File Checker (rev60)

Description:

My friend sent me this file. He told that if I manage to reverse it, I’ll have access to all his devices. My misfortune that I don’t know anything about reversing :/

Files:

rev60.zip

Solution:

Unzipping the supplied archive yielded a single file named filechecker. Running file at it told me that this was a 64bit ELF for Linux, so I fired up IDA pro and started poking.

After a quick tidy up and rename of the important bits I had the following code:

signed __int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
  signed __int64 result; // rax@2
  int fileChar; // [rsp+18h] [rbp-18h]@6
  int fileLength; // [rsp+1Ch] [rbp-14h]@5
  FILE *stream; // [rsp+20h] [rbp-10h]@3
  int count; // [rsp+28h] [rbp-8h]@5
  int checkResult; // [rsp+2Ch] [rbp-4h]@5

  if ( (unsigned int)checkForFile() )
  {
    stream = fopen(".password", "r");
    if ( stream )
    {
      fileLength = 15;
      checkResult = 0;
      for ( count = 0; count < fileLength; ++count )
      {
        fileChar = fgetc(stream);
        if ( feof(stream) )
        {
          checkResult |= 0x1337u;
          break;
        }
        checkChar(count, (unsigned int *)&fileChar);
        checkResult |= fileChar;
      }
      if ( checkResult <= 0 )
      {
        fclose(stream);
        puts("Congrats!");
        result = 0LL;
      }
      else
      {
        puts("Error: Wrong characters");
        result = 1LL;
      }
    }
    else
    {
      puts("Error: Could not read file");
      result = 1LL;
    }
  }
  else
  {
    printf("Fatal error: File does not exist", a2);
    result = 1LL;
  }
  return result;
}

We can see that program is looking for a file named ’.password’ (not present in the zip) and it is taking 15 characters from the file and pushing them into the function I have named checkChar() along with the current character count.

Lets take a look at checkChar():

__int64 __fastcall checkChar(int count, unsigned int *fileChar)
{
  unsigned int v2; // ecx@1
  __int64 result; // rax@1
  int v4[15]; // [rsp+10h] [rbp-40h]@1

  v4[0] = 0x12EE;
  v4[1] = 0x12E0;
  v4[2] = 0x12BC;
  v4[3] = 0x12F1;
  v4[4] = 0x12EE;
  v4[5] = 0x12EB;
  v4[6] = 0x12F2;
  v4[7] = 0x12D8;
  v4[8] = 0x12F4;
  v4[9] = 0x12EF;
  v4[10] = 0x12D2;
  v4[11] = 0x12F4;
  v4[12] = 0x12EC;
  v4[13] = 0x12D6;
  v4[14] = 0x12BA;
  v2 = (signed int)(v4[count] + *fileChar) % 0x1337;
  result = v2;
  *fileChar = v2;
  return result;
}

I had to do a bit of fixing up here so that IDA recognised that v4 was an array. However, we can see that the incoming character values are added to the corresponding integer value in the v4 array (using the count parameter passed in from the main() function), then the result is divided by x01337, with the remainder being returned to the caller.

Skipping back to main() we see that the results of the character check are logically OR’d with checkResult:

        checkChar(count, (unsigned int *)&fileChar);
        checkResult |= fileChar;
      }
      if ( checkResult <= 0 )
      {
        fclose(stream);
        puts("Congrats!");
        result = 0LL;
      }

It looks like the checkChar() function needs to return 0 for each character in order for the ‘Congrats!’ message to be printed.

So, lets steal those hex values from the v4 array and brute force a standard set of characters against the check to find what the ‘.password’ file should contain:

import sys

testVals = [0x12EE, 0x12E0, 0x12BC, 0x12F1, 0x12EE, 0x12EB, 0x12F2,
	    0x12D8, 0x12F4, 0x12EF, 0x12D2, 0x12F4, 0x12EC, 0x12D6, 0x12BA]
input = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ{}_-'

for v in testVals:
	for ch in input:
		res = (ord(ch) + v) % 0x1337
		if res == 0:
			sys.stdout.write(ch)

The output from the code is: IW{FILE_CHeCKa}.

Placing that string in ’.password’ and running the filechecker binary prints the ‘Congrats!’ message. Better still submitting it to the scoreboard gets us 60 points!

Hell Yeah

Categories: Hacking CTF

Site powered by Hugo.
Polymer theme by pdevty, tweaked by Codehead