Skip to content

Latest commit

 

History

History
84 lines (62 loc) · 2.94 KB

README.md

File metadata and controls

84 lines (62 loc) · 2.94 KB

Warmup (re, 600p, 31 solved)

Description

In the task we get ELF binary. It's pretty large and statically compiled, but by looking at strings we immediately notice that (ironically) it's strings! We suspect that there is some added secret functionality and we need to locate this patch.

Analysis

Initially we thought about something like Diaphora or just bindiff, but for statically compiled binary this could be rather hard to do.

Fortunately we quickly noticed one strange quirk - the usage was providing description for the parameters, as it normally should! From this clue we looked at available parameters in the binary -> adfhzHn:wot:e:T:s:Vv0123456789

If we compare this with original strings binary, you will notice there is a special z parameter which normally is not present.

We can now follow this thread and see what exactly does this parameter do. Sadly ghidra didn't like the switch expression which parses the parameters, so we switched to gdb for a moment, just to follow the switch, and we hit:

004010a8 MOV dword ptr [magic_flag ],0x1

So we know that special parameter sets this flag to 1. Now we follow x-refs to this flag, to see where it's used. There is only one function at 0x00400e10.

This code reads input file, allocates memory and eventually we arrive at:

  index = 0;
  do {
    allocated_buffer[index] =
         ((file_content[index] ^ (byte)index) + 0x41) - (char)(0x42 % (long)((int)index + 1));
    index = index + 1;
  } while ((ulong)(iVar3 - 1) + 1 != index);


  cVar2 = *allocated_buffer;
  lVar5 = 0x2d;
  pointer_to_consts = &some_consts;
  pcVar6 = acStack72;
  while (lVar5 != 0) {
    lVar5 = lVar5 + -1;
    *pcVar6 = *pointer_to_consts;
    pointer_to_consts = pointer_to_consts + (ulong)bVar7 * -2 + 1;
    pcVar6 = pcVar6 + (ulong)bVar7 * -2 + 1;
  }
  

  if (cVar2 == -0x56) {
    lVar5 = 1;
    do {
      if (lVar5 == index) goto LAB_00400f06;
      pcVar6 = allocated_buffer + lVar5;
      pcVar1 = acStack72 + lVar5;
      lVar5 = lVar5 + 1;
    } while (*pcVar6 == *pcVar1);
  }
  • First part is clearly some encryption/decryption process on the input file.
  • Second part is just strcpy of some constant values to the stack buffer.
  • Third part is just strcmp of input file encryption/decryption result with the loaded stack buffer

Solution

We want now to simply invert the logic -> get the constants and apply inverse of the encryption operation to, hopefully, recover the flag:

def main():
    data = [0xAA, 0xB0, 0xA2, 0xB6, 0xA2, 0x91, 0x71, 0xB1, 0xA7, 0x80, 0x96, 0x97, 0x78, 0xB6, 0x9E, 0x99, 0x72, 0x97, 0x85, 0x98, 0x8F, 0x91, 0x7F, 0x77,
            0x7C, 0x80, 0x9D, 0x61, 0xAB, 0x95, 0x8A, 0x7F, 0xB4, 0x8F, 0x9F, 0x35, 0x9F, 0x87, 0x8D, 0x98, 0x95, 0x9F, 0x8D, 0xAA]
    result = ''
    for i, d in enumerate(data):
        result += chr((d + 0x42 % (i + 1) - 0x41) ^ i)
    print(result)


main()

And we get: inctfU5uaL_W4rmUPs_NEED_STr1nGS_SO_1_GAVE_IT