Download as pdf or txt
Download as pdf or txt
You are on page 1of 55

iDRACKAR,集成式戴尔远程访问控制器对内

存的友好处理方法

尼古拉-尤斯
nicolas.iooss@ssi.gouv.fr
ANSSI

摘要当底板管理控制器(BMC)作为远程管理和监控服务器的解决

方案越来越受欢迎时,最近发现了几个针对它们的关键漏洞。在惠

普公司生产的服务器上,有消息称,攻击者通过直接内存访问(

DMA)通道入侵 BMC,从而读写主操作系统的内存。由于这些通

信通道并非惠普公司特有,因此可以预计,允许攻击者在其他制造

商生产的 BMC 上执行任意代码的漏洞也会提供类似的访问权限。

2018 年,一个针对戴尔 BMC(名为 iDRAC)的远程代码执行漏洞

被公布。利用该漏洞提供的访问权限使攻击者处于类似于在数据中

心对服务器进行物理访问的位置:他们可以观看屏幕、使用键盘和

鼠标、重启服务器等。但是,他们无法读写服务器的 RAM。更确

切地说,没有人描述过 iDRAC 如何对服务器的主 RAM 执行 DMA

在戴尔 PowerEdge 服务器上,iDRAC 可以对许多硬件组件进行低级

访问,例如监控 CPU 的功率和温度。它通常不对主存储器执行

DMA,但如果 iDRAC 可以访 问 相关硬件接口,则有可能实现这一

点。本文将深入研究 iDRAC 8 使用的接口,以了解它是否能访问主

存储器。文章还重点介绍了更有可能提供这种访问的组件,如虚拟

USB 设 备 、 与 iDRAC 连 接 的 CPLD 以 及 iDRAC 前 几 版 暴 露 的

PCIe 设备。最终,这些设备似乎都无法访问主操作系统的内存。不

过,iDRAC 与一个 H8S 微控制器有联系,该微控制器似乎与 PCIe

总线密切相关。对这种新型微控制器的分析工作仍在进行中。

1 导言
一些服务器制造商一直在开发通过专用网络接口和操作系统对服

务器进行带外监控和管理的系统。这些系统被称为底板管理控制器(

BMC),在专用处理器上运行,并测量服务器的性能。
2 iDRAC 分析

服务器组件(温度、功耗、风扇、内存状态等)。

戴尔公司至少从 1999 年起就开始开发一种名为 "戴尔远程访问控

制器(DRAC)"的 BMC。该产品最初是插拔式设备,后来成为服务
器主板上的集成芯片组(iDRAC 6)。如今,每一代戴尔 PowerEdge

服务器都会对芯片组进行新的修订:iDRAC 7 出现在第 12 代(2012

年),iDRAC 8 出现在第 13 代(2014 年),i D R A C 9 出现在第 14

代(2017 年)。自 iDRAC 6 以来,iDRAC 的架构和功能发生了多次

变化。例如,戴尔在 2016 年引入了 HTML5 远程控制台(取代了

Java applet),并实施了 Redfish API(通过 HTTPS 的标准化 REST

API,用于执行与系统管理相关的若干操作)。此外,随着 iDRAC 9

的发布,最重要的变化之一是从瑞萨 SuperH CPU(名为 SH4)过渡

到 ARMv7 CPU。现在,iDRAC 的固件与普通 Linux 系统类似。

它基于 GNU/Linux 内核,使用 systemd 作为启动系统,并使用

OpenSSL 库进行加密操作。多年来,iDRAC 已发现并修复了多个

漏洞。例如,去年发现了一个关键漏洞 CVE-2018-1207。它允许

任何人获得 root shell 并在 iDRAC 上执行任意代码。利用这个漏洞

,任何人都可以访问 iDRAC 管理控制台,并执行控制虚拟键盘和鼠

标、观看屏幕内容、从文件插入虚拟光驱、重启托管服务器,以及使

用 iDRAC 专用的网络接口控制器与邻居系统通信等操作。这些操作与

潜入数据中心并实际访问服务器的攻击者所能执行的操作类似。

然而,在 iDRAC 上执行代码的攻击者并不在服务器旁边,而是在

服务器内部。这就引出了以下问题:从 iDRAC 系统的 root shell 是

否有可能读取服务器主物理内存中的数据,从而破坏密码或加密密钥

?是否有可能对其进行修改?主操作系统能否防止此类意外访问

,如适当配置 IOMMU1 ?

尽管戴尔服务器的 iDRAC 可对许多硬件组件进行底层访问,

但它通常不会访问主内存中的数据。因此,本文将介绍 iDRAC 所
N.Iooss 3

使用的接口,以了解它是否可以访问主存储器。

1.输入输出存储器管理单元是一个限制设备访问主存储器的组件。
4 iDRAC 分析

在对 iDRAC 提供的合法和有记录的功能进行简短描述后,本报告

重点关注更有可能提供这种访问的组件。更确切地说,它研究了

iDRAC 与主操作系统之间共享的设备,如一些 USB 设备和屏幕。

由于这些设备并不提供从 iDRAC 访问 PCIe 总线的权限,因此本

文将继续描述更具体的组件,如使用的 CPLD2 和名为 "PBI 设备 "

的神秘 PCIe 端点。分析最后发现了 iDRAC 引导加载程序用于闪

存名为 "PCIe 桥 "的组件的文件。该文件包含的代码似乎使用了一

种不常见的指令集 H8S,以及从主操作系统中看到的一些 PCIe 开

关和桥接器的 16 位标识符。对这些代码的分析工作仍在进行中,

目 前 还 不 清 楚 运 行 H8S 代 码 的 组 件 是 否 可 以 向 主 存 储 器 执 行

DMA 请求。

由于所有有希望的线索目前都已失败,iDRAC 似乎无法直接访问

PCIe 总线以读取主存储器。至于能否通过间接方式(例如修改由

iDRAC 引导加载程序刷新的 PCIe 桥固件)进行访问,目前尚不得而

知。

本文所介绍的工作要感谢 ANSSI,它为作者提供了一台戴尔

PowerEdge R730 服务器(第 13 代)。该服务器配备了 iDRAC 8

版本

2.40.40.40 和一些漏洞。iDRAC 9 与 iDRAC 9 存在重大差异(如

CPU 架构),因此预计本文中的许多内容不适用于 iDRAC 9 和未

来版本。

2 最新技术

底板管理控制器(BMC)的实现已有二十多年的历史:戴尔的首

款远程访问控制器(DRAC)至少从 1999 年就已问世,惠普于 2002

年推出了 ProLiant BL20p 及其 iLO(集成熄灯),英特尔在其管理


N.Iooss 5

引擎(ME)上采用了主动管理技术(AMT),该技术可在 2005

年推出的芯片组上找到,等等。

自这些系统诞生以来,已经发现了许多漏洞。最近发现的漏洞

包括

2. 复杂可编程逻辑器件是一种可编程逻辑器件,可用于实现算法,而无需制

造定制芯片组。
6 iDRAC 分析

AMT(CVE-2017-5689)和 iLO(CVE-2017-12542)上的多个验证后

远 程 代 码 执 行 漏 洞 、 iLO ( CVE-2017- 12542 、 CVE-2018-7078 和

CVE-2018-7105)和 iDRAC(CVE-2018-7105)上的多个验证后远程

代码执行漏洞。

1207)和 iDRAC 上的堆损坏(CVE-2018-1000116)。

一些 BMC 实施了一套名为智能平台管理接口(IPMI)的规范。多年

来,人们对这些规范及其实施进行了深入研究。2013 年,Anthony

Bonkoski、Russ Bielawski 和 J. Alex Halderman 描述了几个实施方

案(惠普的 iLO、戴尔的 iDRAC、甲骨文的 iLOM 和联想的 IMM

)以及针对它们的一些漏洞[1]。2015 年,Felix Emmert 分析了 iDRAC

7 提供的功能,并撰写了一份关于固件的简短说明[2]。2017 年,来

自 Pos- itive Technology 的 Mark Ermolov 和 Maxim Goryachy 在欧洲黑

帽大会上介绍了他们对英特尔 ME 和 AMT 的研究[3]。同年,

CERT-FR 发 布 了 一 些 与 IPMI 配 置 相 关 的 指 南 [4] 。 2018 年 ,

Fabien Périgaud、Alexandre Gazet 和 Joffrey Czarny 在多个会议(

Recon Brussels [6]、SSTIC [5] 和 ZeroNights [7])上介绍了他们关

于惠普 iLO 的工作。2018 年夏季,来自 Immunity 公司的 Matias

Soler、Sebastian Soler 和 Nico Waisman 在美国黑帽大会上介绍了

针对惠普 iLO 和戴尔 iDRAC 的其他漏洞[8]。这些漏洞包括 CVE-

2018-1207,允许未经认证的远程用户在 iDRAC 上以 root 身份运

行代码。

许多已公布的漏洞都有可能在 BMC 上执行任意代码。一旦实现

了这一点,攻击者就可以根据平台的不同:

— 窃取 BMC 使用的本地凭证(iLO 上的未加密账户密码、

iDRAC 上的密码哈希值等);

— 连接到虚拟键盘-视频-鼠标界面,与主操作系统进行交互;

— 使用虚拟键盘-视频-鼠标和虚拟媒体接口重启服务器并运行任
N.Iooss 7

意操作系统;

— 在 iLO 上使用直接内存访问 (DMA) 控制器读取或修改主物

理内存 (RAM) 的内容;

— 使用 BMC 可以使 用 的以太网接口,向连接到同一网络的设备

传输网络流量;

— 升级 BMC 固件和服务器的其他关键组件,最终使用后台固

件镜像;

— 等等

作者通常会描述他们实现了哪些操作,以及他们使用的漏洞的内

部结构。这种方法使
8 iDRAC 分析

读者需要考虑漏洞的严重性,同时对一旦在 BMC 上执行任意代

码后真正可能实现的目标保持一定的警惕。

例如,从 BMC 访问主存储器在 iLO 上是可行的。但是,从被入

侵的 iDRAC 中访问主存储器的情况还没有被描述过。这是否意味着

这种访问是不可能的?如果可能,那就应该由可从 iDRAC 访问的硬

件组件提供。这就是为什么与其他著作相比,本文更关注服务器的

硬件组件,而较少关注网络提供的服务。

3 发现 iDRAC 8 系统

3.1 使用标准协议的服务

在服务器上配置 iDRAC 8 后,它可为用户管理服务器提供许多服

务。这些服务是通过几个标准协议实现的:

— HTTPS 由网络服务器使用,可提供
— 使用 HTML5 WebSockets 远程查看屏幕;
— JSON:API3 端点,实现 Redfish 1.0 API;
— 命令行界面(SMASH CLP)使用的 SSH;
— IPMI 通过 UDP 和 SNMP,由各自的服务使用;
— IPMI over SMBus,用于主操作系统与 iDRAC 之间的通信

对这些接口的研究有助于更好地了解 iDRAC 的底层能力。

如以前的出版物[1]所述,这些界面可能要求用户在执行操作前进

行身份验证。例如,网络服务器的主页面包含一个要求输入用户名和

密码的表单(图 1)。

通过身份验证的用户可以启动虚拟控制台(网址为
/virtualconsolehtml5.html),以显示服务器屏幕的内容,并使用键

盘和鼠标与之交互(图 2)。按下的键和鼠标的移动通过网络浏览
N.Iooss 9

器和 iDRAC 传送到主操作系统,主操作系统将其视为来自一个名为

"Avocent 键盘/鼠标功能 "的 USB-HID 设备,该设备连接到一个名为 "

戴尔计算机 "的 USB 集线器上。

3. JSON:API 是使用 JavaScript Object Notation(https://jsonapi.org/)构建

应用程序编程接口的规范名称。
10 iDRAC 分析

图 1.iDRAC 登录页面 8.

图 2.iDRAC 8 上的远程控制台。
N.Iooss 11

Corp.Hub"。这意味着 iDRAC 能够模拟主操作系统的某些 USB 设

备。第 4 节将详细介绍这种交互。

用户还可以从网站的认证部分重新配置 iDRAC、触发服务器重

启、更改 UID LED4 的状态等。所有这些功能都要求 iDRAC 与主

操作系统共享一些主板组件的访问权限。

网络服务器还实现了 Redfish 1.0 应用程序接口,网址为


/该 API 可让通过身份验证的用户执行 BMC 提供的大部分操作(监控

服务器、将账户添加到 iDRAC5 等),但采用的方式更易于与程序集

成。在惠普 iLO 使用的 Web 服务器上,该界面存在身份验证绕过漏

洞(CVE-2017-12542),Périgaud、Gazet 和 Czarny 公布了一种利用

该漏洞完全入侵惠普服务器的方法 [6]。尽管 iDRAC 上不存在此漏洞

,但这证明了此 API 的强大功能,以及 iDRAC 的网络服务器需要对

服务器的硬件组件拥有访问权限的事实。戴尔的实施方案让网络服务

器以 root 身份运行,这可能与所需的访问权限有关。

Redfish API 提供的操作也由通过 SSH 提供的 SMASH CLP(服务

器硬件系统管理架构--命令行协议)提供。尽管 iDRAC 使用的是

GNU/Linux 内核,但用户验证 iDRAC SSH 服务器时出现的提示符是

SMASH CLP 提示符,而不是 bash 等常用 shell。

3.2 固件自由

戴尔在 iDRAC 中使用了大量免费软件。例如,这可以从随固件更

新发布的更新日志中看出。例如,iDRAC 8 更新到 2.50.50.506 版时包

含了 "将 OpenSSH 升级到 7.4p1 "和 "升级到 OpenSSL 1.0.2k "等更改

。此外,戴尔还在 iDRAC 网站的 "关于 "页面上发布了这些软件的源

代码,其中包含所做的更改。该页面包含以下内容:

以下部分软件可能包含开放源码软件,您可以根据开放源码软件发布所依据

的特定许可证的条款和条件使用这些软件。对于某些开源软件许可、
12 iDRAC 分析

4. 单元 ID LED 是服务器上的一个发光二极管,有助于识别服务器。
5. 可使用 /redfish/v1/Managers/iDRAC.Embedded.1/ Accounts 端点添加账户


6. https://www.dell.com/support/home/us/en/04/drivers/driversdetails?
driverId=278FC
N.Iooss 13

您也有权获得相应的源文件。您可以在 https://opensource.dell.com 上找到该程

序的相应源文件。

可从 https://opensource.dell.com/releases/ idrac8/ 下载 iDRAC 8 组

件的数千兆字节压缩数据。提取后,这些数据包括

— iDRAC 使用的一些自由软件项目的源代码(在
externalsrc/):
— 在 externalsrc/linux-yocto/ 中的 GNU/Linux 内核,以及

iDRAC 片 上 系 统 (SoC) 的 特 定 文 件 , 如

arch/sh/boards/board-sh7757lcr.c ;

— iDRAC 固件中使用的戴尔定制内核模块。
externalsrc/linux-drivers/ ;
— U-Boot 引导加载程序位于 externalsrc/u-boot-idrac8/ 目录

, iDRAC SoC 专 用 文 件 位 于 u-

boot_B0/board/renesas/sh7757lcr/ 目录;

— OpenSSL、OpenSSH 补丁等;
— 在 i p k - d r o p b o x / 中有许多二进制可执行文件(ELF 格式

的程序和共享库),这些文件是为 SH4 CPU 编译的;

— 许多其他目录(meta-drac、meta-oe、poky 等)。

通过分布式源代码中的注释,可以更好地了解 iDRAC 固件如

何使用硬件。

此外,固件更新没有加密。Linux 系统的更新包由一个 shell

脚本和一个 tar.gz 格式的压缩包组成。可以使用常见 Linux 系

统中的工具(如 tar 命令)提取该压缩包。它包含几个工具,可

用于运行 Linux 的戴尔服务器,使用 Linux 的 IPMI 驱动程序(通过

/dev/ipmi0)升级 iDRAC 的固件。新固件位于 payload/firmimg.d7 文

件中,包含 U-Boot 映像头、Linux 内核和两个 Squashfs 格式的文件


14 iDRAC 分析

系统,可使用 Binwalk 提取。其中一个文件系统是 iDRAC 的根文

件系统,包含常用目录(/bin、/dev、/etc、/usr 等)。有关制作

固件所使用的 Linux 发行版的信息,可在多个文件中找到:

— /etc/issue 为 "Poky 8.0(Yocto Project 1.3 参考发行版)1.3";


— /bin/net-snmp-config 是 一 个 shell 脚 本 , 包 含 sh4-poky-

linux-gcc 的选项,如 --sysroot=


/home/jenkins/jenkins_slave_builds_prod/workspace/
idrac-13g-ducati1.5-master-release-A-Rev/
build-yocto-sh4/tmp/sysroots/idrac8;
N.Iooss 15

— 许多二进制文件在引用其源文件路径时,都会参考 Jenkins 目

录。

正如 Poky 网站7 上所描述的,"Poky 是一个参考发行版,它包含了


以下内容
Yocto项目 ◯R "。Yocto 项目 ◯R 是一个项目,其目标是
开发能创建 Linux 发行版的工具和程序
Poky 是一个独立于嵌入式硬件底层架构的嵌入式和物联网软件发

行版8 。找到的文件显示,Poky 是戴尔用于构建 iDRAC 固件的发

行版。

3.3 获取外壳

Matias Soler、Sebastian Soler 和 Nico Waisman 在 Black Hat

USA 2018 上介绍了一种利用 CVE-2018-1207 漏洞在 iDRAC 上执

行任意命令的方法 [8]。利用这一漏洞,攻击者可以通过 iDRAC

网站上传共享库,并在浏览器启动的进程中加载共享库。利用在

加载库后立即执行的函数,攻击者可以在 iDRAC 上以 root 用户身

份运行任意代码。研究人员利用该漏洞从网络服务器启动了一个反

向 shell(通过建立 TCP 连接并将其绑定到新的 /bin/sh 实例)。


这个 shell 是以用户 root 的身份启动的。如果该 shell 可直接通过

SSH 访问,分析 iDRAC 就会更加容易。清单 1 列出了

/etc/passwd 的初始内容。racuser 的 shell 是 /usr/bin/clpd,它是

实现 SMASH CLP 的程序。实验表明,iDRAC 使用 racuser 创建

SSH 连接产生的进程9 。将 racuser 的 shell 替换为 /bin/sh(使用 CVE-

2018-1207 获得的反向 shell)后,当用户通过 SSH 连接到 iDRAC 时,

真正的 shell

而不是 SMASH CLP。


16 iDRAC 分析

root : x :0:0: root :/:/ bin / sh


user 1 : x :500 :500 : Linux 用户 ,,,:/:/ bin / sh
racuser : x :1000 :500 : Linux 用户 ,,,:/ tmp :/ usr / bin / clpd
avahi : x :70:70:Avahi m DNS / DNS - SD Stack :/ var / run / avahi - daemon
:/ sbin /
糯米
sshd : x :74:74:Privilege - separated SSH :/ var / empty / sshd :/ bin /
false messagebus : x :999 :997 ::/ var / lib / dbus :/ bin / false
_lldpd : x :1001 :1001 : Linux 用户 ,,,:/ home / _lldpd :/ bin / sh

清单 1. iDRAC 固件中的原始 /etc/passwd。

7. https://www.yoctoproject.org/software-item/poky/
8. https://en.wikipedia.org/wiki/Yocto_Project
9. 这种行为是由 Avocent 编写的一个补丁引起的,该补丁由戴尔发布在

https://opensource.dell.com/releases/idrac8/ 上 的 版 本 中 , 文 件 名 为 meta-

drac/recipes-yoctofixes/openssh/files/avocent.patch。
N.Iooss 17

不过,这个 shell 是以 racuser 用户身份运行的,其权限不如 root 用

户。iDRAC 的固件更新包含一个名为 /etc/shadow 的文件,其中保

存 了 密 码 的 哈 希 值 ( 清 单 2 ) 。 user1 的 密 码 哈 希 值 与 密 码

"user1234 "一致,但 root 的密码似乎尚未公开,尽管其哈希值几年

前已由 Emmert [2] 发布。

root : $ 1 $f Y 6 DG 6 Hu$Opw CBE 01 ILIS 1 H / Lxq /7 d0 :13502 :0 :99999 :7 :::


用户 1 : $ 1 $n VOr 80 r B$HDAd 6 FRl G 24 k / WN 4 Zu YPC 0 :0 :0 :99999 :7 ::::
racuser :!:0 :0 :99999 :7 :::
avahi :!:15569 ::::::
sshd :*:11880 :0 :99999 :7 : -1 : -1 :0
messagebus :!:15873 :0 :99999 :7 :::
_lldpd :!:16555 :0 :99999 :7 :::

清单 2. iDRAC 固件中的原始 /etc/shadow。

尽管该密码未知,但之前的漏洞允许在 /etc/shadow 中覆盖其

值。这样就可以在 iDRAC 上通过 SSH 以 root 身份运行 shell。然

后就可以发出一些命令,以收集有关固件版本和 iDRAC 环境的精

确信息,如清单 3 所示。

[ SH 7757 / flash / data 0 / home / root ] $ su


root 的密码 :

[ SH 7757 / flash / data 0 / home / root ] $ id


uid =0( root ) gid =0( root ) groups =0( root )

[ SH 7757 / flash / data 0 / home / root ] $ uname -a


Linux Mp COZl Z 3.4.11 #1 Thu Aug 18 13:03 :21 CDT 2016 sh 4 a GNU / Linux

[ SH 7757 / flash / data 0 / home / root ] $ cat / proc / version


Linux 版本 3.4.11 ( jenkins@ gitbuild 12 g 105 ) ( gcc 版本 4.7.2 (
GCC ) )#1 Thu Aug 18 13:03 :21 CDT 2016

[ SH 7757 / flash / data 0 / home / root ] $ cat / etc / issue


Poky 8.0 ( Yocto Project 1.3 Reference Distro ) 1.3\ n \ l

[ SH 7757 / flash / data 0 / home / root ] $ cat / flash / pd0 / fw_ver


2 .40 .45 .40.40
2 .40 .40 .40 .107
系统
Thu Aug 18 13:26 :24 CDT 2016
160818132624
IDRAC SVN Rev =
Hudson Project = idrac -13 g - ducati 1 .5 - master - release -A -
Rev Hudson Build # = 619
发布 ID =
MSC 修订版 = https :// pgre - svn 2 . us . dell . com / svn / LC /13 g /
branches /
rts_Plus Plus Plus / msc 4876
18 iDRAC 分析

[ SH 7757 / flash / data 0 / home / root ] $ cat / flash / pd0 / lc_ver ;


echo
2 .40 .40 .40 .107

[ SH 7757 / flash / data 0 / home / root ] $ cat / proc


/ cpuinfo machine :SH 7757 LCR
处理器 : 0
CPU 系列 :sh 4 a
CPU 类型 :SH 7758
切割 : 11. x
CPU 标志 :fpu perfctr
llsc 缓存类型 : split ( harvard
) 缓存大小 :32 KiB(4 路)
dcache 大小 :32 KiB(4 路)
地址尺寸 :32 位物理地址
:576.00

[ SH 7757 / flash / data 0 / home / root ] $ cat / proc / cmdline


root =/ dev / mmcblk 0 p 2 rootwait rw rootfstype = squashfs mem = 239616
k console = ttyS2 ,115200 < NULL >
mac 1 = 18:66: DA : XX : XX : XX mac 2 = 18:66: DA : XX : XX : XX
模式 = 正常 reset_cause = ac nmi_buf =0 x 83000000 quiet
console = ttySC2 ,115200 init =/ sbin / init

[ SH 7757 / flash / data 0 / home / root ] $ ls -l / sbin / init


lrwxrwxrwx 1 root 0 20 Aug 18 2016 / sbin / init -> / lib / systemd /
systemd

清单 3. iDRAC 8 上 root shell 的一些命令。

在探索现在可以访问的系统时,似乎有些不对劲:尽管 iDRAC 使

用账户(用于其 Web 界面、SMASH CLP 等),但其用户名和密

码与 Linux 用户账户不同。造成这种差异的原因是 PAM 子系统10

的 自 定 义 配 置 。 事 实 上 , /etc/pam.d/ 包 含 了 引 用

pam_ldap_manager.so 和 pam_local_manager.so 模块的文件(清单

4)。

授权 充足 pam_ldap_manager .so
授权 充足 pam_local_manager .so use_first_pass
授权 所需 pam_auth_status .so caller = login sessiontype = CLP

清单 4. 从 iDRAC 8 中的 /etc/pam.d/login 提取。

库 /lib/security/pam_local_manager.so 使 用 了 其 他 库 (

libosi.so.1.2.3 、 libaim.so.1.2.3 和 libfnmgr-client.so.9.9.9 ) 中 的

函 数 来 验 证 帐 户 凭 据 , 这 些 函 数 都 与 glibc 中 的 常 用 函 数
N.Iooss 19

getpwnam() 和 getspnam() 无关。

10. 可插拔身份验证模块子系统是一套库和配置文件,通常用于基于 Linux 的

系统,以验证用户身份和管理会话。
20 iDRAC 分析

最后,账户凭据存储在凭据库文件系统中,该系统由

/etc/init.d/credential-vault-13g.sh 配置。该脚本会将加密文件11

挂载到 /flash/13g-cv 和/etc/init.d/credential-vault-13g.sh。

/flash/data0/cv。iDRAC 账户的凭证位于
/flash/13g-cv/avctpasswd,密码使用加盐 SHA256 算法散列12 。

4 从 Linux 的角度看硬件

上一节介绍了 iDRAC 提供的主要服务,解释了如何下载和提取固

件及部分源代码,并介绍了在 iDRAC 上获取 root shell 的方法。所有

这些都有助于研究 iDRAC 与服务器硬件的交互,从而找到与主操作

系统的通信渠道。

4.1 从主操作系统看到的硬件

主操作系统通过硬件组件提供的多个通道与 iDRAC 通信。当

操作系统为 Linux 时,/sys 中的虚拟文件系统会提供有关可用硬

件的详细信息。利用 graph-hw13 (该工具已在 SSTIC14 上发布)

等工具,可以将这些信息表示成更易于分析的图形(图 3)。

暴露的硬件外设如下:

— 名为 "Avocent 键盘/鼠标功能 "的 USB-HID 设备(键盘、鼠标

)连接到名为 "Dell Computer Corp.集线器 "的 USB 集线器,

该集线器本身与英特尔公司的 USB 集线器相连,而英特尔

公司的 USB 集线器与 USB 控制器相连。此外,当 USB 设

备连接到所研究的戴尔服务器的前面板时,它会出现在同

一个英特尔 USB 集线器的下方。因此,该集线器很可能是

服务器中的真实设备。然后,iDRAC 使用真正的 USB

11. 文件是 /mmc1/.cv.img,并通过 losetup、dmsetup create 和 mount 挂载


N.Iooss 21

。使用的加密密码是 aes-ecb-essiv:sha256 ,密钥是脚本 /etc/init.d/credential-

vault-13g.sh 中的硬编码,似乎不能在每次安装中自定义。

12. 如果将 /flash/13g-cv/avctpasswd 中的每一行都视为以": "分隔的字段列表

,字段 #0 是用户名,字段 #15 是以十六进制编码的 16 字节长的盐,字段

#14 是以十六进制编码的 SHA256(password || salt)。


13. https://github.com/fishilico/home-files/blob/master/bin/graph-hw
14. 题为 "Représenter l'arborescence matérielle "的残缺会议可在以下网址查阅
https://www.sstic.org/2018/presentation/2018_rumps/。
22 iDRAC 分析

图 3.从主操作系统中提取的设备树(绿色:PCIe设备、
2
蓝色USB设备,橙色HID和图形设备,灰色:I C 设备)。
N.Iooss 23

连接,将其虚拟键盘和鼠标连接到主操作系统的硬件树 15

— 显卡(Matrox G200eR2,通过图 3 右侧的设备节点 /dev/fb0

和 /dev/dri/card0 标识)通过 PCI 交换机和桥接器链访问。其中

几个设备被命名为 "Renesas [...] SH7758"(图 4),这是 iDRAC

使用的 CPU 的名称。这意味着 iDRAC CPU 可以直接访问

PCIe 总线。

— Linux 内核会创建一个名为 /dev/ipmi0 的设备节点,用于向

iDRAC 发出 IPMI 命令。该设备的驱动程序栈使用内核模块

ipmi_devintf、ipmi_si、ipmi_ssif 和 ipmi_msghandler,以便

通过 SMBus(系统管理总线)传输和接收 IPMI 信息,协议

包括 KCS(键盘控制器风格)、SMIC(系统管理接口芯片)或

BT(块传输)。

供应商 ID 设备 ID 供应商名称 设备名称


C610/X99 系列 PCI 芯片组
8086 8d1e 英特尔公司
快速根端口 #8
1912 001d 瑞萨科技公司 SH7758 PCIe 交换机 [PS]
1912 001a 瑞萨科技公司 SH7758 PCIe-PCI 网桥 [PPB]
Matrox Electronics
102b 0534 G200eR2
系统有限公司

图 4.从主操作系统看到的显卡路径上的 PCIe 设备标识符表。

iDRAC 与主操作系统之间可能存在更多接口,而且可能更难发现

。iDRAC 的固件是如何使用这些接口的?

4.2 从 iDRAC 看到的硬件

由于 iDRAC 的固件是通过 Linux 构建的,因此可通过浏览以下网

页收集有关 iDRAC 可访问的硬件的信息

/dev 和 /sys,读取内核日志和 /proc/iomem 等。此外,固件还使用


24 iDRAC 分析

自定义内核模块,其源文件可在 https://opensource.dell.com/ 上免费获

取。通过这些源文件,可以更好地了解硬件组件。

15. 这是戴尔 iDRAC 和惠普 iLO4 之间的主要区别,因为后者在固件中实现了虚拟

USB 控制器。
N.Iooss 25

首先,iDRAC 的固件看不到任何 PCI 设备树:/sys/bus/pci/

和 /sys/devices/ 中都没有 PCI 设备。但存在一个名为 "R8A66597 "的

USB 设备控制器(UDC)。该控制器暴露了多个 USB 小设备(图 5

)。

目录名称在
/sys/devices/platform/ 司机姓名 设备节点
r8a66597_udc.0 g_hub
r8a66597_udc.1 g_kbdmouse /dev/avct/usb_keyboard
/dev/avct/usb_mouse
r8a66597_udc.2 g_mass_storage /dev/avct/usb_iface1
r8a66597_udc.3
r8a66597_udc.4 g_mass_storage1 /dev/avct/usb_iface2
r8a66597_udc.5 g_mass_storage2 /dev/avct/usb_iface3
r8a66597_udc.6 g_mass_storage3 /dev/avct/usb_iface4
r8a66597_udc.7 g_ether 网络接口 usb1

图 5.iDRAC 的 R8A66597 UDC 使用的 USB 小设备表。

USB 键盘和鼠标与主操 作 系 统 中的 USB 设备相匹配。当用户

在远程控制台启用虚拟 CDROM 或虚拟软盘时,大容量存储 USB 设

备会出现在主操作系统上。主操 作 系 统 的 USB 设备中没有以太网网

络接口。不过,通过研究 iDRAC 上的可用命令,似乎可以使用名

为 "racadm "的子命令(清单 5),通过 iDRAC 的 shell(SHASH

CLP)访问命令来启用该接口。这样,网络接口就会作为键盘/鼠

标 USB 设备旁边的以太网-USB 接口出现在主操作系统上。在运

行 systemd 的系统中,该接口被命名为 idrac,可以像普通网络接

口一样进行配置。Immunity 公司的研究人员发现,主操作系统也

可通过 IPMI 通道使用该命令[8]。

[ SH 7757 / flash / data 0 / home / root ] $ clpd


/ admin1 - > racadm get i DRAC .操作系统 - BMC
[ 密钥 = i DRAC .Embedded .1# 操作系统 - BMC .1]
管理状态 = 已禁用 OSIp 地
址 = 0 .0 .0.0
# PTCapability = Capable
PTMode = usb - p2p
Usb 网卡 IP 地址 = 169 .254 .0 .1

/ admin1 - > racadm set i DRAC .操作系统 - BMC .管理状态 已启用


[ 密钥 = i DRAC .Embedded .1# 操作系统 - BMC .1]
对象值修改成功
26 iDRAC 分析

清单 5.从 iDRAC 的 shell 启用网络接口。


N.Iooss 27

iDRAC 似乎无法以通常的方式访问服务器图形卡,因为文件系

统 没 有 显 示 /dev/dri/ 、 /dev/fb0 或 /sys/class/drm/ 。 不 过 ,

/proc/iomem 包含一些指向视频设备的条目(清单 6)。

[ SH 7757 / flash / data 0 / home / root ] $ grep video / proc / iomem


fe 900000 - fe 90003 b :
aess_video fea 02000 - fea 02
fff : aess_video ff 000030 - ff
000047 : aess_video
FFC 10000 - FFC 1013 F : AESS_VIDEO

清单 6./proc/iomem 中与视频相关的条目。

还有一些与视频设备相关的特殊文件:

— /dev/avct/video 是一个字符型设备,主设备号为 253,次设

备号为 0。

— /proc/aess_video 提供了有关视频设备的一些信息(内存地

址、校验和等信息)。

aess_video16 的源代码包含一些注释,对 /proc/iomem 中确定的内

存区域的作用进行了描述(清单 7)。

/*
* DVC 5 寄存器基址
*/
# define PBASE_DVC 5 _ADDR 0 x FEA 02000
# 定义 VIDEO_CORE_REG_SIZE 0 x1000

/*
* 图形控制器寄存器基地址
*/
# define PBASE_GCTRL_ADDR 0 x FFC 10000
# define GCTRL_REG_SIZE 0 x140

/*
* ECD 寄存器基地址
*/
# define PBASE_ECD_ADDR 0 x FE 900000
# 定义 ECD_REG_SIZE 0 x3C

/*
* SH 7757 版本和产品注册表
*/
# define PBASE_VERSION_ADDR 0 x FF 000030
# 定义 VERSION_REG_SIZE 0 x18
28 iDRAC 分析

清单 7. externalsrc/linux-driver/video_driver/aess_video.h.

16. externalsrc/linux-drivers/video_driver 目录来自从

https://opensource.dell.com/ 下载的档案。
N.Iooss 29

该内核模块使用一些没有明确定义的缩写命名的组件:"DVC

引 擎 " 和 "ECD/ECC" 。 在 另 一 个 文 件 的 函 数 注 释 中 也 使 用 了

"DVC",用于去描述一种视频文件格式(清单 8)。iDRAC 的固

件 中 似 乎 没 有 使 用 该 函 数 , 但 附 近 一 个 名 为

avct_vkvm_capture_screen 的函数可通过 avct_control 命令直接使用

,以 PNG 格式截图(清单 9)。为了了解 avct_control 如何与屏幕

交互,我们使用了 strace,发现 avct_control 执行的唯一相关操作

是通过位于 /tmp/rpSocket 的 Unix 套接字向 /sbin/avct_server 发送

消息。

/*!
* 描述:开始以 DVC 格式向指定 文件 捕捉主机视频。
*
* szName - 要存储 文件的 文件名 (包括路径) 。
* ulSize - 视频文件 的最大 大小。
*/
int a vc t_vk vm_start_video_ c a p t u r e ( const char * szName , uint 32 _t
ul Size );

清单 8.从头文件 ipk-dropbox/librpipc/image/usr/

include/librpipc/avct/rpipc.h 中提取。

[ SH 7757 / dev / shm ] $ avct_control -- file $ ( pwd )/ my - screen . png


capture
将屏幕捕捉到文件"/ dev / shm / my - screen . png '...
抓获 .
[ SH 7757 / dev / shm ] $ hd < / dev / shm / my - screen . png
00000000 89504 E 470 D 0 A 1 A 0 A 0000000 D 49484452 ..........|.PNG IHDR
||.
00000010 0000050000000400 080200000031 f 163 |.................................1 . c |
00000020 1400002000494441 547801 eddd 4192 a 3 |... .IDATx ...A ..|
00000030 B 8120050 BBA 3161 C 8 FA 58 FE 825 C 7 F 3 F 2 ..............|...P
........% |
...

清单 9.iDRAC 的 SSH 截图。

最终,iDRAC 没有使用 PCIe 总线与图形卡交互,而是使用特定

组件来检索屏幕内容。

4.3 大型 GPIO 设备 CPLD


30 iDRAC 分析

iDRAC 上的多个文件、程序和库都提到了 CPLD17 ,这是一种可

编程逻辑器件,可用于实现各种功能和应用。

17. 复杂可编程逻辑器件。在所研究的服务器上,它是一个英特尔 Altera MAX II

,零件编号为 EPM2210F324C5N。
N.Iooss 31

算法,而无需制造定制芯片组。这种设备可用于实现 PCIe 端点,因

此研究其在 iDRAC 上的应用很有意义。

iDRAC 8 的 CPLD 可通过程序库使用、


/usr/lib/libcpld.so.1.2.3,它使用一个字符设备节点、
/dev/dell_cplddrv,用于获取和设置 CPLD 中的位。该节点上的操

作 由 名 为 dell_cplddrv.ko 的 内 核 模 块 实 现 , 源 代 码 可 从

https://opensource.dell.com/ 上获取。代码中包含一些 USB 可移动

事件(参见清单 10)。

/* 保存中断原因供用户检索 */
intrcause = ( cpld_read (0 x10 )&0 xf ); // ID 按钮 锁存
if ( intrcause & ID_LATCH_MASK ){
cpld_rmw ( ID_LATCH_MASK , ID_LATCH_MASK , 0 x10 );
// 清除
中断
}
/* ...*/
/* 检查 CPLD 0 x14000019 位 1 是否被置信 */
如果 ( USB_REMOVAL_MASK == ( cpld_read (0 x19 ) & USB_REMOVAL_MASK ) )
{
CPLD_USB_PCH_REMOVAL_MASK 、
cpld_usb_pch_removal_mask , c pl d_ us b_ co nf ig _o ff se t ); //
清零
intrcause |= C PL D_ IN T _ P C H _ U S B _R EM OV E ;
up (& pchusb_removal_sem );
}

上市 10. 提取 的 的 cpldisr_13g 函数、 从 文件


externalsrc/linux-drivers/cpld_driver/dell_cplddrv.c.

iDRAC 使用 CPLD 的某些位来读取服务器 "ID 按钮 "的状态。

其他位用于连接和断开虚拟 USB 设备,如虚拟控制台使用的鼠标

和键盘。对 CPLD 使用情况的分析给人的印象是,它的行为类似

于 GPIO 设备:每个位都有特定的含义,可用作布尔输入/输出接

口。因此,iDRAC 的 CPLD 不大可能提供访问服务器主存储器的

方法。此外,一些架构图(图 6)显示,CPLD 设备位于 iDRAC 和主

CPU 之间总线的另一侧。这使得 CPLD 难以从 iDRAC 进入主存

储器。
32 iDRAC 分析

4.4 神秘的 PBI 设备

在查找 PCIe 根复合体和图形卡之间的 PCIe 桥接器数据时(第 4.1

节),有几种搜索方法
N.Iooss 33

引 擎 给 出 了 Ubuntu 认 证 硬 件 网 站 18 上 的 页 面 。 例 如 ,
https://certification.ubuntu.com/catalog/component/pci/ 1912%3A001d/
列出了共享 "Renesas Technology Corp.SH7758 PCIe Switch [PS]"。

图 6.iDRAC 硬件示意图。
来源:https://www.manualslib.com/manual/624251/Dell-Poweredge-R820.html?page=54

另 一 个 页 面 https://certification.ubuntu.com/catalog/

component/pci/1912%3A001b/ 列 出 了 拥 有 名 为 "Renesas

Technology Corp. SH7758 PCIe Endpoint [PBI]"的 PCIe 端点设备

的服务器列表。SH7758 PCIe End-Point [PBI]"。所研究的戴尔

PowerEdge R730 服务器上似乎不存在该设备,但固件中的一个内

核模块提到了它。在从 https://opensource.dell.com/ 下载的文件中

,externalsrc/linux-drivers/pbi_driver/ 目录包含一个模块的源代

码,该模块被描述为 "瑞萨 SH7757 iBMC 控制器上 PBI 共享内


34 iDRAC 分析

存和邮箱 FIFO 的 Linux 驱动程序"。该模块

18. https://certification.ubuntu.com/
N.Iooss 35

使 用 映 射 到 0xffca0000 和 0xffcaa000 地 址 的 硬 件 寄 存 器 。 从

/proc/iomem 中 看 不 到 这 些 地 址 , 但 这 并 不 意 味 着 所 研 究 的

iDRAC 系统不支持该设备。通过 iDRAC 的固件搜索这些地址,可以

找到 U-Boot 和 Linux 中的功能(见表 11 和 12)。

HAL_writel (0 x1 , 0 xffca 1420 ); // PCIE_BARMAP 0 , 邮箱 BAR 映射


HAL_writel (0 x4 , 0 xffca 1470 ); // HAL_writel (0 x0 , 0 xffca
1604 ); // PCIE_BSTCTL 0 , Disable Burst Xfer
HAL_writel (0 x30000 , 0 xffca 160 c ); // PCIE_ENDICTL 0
HAL_writel (0 x3 , 0 xffca 1610 ); // pcie_endictl 1

HAL_writel (0 xffcaa 000 , 0 xffca 1260 ); // PCIE_LAD 0 , 本地地址 寄存器


0
HAL_writel (0 xff2 , 0 xffca 1264 ); // PCIE_LADMSK 0 , 本地 地址 屏蔽 寄存器
0
HAL_writel (0 xe 500 e 000 , 0 xffca 1268 ); // PCIE_LAD 1
HAL_writel (0 x72 , 0 xffca 126 c ); // pcie_ladmsk 1
/* ...*/
/*
* DF 533855 PCIe 培训修复。 我不知道这是什么 / 做什么用的。
* Renesas 说 要把它放进去。
*/
*( u32 *) 0 x FFEE 0150 = 0 x 40010000 ;

snprintf ( msg , MAX_MSG_LEN , " Init PCIe mailbox ( PCIe 0 x FFEE 0150
=0 x 40010000 )");

清单 11.从 externalsrc/ u-boot-idrac8/u-

boot_B0/board/renesas/sh7757lcr/util_idrac_main.c 中的 U-Boot 函数

init_mailbox 中摘录。

# 定义 PCIE_BASE0 xffca0000
# define LADMSK 0 ( PCIE_BASE + 0 x1264 )
# define BARMAP ( PCIE_BASE + 0 x1420 )

static int __init sh_pcie_init ( void )


{
printk ( KERN_INFO " enable PCIe shared memory area\ n");

__raw_writel (0 x 00000 ff 2 , LADMSK 0 );


__raw_writel(0 x 00000001 , BARMAP );

返回 0;
}

清单 12. 摘自戴尔 Linux 源代码树,位于 externalsrc/ linux-

yocto/arch/sh/boards/board-sh7757lcr.c。

为了读取这些硬件寄存器的当前配置,可 以 编写一个程序,打
36 iDRAC 分析

开 /dev/mem 并从 iDRAC 的物理内存中读取数据。但这并不是必需的

, 因 为 戴 尔 提 供 了 两 个 可 用 于 访 问 内 存 的 程 序 : MemAccess 和

MemAccess2(清单 13)。
N.Iooss 37

[ SH 7757 /] $ Mem Access 2 - rl -a ffca 0000


0 XFFCA 0000 = 001 B 1912 00100007 : 05000000 00000000
0 xffca 0010 = 91901000 91900000 : 00000000 00000000
0 XFFCA 0020 *
0 xffca 0030 = 00000000 00000040 : 00000000 000001 ff

清单 13.使用 MemAccess2 读取 PBI 的 PCIe 配置。

在另一台计算机上使用 lspci 对转储数据进行解码后,输出

结果似乎与 PCIe 配置寄存器(列表 14)相符。

$ lspci - nnvvvxxx -F pbi - config - dump .


RAM 内存 [0500]:Renesas Technology Corp .SH 7758 PCIe 端点 [
PBI ][1912 :001 b ]
控制:I/O + Mem + Bus Master + Spec Cycle - Mem WINV - VGASnoop - VGASnoop -
VGASnoop
ParErr - Stepping - SERR - Fast B2B - Dis INTx - ParErr - Stepping -
SERR - Fast B2B - Dis INTx
状态:Cap + 66 MHz - UDF - Fast B2B - ParErr - DEVSEL = fast > TAbort - <
TAbort - < MAbort - > SERR - < PERR - INTx-
延迟 : 0
中断:引脚 A 路由至 IRQ 255
区域 0:内存位于 91901000(32 位,不可预取) 区域 1:内存
位于 91900000(32 位,不可预取) 功能: [40] 电源管理版本 3
标志 :PMEClk - DSI - D1 - D2 - 辅助电流 =0 mA PME ( D0 -, D1 -, D2 -,
D3 -, D4 -, D5 -, D6 -, D7 -, D8 -, D9 -)
D3 热 +,D3 冷 -)
状态:D0 无软启动 + PME - 启用 - DSel =0 DScale =0 PME - 启用
功能: [50] MSI:启用 - 计数 =1/8 可屏蔽 - 64 位 +
地址 : 000000000000 数据 :0000
功能:[70] Express ( v2 ) 端点,MSI 07
Dev Cap : Max Payload 128 bytes , Phant Func 0 , Latency L0s <64
ns
, L1 < 1 us
Ext Tag + Attn Btn - Attn Ind - PwrInd - RBE + FLReset +
插槽功率限制 0.000 W
Dev Ctl : 报告错误 : 可更正错误 - 非致命错误 + 致命错误 + 可更正错误
不支持 +
Rlxd Ord + Ext Tag + Phant Func - AuxPwr - No Snoop + FLReset - -
Rlxd Ord + Ext Tag + Phant Func - AuxPwr - No Snoop + FLReset
最大有效载荷 128 字节 , 最大读取请求 4096 字节
发展阶段 : Corr Err - Uncorr Err - Fatal Err - Unsupp Req - AuxPwr -
Fatal Err
Trans Pend -
Lnk Cap : Port #0 , Speed 2.5 GT /s , Width x1 , ASPM L0s , Exit
Latency L0s 无限制
Clock PM - Surprise - LLAct Rep - BwNot - ASPMOpt Comp +
Lnk Ctl : ASPM 已禁用;RCB 64 字节已禁用 - Comm Clk
Ext Synch - Clock PM - Aut Wid Dis - BWInt - Aut BWInt - Ext Synch -
Clock PM - Aut Wid Dis - BWInt - Aut BWInt
Lnk Sta :速度 2.5 GT /s , 宽度 x1 , TrErr - Train - Slot Clk -
DLActive - BWMgmt - ABWMgmt - BWMgmt - ABWMgmt
Dev Cap 2:完成超时: 不支持,超时 Dis +,LTR
-不支持 OBFF
Dev Ctl 2:完成超时:50 us 至 50 ms , 超时 Dis -, LTR
-禁用
原子操作中心:ReqEn -
Lnk Ctl 2 : 目标链接速度 : 2 .5 GT /s , Enter Compliance -
速断
38 iDRAC 分析
传输余量 : 正常工作范围 、
输入修改后的合规性--合规性 SOS--。
N.Iooss 39

合规性 - 强调 : -6 dB
Lnk Sta 2 : 当前去重电平 : -6 dB 、
均衡化完成 - , 均衡化第 1 阶段 -, 均衡化第 2 阶段 -, 均衡化第 3 阶段
-, 均衡化第 4 阶段
均衡化阶段 2 - ,均衡化阶段 3 - 、
链接均衡请求
00: 12 19 1 b 00 07 00 10 00 00 00 00 05 00 00 00 00
10: 00 10 90 91 00 00 90 91 00 00 00 00 00 00 00 00
20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
30: 00 00 00 00 40 00 00 00 00 00 00 00 ff 01 00 00
40: 01 50 03 40 08 00 00 00 00 00 00 00 00 00 00 00
50: 05 70 86 00 00 00 00 00 00 00 00 00 00 00 00 00
60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
70: 10 00 02 0 e 20 80 00 10 1 e 59 00 00 11 f4 43 00
80: 00 00 11 00 00 00 00 00 00 00 00 00 00 00 00 00
90: 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00
a0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
b0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
d0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
e0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
f0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

清单 14.使用 lspci 解析 PBI 的 PCIe 配置。

PBI 的内核模块创建了设备节点 /dev/sh_pbi,iDRAC 的用户

空间程序可以使用该节点。iDRAC 的固件包含命令 pbitest 和

libpbidrv.so 库,它们使用该设备与使用 邮箱的 未知设备通信。

阅 读 lib_pbidrv.h 的 内 容 后 发 现 , PBI 被 用 作 主 操 作 系 统 与

iDRAC 之间的通信通道,以控制服务器前面板上的 LCD 屏幕

:该 LCD 由 iDRAC 管理,主操作系统可以发出命令,让 iDRAC 对

其执行某些操作(显示文本、读取按钮状态等)。

回顾这些发现,似乎缺少了什么:尽管主操作系统可以控制 LCD

的内容,但该 PBI 设备并未出现在所研究服务器主操作系统的 PCIe

设备树中。通过阅读更多网页,我们找到了几个脚本和一份名为 "使

用 IPMItool 原始命令远程管理戴尔 PowerEdge 服务器 "的戴尔文档19

。ipmitool 通过 SMBus 或网络(而非 PCIe 总线)向 iDRAC 发送

IPMI 命令。

ipmitool raw 0 x6 0 x58 193 0 0 长度 ASCII_hex_values


ipmitool raw 0 x6 0 x58 194 0

清单 15.使用 IPMItool 创建自定义 LCD 信息。

19. https://www.dell.com/downloads/global/power/ps4q07-20070387-Babu.pdf
40 iDRAC 分析

尽管主操作系统不需要使用诸如 PBI 这样的 PCIe 设备来定义服

务器 LCD 显示屏上显示的信息,但 PBI 仍然存在。它的 PCIe 配置

寄存器存在于 iDRAC 的物理内存中,但该设备似乎以 某种方式被禁

用了。U-Boot 源代码中的一条注释澄清了这一情况:戴尔将该设备

配置为 "隐藏"(清单 16)。

// 在 13 G 系统 上,修复隐藏 PBI 设备的问题。写入


PSPPBCTL DRS [1:0 ] = '01 b'
if ( is_sh 7758 ())
writel(0 x 00000100 , 0 xffd 60080 );

上市 16. 从 从 U-Boot 的 init_pcie_bridge 函数的摘录、



externalsrc/u-boot-idrac8/u-boot_B0/board/renesas/sh7757lcr/sh7757lcr.c.

由于隐藏设备是通过将位于 0xffd60080(iDRAC 物理内存中)的

32 位值中的一位设置为 1 来实现的,因此将该位设置为 0 可能会解

除隐藏。遗憾的是,使用 MemAccess2 -wl -a ffd60080 -d 00000000 清

除该位会导致主操作系统冻结,无法启动(屏幕保持黑色)。将该位

设置回 1(使用 MemAccess2 -wl -a ffd60080 -d 00000100)可使主操

作系统再次启动。这可能是戴尔遇到的一个问题,导致第 13 代服务

器(使用 iDRAC 8)上的 PBI 设备被隐藏。

最后,iDRAC 8 的固件包含一个名为 PBI 的隐藏 PCIe 设备的代码

。该设备可能用于允许主操作系统定义服务器 LCD 显示屏的内容

,但在 iDRAC 8 中存在另一种执行该操作的方法,即通过 IPMI 命令

。隐藏 PBI 的代码修改了 U-Boot 代码中名为 "PCIe 桥接器 "组件

的寄存器。下一部分将重点介绍该组件。

4.5 神话般的 PCIe 网桥微码

在查看戴尔 U- Boot 代码中对 PCIe 总线的引用时,有几个

部分提到了 PCIe 桥接器。例 如 ,externalsrc/u-boot-idrac8/u-


N.Iooss 41

boot_B0/board/renesas/sh7757lcr/ bld_bridge.c 定义了一个使用函

数,该函数会打印

使用方法: bld_bridge <pcie_bridge.src> <7757|7758>


<util_pciebridge775X.c>

该文件还包含戴尔开发人员的评论:
42 iDRAC 分析

瑞萨处理器的 PCIe 部分需要 u-boot 来加载 PCIe 微代码。瑞萨使用专用

扇区存储此信息。戴尔公司不能将其作为一个单独的扇区,因为版本控

制和测试矩阵会将其搞得一团糟。因此,我们将把它作为 u-boot 的一部

分。

加载 PCIe 微代码的函数是 sh7757lcr.c(清单 17)中的

init_pcie_bridge。它使用四个硬件寄存器:

— PCIEBRG_CTRL_H8S = 0xffd60000,以便重置和启动 PCIe 桥

接控制器 ;

— PCIEBRG_CP_ADDR = 0xffd60010,以便配置已加载微码的起始

地址(0x0000);

— PCIEBRG_CP_DATA = 0xffd60014,以便按 16 位分块加载微代

码;

— PCIEBRG_CP_CTRL = 0xffd60018。

writew (0 xa501 , PCIEBRG_CTRL_H 8 S ); /* 复位 */


writew(0 x0000 , PCIEBRG_CP_CTRL);
writew(0 x0000 , PCIEBRG_CP_ADDR);
for ( i = 0; i < pcie_cnt ; i += 2) {
tmp = ( data [ i ] << 8) | data [ i + 1];
writew ( tmp , PCIEBRG_CP_DATA);
}
writew (0 xa500 , PCIEBRG_CTRL_H 8 S ); /* 启动 */
if (! is_sh 7757 _b 0 ()) /* Cn 或 Shasta */
writel(0 x 00000001 , PCIE_PBICTL 3 ); /* PBI 控制寄存器 3 */

上市 17. 从 从 U-Boot 的 init_pcie_bridge 函数的摘录、



externalsrc/u-boot-idrac8/u-boot_B0/board/renesas/sh7757lcr/sh7757lcr.c.

加载的微码可在 https://opensource.dell.com/ 上 U-Boot 代码旁

边 的 存 档 中 找 到 。 这 些 微 码 实 际 上 来 自 bridge7757.mot 或

bridge7758.mot,它们是 Mo- torola S-Record 格式的文件。可以使用

objcopy -I srec -O binary input-file.mot output-file 等命令将这些

文件转换为原始二进制文件。为了找出所研究的 Dell PowerEdge

R730 服务器上使用的文件,一种可能的方法是使用 iDRAC 的

shell 中的 "dellutil ublog "读取 U-Boot 的日志(清单 18)。由于


N.Iooss 43

日志中包含 "SH7758_A0",因此 bridge7758.mot 包含已加载的微

代码。

$ dellutil ublog
INFO : 00:007 SH -4 A Product : Major Ver =0 x31 小版本 =0 x20 D0 Little
endian
家庭 =0 x10 主要版本 =0 x30 次要版本 =0 x0b
...
PASS : 00:008 PCIe SH 7758 _A 0 Ver =0.03 MCTP en , CRC =0 x 70 ae 6992
@ 0 x 8 EFD 591 C CNT =0 x 18000
INFO : 00:008 Init PCIe mailbox ( PCIe 0 x FFEE 0150 =0 x 40010000 )

清单 18.从 dellutil u b l o g 命令中提取的内容。


44 iDRAC 分析

微代码的二进制内容以一种标头开始,使用 util_idrac_main.c 中

的 struct pcie_brg_hdr 对 标 头 进 行 解 析 , 然 后 是 一 些 从 偏 移 量

0x100 开始的数据。这些数据看起来不够随机,无法压缩或加密。

16 位模式的重复表明,这些数据包含使用 16 位指令集的 CPU

的代码,这既不是 x86 也不是 SH4。回看 sh7757lcr.c 中的代码

(清单 17),H8S 似乎是瑞萨公司生产的 16 位微控制器系列的名

称。它属于 H8 系列,其中还包括乐高头脑风暴 RCX 可编程砖中使

用的 8 位 H8/300 微控制器。

Hex-Rays 的交互式反汇编器 (IDA) 支持 H8 系列的许多指令集,

包 括 " 日 立 H8S 高 级 " 。 这 样 就可 以 确 认 加 载 的 微 码 包 含 偏 移 量

0x100 处的代码。进一步分析后,bridge7758.mot 的解码内容映射如

下:

— 0x0000 至 0x003b:固件头(列表 19)。


— 0x0000:入口点或重置向量入口的地址(0x0100,32 位

大二进制整数)。

— 0x0004:芯片版本,SH7758 A0 为 0x03(SH7757 A0 为

0x00,SH7757 B0 为 0x01,SH7757 C0 为 0x02)。

— 0x0005:芯片切片,0x00 .
— 0x0006:固件版本,0x03。
— 0x0007:MCTP(管理组件传输协议)模式,0x01(已启用

)。

— 0x0030 至 0x003b:可能是中断向量表,包含三个 32 位

函数地址(0x010a、0x01f8、0x033c)。

— 0x0100 至 0x03a9:使用 H8S 指令集的代码段。该代码段实

现了中断处理程序和重置处理程序,重置堆栈至 0x00ffc000

,并在循环中调用位于 0x0001685a 的函数。该函数很可能是

固件的主函数。
N.Iooss 45

— 0x03aa 至 0x2105:只读数据段。该段包含 16 位字,与图 4(

第 4.1 节)中列出的 PCIe 网桥的 PCI 供应商 ID 和设备 ID 相

匹配。

— 0x2106 至 0x16929:代码段,采用 H8S 指令集。该代码段实

现了固件的大部分功能。

— 0x1692a 至 0x017fff:填充零。
0000: 0000 0100 0300 0301 0000 0000 0000 0000
0010: 0000 0000 0000 0000 0000 0000 0000 0000
0020: 0000 0000 0000 0000 0000 0000 0000 0000
0030: 0000 010 a 0000 01 f8 0000 033 c 0000 0000

清单 19.bridge7758.mot 头信息的十六进制转储。
46 iDRAC 分析

分析固件的第一步是找出 H8S 微控制器内存空间的组织方式。通

过研究已执行的内存访问,可以得出以下布局:

— 0x000000 至 0x017fff:已加载固件(98304 字节)


— 0xffa000 至 0xffc000:RAM(8192 字节,全局变量和堆栈

,从顶部开始递减)

— 0xffc000 至 0xffffff:内存映射输入/输出(许多硬件寄存器

H8S 微控制器使用 24 位地址。这使得使用普通软件进行分析变得

困难,因为大多数软件要么将地址空间限制为 16 位,要么限制为 32

位 。 例 如 , Hex-Rays 的 IDA 软 件 在 使 用 处 理 器 "Hitachi H8S

advanced (h8s300a) "时,将 16 位地址扩展到了 32 位,从而导致位于

RAM 和 IO 区域的数据引用出现混乱。幸好 IDA 的处理器 "Hitachi

H8/300H advanced (h8300a) "将 16 位地址扩展到了 24 位,因此可以

使用该处理器模块代替 H8S。

在阅读固件中许多功能的代码时,我们会发 现 一个共同的模式:

几乎所有功能都是从将地址 0xffa9be 的 16 位变量设置为一个常量值

开始的。例如,从 0x002106 开始的函数将该值设置为 0x64,从

0x002156 开始的函数将该值设置为 0x65,从 0x0021a4 开始的函数将

该值设置为 0x66,等等。这似乎表明了一种独特的函数标识符,有

助于在调试代码时产生跟踪结果。

该全局变量的值只在固件的一个函数中读取:从 0x00010a 开始

的函数。该函数可以是一个中断处理程序(例如处理定时器)。它

首先读取位于 0xffd033 的字节的最小有效位。如果该位被置位,

则重置该位,然后从 0xffd034 读取一个 16 位整数,并根据该值

运 行 指 令 。 然 后 , 函 数 将 执 行 指 令 后 得 到 的 16 位 整 数 写 入

0xffd022。

简而言之,0x00010a 处的中断处理程序解析硬件寄存器中的 16
N.Iooss 47

位操作码,执行指定操作,并将结果写入另一个硬件寄存器。图 7

列举了可能的命令。

iDRAC 能否通过这些 16 位操作码向 H8S 发出指令?通过研究位

于 0xffd000 的硬件寄存器的使用情况,我们发现了几个事实:

1. 在多个位置,固件将 0xffd000 设置为 0xa501 值


并将寄存器 sp(堆栈指针)设置为 0xffc000。
48 iDRAC 分析

2. iDRAC 通过设置 0xffd60000 复位 H8S 微控制器


(iDRAC物理内存中)的值为0xa501(参见清单17)。

3. 0xffd000 紧挨着 H8S 微控制器内存中 0x00010a 处函数使用的

地址。

操作码 说明
0x0XXX 获取 0xffc000 + (0xXXX&0xffe) 位置的 16 位整数
0xXXX ≤ 0x7ae (这是内存映射 I/O 区域的起始位置)
0x0800 获取 0x000004(即 0x0300)处的 16 位整数
0x0802 获取 0x000006(即 0x0301)处的 16 位整数
0x0900 获取 0xffa9be(函数标识符)处的 16 位整数
该值也可通过命令 0x70bc 和 0x70bd 读取。
0xXYYY 在
0xX ≥ 1 和 0xffa000 + ((0xX - 1) × 0x180) + (0xYYY&0xffc)
0xYYY ≤ 0x157 如果 0xYYY&2 = 0,则使用最小有效的 16 位字、
否则,最有可能。
其他 不要更改 0xffd022 处的值

图 7.H8S 微控制器执行的命令表。所有整数均为大尾数,0xX 表示 "以 16

为基数的数字"(又称十六进制数字),& 表示比特-AND 运算。

因此,iDRAC 中位于 0xffd60000 地址的寄存器可以与微控制器中

位于 0xffd000 的寄存器匹配。其他寄存器的映射情况并不理想,但

通过对某些寄存器进行暴力破解,发现 iDRAC 确实可以向 H8S 发出

命令(图 8)。

iDRAC 的地址 H8S 的地址 说明


0xffd60000 0xffd000 U-Boot 源代码中的 PCIEBRG_CTRL_H8S:
写入数值 0xa501 复位微控制器 写入数值
0xa500 启动微控制器
0xffd60028 0xffd022 命令结果(16 位大尾数)
0xffd60030 0xffd033 命令触发:
写入 0x01 会触发命令执行
0xffd60034 0xffd034 命令操作码(16 位大端码)

图 8.iDRAC 和 H8S 共享的硬件寄存器的所谓映射。

例如,在 iDRAC 的 shell 中运行清单 20 中编写的命令,可以确认


N.Iooss 49

命令 0x0802 返回 0x0301。

内存访问 2 - ww -c 1 -a 0 xffd 60034 -d 0802


内存访问 2 - ww -c 1 -a 0 xffd 60030 -d 0001
内存访问 2 - rw -c 1 -a 0 xffd 60028

清单 20.在 H8S 微控制器上执行 0x0802 操作。


50 iDRAC 分析

总之,当 iDRAC 启动时,其引导加载程序会向名为 "PCIe 桥接器

"的 H8S 微控制器加载固件。该固件包含对一些 PCIe 组件的引用,

这些组件位于 PCIe 根复合体和图形卡之间(4.1 节中的图 4)。通过

对固件的分析,我们发现了一个通信通道,可以让 iDRAC 在这个新

的微控制器上发出指令。

5 结论

在戴尔服务器中,iDRAC 的功能相当强大,但它似乎无法直接

访问 PCIe 总线以读写主存储器。更确切地说,与 PCIe 总线密切

相关的设备(虚拟 USB 设备、图形卡、PBI 设备等)都不提供这

种访问。

通过分析,iDRAC 的引导加载程序发现了一个名为 "PCIe 桥 "的

奇怪组件。该组件使用与戴尔服务器 PCIe 总线相关的 H8S 微控制器

。目前尚未发现该微控制器能否向主存储器发送 DMA 请求。撰写本

文时(2019 年 4 月),分析 H8S 固件的工作仍在进行中。

无论如何,建议限制对 iDRAC 提供的服务(Web 服务器、SSH、

IPMI、SNMP 等)的访问,例 如 , 仅在专用网络上使用这些服务,

并禁用不使用的服务。此外,还建议及时更 新 iDRAC 的固件,以防

止攻击者利用已知的关键漏洞(如 CVE-2018-1207)。法语读者可参

阅 CERT-FR 发布的建议,了解更多详情 [4]。

A 术语表

BMC:底板管理控制器,计算机内部几乎万能的计算机。

DMA:直接内存访问,外设读写计算机主机内存(RAM)数据的

一种方式。

iDRAC:集成的戴尔远程访问控制器,戴尔的 BMC。IOMMU:输
N.Iooss 51

入输出内存管理单元,一种限制在计算机上使用 DMA 的设备。

IPMI:智能平台管理接口,BMC 实施的一种标准,用于帮助用户管

理计算机。
52 iDRAC 分析

KVM:键盘-视频-鼠标接口,这是现实世界中与计算机交互的主要

方式。BMC 可为远程用户提供虚拟 KVM。

SMASH CLP:服务器硬件系统管理架构--命令行协议,是 BMC

为帮助命令行用户管理计算机而实施的一项标准。

SMBus:系统管理总线,一种源自 I2 C 的简单双线总线。SSIF:

SMBus System InterFace:SMBus 系统接口,一种可通过 SMBus

与支持该协议的 BMC(如戴尔的 iDRAC)进行交互的协议。

UDC:USB 设备控制器,一种控制 USB 设备的组件。在服务器上

,这种组件可托管由 BMC 提供的虚拟 USB 设备。

参考资料

1. Anthony Bonkoski、Russ Bielawski 和 J. Alex Halderman。揭示熄灯服务

器管理的安全问题。第 7 届 USENIX 进攻性技术研讨会(WOOT'13)论文

集,2013 年。https:
//jhalderm.com/pub/papers/ipmi-woot13.pdf。
2. 费 利 克 斯 - 埃 默 特 带 外 网 络 管 理 》 。 网 络 》 , 69 , 2015 。 https://

pdfs.semanticscholar.org/5046/999858f4409c9b6b533a04de36cd508848bd.pdf。

3. 马 克 - 埃 尔 莫 洛 夫 ( Mark Ermolov ) 和 马 克 西 姆 - 戈 里 亚 奇 ( Maxim

Goryachy)。如何入侵已关机的计算机,或在英特尔管理引擎中运行未签

名 代 码 》 。 黑 帽 欧 洲 , 2017 年 。 https://www.blackhat.com/eu-
17/briefings.html#how-to-hack-a-turned-
off-computer-or-running-unsigned-code-in-intel-management-engine.
4. CERT FR.Bulletin d'actualité CERTFR-2017-ACT-014.2017. https://www.cert.
ssi.gouv.fr/actualite/CERTFR-2017-ACT-014/.
5. Fabien Périgaud、Alexandre Gazet 和 Joffrey Czarny。 通过

BMC 入侵服务器:HPE iLO4 案例。 SSTIC, 2018.


https://www.s s t i c . o r g / 2 0 1 8 / p r e s e n t a t i o n / b a c k d o o r i n g _ y o
u r _ s e r v e r _ through_its_bmc_the_hpe_ilo4_case/.
6. Fabien Périgaud、Alexandre Gazet 和 Joffrey Czarny。 通过 BMC 颠覆服务

器:HPE iLO4 案例。 Recon Brussels, 2018.

https://recon.cx/2018/brussels/talks/subvert_server_bmc.html 和
h t t p s : / / g i t h u b . c o m / a i r b u s -
s e c l a b / a i r b u s -
s e c l a b . g i t h u b . i o / b l o b / m a s t e r /
N.Iooss 53

i l o / R E C O N B R X 2 0 1 8 - S l i d e s -
S u b v e r t i n g _ y o u r _ s e r v e r _ t h r o u g h _ its_
B M C _ t h e _ HPE_iLO4_case-perigaud-gazet-czarny.pdf。

7. Fabien Périgaud、Alexandre Gazet 和 Joffrey Czarny。 把你的 BMC 变成

旋转门。 ZeroNights, 2018.


https://2018.zeronights.ru/
en/reports/turning-your-bmc-into-a-revolving-door/、 https://airbus-
seclab.github.io/ilo/ZERONIGHTS2018-Slides-EN-Turning_your_BMC_into_a_
revolving_door-perigaud-gazet-czarny.pdf.
8. 马蒂亚斯-索勒、塞巴斯蒂安-索勒和尼科-韦斯曼。难以承受的 BMC 之轻

》 。 Black Hat US , 2018 。 https://www.blackhat.com/us-18/briefings/

schedule/index.html#the-unbearable-lightness-of-bmcs-10035。

You might also like