> For the complete documentation index, see [llms.txt](https://warsang.gitbook.io/awesome-security-blog/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://warsang.gitbook.io/awesome-security-blog/crackmesone.md).

# Crackmesone

## CryptPad

That one is a notepad-like exe that has an encrypted file containing the flag. The Cryptpad can encrypt (and not decrypt) files for us. Taking a look in IDA, this function stood out to me as being encryption related:\ <br>

```
char __stdcall sub_4014EB(_BYTE *a1, int a2, int a3)
{
  unsigned int v3; // ecx
  _BYTE *v4; // esi
  int v5; // eax
  char result; // al
  _BYTE *v7; // esi
  _BYTE *v8; // edi
  DWORD v9; // ecx
  int v10; // edx
  int v11; // ecx
  _BYTE *v12; // esi
  int v13; // ecx
  int v14; // ebx
  int v15; // ebx
  _BYTE *v16; // esi
  int v17; // eax
  int v18; // ecx
  char v19; // dl
  _BYTE *v20; // edx
  int v21; // eax
  int v22; // ebx
  int v23; // ecx
  int v24; // ecx
  char v25; // dh
  char v26; // dl
  _BYTE *v27; // esi
  _BYTE *v28; // edi
  DWORD v29; // ecx
  int v30; // edx
  _BYTE *v31; // edi
  _BYTE *v32; // [esp-8h] [ebp-Ch]
  int v33; // [esp-4h] [ebp-8h]

  if ( a3 )
  {
    if ( a3 != 1 )
      return MessageBoxA(0, 0, 0, 0);
  }
  else
  {
    v3 = *(_DWORD *)&a1[a2 - 1];
    v4 = &a1[a2 - 1 - v3];
    qmemcpy(byte_4024C5, v4, v3);
    v5 = *((_DWORD *)v4 - 1);
    *((_DWORD *)v4 - 1) = 0;
    a2 = v5;
  }
  v7 = a1;
  v8 = byte_4024C5;
  v9 = NumberOfBytesWritten;
LABEL_6:
  v10 = 0;
  do
  {
    *v7++ ^= *v8++;
    if ( ++v10 == 8 )
      goto LABEL_6;
    --v9;
  }
  while ( v9 );
  v11 = 256;
  do
  {
    byte_403795[(unsigned __int8)-(char)v11] = -(char)v11;
    --v11;
  }
  while ( v11 );
  v12 = &unk_403695;
  v13 = 256;
  v14 = 0;
  do
  {
    if ( v14 >= 8 )
      v14 = 0;
    *v12++ = byte_4024C5[v14++];
    --v13;
  }
  while ( v13 );
  v15 = 0;
  v16 = v12 - 256;
  v17 = 0;
  v18 = 256;
  do
  {
    LOBYTE(v15) = byte_403795[v17] + v16[v17] + v15;
    v19 = byte_403795[v17];
    byte_403795[v17] = byte_403795[v15];
    byte_403795[v15] = v19;
    ++v17;
    --v18;
  }
  while ( v18 );
  v20 = a1;
  v21 = 0;
  v22 = 0;
  v23 = a2;
  do
  {
    v33 = v23;
    v24 = (unsigned __int8)(v21 + 1);
    v32 = v20;
    v25 = byte_403795[v24];
    LOBYTE(v22) = v25 + v22;
    v26 = byte_403795[v22];
    byte_403795[v24] = v26;
    byte_403795[v22] = v25;
    LOBYTE(v24) = byte_403795[(unsigned __int8)(v25 + v26)] ^ a1[v21];
    v20 = v32;
    v32[v21++] = v24;
    v23 = v33 - 1;
  }
  while ( v33 != 1 );
  v27 = a1;
  v28 = byte_4024C5;
  v29 = NumberOfBytesWritten;
LABEL_20:
  v30 = 0;
  do
  {
    result = *v28 ^ *v27;
    *v27++ = result;
    ++v28;
    if ( ++v30 == 8 )
      goto LABEL_20;
    --v29;
  }
  while ( v29 );
  if ( a3 == 1 )
  {
    v31 = &a1[a2 - 13 + RandomBufferLength];
    *(_DWORD *)v31 = a2;
    v31 += 4;
    qmemcpy(v31, byte_4024C5, 8u);
    v31[8] = 8;
    return RandomBufferLength + a2;
  }
  return result;
}
```

This is actually more readable using IDA's graph mode.\
\
What this does is: XOR8( RC4( XOR8( plaintext ) ) )\
Where XOR8 is just a XOR with an 8 byte key.\
\
When a3 == 1 we're in encryption mode and we use the static key:\
\
`byte_4024C5 =` DE BC 0A 89 67 45 23 01

And after the encryption, we append a footer to the file:\
\
\[ original\_size (4 bytes) ]\
\[ key (8 bytes) ] ( copied from byte\_4024C5)\
\[ 8 ]

This caught my eye in particular when comparing the hex of the flag.enc with one of aaaa I generated:\ <br>

```
C9 98 8F C7 A6 1C 02 6B E2 06 F3 52 49 16 27 59 45 5C 4C 47 BC 4E 28 A6 2F 71 C7 D8 06 85 42 03 08 50 7D 93 F5 FE E5 99 48 4E 82 2B E2 00 57 26 16 F6 B4 1C 00 00 00 E8 17 1B F4 50 3F 3D 70 08
```

And:\ <br>

```
02 8B 0F 4D E5 B0 AC 6E 6C 20 EA AD 88 3A DF 65 16 F1 79 15 42 D9 23 16 B9 B5 08 08 11 3E 33 78 03 B1 DE 31 ED BE 8B 02 17 0C 67 D4 70 D7 CD F3 11 54 81 06 00 00 00 13 08 9A CE F4 C2 7F 4B 08
```

The 3 null bytes showing up in the footer caught my interest.

The 06 right before the 3 null bytes as well: I encrypted 5 a's and a null byte so size 06 meaning our flag is size 1C if we follow that logic.\
\
We can write a python script to parse out the footer and apply xor8 rc4 xor8 with our key and decrypt  flag.enc: \ <br>

```
def rc4(data: bytes, key: bytes) -> bytes:
    # KSA
    S = list(range(256))
    j = 0
    key_len = len(key)

    for i in range(256):
        j = (j + S[i] + key[i % key_len]) % 256
        S[i], S[j] = S[j], S[i]

    # PRGA
    i = 0
    j = 0
    output = bytearray()

    for byte in data:
        i = (i + 1) % 256
        j = (j + S[i]) % 256
        S[i], S[j] = S[j], S[i]
        k = S[(S[i] + S[j]) % 256]
        output.append(byte ^ k)

    return bytes(output)


def xor8(data: bytes, key: bytes) -> bytes:
    return bytes(b ^ key[i % 8] for i, b in enumerate(data))


def decrypt_file(path):
    with open(path, "rb") as f:
        data = bytearray(f.read())

    # Extract footer
    key = data[-9:-1]         # 8 bytes
    original_size = int.from_bytes(data[-13:-9], "little")

    encrypted_data = data[:original_size]

    # Reverse the algorithm
    stage1 = xor8(encrypted_data, key)
    stage2 = rc4(stage1, key)
    plaintext = xor8(stage2, key)

    return plaintext


decrypted = decrypt_file("flag.enc")
open("decrypted.bin", "wb").write(decrypted)

```

We end up with:\
\
CMO{r0ll\_y0ur\_0wn\_b4d\_c0d3}\
\ <br>
