[Semi Thesis Review For me] Spectre Attacks: Exploiting Speculative Execution

2020. 6. 30. 17:20Computer Architecture/Cache security

Author: Paul Kocher1 , Jann Horn2 , Anders Fogh3 , Daniel Genkin4 , Daniel Gruss5 , Werner Haas6 , Mike Hamburg7 , Moritz Lipp5 , Stefan Mangard5 , Thomas Prescher6 , Michael Schwarz5 , Yuval Yarom8 1 Independent (www.paulkocher.com), 2 Google Project Zero, 3 G DATA Advanced Analytics, 4 University of Pennsylvania and University of Maryland, 5 Graz University of Technology, 6 Cyberus Technology, 7 Rambus, Cryptography Research Division, 8 University of Adelaide and Data61

 

wirter: Yu-gyoung yun

searchien@dgist.ac.kr

 

[Abstract]

  • Modern processors use branch prediction and speculative execution to maximize performance.
  • Speculative logic is unfaithful in how it executes, can access the victim's memory and registers, and can perform operations with measurable side effects.
  • Spectre attacks involve inducing a victim to speculatively perform operations that would not occur during correct program execution and which leak the victim's confidential information via a side channel to the adversary.
  • This paper describes practical attacks that combine methodology from side channel attacks, fault attacks, and return-oriented programming that can read arbitrary memory from the victim's process.

[1. Introduction]

Physical side-channel attacks can also be used to extract secret information from complex devices such as PCs and mobile phones.

The CPU attempts to guess the direction of cotrol flow, saves a checkpoint of its register state, and proceeds to speculatively execute the program on the guessed path. 

When the value eventually arrives from memory, the CPU checks the correctness of its initial guess.

If the guess was wrong, the CPU discards the incorrect speculative execution by reverting the register state back to the stored checkpoint.

From a security perspective, because CPUs are designed to maintain functional correctness by reverting the results of incorrect speculative executions to their prior states, these errors were previously assumed to be safe.

[A. Our Results]

Spectre attack: microarchitecture attack 

By influencing which transient instruction s are speculatively executed, we are able to leak information from within the victim's memory address space.

[Attacks using Native Code], [Attacks using JavaScript and eBPF]

[B. Our Techniques]

At a high level, Spectre attacks violate memory isolation boundaries by combining speculative execution with data exfiltration via microarchitectural covert channels.

While many choices are possible for the covert channel component, the implementations described in this work use cache-based covert channels, i.e., Flush+Reload and Evict+Reload.

 

Variant 1: Exploiting Conditional Branches.

the attacker mistrains the CPU's branch predictor into mispredicting the direction of a branch, causing the CPu to temporarily violate program semantics by executing code that would not have been executed otehrwise.

Image from this thesis paper.

X: attacker-controlled data

training the branch predictor to expect that the if will be true.

 

Variant 2:Exploiting Indirect Branches.

Drawing form return-oriented programming (ROP), in this variant the attacker chooses a gadget from the victim's address space and influences the victim to speculatively execute the gadget.

ROP참고 사이트: https://shayete.tistory.com/entry/6-Return-Oriented-Programming

 

6. Return Oriented Programming (ROP)

6. python programming 관련 동영상입니다. 설명은 생략하도록 할게요. 필요하신 분은 참고하세요! python 바이너리 사용법은 ./python [port] 입니다. 7. ROP 6은 건너뛰고 왜 7이냐면, 중간에 python..

shayete.tistory.com

프로그램을 마음대로 조종할 수 있는 취약점을 발견했지만 코드를 실행 가능한 메모리 영역(excutable memory)에 올릴 수 있는 확실한 방법이 없을 때 rop를 사용한다.

 

Unlike ROP, the attacker does not rely on a vulnerability in the victime code.

To mistrain the BTB, the attacker finds the virtual address of the gadget in the victim's address space, then performs indirect branches to this address. This training is done from the attacker's address space. It does not matter what resides at the gadget address in the attacker's address space.

 

**Meltdown과의 차이: 

Meltdown accesses kernel memory from user psace. This access causes a trap, but before the trap is issued, the instrcutions that follow the access leak the contents of the accessed memory through a cache covert channel.

[2. Background]

E. Microarchitectural Side-Channel Attacks

Initial microarchitectural side channel attacks exploited timing variability and leakage through the L1 data cache to extract keys from cryptographic primitives.

 

In this work, we use the Flush+Reload technuque, and its variant Evict+Reload.

1. Evicting a cache line

2. Perform a memory read at the address corresponding to the evicted cache line

3. data will be cached, and the access will be fast.

 

[3. Attack Overview]

1. setup phase, the adversary can also prepare the covert channel that will be used for extracting the victim's information, e.g., by performing the flush or evict part of a Flush+Reload or Evict+Reload attack.

2. the processor speculatively executes instruction(s) that transfer confidential information from the victim context into a microarchitectural covert channel.

3. the sensitive data is recovered. 

 

Spectre attacks only assume that speculatively executed instructions can read from memory that the victim process could access normally, e.g., without triggering a page falut or exception.

Hence, Spectre is orthogonal to Meltdown which exploits scenarios where some CPUs allow out-of-order execution of user instructions to read kernel memory. Consequently, even if a processor prevents speculative execution of instructions in user processes from accessing kernel memory, Spectre attacks still work.

 

[4. Variant 1: Exploiting Conditional Branch Misprediction]

Listing 1: Conditional Branch Example

The code fragment begins with a bounds check on x which is essential for security. 

Otherwise, an out-of-bounds input x could trigger an exception or could cause the processor to access sensitive memory by supplying x = (address of a secret byte to read) - (base address of array1).

 

Image from this thesis paper.

four cases of bounds check with speculative execution.

Before the result of the bounds check is known, the CPU speculatively executes code following the condition by predicting the most likely outcome of the comparison.

 

true-ture, false-false: correct prediction of the condition --> faster overall execution.

suppose an adversary causes the code to run such that:

    • the value of x is maliciously chosen (out-of-bounds), such that array1[x] resolves to a secret byte k somewhere in the victim’s memory;

    • array1_size and array2 are uncached, but k is cached; and

    • previous operations received values of x that were valid, leading the branch predictor to assume the if will likely be true.

 

This cache configuration can occur naturally or can be created by an adversary, e.g., by causing eviction of array1_size and array2 then having the kernel use the secret key in a legitimate operation.

 

1. processor begins by comparing the malicious value of x against array1_size.

2. Reading array1_size results in a cache miss --> caching from the DRAM

3. In the meantime, the branch predictor assumes the if will be true.

4. Consequently, the speculative execution logic adds x to the base address of aaray1 and requests the data at the resulting address from the memory subsystem. --> cache hit, quickly returns the value of the secret byte k.

5. The specultavie execution logic then uses k to compute the adderss of array2[k*4096].

6. array2[k*4096] --> cache miss.

7. While the read from array2 is already in flight, the branch result may finally  be determined.

 

--> the processor realized that its specultavie execution was erroneous and rewinds its register state.

But) the speculative read from array2 affects the cache state in an address-specific manner, where the address depends on k.

 

8. the adversary measures which location in array2 was brought into the cache, e.g., via Flush+Reload or Prime+Probe. --> reveals the value of k, since the victim's speculative execution cached array2[k*4096].

* Evict+Time, i.e., immediately call the target function again with an in-bounds value x' and measure how long this second call takes. If array1[x']==k, then the location accessed in array2 is in the cache, and the operation tends to be faster.

 

Instead of performing a bounds check, the mispredicted conditional branch(es) could be checking a previously-computed safety result or an object type.

 

For example, in some scenarios, the attack works even if array1_size is cached, e.g., if branch prediction results are applied during speculative execution even if the values involved in the comparison are known. Depending on the processor, speculative execution may also be initiated in a variety of situations. Further variants are discussed in Section VI.

 

A. Experimental Results

Image from this thesis paper.

 

C.Example Implementation in JavaScript

We developed a proof-of-concept in JavaScript and tested it in Google Chrome version 62.0.3202 which allows a website to read private memory from the process in which it runs. The code is illustrated in Listing 2.

Image from this thesis paper.

 

1. On branch-predictor mistraining passes, index is set to an in-range value. 

2. On the final iteration, index is set to an out-of-bounds address into simpleByteArray.

3. localJunk: to ensure that operations are not optimized out.

 

E. Accuracy of Recovered Data

Spectre attacks can reveal data with high accuracy, but errors can arise for several reasons.

[reasons for errors]

1. whether a memory location is cached typically use timing measurements, whose accuracy may be limited.

2. Errors can also occur if aaray2 elements become cached unexpectedly e.g., as a result of hardware prefectching, operating system activities, or other processes accessing the memory.

 

[5. Variant 2: POISONING INDIRECT BRANCHES]

In Spectre variant 2, the adversary mistrains the branch predictor with malicious destinations, such that sepculative execution continues at a location chosen by the adversary.

Image from this thesis paper.

예시로, attacker가 victim의 메모리를 보는 상황을 살펴보자.

victim의 메모리는 indirect branch가 일어났을 때 two register에 의해 컨트롤된다. 

This commonly occurs in real-world binaries since functions manipulating externally-received data routinely make function calls while registers contain values that an attacker cotnrols. Often these values are ignored by the called function and instead they are simply pushed onto the stack in the function prologue and restored in the function epilogue.

 

The attacker also needs to locate a "Spectre gadget", i.e., a code fragment whose speculative execution will transfer the victim's sensitive information into a covert channel.

1. adds(or XORs, subtracts, etc.) the memory location addressed by an attacker-controlled register R1 onto an attacker-controlled register R2, 

2. followed by any instruction that accesses memory at the address in R2.

 

 

 

 

 

[8. Conclusions]

A fundamental assumption underpinning software security techniques is that the processor will faithfully execute program instructions, including its safety checks.


More broadly, there are tarade-offs between security and performance.