# Investigative Reversing 2

## 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-2\_6\_2ea0f420e29d29b575882f681dc272d5 on the shell server.

* [Binary](https://github.com/HHousen/PicoCTF-2019/tree/24b0981c72638c12f9a8572f81e1abbcf8de306d/Forensics/Investigative%20Reversing%202/mystery/README.md)
* [Image](https://github.com/HHousen/PicoCTF-2019/tree/24b0981c72638c12f9a8572f81e1abbcf8de306d/Forensics/Investigative%20Reversing%202/encoded.bmp)

## Solution

1. Run `file mystery` which shows its is a ELF executable: `mystery: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld`...
2. Reverse the binary file using [Ghidra](https://ghidra-sre.org/) ([cheat sheet](https://ghidra-sre.org/CheatSheet.html)). Open it and in the symbol tree click on main. The decompiled main function will show on the right.

   \`\`\`c++ undefined8 main(void)

   { size\_t sVar1; long in\_FS\_OFFSET; char local\_7e; char local\_7d; int local\_7c; int local\_78; int 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("original.bmp is missing, please run this on the server"); } sVar1 = fread(\&local\_7e,1,1,local\_58); local\_7c = (int)sVar1; local\_68 = 2000; 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("flag is not 50 chars"); / *WARNING: Subroutine does not return* / exit(0); } local\_74 = 0; while (local\_74 < 0x32) { local\_70 = 0; while ((int)local\_70 < 8) { local\_7d = codedChar((ulong)local\_70,(ulong)(uint)(int)(char)(local\_48\[local\_74] + -5), (ulong)(uint)(int)local\_7e, (ulong)(uint)(int)(char)(local\_48\[local\_74] + -5)); fputc((int)local\_7d,local\_50); fread(\&local\_7e,1,1,local\_58); local\_70 = local\_70 + 1; } 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(); }

````
ulong codedChar(int param_1,byte param_2,byte param_3)

{
byte local_20;

local_20 = param_2;
if (param_1 != 0) {
    local_20 = (byte)((int)(char)param_2 >> ((byte)param_1 & 0x1f));
}
return (ulong)(param_3 & 0xfe | local_20 & 1);
}
```
````

1. This time the program jumps to offset 2000, and hides a 50 character flag using [LSB](https://en.wikipedia.org/wiki/Bit_numbering#Least_significant_bit) encoding. More info on [BoiteAKlou's Infosec Blog](https://www.boiteaklou.fr/Steganography-Least-Significant-Bit.html) ([Archive](https://web.archive.org/web/20200603202609/https://www.boiteaklou.fr/Steganography-Least-Significant-Bit.html)). The error string `"flag is not 50 chars"` reveals that the flag is 50 characters long.
2. We can see that up to offset 2000 (`0x7d0`) we have a constant value of `0xe8`. Then, for `50 * 8` bytes we have different values (switching between `0xe9` and `0xe8`), and finally, at offset `0x960` we're back to `0xe8`. `0xe8` in binary is `0b11101000` and `0xe9` is `0b11101001`. In binary you can easily see the "least significant bit" modification that was made. Output of `xxd -g 1 -s $((2000 - 32)) -l $((50*8 + 64)) encoded.bmp`:

   ```bash
    000007b0: e8 e8 e8 e8 e8 e8 e8 e8 e8 e8 e8 e8 e8 e8 e8 e8  ................
    000007c0: e8 e8 e8 e8 e8 e8 e8 e8 e8 e8 e8 e8 e8 e8 e8 e8  ................
    000007d0: e9 e9 e8 e9 e8 e9 e9 e8 e8 e8 e9 e8 e8 e9 e9 e8  ................
    000007e0: e8 e9 e9 e9 e9 e8 e9 e8 e8 e9 e8 e9 e8 e9 e9 e8  ................
    000007f0: e8 e9 e9 e9 e9 e9 e8 e8 e9 e9 e9 e9 e8 e8 e9 e8  ................
    00000800: e9 e8 4e 4e 4e 4e 4f e8 e8 e9 e9 e8 e9 e9 e9 e8  ..NNNNO.........
    00000810: e9 e8 e8 e9 e8 e9 e9 e8 e8 e9 e9 e9 e8 e9 e8 e8  ................
    00000820: e9 e9 e8 e8 e9 e9 e9 e8 e9 e9 e9 e9 e8 e9 e9 e8  ................
    00000830: e8 e9 e8 e9 e9 e8 e9 e8 e9 e9 e8 e9 e8 e9 e8 e8  ................
    00000840: e9 e8 e8 e9 e8 e9 e9 e8 e8 e9 e9 e9 e8 e9 e8 e8  ................
    00000850: e9 e9 e8 e9 e8 e9 e8 e8 e9 e9 e8 e9 e8 e9 e8 e8  ................
    00000860: e9 e9 e8 e9 e8 e9 e8 e8 e9 e9 e8 e9 e8 e9 e8 e8  ................
    00000870: e9 e9 e8 e9 e8 e9 e8 e8 e9 e9 e8 e9 e8 e9 e8 e8  ................
    00000880: e9 e9 e8 e9 e8 e9 e8 e8 e9 e9 e8 e9 e8 e9 e8 e8  ................
    00000890: e9 e9 e8 e9 e8 e9 e8 e8 e9 e9 e8 e9 e8 e9 e8 e8  ................
    000008a0: e9 e9 e8 e9 e8 e9 e8 e8 e9 e9 e8 e9 e8 e9 e8 e8  ................
    000008b0: e9 e9 e8 e9 e8 e9 e8 e8 e9 e9 e8 e9 e8 e9 e8 e8  ................
    000008c0: e9 e9 e8 e9 e8 e9 e8 e8 e9 e9 e8 e9 e8 e9 e8 e8  ................
    000008d0: e9 e9 e8 e9 e8 e9 e8 e8 e9 e9 e8 e9 e8 e9 e8 e8  ................
    000008e0: e9 e9 e8 e9 e8 e9 e8 e8 e9 e9 e8 e9 e8 e9 e8 e8  ................
    000008f0: e9 e9 e8 e9 e8 e9 e8 e8 e9 e9 e8 e9 e8 e9 e8 e8  ................
    00000900: e9 e9 e8 e9 e8 e9 e8 e8 e9 e9 e8 e9 e8 e9 e8 e8  ................
    00000910: e9 e9 e8 e9 e8 e9 e8 e8 e9 e8 e8 e8 e9 e9 e8 e8  ................
    00000920: e8 e9 e9 e9 e9 e8 e9 e8 e8 e9 e8 e8 e9 e9 e8 e8  ................
    00000930: e8 e9 e9 e9 e8 e9 e8 e8 e9 e8 e9 e9 e8 e9 e8 e8  ................
    00000940: e8 e9 e9 e9 e9 e8 e9 e8 e8 e8 e8 e8 e8 e9 e9 e8  ................
    00000950: e8 e8 e8 e8 e8 e9 e9 e8 e8 e8 e8 e9 e9 e9 e9 e8  ................
    00000960: e8 e8 e8 e8 e8 e8 e8 e8 e8 e8 e8 e8 e8 e8 e8 e8  ................
    00000970: e8 e8 e8 e8 e8 e8 e8 e8 e8 e8 e8 e8 e8 e8 e8 e8  ................
   ```
3. Run the [script.py](https://github.com/HHousen/PicoCTF-2019/tree/24b0981c72638c12f9a8572f81e1abbcf8de306d/Forensics/Investigative%20Reversing%202/script.py) to select the last bits from offset 2000 bytes to 2000+50\*8 bytes and then convert them to ascii. View the code for the low-levels details about how the code works (60% of the file is purely comments).

### Flag

`picoCTF{n3xt_0n300000000000000000000000006c732cee}`


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://picoctf2019.haydenhousen.com/forensics/investigative-reversing-2.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
