【问题标题】:Understanding Spectre and memory addressing了解 Spectre 和内存寻址
【发布时间】:2018-01-08 19:42:06
【问题描述】:

首先声明:我无意破解任何人,我只想在我自己的机器上看到该漏洞利用。

我已经在 x64 Windows 10 上的 VS2017 中编译了 Spectre 示例。

该示例在从其自己的进程内存中读取时有效,但如果我尝试从我的测试应用程序中读取,我只会得到零字符串或其他类似字符。

测试应用:

#include "stdafx.h"
#include <string>
#include <iostream>

const char *gotroot = "The Magic Words are Squeamish Ossifrage.";

using namespace std;
int main()
{
    printf("%p",gotroot);

    string endd;
    cin >> endd;

    printf("%s", gotroot);
    return 0;
}

我启动应用程序并将地址复制粘贴到 Spectre 命令行,但我没有得到字符串。

我不知道 Windows 10 是否已经打过补丁?

但我也尝试过一段时间未更新的 Ubuntu 17.04,结果相同。

我的方法有问题吗?

【问题讨论】:

    标签: memory x86 spectre


    【解决方案1】:

    Spectre 是一个漏洞。我假设您提到的这个“幽灵命令行”是一些特定的实现/测试工具?它利用什么目标分支?大概是内核中的一个间接分支,否则你只能给它在它所攻击的任何目标程序的虚拟地址空间中的地址。

    因此,您需要目标进程正在使用的物理内存的内核地址,该地址位于映射所有物理内存的内核虚拟地址空间部分。 (或者无论 Windows 做什么,我都忘记了。但它显然不同于 Linux 的简单的 map-all-the-memory 和 1G 巨页设计)。但两者都将虚拟地址空间的上半部分用于内核地址。 Meltdown 论文解释了内核如何/为什么映射所有内存(并且如果内核不需要在 Intel CPU 上解决 Meltdown 问题,则会将其映射为全局,并受页表中的用户/主管位保护。Meltdown 破坏了该权限位.) 但是内核会在它执行其自己的代码时对其进行映射,因此 Spectre 可以利用该映射。 Meltdown 解决方法是在运行用户空间代码时取消映射内核页面。 Spectre 会诱使 CPU 在内核模式下推测性地执行一些内核指令。

    无论如何,这与您的进程在其自己的虚拟地址空间中使用的char* 值不同。物理内存的同一页被全局映射到高地址,作为内核映射所有区域的一部分,并且(当您的进程正在执行时)也映射到低地址以供用户空间代码使用。您使用%p 看到的是后一个地址。

    【讨论】:

    • 我指的是 Spectre 论文中的示例:spectreattack.com/spectre.pdf
    • 是否可以计算用户空间进程中某个地址的内核地址?我只是想知道为什么他们添加了一个命令行参数来输入地址,如果它不能访问除了它自己的进程之外的任何内存?
    • 不,不是。内核 ASLR 的存在是有原因的。但是,如果您使用内核调试器、内核日志记录或任​​何其他方式来查找地址,则可以使用此工具来读取它。如果该工具采用内核地址,它只是一个 Spectre 演示器,不是为可用性而打包的完整工作漏洞。
    • 好的。最后一个问题。我仍然感到困惑的一件事是,我在另一篇文章中读到 C 实现对物理地址一无所知。从物理地址空间到虚拟地址空间的转换超出了过程。但是 C 程序如何访问内核地址呢?
    • @user3866319:内核在启用分页的情况下运行;要使用物理内存页(供自己使用,或将其设置为用户空间进程),内核会在页表中建立映射,然后访问 virtual 地址,其中它映射了那个物理页面。一些内核(例如 Linux)将所有物理内存直接映射到一个连续的虚拟地址范围,以便轻松访问任何物理地址(通过在映射所有内容的区域中使用偏移量)。请注意,一个物理页面(也称为页框)可以由多个虚拟页面映射。
    猜你喜欢
    • 2013-11-05
    • 1970-01-01
    • 1970-01-01
    • 2011-03-12
    • 1970-01-01
    • 1970-01-01
    • 2016-01-13
    • 1970-01-01
    • 2015-11-15
    相关资源
    最近更新 更多