攻击UEFI运行时服务和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运行时服务
最初,运行时服务功能的位置通过运行时服务表传送到操作系统。每个函数的物理地址是64位/8字节长,并以小端存储的形式保存在内存中。然而,到目前为止,所有系统的内存地址都在32位范围内。物理内存地址似乎是完全不变的,即在重新启动之间不发生随机化。
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,我们可以调用命令
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
Linux网络服务之DNS服务 DNS 是域名系统 (Domain Name System) 的缩写,是因特网的一项核心服务,它作为可以将域名和IP地址相互 映射的一个分布式数据库,能够使人更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串。
云栖大讲堂 擅长前端领域,欢迎各位热爱前端的朋友加入我们( 钉钉群号:23351485)关注【前端那些事儿】云栖号,更多好文持续更新中!
相关文章
- linux date -d参数用法
- 【Linux开发】linux设备驱动归纳总结(三):4.ioctl的实现
- error:command ‘aarch64-linux-gnu-gcc‘ failed with exit status 1| TX2安装jupyter
- 简易的 Linux 流量实时监控工具 watch+ifstat
- Linux pwn入门教程(10)——针对函数重定位流程的几种攻击
- Linux 4.9内核终被“扶正”,落实说好的LTS待遇
- Mumblehard:攻击Linux和FreeBSD的恶意软件
- ***在Linux环境下mysql的root密码忘记解决方法(三种)-推荐第三种
- Fairware勒索软件频繁攻击Linux服务器 大家赶紧做好备份
- Linux网络协议栈(一)——Socket入门(1)
- 学习 Linux,302(混合环境): Samba 角色
- Kali Linux中的十大WiFi攻击工具介绍
- Linux kernel内核调用crypto算法的方法
- Mirai物联网僵尸攻击竟然可以在Linux平台和Windows平台之间交叉传播
- Linux环境Oracle数据库访问出现ORA-01034错误:oracle not available解决
- Linux下Oracle client(sqlplus)安装和配置
- linux arp攻击解决方法 测试很有效
- 《Linux From Scratch》第二部分:准备构建 第四章:最后的准备- 4.5. 关于 SBU
- IDEA中Springboot项目部署到阿里云linux服务器
- 环境变量解释以及在Linux下的环境变量设置