攻击UEFI运行时服务和Linux

简介:

Linux

前言

具有物理访问权限的攻击者能够在许多具有DMA-直接内存访问的完全修补的计算机上攻击固件。一旦在UEFI/EFI运行时服务中执行代码,就可以使用脚本来控制正在运行的Linux系统。

Linux 4.8内核完全随机化了内核的物理内存地址。如果计算机拥有足够大的内存,内核很有可能随机化到4G以上的地址空间上。这意味着DMA硬件攻击仅能够攻击32位的地址(4GB),如PCILeech,不能直接攻击Linux内核。

由于EFI运行时服务通常位于4GB以下,因此它们在高内存EFI引导系统上提供了一种进入Linux的方法。

什么是EFI运行时服务?

PC上的UEFI,mac上的EFI是现代化的BIOS。UEFI是统一的可扩展固件接口的缩写。UEFI负责检测硬件和配置设备,以便于将控制移交给正在加载的操作系统。

UEFI的两个主要组件是引导服务和运行时服务。操作系统上很早就调用ExitBootServices。随后引导服务就不再使用。

即使在操作系统加载和运行后,EFI Runtime Services仍然保持运行。它们提供操作系统可以调用的各种功能。UEFI规范指定了运行时服务应该向操作系统提供的一组固定的函数,如下所示。

UEFI规范指定了运行时服务应该向操作系统提供的一组固定的函数

UEFI运行时服务

最初,运行时服务功能的位置通过运行时服务表传送到操作系统。每个函数的物理地址是64位/8字节长,并以小端存储的形式保存在内存中。然而,到目前为止,所有系统的内存地址都在32位范围内。物理内存地址似乎是完全不变的,即在重新启动之间不发生随机化。

Linux随后将这些地址映射到虚拟地址空间,并用相应的虚拟地址覆盖表中的初始地址。初始表和被Linux修改后的表的如下所示。

初始表和被Linux修改后的表

EFI Runtime服务表,原始在左边,Linux修改的为右边。

攻击

如果我们使用DMA用自己的代码覆盖EFI运行时服务表会发生什么?或者,如果我们修改EFI运行时服务表的指针,让它指向之前插入的攻击代码,这又会发生什么?

当操作系统调用EFI运行时服务时,会在目标系统上执行代码-例如当它读取一个EFI变量。在特殊上下文中获得执行代码,其中较低的内存页面在虚拟地址与物理地址之间以1:1映射。在正常的虚拟地址中是可以访问到Linux内核的。在ring0/supervisor模式下执行。

然而,调用Linux内核中的所有函数是不可能的。一些函数会调用失败,因为Linux已经为运行时服务设置了特殊的EFI上下文。针对这种情况,可以在Linux内核中patch 一个“随机”的钩子函数。当“正常”内核线程命中该钩子时,被hook的内核代码将会被执行.

目标系统运行Ubuntu 16.10,连接着攻击硬件的PCILeech。右视图为PCILeech

目标

已经在一台具有8GB内存的联想T430和一台具有32G内存的 Intel NUC Skull Canyon做过了测试。T430的ExpressCard插槽用于获得DMA访问,在NUC上,在“BIOS”中设置Thunderbolt模式为“Legacy” – 允许通过Thunderbolt3 / USB-C进行DMA访问。

T430非常简单,只需插入PCILeech设备并调用pcileech.exe kmdload -kmd linux_x64_efi命令。PCILeech将搜索EFI运行时服务表并hook它。然后要求用户执行某些操作来触发已hook过的服务。

NUC是不同的。PCILeech在找到目标之前如果遇到不可读的内存就会失败。幸运的是,运行时服务表的地址是静态的,在重新启动之间不会改变。这适用于所有已测试的系统。找到地址最简单的方法是通过在同一系统或相似系统上以EFI模式用USB引导启动Linux。一旦启动就调用命令cat /sys/firmware/efi/runtime来查看运行时服务表的物理地址。一旦知道地址是0x3b294e18,我们可以调用命令


 
 
  1. pcileech.exe kmdload -kmd linux_x64_efi -min 0x3b294000 -max 0x3b295000 

显示被攻击的运行时服务表

备注

如果你也想试试,可以查看Github上的PCILeech。

虽然漏洞总是在运作,但是攻击并不是100%稳定的。有时,搜索运行时服务表会失败,有时很难触发对运行时服务表的调用。有时目标系统也会崩溃。

结论

在Linux 4.8操作系统上,如Ubuntu 16.10。由于可以利用PCILeech,所以不再是完全安全的。 即使你的笔记本电脑可能没有一个ExpressCard插槽,但是如果拧开后盖,它可能会有一个mini-PCIe或M.2插槽。

操作系统将重要的数据放在高于32-bit/4GB的地址上并不能阻止DMA攻击。32位硬件(如PCILeech)会攻击低于4GB的代码和数据。其他恶意硬件也可能攻击多达到64位地址空间。

操作系统应该启用VT-d来保护自身和固件(例如运行时服务)免受恶意设备的攻击。


作者:胖胖秦

来源:51CTO

相关文章
|
9月前
|
Linux 网络安全 Docker
盘古栈云,创建带ssh服务的linux容器
创建带ssh服务的linux容器
468 146
|
10月前
|
缓存 安全 Linux
六、Linux核心服务与包管理
在没有网络的情况下,使用系统安装光盘是获取RPM包的常用方法。场景二:配置本地文件镜像源 (使用系统安装光盘/ISO)(检查RPM包的GPG签名以保证安全) 或。YUM/DNF包管理工具 (yum/dnf)(此处可以放置您为本主题制作的思维导图)处理依赖问题的危险选项 (应极力避免)(覆盖文件、替换已安装包)。(list) 则是列出文件。(query file) 是。(假设系统安装光盘已挂载到。信息 (verbose)。(upgrade) 选项。(all) 已安装的包。(package) 选项
688 11
|
Linux Shell
在Linux、CentOS7中设置shell脚本开机自启动服务
以上就是在CentOS 7中设置shell脚本开机自启动服务的全部步骤。希望这个指南能帮助你更好地管理你的Linux系统。
2286 25
|
Linux Docker 容器
Linux 中停止 Docker 服务报 warning 导致无法彻底停止问题如何解决?
在 Linux 系统中,停止 Docker 服务时遇到警告无法彻底停止的问题,可以通过系统管理工具停止服务、强制终止相关进程、检查系统资源和依赖关系、以及重置 Docker 环境来解决。通过以上步骤,能够有效地排查和解决 Docker 服务停止不彻底的问题,确保系统的稳定运行。
1267 19
|
Linux iOS开发 MacOS
Gitea Enterprise 23.4.0 (Linux, macOS, Windows) - 本地部署的企业级 Git 服务
Gitea Enterprise 23.4.0 (Linux, macOS, Windows) - 本地部署的企业级 Git 服务
486 0
Gitea Enterprise 23.4.0 (Linux, macOS, Windows) - 本地部署的企业级 Git 服务
|
监控 Linux
Linux systemd 服务启动失败Main process exited, code=exited, status=203/EXEC
通过以上步骤,可以有效解决 systemd 服务启动失败并报错 `Main process exited, code=exited, status=203/EXEC` 的问题。关键在于仔细检查单元文件配置、验证可执行文件的有效性,并通过日志分析具体错误原因。确保可执行文件路径正确、文件具有执行权限,并且可以独立运行,将有助于快速定位和解决问题。
6756 7
|
安全 网络协议 Linux
结合 `nc` 工具利用笑脸漏洞(Smile Bug)攻击 Metasploitable2 Linux
本文介绍如何使用 `nc`(Netcat)工具结合笑脸漏洞(Smiley Bug)攻击 Metasploitable2 Linux 靶机。首先概述了 `nc` 的基本功能和高级用法,包括建立连接、监听端口、文件传输等操作。接着详细描述了笑脸漏洞的原理及其在网络攻防中的应用,展示了通过 `nc` 发送恶意输入检测漏洞的方法。最后结合 Python 脚本实现更复杂的攻击场景,并强调了合法性和环境隔离的重要性。
676 13
|
Ubuntu Linux Go
golang编译成Linux可运行文件
本文介绍了如何在 Linux 上编译和运行 Golang 程序,涵盖了本地编译和交叉编译的步骤。通过这些步骤,您可以轻松地将 Golang 程序编译成适合 Linux 平台的可执行文件,并在目标服务器上运行。掌握这些技巧,可以提高开发和部署 Golang 应用的效率。
3256 14
|
Linux 应用服务中间件 Shell
linux系统服务二!
本文详细介绍了Linux系统的启动流程,包括CentOS 7的具体启动步骤,从BIOS自检到加载内核、启动systemd程序等。同时,文章还对比了CentOS 6和CentOS 7的启动流程,分析了启动过程中的耗时情况。接着,文章讲解了Linux的运行级别及其管理命令,systemd的基本概念、优势及常用命令,并提供了自定义systemd启动文件的示例。最后,文章介绍了单用户模式和救援模式的使用方法,包括如何找回忘记的密码和修复启动故障。
504 5
linux系统服务二!
|
Linux 应用服务中间件 Shell
linux系统服务!!!
本文详细介绍了Linux系统(以CentOS7为例)的启动流程,包括BIOS自检、读取MBR信息、加载Grub菜单、加载内核及驱动程序、启动systemd程序加载必要文件等五个主要步骤。同时,文章还对比了CentOS6和CentOS7的启动流程图,并分析了启动流程的耗时。此外,文中还讲解了Linux的运行级别、systemd的基本概念及其优势,以及如何使用systemd管理服务。最后,文章提供了单用户模式和救援模式的实战案例,帮助读者理解如何在系统启动出现问题时进行修复。
481 3
linux系统服务!!!