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
Nice tag 😆
Naja, mich würde schon abschrecken, dass man den Hexcode abschreiben muss. 😐