– yes we can ;)

So the British Government Communications Headquarters (GCHQ) wants to recruit smart people. Well, there should be enough around. Although they seem to look for some 1337 h4x0rz, not some serious people from all indicators.

The original one (MD5: 1585DFECC90AE7549814DCE52CA4EDDA) filled the buffer as follows, before calling the mysterious function to get the keyword:

unsigned char buf[0x100];

for(size_t i = 0; i < sizeof(buf)/sizeof(buf[0]); i++)
    buf[i] = (unsigned char)i;

unsigned char idx = 0;
unsigned char const offs[4] = { 0xEF, 0xBE, 0xAD, 0xDE };
size_t const len = sizeof(offs)/sizeof(offs[0]);

for(size_t i = 0; i < sizeof(buf)/sizeof(buf[0]); i++)
    unsigned char const temp = buf[i];
    idx += temp;
    idx += offs[i % len];
    buf[i] = buf[idx];
    buf[idx] = temp;

Obviously this is C99 or C++, so don't bother telling me it's "not valid C", it is ... just not valid C89. The second one (MD5: C1C82FB25709F889750CBB7FAFEE1C61) is identical in that regard. What differs are the contents of the called function, but only in two opcodes.

There is but one major issue with those crackmes. No one knows whether the result typed into ones editor is correct, because those professionals didn't give either a copy&paste variant of their crackme or a cryptographic hash to verify or simply a download ... ๐Ÿ™„

Either way, this is how the filled buffer looks:

EF 0A 1B DD 31 A6 02 15 3F 1A AE 7B E5 36 6B 0B
57 26 30 B8 D9 28 24 64 0E 42 4A B5 B0 A3 B3 0D
01 93 4B 69 81 38 6D 27 03 9B FC 67 5C 60 E6 84
A0 D4 1E CA E7 04 98 52 51 75 35 39 BA E0 EB 83
8D BD 65 70 74 53 66 18 76 4F 5F 48 61 07 C9 CF
17 F9 40 5A 78 1F 68 06 34 B6 A8 21 BF EC B4 C8
7E C3 E1 9C 55 D3 2E F4 82 49 C0 4E B7 2C 73 E4
E8 91 AD 5B 50 77 7C 20 9D 08 AA 63 FE B1 DC F0
45 8A 0F 85 F8 BE D8 A5 05 3A B9 CB F5 54 2D 1D
C5 37 25 4C DB 97 D7 AF 41 6C 92 44 8E 99 62 10
0C 87 4D CC F6 7A E3 E9 6A 6E B2 16 8C 90 22 5E
FA 09 00 BB F7 D1 89 D2 D6 80 86 29 95 33 C2 59
BC 94 8B 8F 23 11 AB 19 D5 12 E2 FF 43 C7 88 C1
CD FD 79 2A EE DE 71 ED F1 9F 96 F2 EA FB DA 3B
6F DF 47 2B 3E C4 46 14 9E A1 58 AC A7 7F 7D 32
1C 5D 2F A4 13 CE A9 D0 F3 56 A2 C6 3D 3C 9A 72

I leave the rest of the exercise to my readers ๐Ÿ˜‰ ... attached (MD5: 0c4c2cdba60d15ef70dc4959bad86393) is the disassembly of the previous and (hopefully) current version, along with a visual diff of the two and the binary files. Here is the diff for easy viewing in a browser.

Now, it's unknown how often those guys change the crackme (because many of us geeks have simply taken on the challenge and solved that and then also posted the results in many cases), but since there is no versioning, no method to verify ones own version and no easy way to get the actual binary file as it should be, so no idea whether any of my findings is valid, but the code seems to make sense (somewhat ๐Ÿ˜‰ ).

But since I despise nobility and monarchs I could not possibly even apply for this job in HM's service ๐Ÿ˜†

// Oliver

This entry was posted in C/C++, EN, Germans have no notion of sarcasm, Programming, Reversing, Software. Bookmark the permalink.

One Response to – yes we can ;)

  1. yasrick says:

    Nice tag ๐Ÿ˜†

    Naja, mich wรผrde schon abschrecken, dass man den Hexcode abschreiben muss. ๐Ÿ˜

Leave a Reply

Your email address will not be published. Required fields are marked *