代码之家  ›  专栏  ›  技术社区  ›  Jean-Pierre Coffe

segfault期间是否访问了物理内存的其他部分?

  •  1
  • Jean-Pierre Coffe  · 技术社区  · 6 年前

    作为学习项目的一部分,我对幽灵和熔毁POC进行了一些研究,以使自己更容易理解这个概念。我已经设法使用时钟计时器恢复以前访问过的数据,但现在我想知道他们如何从那一点读取物理内存。

    这就引出了我的问题:在许多Spectre v1\v2示例中,您可以阅读以下玩具代码示例:

    if (x<y) {
      z = array[x];
    }
    

    假设x等于:attacked\u address-address\u of\u array,这将有效地导致z获得attacked\u address处的值。

    在这个例子中,很容易理解,但实际上他们怎么知道attacked\u address是什么样子的呢? 它是一个带有偏移量的虚拟地址,还是一个物理地址,它们如何首先找到“重要内存”所在的位置?

    1 回复  |  直到 6 年前
        1
  •  1
  •   Andriy Berestovskyy    6 年前

    在这个例子中,很容易理解,但实际上他们怎么知道attacked\u address是什么样子的呢?

    你说得对,幽灵和熔毁只是可能,不是现成的攻击。如果您知道来自其他来源的攻击地址,即使使用浏览器,幽灵和熔毁也是获取数据的方法。

    它是一个带有偏移量的虚拟地址,还是一个物理地址,它们如何首先找到“重要内存”所在的位置?

    当然,它是一个虚拟地址,因为它都发生在用户空间程序中。但在最近的内核补丁之前,我们将完整的内核空间映射到每个用户空间进程中。这样做是为了加速系统调用,即只对每个系统调用执行权限上下文切换,而不是进程上下文切换。

    因此,由于这种设计和崩溃,可以从未修补内核上的非特权用户空间应用程序(例如浏览器)读取内核空间。

    通常,最简单的攻击场景是针对具有旧内核的机器,而旧内核不使用地址随机化,即内核符号位于运行特定内核版本的任何机器上的相同位置。基本上,我们在测试机器上运行特定的内核,写下“重要内存地址”,然后使用这些地址在受害者机器上运行攻击。

    看看我的基于Specter的熔毁PoC(即2合1): https://github.com/berestovskyy/spectre-meltdown

    它比Specre论文中的原始代码更简单、更容易理解。它只有99行C语言(包括注释)。

    它使用上述技术,即对于Linux 3.13,它只是尝试读取预定义的地址 0xffffffff81800040 这是 linux_proc_banner 位于内核空间的符号。它在内核为3.13的不同机器上无任何权限运行,并成功读取每台机器上的内核空间。

    它是无害的,但只是一个很小的工作PoC。