# 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}
```


---

# 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://zwique.gitbook.io/zwique_notes/writeups/random-ctf-writeup/bearcatctf-2024/shimbles-the-e-l-f.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.
