1. // by petter wahlman, twitter: @badeip
  2. // solution to part #1 of http://www.canyoucrackit.co.uk/
  3. //
  4. // part2.h will be published along with solutions to the subsequent levels after 12 December 2011
  5.  
  6. #include <stdio.h>
  7. #include <stdint.h>
  8. #include <malloc.h>
  9. #include <stdlib.h>
  10. #include <errno.h>
  11. #include <string.h>
  12. #include <time.h>
  13. #include <sys/types.h>
  14. #include <sys/mman.h>
  15. #include <sys/utsname.h>
  16.  
  17. #include "part2.h" // see information above
  18.  
  19. static char part1[] = {
  20.     0xeb, 0x04, 0xaf, 0xc2, 0xbf, 0xa3, 0x81, 0xec,   0x00, 0x01, 0x00, 0x00, 0x31, 0xc9, 0x88, 0x0c,
  21.     0x0c, 0xfe, 0xc1, 0x75, 0xf9, 0x31, 0xc0, 0xba,   0xef, 0xbe, 0xad, 0xde, 0x02, 0x04, 0x0c, 0x00,
  22.     0xd0, 0xc1, 0xca, 0x08, 0x8a, 0x1c, 0x0c, 0x8a,   0x3c, 0x04, 0x88, 0x1c, 0x04, 0x88, 0x3c, 0x0c,
  23.     0xfe, 0xc1, 0x75, 0xe8, 0xe9, 0x5c, 0x00, 0x00,   0x00, 0x89, 0xe3, 0x81, 0xc3, 0x04, 0x00, 0x00,
  24.     0x00, 0x5c, 0x58, 0x3d, 0x41, 0x41, 0x41, 0x41,   0x75, 0x43, 0x58, 0x3d, 0x42, 0x42, 0x42, 0x42,
  25.     0x75, 0x3b, 0x5a, 0x89, 0xd1, 0x89, 0xe6, 0x89,   0xdf, 0x29, 0xcf, 0xf3, 0xa4, 0x89, 0xde, 0x89,
  26.     0xd1, 0x89, 0xdf, 0x29, 0xcf, 0x31, 0xc0, 0x31,   0xdb, 0x31, 0xd2, 0xfe, 0xc0, 0x02, 0x1c, 0x06,
  27.     0x8a, 0x14, 0x06, 0x8a, 0x34, 0x1e, 0x88, 0x34,   0x06, 0x88, 0x14, 0x1e, 0x00, 0xf2, 0x30, 0xf6,
  28.     0x8a, 0x1c, 0x16, 0x8a, 0x17, 0x30, 0xda, 0x88,   0x17, 0x47, 0x49, 0x75, 0xde, 0x31, 0xdb, 0x89,
  29.     0xd8, 0xfe, 0xc0, 0xcd, 0x80, 0x90, 0x90, 0xe8,   0x9d, 0xff, 0xff, 0xff, 0x41, 0x41, 0x41, 0x41,
  30. };
  31.  
  32. // code to dump the decrypted memory:
  33. static const char dump_mem[] = {
  34.         0x8d, 0x7f, 0xce,               // lea    edi,[edi-0x32]
  35.         0x57,                           // push   edi
  36.         0x31, 0xc9,                     // xor    ecx,ecx
  37.         0x30, 0xc0,                     // xor    al,al
  38.         0xf7, 0xd1,                     // not    ecx
  39.         0xfc,                           // cld    
  40.         0xf2, 0xae,                     // repne scasb
  41.         0xf7, 0xd1,                     // not    ecx
  42.         0x49,                           // dec    ecx
  43.         0x89, 0xca,                     // mov    edx,ecx
  44.         0x5f,                           // pop    edi
  45.         0x89, 0xf9,                     // mov    ecx,edi
  46.         0xb8, 0x04, 0x00, 0x00, 0x00,   // mov    eax,0x4
  47.         0x31, 0xdb,                     // xor    ebx,ebx
  48.         0xfe, 0xc3,                     // inc    bl
  49.         0xcd, 0x80,                     // int    0x80
  50.         0x89, 0xd3,                     // mov    ebx,edx
  51.         0x31, 0xc0,                     // xor    eax,eax
  52.         0xfe, 0xc0,                     // inc    al
  53.         0xcd, 0x80,                     // int    0x80
  54. };
  55.  
  56. uint32_t patch_mem(char *ptr, size_t size)
  57. {
  58.     uint32_t i;
  59.  
  60.     for (i = 0; i < size; i++) {
  61.         if (*(uint16_t *)&ptr[i] == 0x80cd) {
  62.             *(uint16_t *)&ptr[i] = 0x45eb;
  63.             return 0;
  64.         }
  65.     }
  66.     return 1;
  67. }
  68.  
  69. uint32_t check_arch(void)
  70. {
  71.     struct utsname kernel_info;
  72.  
  73.     uname(&kernel_info);
  74.     return strcmp(kernel_info.machine, "i686") ? 1 : 0;
  75. }
  76.  
  77. int main(int argc, char **argv)
  78. {
  79.     void *mem;
  80.  
  81.     if (check_arch()) {
  82.         printf("[-] this program must run on a 32-bit architecture\n");
  83.         return 1;
  84.     }
  85.  
  86.     printf("[*] allocating page aligned memory\n");
  87.     mem = memalign(4096, 4096);
  88.     if (!mem) {
  89.         printf("[-] error: %s\n", strerror(errno));
  90.         return 1;
  91.     }
  92.     memset(mem, 0, 4096);
  93.  
  94.     printf("[*] setting page permissions\n");
  95.     if (mprotect(mem, 4096, PROT_READ | PROT_WRITE | PROT_EXEC)) {
  96.         printf("[-] error: %s\n", strerror(errno));
  97.         return 1;
  98.     }
  99.  
  100.     printf("[*] copying payload\n");
  101.  
  102.     memcpy(mem, part1, sizeof(part1));
  103.     memcpy(mem + sizeof(part1), part2, sizeof(part2));
  104.     memcpy(mem + sizeof(part1) + sizeof(part2), dump_mem, sizeof(dump_mem));
  105.  
  106.     printf("[*] adding dump_mem payload\n");
  107.     if (patch_mem(mem, sizeof(part1))) {
  108.         printf("[-] failed to patch memory\n");
  109.         return 0;
  110.     }
  111.  
  112.     printf("[*] executing payload..\n\n");
  113.  
  114.     ((int(*)(void))mem)();
  115.  
  116.     return 0;
  117. }