Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Spectre et Meltdown, 15 min pour tout comprendr...

Spectre et Meltdown, 15 min pour tout comprendre @Breizhcamp

Impossible de l’avoir manqué en ce début d’année 2018, 2 failles de sécurité majeures affectant l’ensemble des CPU ont été découvertes.

Au cours de ce Quickie, je présenterais leur principe, leur origines et les différentes contre-mesures proposées à l’heure actuelle.

Nous aborderons également les exploits possibles et leur impact, ainsi que les attaques de type side-channels, actuellement très en vogue dans le milieu académique et qui ont permis la découverte de Spectre et Meltdown par 4 équipes de recherche, presque simultanément à travers le monde.

Alexis DUQUE

March 30, 2018
Tweet

More Decks by Alexis DUQUE

Other Decks in Research

Transcript

  1. ALEXIS DUQUE ★ Embedded Software engineer & R&D leader at

    Rtone ★ PhD Student at CITI Lab, INSA de Lyon ★ @alexis0duque ★ alexisduque ★ [email protected] ★ alexisduque.me ★ https://goo.gl/oNUWu6 About Me 2
  2. ★ WHAT? ★ WHEN? ★ WHO? ★ WHY AND HOW?

    A CREPE PARTY STORY ★ WHAT SHOULD I DO? ★ WHAT IS NEXT? Summary 3
  3. A NEW CLASS OF VULNERABILITIES ★ A “Feature” of modern

    CPU What are Spectre & Meltdown 5 https://twitter.com/PotatoPlanetFTW/status/9507371815088209 8
  4. MELTDOWN ★ Werner Haas, Thomas Prescher (Cyberus Technology) ★ Daniel

    Gruss, Moritz Lipp, Stefan Mangard, Michael Schwarz (Graz University of Technology) ★ Jann Horn (Google Project Zero) ★ Anders Fogh (GData) SPECTRE ★ Paul Kocher, Daniel Genkin (University of Pennsylvania and University of Maryland), Mike Hamburg (Rambus), Moritz Lipp (Graz University of Technology), and Yuval Yarom (University of Adelaide and Data61) ★ Jann Horn (Google Project Zero) Who & When? 6
  5. RAM, CACHE & CPU How and Why ? 8 L2

    LLC Slice 0 L1 Core 0 L1 Core 1 L2 LLC Slice 1 Core 2 L2 LLC Slice 2 L1 Core 3 L2 LLC Slice 3 L1 Ring Bus RAM
  6. SIDE CHANNEL ATTACKS What is a side channel ★ A

    side channel is a source of information about secret information besides the actual communication channel ★ In most cases the source of information a consequence of the system design unintended hard to control ★ Side channels and side-channel analysis is very common – also in everyday life How and Why ? 9 Personal identification system based on rotation of toilet paper rolls, Kurahashi et al. , IEEE PCC 2017
  7. CACHE-BASED COVERT CHANNEL ★ Memory access patterns affect data cache

    state ★ Cache state affects memory access timing ★ Measuring access timings reveals information about memory access patterns ◦ here: FLUSH+RELOAD Page Index Access Time (Cycle) How and Why ? 10
  8. CONDITIONAL BRANCH VS INDIRECT BRANCH ★ Conditional Branch: the processor

    must select one of two choices depending on the value of a condition (e.g. A > D). ★ Indirect branch: the processor reads a value that tells it where to fetch the next instruction. How and Why ? 12 Redirect execution to whatever address at memory location 0x10000c5f0. In this case, it will call the initterm function.
  9. SPECULATIVE AND OUT-OF-ORDER EXECUTION, BRANCH PREDICTION ★ Instructions can be

    executed in a different order and in parallel ★ Branches are predicted before the target is known How and Why ? 13 if (foo_array[index1] ^ foo_array[index2]== 0) { result = bar_array[100]; } else { result = bar_array[200]; }
  10. How and Why ? 14 OUT-OF-ORDER EXECUTION, SPECULATIVE EXECUTION AND

    BRANCH PREDICTION if (foo_array[index1] ^ foo_array[index2]== 0) { result = bar_array[100]; } else { result = bar_array[200]; }
  11. IN CASE OF MISSPECULATION ★ Exceptions & incorrect branch prediction

    can cause rollback of transient instructions ★ Old register states are preserved, can be restored ★ Memory writes are buffered, can be discarded ➔ Cache modifications are not restored! How and Why ? 15
  12. COVERT CHANNEL OUT OF MISSPECULATION ★ Sending via cache-based covert

    channel works from transient instructions How and Why ? 16
  13. SPECTRE CVE-2017-5753 ★ Variant 1 ★ Bounds Check Bypass ➔

    Primarily affects interpreters/JITs MELTDOWN CVE-2017-5754 ★ Variant 3 ★ Rogue Data Cache Load ➔ Affects kernels (and architecturally equivalent software) Attacks Overviews 18 CVE-2017-5715 ★ Variant 2 ★ Branch Target Injection ➔ Primarily affects kernels/hypervisors
  14. ROGUE DATA CACHE LOAD ★ Privilege-checks for memory access based

    on page table entries ★ Privilege-checks can be performed asynchronously ★ Dependent instructions can execute before execution is aborted! ★ Race condition in the privilege check ★ Straightforward attack: leak cached data ★ TU Graz result: uncached data can also be leaked ★ Suppression of architectural pagefault ◦ signal handler ◦ TSX ◦ mispredicted branch MELTDOWN / VARIANT 3 20
  15. ROGUE DATA CACHE LOAD MELTDOWN / VARIANT 3 21 char

    data = *(char *) 0xffffffff81a000e0; array[data * 4096] = 0; Kernel address
  16. MITIGATIONS: KERNEL ADDRESS SPACE ISOLATION (KAISER) A patch to the

    linux kernel that separates address spaces ★ 2 page tables ◦ “main” - unchanged but only accessible from kernel ◦ "shadow" page table contains a copy of all of the user-space mappings, but leaves out the kernel side. ★ Proposed by Gruss et al 2016 https://gruss.cc/files/kaiser.pdf ★ Later implemented to production quality by linux contributor Dave Hansen as KPTI ★ The defense provided by KAISER/KPTI is not complete, in that a small amount of kernel information must still be present to manage the switch back to kernel mode ◦ mispredicted branch MELTDOWN / VARIANT 3 22
  17. CONDITIONAL BRANCH EXAMPLE if (x < array1_size) y = array2[array1[x]

    * 256]; Execution without speculation is safe ★ CPU will never read array1[x] for any x ≥ array1_size Execution with speculation can be exploited ★ Attacker sets up some conditions ◦ train branch predictor to assume ‘if’ is likely true ◦ make array1_size and array2[] uncached Variant 1: Bounds Check Bypass 25
  18. SPECTRE if (x < array1_size) y = array2[array1[x] * 256];

    Invokes code with out-of-bounds x such that array1[x] is a secret ★ NOTE: This read changes the cache state in a way that depends on the value of array1[x] ★ … recognizes its error when array1_size arrives, restores its architectural state, and proceeds with ‘if’ false Attacker detects cache change (e.g. basic FLUSH+RELOAD or EVICT+RELOAD) ★ next read to array2[i*256] will be fast i=array[x] since this got cached Variant 1: Bounds Check Bypass 26
  19. Variant 1: Bounds Check Bypass 27 char* data = "textKEY";

    if (index < 4) index = 0; LUT[data[index]4096] 0 then else Prediction
  20. Variant 1: Bounds Check Bypass 28 char* data = "textKEY";

    if (index < 4) index = 0; LUT[data[index]4096] 0 then else Prediction Speculate
  21. Variant 1: Bounds Check Bypass 29 char* data = "textKEY";

    if (index < 4) index = 0; LUT[data[index]4096] 0 then else Prediction Execute
  22. Variant 1: Bounds Check Bypass 30 char* data = "textKEY";

    if (index < 4) index = 1; LUT[data[index]4096] 0 then else Prediction
  23. Variant 1: Bounds Check Bypass 31 char* data = "textKEY";

    if (index < 4) index = 1; LUT[data[index]4096] 0 then else Prediction Speculate
  24. Variant 1: Bounds Check Bypass 32 char* data = "textKEY";

    if (index < 4) index = 1; LUT[data[index]4096] 0 then else Prediction
  25. Variant 1: Bounds Check Bypass 33 char* data = "textKEY";

    if (index < 4) index = 2; LUT[data[index]4096] 0 then else Prediction
  26. Speculate Variant 1: Bounds Check Bypass 34 char* data =

    "textKEY"; if (index < 4) index = 2; LUT[data[index]4096] 0 then else Prediction
  27. Variant 1: Bounds Check Bypass 35 char* data = "textKEY";

    if (index < 4) index = 2; LUT[data[index]4096] 0 then else Prediction
  28. Variant 1: Bounds Check Bypass 36 char* data = "textKEY";

    if (index < 4) index = 3; LUT[data[index]4096] 0 then else Prediction
  29. Speculate Variant 1: Bounds Check Bypass 37 char* data =

    "textKEY"; if (index < 4) index = 3; LUT[data[index]4096] 0 then else Prediction
  30. Variant 1: Bounds Check Bypass 38 char* data = "textKEY";

    if (index < 4) index = 3; LUT[data[index]4096] 0 then else Prediction
  31. Variant 1: Bounds Check Bypass 39 char* data = "textKEY";

    if (index < 4) index = 4; LUT[data[index]4096] 0 then else Prediction
  32. Speculate Variant 1: Bounds Check Bypass 40 index = 4;

    LUT[data[index]4096] 0 then else Prediction char* data = "textKEY"; if (index < 4)
  33. Variant 1: Bounds Check Bypass 41 index = 4; LUT[data[index]4096]

    0 then else Prediction char* data = "textKEY"; if (index < 4) Execute
  34. Variant 1: Bounds Check Bypass 42 index = 5; LUT[data[index]4096]

    0 then else Prediction char* data = "textKEY"; if (index < 4)
  35. Speculate Variant 1: Conditional Branch Example 43 index = 5;

    LUT[data[index]4096] 0 then else Prediction char* data = "textKEY"; if (index < 4)
  36. else Execute Variant 1: Bounds Check Bypass 44 index =

    5; LUT[data[index]4096] 0 then Prediction char* data = "textKEY"; if (index < 4)
  37. Variant 1: Bounds Check Bypass 45 1 if (index <

    data.length) { 2 index = data[index | 0]; 3 index = (((index * TABLE1_STRIDE)|0) & (TABLE1_BYTES-1))|0; 4 localJunk ^= probeTable[index|0]|0; 4096B = page size Teach JIT that index is in bounds for data[] so it can omit bounds check in next line. Want length uncached for attack passes index will be in-bounds on training passes, and out-of-bounds on attack passes Do the out-of-bounds read on attack passes! This AND keeps the JIT from adding unwanted bounds checks on the next line Leak out-of-bounds read result into cache state! Need to use the result so the operations aren’t optimized JS optimizer trick (make result an int.)
  38. MITIGATIONS Workaround: insert instructions stopping speculation ★ insert after every

    bounds check ★ x86: LFENCE, ARM: CSDB ★ Available on all Intel CPUs, retrotted to existing: ARMv7 and ARMv8 Attacker detects cache change (e.g. basic FLUSH+RELOAD or EVICT+RELOAD) ★ next read to array2[i*256] will be fast i=array[x] since this got cached Variant 1: Bounds Check Bypass 46
  39. BASICS Branch predictor state is stored in a Branch Target

    Buffer (BTB) ★ Indexed and tagged by (on Intel Haswell): ◦ partial virtual address ◦ recent branch history fingerprint Branch prediction is expected to sometimes be wrong ★ Unique tagging in the BTB is unnecessary for correctness ★ BTB implementations do not tag by security domain ★ Prior research: Break Address Space Layout Randomization (ASLR) across security domains ➔ Inject misspeculation to controlled addresses across security domains Variant 2: Branch Target Injection 47
  40. spreadChoco() Variant 2: Branch Target Injection 48 LUT[data[index]4096] 0 fryEggOnions()

    Prediction Crepe* c = complete; c->prepare() spreadChoco()
  41. Speculate spreadChoco() Variant 2: Branch Target Injection 49 LUT[data[index]4096] 0

    fryEggOnions() Prediction Crepe* c = complete; c->prepare() spreadChoco()
  42. spreadChoco() Variant 2: Branch Target Injection 50 LUT[data[index]4096] 0 fryEggOnions()

    Prediction Crepe* c = complete; c->prepare() spreadChoco() Execute
  43. spreadChoco() Variant 2: Branch Target Injection 51 LUT[data[index]4096] 0 fryEggOnions()

    Prediction Crepe* c = complete; c->prepare() fryEggOnions()
  44. spreadChoco() Variant 2: Branch Target Injection 52 LUT[data[index]4096] 0 fryEggOnions()

    Prediction Crepe* c = complete; c->prepare() fryEggOnions() Speculate
  45. spreadChoco() Variant 2: Branch Target Injection 53 LUT[data[index]4096] 0 fryEggOnions()

    Prediction Crepe* c = complete; c->prepare() fryEggOnions()
  46. spreadChoco() Variant 2: Branch Target Injection 54 LUT[data[index]4096] 0 fryEggOnions()

    Prediction Crepe* c = chocoNuts; c->prepare() fryEggOnions()
  47. Speculate spreadChoco() Variant 2: Branch Target Injection 55 LUT[data[index]4096] 0

    fryEggOnions() Prediction Crepe* c = chocoNuts; c->prepare() fryEggOnions()
  48. spreadChoco() Variant 2: Branch Target Injection 56 LUT[data[index]4096] 0 fryEggOnions()

    Prediction Crepe* c = chocoNuts; c->prepare() fryEggOnions()
  49. Execute spreadChoco() Variant 2: Branch Target Injection 57 LUT[data[index]4096] 0

    fryEggOnions() Prediction Crepe* c = chocoNuts; c->prepare() fryEggOnions()
  50. EXPLOIT AGAINST KVM Break hypervisor ASLR using branch prediction ★

    Misdirect first indirect call with memory operand after guest exit ★ Flush cache line containing memory operand ★ Guest register state stays across VM exit ★ Guest memory is mapped ★ Abuse eBPF bytecode interpreter; call through register-loading gadget Variant 2: Branch Target Injection 58 rsi,r9 ffffffff81514edd: mov ffffffff81514ee0: call QWORD PTR [r8+0xb0] static unsigned int _bpf_prog_run(void *ctx, const struct bpf_insn *insn)
  51. MITIGATIONS Intel released microcode updates ★ Indirect Branch Restricted Speculation

    (IBRS) ◦ Do not speculate based on anything before entering IBRS mode ★ Indirect Branch Predictor Barrier (IBPB): ◦ Flush branch-target buer ★ Single Thread Indirect Branch Predictors (STIBP): ◦ Isolates branch prediction state between two hyperthreads and a compiler extension (software): Retpoline ★ Always predict to enter an endless loop instead of the correct (or wrong) target function! ★ Performance? ARM provides hardened Linux kernel Variant 2: Branch Target Injection 59
  52. Covert channels in CPUs are useful for more than transferring

    secrets between isolated processes Not all security issues are correctness issues Increasing complexity introduced by Intel to improve performance breaks security assumptions Conclusion
  53. Papers, Blogposts on Meltdown & Spectre Spectre: https://spectreattack.com/spectre.pdf Meltdown: https://meltdownattack.com/meltdown.pdf

    https://blog.cyberus-technology.de/posts/2018-01-03-meltdown.html https://googleprojectzero.blogspot.com/2018/01/reading-privileged-memory-with-side.html https://cyber.wtf/2017/07/28/negative-result-reading-kernel-memory-from-user-mode/ Prior research Y. Yarom, K. Falker, "FLUSH+RELOAD: a High Resolution, Low Noise, L3 Cache Side-Channel Attack" D. Evtyushkin, D. Ponomarev, N. Abu-Ghazaleh, "Jump Over ASLR: Attacking Branch Predictors to Bypass ASLR" F. Wilhelm, "PoC for breaking hypervisor ASLR using branch target buffer collisions", https://github.com/felixwilhelm/mario_baslr References
  54. 65