githubEdit

Investigative Reversing 3

Problem

We have recovered a binary and an image See what you can make of it. There should be a flag somewhere. Its also found in /problems/investigative-reversing-3_1_8670aba71322d7b19d278027f10f2935 on the shell server.

Solution

  1. Reverse the binary file using Ghidraarrow-up-right (cheat sheetarrow-up-right). Open it and in the symbol tree click on main. The decompiled main function will show on the right.

     undefined8 main(void)
    
     {
     size_t sVar1;
     long in_FS_OFFSET;
     char local_7e;
     char local_7d;
     int local_7c;
     int local_78;
     uint local_74;
     uint local_70;
     undefined4 local_6c;
     int local_68;
     int local_64;
     FILE *local_60;
     FILE *local_58;
     FILE *local_50;
     char local_48 [56];
     long local_10;
    
     local_10 = *(long *)(in_FS_OFFSET + 0x28);
     local_6c = 0;
     local_60 = fopen("flag.txt","r");
     local_58 = fopen("original.bmp","r");
     local_50 = fopen("encoded.bmp","a");
     if (local_60 == (FILE *)0x0) {
         puts("No flag found, please make sure this is run on the server");
     }
     if (local_58 == (FILE *)0x0) {
         puts("No output found, please run this on the server");
     }
     sVar1 = fread(&local_7e,1,1,local_58);
     local_7c = (int)sVar1;
     local_68 = 0x2d3;
     local_78 = 0;
     while (local_78 < local_68) {
         fputc((int)local_7e,local_50);
         sVar1 = fread(&local_7e,1,1,local_58);
         local_7c = (int)sVar1;
         local_78 = local_78 + 1;
     }
     sVar1 = fread(local_48,0x32,1,local_60);
     local_64 = (int)sVar1;
     if (local_64 < 1) {
         puts("Invalid Flag");
                         /* WARNING: Subroutine does not return */
         exit(0);
     }
     local_74 = 0;
     while ((int)local_74 < 100) {
         if ((local_74 & 1) == 0) {
         local_70 = 0;
         while ((int)local_70 < 8) {
             local_7d = codedChar((ulong)local_70,(ulong)(uint)(int)local_48[(int)local_74 / 2],
                                 (ulong)(uint)(int)local_7e,
                                 (ulong)(uint)(int)local_48[(int)local_74 / 2]);
             fputc((int)local_7d,local_50);
             fread(&local_7e,1,1,local_58);
             local_70 = local_70 + 1;
         }
         }
         else {
         fputc((int)local_7e,local_50);
         fread(&local_7e,1,1,local_58);
         }
         local_74 = local_74 + 1;
     }
     while (local_7c == 1) {
         fputc((int)local_7e,local_50);
         sVar1 = fread(&local_7e,1,1,local_58);
         local_7c = (int)sVar1;
     }
     fclose(local_50);
     fclose(local_58);
     fclose(local_60);
     if (local_10 == *(long *)(in_FS_OFFSET + 0x28)) {
         return 0;
     }
                         /* WARNING: Subroutine does not return */
     __stack_chk_fail();
     }
  2. The flag is encoded using LSB encoding, similarly to the previous challenge. However, this time the encoding starts from offset 0x2d3 and every 9 bytes the image is left as-is. In essence, 8 bits of payload are encoded in the LSB of 8 bytes of the image, and then one byte of the original image is placed as-is.

  3. The encoding script accomplishes the above by looping the following 100 times:

    • If (local_74 & 1) == 0 (if the last bit of the current iteration index is 0; this effectively switches back and forth between the if and else clauses for each iteration):

      • Loop 8 times (write 8 bites (1 byte) of the flag to 9 bytes of the image):

        • Write a bit of the flag to the current byte in the image. The divided by 2 in local_48[(int)local_74 / 2] is necessary because every other iteration of the outer 100 times loop leaves a bit of the regular image alone. Since, the looping variable is twice the required value, it is divided by

    • Else (every other loop):

      • Write a bit of the original image

  4. The above is reflected in the reversal script.pyarrow-up-right.

  5. Run the script.pyarrow-up-right and get the flag.

Flag

picoCTF{4n0th3r_L5b_pr0bl3m_0000000000000dbd98691}

Last updated