Tesla Model S 是如何更新固件的?对显示器和仪表盘进行逆向时,我们发现了这些:
第1部分:对Tesla Model S 的硬件逆向分析研究:https://www.4hou.com/posts/XkEv
第2部分:对Tesla Model S 固件更新过程的逆向研究
CID VCM软件架构
与大多数嵌入式系统相比,CID更大更复杂;对于嵌入式系统而言,CID是Linux发行的Ubuntu的完整版本,这与嵌入式系统不同。
在内核中,我们找到了自定义元素,例如Harman Redbend,该内核是使用Linaro工具链构建的。
为了满足使用开源软件的法律要求,特斯拉在项目进行到一半的时候就透露了内核来源,但是,这对逆向无济于事,因为它仅占系统的一小部分。
引导加载VCM
这似乎与许多Tegra设备相似。BPMP(启动和电源管理处理器)是Tegra SoC的辅助处理器,它执行存储在ROM中的只读引导加载程序,并且是ARM7处理器,此时,我们关闭了Tegra中的主处理器。
当BPMP ROM引导加载程序从NOR闪存中读取一条数据时,会提供大量信息,这就是BCT(引导配置表),信息包括:
· 内存中几个引导程序的地址
· 将引导程序加载到SDRAM的位置
· SDRAM中引导加载程序的入口点
· 连接到系统的SDRAM的配置(需要进行引导才能访问)
将第一阶段引导加载程序复制到SDRAM之后,BPMP开始执行,此时尚未打开Tegra中的主处理器。
第一阶段的引导加载程序为QUICKBOOT,其大小约为56KiBytes。明确引用了AES-CMAC(消息认证代码),“ AES-CMAC Xor”是在此使用的字符串之一,这些字符串也在U-boot(开源的引导程序)中可以找到。
(https://github.com/u-boot/u-boot/commit/b149c4c399b111cec1ff7505ca9fabbeeb4fe394)
来自第一阶段引导程序的字符串
有人可能会认为引导加载程序是基于U-boot的,但是特定的加密功能实际上是由Nvidia编写的,因此可以由Nvidia在其他地方自由使用。
当第一阶段引导加载程序正确设置SoC时,主处理器就会启动,然后加载第二阶段的引导加载程序,以允许主处理器运行。
当解压缩并运行内核时,我们发现第二阶段的引导程序非常简单,没有看到任何加密保护的迹象。
宽松地遵循Android bootimg格式,内核映像由一个文件中的内核和ramdisk组成。内核激活后,将运行/sbin/init-stage-0.sh脚本,其主要目的是通过安装NAND闪存分区使系统完全可操作。
NOR flash
我们在NOR flash中找到了BCT、第一级和第二级引导程序以及内核。
CID NOR闪存的布局
我们发现许多分区已镜像到主分区和恢复分区上了。
NAND flash
/ usr /文件系统存储为sqaushfs文件系统,其中包含在正常操作期间不会更改的二进制文件和脚本。SquashFS在低资源嵌入式系统中很常见,它是一种压缩的只读文件系统,它允许文件系统的不可更改部分占用较小数量的闪存。
/ var /目录包含日志,是一个小的128Mb ext4文件系统。
/ home /目录包含升级文件和临时数据,并作为ext4文件系统存储在其余的闪存中。
/ home和/ var目录覆盖在只读文件系统上,仅允许少数几个目录被读/写,这意味着系统的大部分内容都是只读的。
Dual-bank 固件
初始ROM引导加载程序运行后,引导加载过程可以选择两个映像:
· ROM引导加载程序,仅提供一个副本。除非存在灾难性的硬件问题,否则它是不变的。
· stage1_primary / stage1_recovery 由ROM引导程序顺序选择。如果第一个失败,则第二个运行,除了内存中的位置,这两个引导程序看上去几乎相同。
· stage2_primary / stage2_recovery 在此运行的引导程序由哪个stage1引导程序运行确定。同样,两个引导加载程序看起来几乎相同,除了内存中的位置外。
· kernel_a / kernel_b 这两个内核的引导参数非常不同。
· 系统启动时可以挂载在线/离线usr分区。
这是两个内核的引导参数:
init-stage-0.sh脚本读取thispartid的值,并加载两个/ usr / squashfs分区之一,如果其中一个损坏,则可以使用另一个恢复。
我们还可以看到AppArmor通常处于启用状态,该强制访问控制系统允许内核将二进制文件限制为受限的资源集,Ubuntu默认情况下启用此功能,Tesla上的配置看起来是标准配置。
安全 Boot
Tegra支持安全启动,但是围绕它的文档和代码示例很零散。在开发人员论坛中,关于如何实现它的内容也很少,这在高端处理器中很常见。
我们无法最终验证使用安全启动的程度,但是确实发现了几个问题。
ROM引导加载程序通过内部存储的密钥验证BCT的签名,这是SBK,AES-CMAC是BCT的一部分,并经过了验证,这是对称加密,如果发现了密钥,则可以生成有效的BCT。
我们无法确定SBK在每个设备/车辆上是唯一的还是较大的组所共有,需要多个车辆来确定这一点。
另外,Tegra只能在内部存储一个公钥,因此可以使用公钥密码,即使发现了公钥,也仍然无法生成正确签名的BCT图像,这是对称密钥的更强替代方案。据我们估计,在2015年之前(特斯拉CID部署后),软件支持还没有到位。
第一级引导程序执行第二级引导程序的AES-CMAC,无法确定在此使用了哪个密钥,但是Tegra文档指出也可以使用SBK。
第二阶段引导加载程序仅执行内核的CRC。如果信任链中断,攻击者可能会在此阶段将恶意内核加载到设备上。
Userspace 软件
CID一旦启动,便进入用户空间。
一系列Qt二进制文件就会出现在CID的用户界面。我们仅对这些进行了非常有限的逆向,一个8字符的PIN保护CID上的服务菜单,该菜单每天都在变化,并由CID实现。
Shell脚本在车辆中实现了大量功能,逆向很容易,因为它们是可读的文本文件。
固件更新机制
我们观察到了多种固件更新机制。
从车辆到特斯拉系统的出站VPN连接是所有机制的核心。没有发现任何其他形式的传输加密,来自CID的所有请求都是使用未加密的HTTP发出的。
我们看到了以下更新机制:
· Shell脚本,看起来像旧系统,但是与后来的更新程序二进制机制有很多共同点。
· 更新二进制文件,大型的多调用二进制文件轮询以获取更新,下载更新并将其应用于系统。
· 内核/引导加载程序,内核和引导加载程序由特定的二进制文件更新。
· 地图,VPN连接用于下载地图数据
· 常规ECU ,通过CAN网关将固件更新从CID分发到ECU,使用了一个复杂的过程。
· Wi-Fi模块和蜂窝调制解调器的USB固件。
VPN连接
通过CID建立与Tesla服务器的OpenVPN连接。每辆车的钥匙和证书用于执行此操作,车辆的VIN是证书的主题。
示例VPN密钥
我们能够从本地访问CID的文件系统中提取这些密钥,然后通过在另一台计算机上使用它们来连接到Tesla专用网络。密钥已于2018 年5月31 日到期,如果此后没有通过固件更新进行更新,则似乎没有备用机制。
使用安全配置的VPN,将无法拦截通信或对其进行篡改。
可以通过Wi-Fi或蜂窝网络(无论哪个可用)建立VPN,通信使用的是Wi-Fi,大概是为了减少特斯拉的成本。
连接到VPN时,会自动建立许多路由:
· 32.0.0 / 16
· 33.0.0 / 16
· 224.0.0 / 24
· 232.75.0 / 24
· 232.79.0 / 24
根据特斯拉漏洞赏金计划,对这些范围进行了完整的端口扫描,仅发现了少数主机:
· vn.teslamotors.com :车辆数据和状态,安全令牌更新,以访问诊断和IC SSH
· vn.teslamotors.com :固件下载和更新
· Firmware-bundles.vn.teslamotors.com :已失效的固件更新服务器
· vn.teslamotors.com :地图数据和更新
根据特斯拉安全性的早期报道,VPN密钥存储在连接到网关的大型SD卡上,通过卸下SD卡,可以轻松恢复这些卡,被测车辆存储在CID中VCM上的NAND闪存中。
固件服务器
来自服务器的示例JSON响应
Shell脚本固件更新
我们在Tesla文件系统上找到了旧版固件更新机制,该机制采用了一系列Shell脚本来执行更新,即使没有返回有效的下载URL,它也提供了许多有用的信息。
固件下载
通过Tesla VPN,shell脚本/ local / bin / do-firmware-handshake获取并安装固件更新。
该脚本可以通过多种方法启动:
· 定期使用事件管理器
· 响应“ firmware-handshake”事件
· 手动启动
该脚本从高层获取并应用更新,如下所示。
打开升级包并进行安装的Shell脚本将检查“ unpack.sh”脚本是否正在运行,如果正在进行升级,则会退出Do-firmware握手,因为更新已经在进行中。
可以假设网关正在处理升级,并且如果文件小于20分钟,则do-hardware-shash退出。因此,不会对网关执行任何主动检查以查看其是否被占用,如果网关更新的时间早于20分钟,则将其挂起,并且握手过程将继续。
要查看VPN是否已连接,脚本将检查接口tun0是否存在,如果未连接VPN,脚本将等待30秒钟再试一次,没有积极尝试建立VPN隧道。
建立VPN连接后,脚本将连接到以下URL:
http://firmware.vn.teslamotors.com:4567/vehicles/
发送以下数据:
这是一个用逗号分隔的字符串,用于描述网关存储的车辆配置。另一个shell程序脚本/ usr / local / bin / vehicle_hardware_configuration_string生成此字符串。
格式如下:
从/ etc / swver中读取,这是在CID上运行的软件版本。
然后,服务器返回JSON字符串,该字符串应包含以下字段:
· Firmware _download_url –我们将下载的文件的位置
· Firmware_download_file _md5 –我们将下载的文件的MD5校验和
· Download_status_url –用于回传升级状态的URL
· Vehicle_job_status_url
· Unpack_size –解压缩的固件文件的大小
· Install_size –安装固件文件所需的大小
我们发现仍然可以发出这些请求并接收响应,可以使用另一辆汽车的VPN来请求任何VIN。JSON响应不是使用jq之类的健壮解决方案,而是使用awk,gsub和split手动解析。
然后对这些字段进行一些基本的完整性检查。为了告诉升级已经开始,将download_status_url存储在前面的文件中。
通过对文件发出HTTP HEAD请求,然后检查firmware_download_url文件的大小。这是一种奇怪的机制,因为它可以简单地在JSON响应中传输。firmware_download_url在获得的所有响应中都指向服务器firmware-bundles.vn.teslamotors.com,尽管是通过握手过程发出的,但链接无效。
使用JSON响应中的unpack_size和install_size,对Flash文件系统上的备用空间执行基本检查。为了防止CID休眠60分钟,将对在端口4035上的CID上运行的Web API发出请求。
下载文件。它是作为一整个部分下载的,不会以任何方式分块或拆分。如果不是预期的大小,则再次尝试下载。
对于在测试期间获得的示例firmware_download_url,这些文件仅只能通过Tesla VPN下载。然后将文件的md5校验和与期望值进行对照,如果文件不匹配,则再次尝试下载文件。
下载文件后,将通过CID屏幕上的弹出窗口提示用户升级,另一个shell脚本/ usr / local / bin / get-response执行此操作。它向端口4070上CID上运行的Web API发出请求,并等待一个小时以做出响应。
如果用户接受更新,则下载的文件将移至/ home / tesla / dropbox,准备安装。
USB更新
使用USB记忆棒,也可以将更新文件放入/ home / tesla / dropbox,Shell脚本/ usr / local / bin / usb-upgrade执行此操作。
该脚本在文件夹/ toinstall中查找文件名,格式为:
ui_full_package_*__pedigree_v*.tar.gz
使用下表,从车辆的VIN码中查找:
该表表明有带有预设VINS的开发工具。
如果此文件名中没有CID上的软件的当前版本,则将文件复制到Dropbox,然后安装。由于检查是幼稚的,并且忽略了实际版本,因此可以进行固件的升级和降级。
脚本中似乎有一个错误,如果脚本中不存在车辆的VIN,则返回的code就是空白,这将导致以下形式的文件匹配:
ui_full_package _ * __ pedigree_v * .tar.gz
在USB记忆棒上的给定文件夹中,攻击者可以用特制的固件更新文件并执行任意代码,我们尝试了很多次,但是无法触发,另一个安全控制措施是阻止脚本被调用,但是我们无法确定它是什么。
安装 Dropbox
位于/ local / bin的脚本“ unpack.sh”位于/ home / tesla / dropbox文件夹中的软件包,该脚本描述了该过程,并对其进行了大量注释。
尽管它是自定义的,但包格式非常简单,攻击者很容易重新创建。从高层次分析,该过程如下:
检查是否提供了文件名,并且该文件存在。
一旦汽车“停止”,另一个shell脚本将执行此检查-/ usr / local / bin / car-is-parked。在CID的端口4035上,这会向Web API发出HTTP请求,以检查汽车是否处于“停车”档,停放脚本包含用于检查速度为零的函数,但是这些函数不会被调用。
脚本等待5分钟,然后再次检查汽车是否未停放,为了防止CID休眠20分钟,然后在端口4035上向Web API发出请求。
使用程序mktemp在/home/tesla/unpack.tmp-XXXXX中创建一个临时目录,tar文件已解压缩到临时目录中。
检查是否存在4个文件:
· 包名
· 版本号
· 包中文件的md5sums
· tar.gz –与软件包关联的文件
该过程不会检查它是否存在,但是它期望文件“ install.sh”存在。为了检查文件的完整性,将文件md5sums馈送到工具md5sum,这不会增加安全性,纯粹是完整性检查。
将名称,版本和data.tar.gz作为参数传递后,将执行文件install.sh。为了最终控制软件包的功能,install.sh可以执行root用户通常可以执行的任何操作。
install.sh文件可以包含任意命令,并且整个过程以root用户身份运行,为了控制,攻击者可以将有效的升级程序包放置在保管箱中,以对CID或IC进行任意操作。
这些信息表明此过程不健全且存在问题:
这种机制非常不安全,它在VPN提供的传输加密之外几乎没有保护措施,这是不推荐使用的主要原因。
我们不知道为什么它仍然存在于系统中,也许开发人员担心删除众多脚本之一可能会导致意想不到的后果。
更新程序
这是更新固件的正常机制。这是一个大型的整体二进制文件,包含大量功能,逆向静态链接库(将所有代码编译到其中)和调试版本信息(它包含字符串和函数名)使得分析速度加快。
静态链接调试信息
通过更改二进制文件的名称,更新程序可以采用几种不同的“方式”,可以打开一个命令端口和一个HTTP端口,它们侦听设备的所有接口。
· ic-updater – IC的更新程序。打开用于命令的端口28493,并打开21576作为Web服务器。
· cid-updater – CID的更新程序。打开端口25956用于命令,打开20564作为Web服务器。
· gwxfer –用于将文件传输到网关,是gwxfer shell脚本的替代文件。
· sm-updater –尚不清楚“ sm”是指什么。这可能是厂商使用的东西,因为二进制文件的其余部分都引用了“ sitemaster”。
· ethdeploy –将软件包部署到车辆内其他设备的一种方法。
· upackager –与网关有关,采用release.tgz(用于ECU的更新)和internal.dat(车辆的配置)和vhcs(车辆配置字符串)的参数
根据二进制文件的开头名称,二进制文件的行为会有所不同。这包括其执行的服务,其使用的路径和技术,该代码中的方法存储超过330个变量。
为了便于确定代码何时对应什么行为,0对应于IC,1对应于CID,5对应于SM。
用于不同行为的command / http端口
将更新程序作为“集群”运行,该系统与多个设备(CID和IC)一起使用,通过VPN连接并下载固件,CID充当主服务器,在代码中称为“中继器”,然后使用命令/ HTTP端口将固件分发到IC。
更新程序在启动时执行某些任务,例如检查当前系统,将输出连接到固件服务器以及启动命令和Web服务器。
尽管看到了许多错误,但是可以在QEMU中运行二进制文件,二进制程序按预期启动了两个侦听服务。
在qemu中运行IC更新器
二进制文件在初始化期间对其自身执行sha512哈希,尽管sha512输出64个字节,但仅保留了前8个字节,这意味着可以使用暴力破解找到哈希key。
hash_self对二进制文件进行sha512哈希
截断的sha512哈希输出
sha512sum
稍后,当向固件更新服务器发出请求时,此哈希将用作User-Agent字符串的一部分。
哈希被放入请求的User-Agent部分
攻击者可以在运行替代恶意软件的同时获取预期的sha512哈希,服务器可以确定正在使用哪个版本的更新程序,这不是针对恶意行为的有力保护。
通过计时器或按需执行,更新程序可以在缓冲区中处理一系列命令,可以通过cid-updater或打开的命令端口输入它们,从而允许Tesla以太网上的其他设备执行操作。
以下是任务“ fwheartbeat”的示例,该任务以1小时的间隔启动,并调用了函数start_regular_timer:
在计时器上添加了fwhearbeat
通过调用函数do_after_e_ms,还可以在固定时间段后运行命令,这是重启固件下载的示例:
一段时间后正在运行下载重新启动
这些命令由字符串引用,可以采用存储在数组中的许多值。
命令数组
使用不同的参数,命令“ install”和“ patch”都最终调用函数do_install。
像交互式命令处理器一样,该过程的命令端口提供了使用技巧和其他帮助。
ic-updater通过HTTP提供文件示例
通过HTTP下载提供的文件
通过命令端口报告当前状态
需要会话令牌来保护IC和CID之间的命令,每天更改一次,并通过VPN从Tesla服务器进行同步,如果攻击者可以嗅探IC和CID之间的连接,并使用它发送自己的命令,则攻击者可以拦截此令牌。
我们将二进制文件放入开发模式,完成此操作后,包括签名检查在内的大多数安全功能都被禁用。
开发模式导致签名检查被跳过
二进制文件包含大量功能。从最高层来看,最重要的过程如下:
· 握手–将请求发送到包含车辆详细信息的Tesla服务器并接收对车辆执行操作的响应的过程。
· 基于握手下载和解密各种固件更新文件
· 将下载并解密的固件更新文件(bsdiff40(二进制difs)或Redbend delta(专有二进制diff))安装到脱机闪存分区中
· 中继–将固件从CID复制到IC
· 重新部署–将固件的离线状态复制到在线状态以进行恢复其他功能包含在二进制文件中。
握手
类似于shell脚本更新,有关车辆的数据使用VIN进行键控,然后发送到远程服务器,该服务器以任何可用的更新作为响应。
通过功能do_handshake向固件服务器发出POST请求,需要进行固件服务器的配置(包括服务器名称,端口和路径)。
配置握手请求
POST请求中包含的数据比shell脚本版本复杂,包括以下内容:
· 车辆VIN –从网关检索和缓存,而不是从文件中读取,在请求的路径中发送。
· VHCS(车辆硬件配置字符串)–基于从网关恢复的hwids.txt的字符串(使用函数fetch_vhcs生成),作为POST参数发送。
· 当前固件签名–使用函数read_firmware_signatures读取,从保存/ usr /分区的内存分区的后40个字节中读取固件签名,发送base64编码为POST参数。
POST请求的格式字符串
函数request_HTTP发出POST请求。它只能发出HTTP请求,而不能发出HTTPS请求,更新程序二进制文件根本没有TLS功能,这意味着握手总是在纯文本中进行,这取决于Tesla VPN的安全性。
函数tun0_is_up检查VPN连接,仅检查设备tun0是否存在。控制了CID的攻击者可以在没有知道更新程序二进制文件的情况下建立自己的VPN。
更新程序二进制文件本身似乎没有建立VPN连接的任何功能。尽管无法确定是哪一个,但是必须通过外部过程来执行。
服务器对HTTP POST请求给出JSON响应。通常,如果请求格式错误或不正确,则不会给出响应。
典型的握手响应
函数handle_handshake_download处理JSON响应。
在握手响应中,可能存在数十个字段。可以从JSON copy_handshake_var_at中提取各个字段,该字段采用字段名称的参数,对该函数的72个引用中至少使用35个不同的字段名称。
多次调用以查找JSON响应中的字段
这表明特斯拉中固件更新机制非常复杂。这是从函数do_install的握手响应中读取md5哈希的示例。
从响应中读取字段firmware_download_file_md5
然后调用handshake_is_actionable函数。如果正在下载升级,已经在CID上升级,正在中继到IC或正在安装升级,则将阻止握手采取措施。
不进行握手的原因
如果可以进行握手,则调用函数initialize_handshake_install。握手响应存储在文件中以供以后处理,并将命令添加到队列中。
下载
握手响应中可以包含三个不同的字段,以供下载文件:
· Firmware_download_url –根据外壳脚本方法的常规更新
· Bsdiff40_download_url –使用开源解决方案的二进制差异
· Rbdlt_download_url –专有的Redbend增量
使用HTTP,它们似乎都以类似的方式下载。这是一个示例URL:
我们注意到了这些URL的几个有趣的特征:
· 响应每个握手请求而生成,并且显然是唯一的
· 收到握手响应后,有效期始终为两周。
· 出现一个HMAC(哈希消息身份验证代码)以检查其余请求的完整性。
· 可从公共Internet获得从中下载它们的服务器-无需建立VPN连接。
由于到期和HMAC,我们无法猜测或暴力破解其他固件下载链接。
值得注意的是,由于使用公共Internet上的HTTP(未加密)进行下载,因此存在被拦截和篡改的风险。
字段firmware_download_file_md5检查下载的完整性。通过安全的VPN下载哈希值时,将通过公共Internet下载文件。如果攻击者篡改了下载内容,则MD5哈希可能不再匹配。
Wi-Fi或蜂窝连接可用于执行下载。另一个字段wifi_wait_until将允许通过Wi-Fi在有限的时间内进行下载。我们认为,这是为了避免通过蜂窝连接下载的费用,同时允许它们进行必要的更新。
在固件握手响应中可以看到涉及加密的字段:
通过开放Internet下载固件的加密密钥
Salsa20(一种轻量级算法)可用于加密下载的更新文件。函数crypto_and_save_file实现解密。
握手响应通过VPN发送整个256位密钥,因此应保持安全性,以防止Internet上的固件下载被截获。
我们看到的所有下载文件都已加密。应该可以发送未加密的文件,但是我们没有看到任何证据。
安装
可以更新系统的许多不同方面:
· /usr分区
· kernel
· 引导程序
/ usr分区更新涉及更新程序二进制文件中的大部分功能。为此,系统分为在线和离线usr分区,它们被称为usr,而不是已挂载的文件系统,但它们都是原始存储设备(例如/ dev / mmcblock0p1),“ usr”是指存储设备的只读方面。
似乎大多数固件更新都应用脱机分区。然后,可以将脱机分区中所做的更改复制回联机分区,或直接从脱机分区运行。
为了从脱机分区执行更改,会发生以下情况:
· 对脱机分区进行的更改(使用patch,bsdiff或Redbend)
· 检查联机和脱机分区的签名,以确保正确应用了补丁程序。
· 脱机分区安装为/ newusr,然后可以执行/ newusr / deploy /的内容
发生以下情况,将更改从离线复制到在线:
· 对脱机分区进行了更改(使用patch,bsdiff或Redbend)
· 检查联机和脱机分区的签名,以确保正确应用了补丁程序。
· 然后更新重新部署固件,将引导加载程序,内核和usr分区复制到在线分区。
系统可以在固件更新时继续运行。这似乎与恢复分区的概念背道而驰,首先将它们覆盖,由于使用了多个校验和和签名,因此汽车很难变砖了。
从传递的参数可以看出,更新程序文件通过对上述示例更新程序进行系统调用来对内核和引导加载程序进行更新。
选择cid / ic / sm-udpate_sample
调用-update_sample
应用更改的方法可能会有所不同。
常规完整更新
下载tar.gz文件,将其解压缩,然后运行Shell脚本以执行更改,几乎与上面的Shell脚本固件更新相同。
Bsdiff固件更新
通过HTTP下载,解密然后安装,一些固件更新是bsdiff二进制diff文件。
函数patch_from_bsdiff40_to_offline_dev应用更新。
patch_from_bsdiff40_to_offline_dev函数概述
/ this从高层执行以下操作:
· 检查下载的文件是否为BSDIFF40格式。
· 开始使用静态链接的bzip函数处理BSDIFF40文件。
· 确定哪个闪存存储库是脱机usr(未使用)存储库。
· 在整个离线usr分区上应用文件。
在原始闪存级别运行,该过程不知道其中包含的文件系统或文件。在应用更新之前,要求不能修改/ usr分区,整个分区是只读的,没有问题,为确保起点符合预期,在应用更新之前会执行签名检查。
Redbend固件更新
特斯拉CID可以使用Redbend来执行更新,以替代bsdiff。这将获取并应用包含当前固件与新固件之间差异的更新文件。尽管在Android手机中也可以看到它,但Redbend是专门针对汽车的。
从更新程序中的字符串来看,所使用的技术称为vRM或vRapid Mobile。UPI或更新安装程序是在cid-update中运行的软件,UPG或更新生成器是另一种创建已部署更新的软件。
在更新程序的Redbend部分中没有下载更新的功能。
Redbend有大量的RB_前缀函数
UPI处理可包含多个单独更新的DP文件。这些文件具有CRC32校验和,在Redbend软件中称为“签名”,这是一个不正确的术语,CRC仅对非恶意完整性保护有用,而对恶意操纵无效。
正在使用的Redbend vRM版本
在应用到系统的Redbend和bsdiff40更改之间,几乎看不到差异。
中继
CID被设计为充当主服务器,它向握手服务器发出请求,下载更新,应用更新,然后将其“中继”到IC。
ic-updater将拒绝执行握手
有几种不同的中继方法,包括发送整个脱机/ usr分区,以及在CID上的HTTP服务器上提供单个文件,以及请求IC下载它们。
在IC之前,CID更新固件。在我们的测试过程中,未更新CID,尚未将更新传递给IC的过程切实可行,因此我们难以确定其工作方式。
一旦将更改应用于离线闪存分区,更新程序将“重新部署”固件。在重新引导设备之前,这将引导加载程序和内核(使用cid-update_sample二进制文件)和/ usr分区复制到了在线分区。
与中继一样,由于CID或IC都不接受更新,因此在测试过程中没有观察到这一点。
更新 内核和引导加载程序
cid-update_sample程序可用于更新设备的引导程序和内核。我们发现此文件的命名很奇怪,但是在其他几个位置也提到了该文件。
与主更新程序二进制文件不同,它没有CID和IC的多种行为,尽管名称不同,但两个设备上都存在相同的文件。
在qemu中运行cid-update_sample二进制文件
从两个地方调用cid-update_sample二进制文件:
· 名为/ usr / local / bin / qber的shell脚本会更新BCT以及主阶段1和主阶段2引导加载程序,该脚本似乎没有从其他任何地方调用,但是可以从下载的固件更新内部调用
· 从cid-update或ic-updater内部调用
有趣的是,此二进制文件可以执行BCT的部分更新,在帮助文件中指出仅更新SDRAM和设备时序。
SBK 内部存储在Tegra SoC上的AES密钥在BCT中对大多数数据进行签名,签名的数据包括SDRAM和设备时序。必须使用SBK对文件进行签名,以更改SDRAM和设备时序。
我们在/ usr / deploy文件夹中找到了一个示例BCT文件,它不包含任何签名或引导加载程序数据,仅包含SDRAM和设备时序。
我们得出的结论是,cid-update_sample必须检索当前的BCT,合并新的SDRAM和设备时序,并重新签名数据。这意味着二进制文件必须要么能够访问SoC内部的SBK,要么包含它的副本,需要进行进一步的逆向来确认这一点。
更新中的BCT文件不包含所有签名数据
地图更新
映射数据由CID存储在外部microSD卡上,VPN连接可用于定期更新。
脚本/usr/local/bin/nav-sync-and-apply-map-patch.sh和nav-apply-map-patch.sh执行更新它们的机制。
执行以下任务:
· 保汽车保持开启状态,并且在15分钟内不睡眠
· 使用rsync从URL(rsync://filesync.vn.teslamotors.com/mapdata/patches)下载更新。Rsync是一种文件同步工具,可用于通过慢速或不可靠的网络链接将更改有效地传输到大型数据集。
· 更新是将tar文件解压缩到SD卡中。
没有访问控制或身份验证来访问数据,在所有区域拥有有效VPN密钥的任何人都可以下载整个映射数据集。
尽管其他固件更新机制已从shell脚本转移到已编译的二进制文件,但映射更新仍保留为shell脚本。
通过网关进行常规ECU更新
集成到CID中的Tesla网关与许多IVI相似,具有运行媒体/ UI组件的更高功率的系统,并耦合到功率更低的网关,后者又连接到CAN总线。该网关可防止IVI注入CAN总线。
通过使网关的功能受到限制,可以限制攻击面和代码的复杂性,两者都有可能提高安全性。
一般而言,大多数车辆倾向于具有将CAN总线彼此分开的附加CAN网关,例如传动系统与车身系统。Tesla CID中的网关是车辆中唯一的CAN网关,并且还执行此功能。
网关具有2MiByte的集成闪存,是一个MPC5668G微控制器。它专门针对汽车网关应用进行销售,它采用e200z6内核,该内核是PowerPC架构。我们发现该器件提供了完整的数据表和参考手册,这对于汽车专用微控制器来说是不寻常的。
以太网交换机将网关连接到CID VCM,IC和诊断端口。这些实体使用各种UDP和TCP协议进行通信,并且都分配有IP地址。连接到外部CAN收发器的是网关上的多个CAN接口,也有一个LIN接口。在CID主板上,网关直接连接到全尺寸SD卡。
在检查获得的固件升级后,我们发现网关运行定制版本的FreeRTOS。一个小型而简单的实时操作系统,它包括线程/任务,互斥量,信号量等功能,通常在汽车应用中存在。
通过UDP端口3500传输的文件被网关上运行的固件接受,这些传输是通过Perl脚本/ usr / local / bin / gwxfer或CID上的更新程序二进制文件执行的。
Perl gwxfer脚本
该服务没有身份验证,SD卡存储发送到网关的所有文件。
常规传输的文件:
· dat –车辆的配置,其中启用或禁用了某些选项,发送到网关和从网关接收。
· tgz –压缩文件,其中包含CAN连接的ECU的更新。
· img –传输到网关以执行ECU更新的替代固件。
internal.dat的一部分
尝试启用/禁用车辆上的某些功能时,我们无法修改internal.dat文件,网关很可能会向各个ECU发出请求,以增强汽车的功能。
UDP端口1050接受某些命令,例如发送/接收CAN消息,触发更新等,并且也处于打开状态。
ECU高层更新过程:
利用前面提到的其他固件更新机制之一,CID下载更新软件包。
需要两个文件来更新ECU。一个是存档,其中包含所有单独ECUS的更新,称为“ Release.tgz”,另一个是Noboot.img,这是网关更新其他ECU的特定固件。
多种机制可构建release.tgz文件。
“ premastered”版本是第一个,无需进行预处理,就可以从固件服务器下载此更新,并将其直接应用于ECU。
第二种使用“种子”。固件更新机制将各个ECU更新文件下载到“种子”目录中,然后根据需要更新的ECU创建自定义release.tgz,我们认为,这样做的目的可能是减少网关在“更新”模式下花费的时间。
使用脚本/二进制gwxfer,文件被传输到网关并直接存储到SD卡上。
升级期间SD卡的内容
存储在普通网关固件中的公共密钥会检查noboot.img的签名。
当命令发送到网关时,noboot.img被重命名为boot.img,将boot.img复制到0x40000000的RAM中,并在网关重新启动时执行。
网关的正常功能很少包含在noboot.img中。网关处于更新模式时,车辆在很大程度上停止运行,我们无法移动车辆。
来自noboot.img内部的字符串
最新release.tgz文件的内容
noboot.img中的代码将Release.tgz文件解压缩,该文件将发现以下内容:
· 一系列.hex文件,单个ECU的升级
· 清单文件,其中包含.hex文件及其版本的列
· 包含带有签名的文件的CRC32的元数据文件
清单文件
Signed_metadata_map.tsv
再次使用网关固件中存储的公钥,网关似乎正在检查每个文件的CRC32和签名。
命名ECU的二进制固件包含.hex文件。对ECU进行编程时会发生以下情况:
· 为了确保更新安全,请执行规定的措施(例如,使用主接触器断开电池)
· 使用UDS安全访问命令,解锁ECU
· 通过UDS发送固件
· 重新启动ECU
通过直接写入闪存而不是使用UDS,网关还可以自我更新,文件名是gtw.hex。
网关固件中的字符串
更新是顺序执行的。我们为观察到的两个固件更新更新了相同的ECU,这似乎是车辆中的大多数固件,我们无法确定是否执行了部分更新。
默认情况下,车辆周围的ECU通过CAN接口不接受固件更新,必须通过UDS安全访问通过CAN对其进行解锁,在固件更新期间,嗅探了几次UDS安全访问传输。
我们发现某些ECU(即IC)正在使用静态种子/密钥对,其他人似乎在使用不同的种子,没有尝试从各个ECU收集种子来评估其随机性的质量。
在noboot.img中,有几部分代码似乎可以处理不同的UDS种子/密钥算法,但是我们无法确定它是如何确定给定ECU使用的代码。
发送到ECU的固件文件似乎没有任何特定的验证,这可能是由ECU本身执行的。
根据对.hex文件的分析,没有文件签名,可以使用熵分析来识别数字签名,它们几乎总是高熵。
RCCM固件的熵
DSP固件的熵
GTW固件的熵–注意峰值显示可疑的密钥/签名
noboot.img的熵显示出很高的峰值,可能是用于检查签名的公共密钥。
在先前的ECU更新期间,研究发现仅执行了CRC32检查。这使该过程容易受到攻击,因为它允许将恶意固件加载到网关,然后再加载到其他ECU。
SD卡没有完整性保护或签名。攻击者可能会修改内容,这可能具有安全隐患,例如,对使用时间的检查时间(TOCTOU)漏洞,在此漏洞中验证了固件签名,攻击者修改了固件并将其加载到ECU,这很难利用。
UDS安全访问用于更新各个ECU。安全访问是一种简单的质询/响应算法,输入模式可以进行某些操作的情况如下:
· 网关从ECU请求种子
· ECU发送种子
· 网关使用算法将种子转换为正确的密钥
· 密钥被发送回ECU以实现安全操作
· 网关将固件加载到ECU
为了防止重放攻击,种子应该是随机的并且具有足够的长度,在特斯拉上,ECU在某些情况下以固定的种子值进行响应。值得注意的是,这发生在FPGA或电源管理微控制器(组合仪表中的设备)上。
通常,以下一种或多种,用于将种子转换为密钥的算法因ECU而异:
· 按位异或
· 按位移位
· 混合位
· AES加密(对称加密,双方均知道密钥)
· RSA加密(非对称加密,其中ECU仅知道公钥,更新程序则是私钥)
观察种子/密钥对通常会使前三种方法易于逆向,所需的线对数量从几对到数十或数百不等。
由于无法从加密数据中确定密钥,因此AES加密通常可以防止攻击者拦截通信。但是,仍然存在可能直接从端点(ECU或对其编程的设备)恢复密钥的风险。
由于大多数ECU是带有集成闪存的微控制器,因此AES密钥可以存储在内部,从而避免了碎片读写。为了以这种方式获得AES密钥,攻击者可能不得不花很长的时间。
RSA加密仅将公开密钥放在ECU上。攻击者即使无法恢复私钥,也无法在不访问私钥的情况下生成种子/密钥对。这为对称加密增加了额外的安全性,在ECU中,这是一种相对罕见的机制。
编程设备的安全性等同于所有这些方法。如果攻击者可以访问该算法,AES密钥或RSA私钥,则他们可以对其进行恢复,从而激活ECU上的UDS。
传统的汽车诊断和编程工具已使用多种技术来确保自身的安全性:
· 限制向受信任方分发软件
· 限制性许可,包括在线激活和硬件加密狗
· 使用硬件加密狗执行种子/密钥转换
· 使用在线服务远程生成种子/密钥对
由于这些技术,攻击UDS安全访问种子/密钥算法变得更加困难。
但是特斯拉则不同。传统上,可以严格控制的特定笔记本电脑或设备已由经销商或车库用来执行诊断和编程。
Tesla升级是远程执行的。网关必须实现在车辆中所有ECU上执行UDS安全访问的方法,因为编程设备必须在网关本身中实现。
这使攻击者很容易抓包逆向,但是,这仍然是一个非常耗时的过程,特别是考虑到车辆拥有大量ECU。
即使种子/密钥过程被认为是安全的,也不应认为UDS的整个过程对于来自主动攻击者的CAN总线是安全的。一旦网关使用UDS将设备解锁,则无法阻止攻击者与该设备进行交互,这可以使他们执行代码,读出固件并将自己的固件写入设备。
尽管网关检查ECU的单个.hex文件的加密签名,但几乎没有证据表明ECU对通过UDS发送给他们的固件执行签名检查。
ECU,尤其是最基础的ECU,很少进行固件签名检查。作为固件更新过程的一部分,通常仅执行诸如CRC之类的基本检查或简单的模块校验和。
Wi-Fi和蜂窝调制解调器USB固件更新
通过USB连接到CID中的VCM,Wi-Fi模块和蜂窝调制解调器也通过此通道接收更新。
Wi-Fi模块
/ usr / local / bin中的一系列工具和脚本更新了Parrot FC6050W Wi-Fi模块。
如果通过Shell脚本方法执行固件更新,则会调用脚本new-pflasher,为加载程序,安装程序以及最终应用程序提供多个参数,然后,此脚本调用二进制文件new-pflasher-core。
如果固件更新由二进制更新程序执行,则直接从函数do_upgrade_parrot中调用pflasher-core二进制文件。
当我们检查/ usr / deploy /中的固件文件时,没有发现任何特斯拉特定的功能,也找不到模块的任何通用固件。
Parrot Wi-Fi模块固件文件
蜂窝调制解调器
不管用于更新调制解调器的机制如何,都会调用shell脚本/ usr / local / bin / sierra-update。这将调用二进制SwiFirmwareDownloadUMTS,它将固件发送到调制解调器。
我们在/ usr / deploy / sierra /中找到了蜂窝调制解调器的固件,这是两个.cwe文件:
调制解调器固件文件
像Wi-Fi模块一样,找不到任何迹象表明该固件具有任何特定的Tesla功能。
有趣的发现
在研究固件更新机制时,我们发现了许多其他有趣的功能。
启用远程功能
为了启用自动驾驶仪,shell脚本enable-autopilot-after-purchase.sh更新网关internal.dat。
我们认为,这表明可以远程启用和禁用该功能。Internal.dat中未包含范围或电池信息,因此我们无法确定特斯拉如何远程更改这些信息。
启用自动驾驶的Shell脚本
更新安全令牌
为了访问诊断,以root用户身份登录或在CID与IC之间发送命令,必须知道一个安全令牌(每天从Tesla服务器通过VPN下载)。
使用命令获取安全令牌
当前的安全令牌被发送到服务器以获得下一个,这样可以防止具有有效VPN密钥的人获取汽车令牌。
升级策略
在名称从“ INDIFFERENT”到“ SUICIDE_BOMBER”的范围内,更新程序二进制文件中存在一系列升级策略,这些升级策略是用于重试UI上的下载和用户提示的策略。
升级策略
大量使用Shell脚本
/ usr / local / bin目录中有85个Shell脚本实现了各种功能。
CID仍然使用其中的许多,尽管其中一些功能已迁移到二进制文件中。
许多Shell脚本中的一些
通过对这些脚本中的许多脚本进行分析,可以对它们的功能有细致了解。
进一步的工作
我们最大的障碍是缺少备件,如果有备用CID,我们可以进行更详细的逆向分析。
还有一些地方需要进一步研究:
· 我们没有探索很多驱动CID UI的Qt二进制文件。它们包含用于连接到服务器的功能,包括日常服务菜单PIN码算法。
· 我们无法确定特斯拉如何远程更改某些功能(例如,车辆的行驶范围)。
· 在我们检查的系统的任何方面,我们都没有发现车辆追踪,远程保险开关或eCall被盗的证据,我们很想知道如何处理。
· 我们测试的车辆中没有自动驾驶模块,并且在CID上对它的引用很少。自动驾驶仪可能会采用额外的安全措施来自我保护。
本文翻译自:https://www.pentestpartners.com/security-blog/reverse-engineering-the-tesla-firmware-update-process/如若转载,请注明原文地址: