> For the complete documentation index, see [llms.txt](https://zwique.gitbook.io/zwique_notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://zwique.gitbook.io/zwique_notes/writeups/random-ctf-writeup/bearcatctf-2024/shimbles-the-e-l-f.md).

# Shimbles the E-L-F

## Problem

<figure><img src="/files/ZBzcuv3bsif1yhe7gk1p" alt=""><figcaption><p>Description</p></figcaption></figure>

{% file src="/files/ElUG16hfBHhQoA0M9nla" %}

Utilizing Ghidra allows us to see functions effectively.

#### Main function

```cpp
undefined8 main(void)

{
  int iVar1;
  char *pcVar2;
  undefined8 uVar3;
  size_t sVar4;
  long in_FS_OFFSET;
  undefined8 local_e1;
  undefined local_d9;
  undefined8 local_d8;
  undefined8 local_d0;
  undefined2 local_c8;
  undefined local_c6;
  undefined8 local_b8;
  undefined8 local_b0;
  undefined2 local_a8;
  undefined local_a6;
  char local_98 [136];
  long local_10;
  
  local_10 = *(long *)(in_FS_OFFSET + 0x28);
  puts(
      "          __\n         .-\'  |\n        /   <\\|\n       /     \\\n       |_.- o-o\n       / C  -._)\\\n      /\',        |\n     |   `-,_,__,\'\n     (,,)====[_]=|\n       \'.   ____/\n        | -|-|_\n        |____)_)\n"
      );
  puts("Schimbles: Hello, mortal! I am Schimbles, the enchanted gnome.");
  puts("Schimbles: I\'ve encrypted your precious data and you\'ll never see it again...");
  puts("Schimbles: ...unless you can decrypt my file.\n");
  printf("Schimbles: Enter the decryption key: ");
  pcVar2 = fgets(local_98,0x80,stdin);
  if (pcVar2 == (char *)0x0) {
    fwrite("Input error.\n",1,0xd,stderr);
    uVar3 = 1;
  }
  else {
    sVar4 = strcspn(local_98,"\n");
    local_98[sVar4] = '\0';
    local_e1 = encrypted_key;
    local_d9 = DAT_00104018;
    local_d8 = encrypted_flag;
    local_d0 = DAT_00104028;
    local_c8 = DAT_00104030;
    local_c6 = DAT_00104032;
    local_b8 = encrypted_taunt;
    local_b0 = DAT_00104048;
    local_a8 = DAT_00104050;
    local_a6 = DAT_00104052;
    sVar4 = strlen((char *)&local_e1);
    two_layer_decrypt(&local_e1,sVar4,0xaa,3,0x5f,2);
    iVar1 = strcmp(local_98,(char *)&local_e1);
    if (iVar1 == 0) {
      sVar4 = strlen((char *)&local_d8);
      two_layer_decrypt(&local_d8,sVar4,0x77,4,0x3c,3);
      puts("\nSchimbles: Ha! You have bested me!");
      printf("Schimbles: Here is your flag: %s\n",&local_d8);
    }
    else {
      sVar4 = strlen((char *)&local_b8);
      two_layer_decrypt(&local_b8,sVar4,0x6d,2,0x33,5);
      printf("\nSchimbles: %s\n",&local_b8);
    }
    uVar3 = 0;
  }
  if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) {
                    /* WARNING: Subroutine does not return */
    __stack_chk_fail();
  }
  return uVar3;
}
```

#### Two\_layer\_decrypt function

```c
void two_layer_decrypt(long param_1,ulong param_2,byte param_3,undefined4 param_4,byte param_5,
                      undefined4 param_6)

{
  byte bVar1;
  undefined uVar2;
  ulong local_18;
  
  for (local_18 = 0; local_18 < param_2; local_18 = local_18 + 1) {
    bVar1 = rotr(*(byte *)(local_18 + param_1) ^ param_5,param_6);
    uVar2 = rotr(bVar1 ^ param_3,param_4);
    *(undefined *)(param_1 + local_18) = uVar2;
  }
  return;
}

```

#### Explanation

#### `undefined8 main(void)`

The main function simulates a decryption challenge from Schimbles the gnome:

1. **Introduction**: Prints an ASCII art gnome and taunts the user.
2. **User Input**: Prompts the user for a decryption key, reads input, and compares it with an encrypted key.
3. **Key Validation**:
   * Decrypts the encrypted key using `two_layer_decrypt` with parameters `(local_e1, key_length, 0xaa, 3, 0x5f, 2)`.
   * If the input matches, it decrypts and displays the flag with parameters `(local_d8, flag_length, 0x77, 4, 0x3c, 3)`.
   * If incorrect, it decrypts and shows a taunt with parameters `(local_b8, taunt_length, 0x6d, 2, 0x33, 5)`.
4. **Stack Integrity**: Checks for stack corruption at the end.

***

#### `void two_layer_decrypt(long param_1, ulong param_2, byte param_3, undefined4 param_4, byte param_5, undefined4 param_6)`

This function decrypts a byte array using two XOR and rotation layers:

1. **First Layer**: XORs each byte with `param_5`, then rotates by `param_6`.
2. **Second Layer**: XORs the result with `param_3`, then rotates by `param_4`.
3. **Stores Decrypted Byte**: Updates the byte array with the final decrypted value.

This function is used to decrypt keys, flags, and taunts in the main function.

#### Finding the key

* The `x` command in GDB is used for examining memory.
* `8b` specifies that you want to view **8 bytes** (the `b` stands for byte) of memory.
* `x/8bx` tells GDB to show the bytes in hexadecimal format.
* `0x4010` is the **memory address** you are examining. You provided the address `0x4010` to GDB to inspect the contents at that specific location in memory.

{% hint style="info" %}
gef➤ info address encrypted\_key&#x20;

Symbol "encrypted\_key" is at 0x4010 in a file compiled without debugging.
{% endhint %}

<figure><img src="/files/IbXz0JJbBtoibZBdLznm" alt="" width="273"><figcaption><p>GDB</p></figcaption></figure>

#### Solution

```python
def rotr(byte, shift):
    return ((byte >> shift) | (byte << (8 - shift))) & 0xff

def two_layer_decrypt(data, param_3, param_4, param_5, param_6):
    decrypted_data = []
    for byte in data:
        # First layer: XOR with param_5, then rotate right by param_6
        bVar1 = rotr(byte ^ param_5, param_6)
        # Second layer: XOR with param_3, then rotate right by param_4
        uVar2 = rotr(bVar1 ^ param_3, param_4)
        decrypted_data.append(uVar2)
    return bytes(decrypted_data)

# Encrypted key extracted from memory
encrypted_key = bytes([0x59, 0x78, 0x39, 0x58, 0xd9, 0x19, 0xd8, 0x99])

# Decrypt the key using the parameters from the challenge
decrypted_key = two_layer_decrypt(encrypted_key, 0xaa, 3, 0x5f, 2)

# Print the decrypted key
print(f"Decrypted Key: {decrypted_key.decode()}")
```

```
Decrypted Key: elfmagic
```

Run the binary file and enter the key.

```bash
┌──(zwique㉿kali)-[~/Downloads/slv/Shimbles_the_E-L-F]
└─$ ./Shimbles-the-elf  
          __
         .-'  |
        /   <\|
       /     \
       |_.- o-o
       / C  -._)\
      /',        |
     |   `-,_,__,'
     (,,)====[_]=|
       '.   ____/
        | -|-|_
        |____)_)

Schimbles: Hello, mortal! I am Schimbles, the enchanted gnome.
Schimbles: I've encrypted your precious data and you'll never see it again...
Schimbles: ...unless you can decrypt my file.

Schimbles: Enter the decryption key: elfmagic

Schimbles: Ha! You have bested me!
Schimbles: Here is your flag: BCC{n0t_t0day_e1f}
```
