嵌入式GPRS/EDGE、3G、4G和5G模块通常用于很多用途,包括连接设备,如对讲机、警报器、汽车ECU、车载信息娱乐系统(IVI)、租赁汽车的开锁箱(Getaround连接解锁系统使用蓝牙,但也有个备份的移动连接)等等。在疫情期间意外地发现了一些模块设备管理过程中的漏洞,可能导致攻击者利用FOTA更新模块远程控制
这篇文章介绍了移动模块、FOTA攻击向量以及针对不同厂商的几个模块可以找到的不同的漏洞类型
移动模块
这些模块以不同的形式存在 (LGA、PCIe、PCI-SIG M.2),取决于所支持的插槽和为连接对象选择的模块化方式
例如在对讲机中使用的Quectel LGA移动模块
如下图所示,可以看到EC20这样的裸模组:
Quectel mobile(来源:Osmocom)
移动模块包括以下组件:
基带用于处理信号,通过无线电接收和传输数据使用特定的移动堆栈进行通信。在这种情况下,芯片上的应用程序处理器提供了许多功能,包括通过将模块连接到PC(e.g: /dev/ttyUSBx)
Harald Welte和Osmocom团队也展示了基于OE的Linux运行在一些移动模块上比如Quectel EC20,模块中暴露的设备,有的可以通过AT命令进行通信,有的还可以通过暴露的DIAG接口与基带通信
固件更新
为了让客户对新版本和新功能满意,同时也对模块进行修复,供应商通常支持两种类型的固件更新方法:
对于串行线路更新,供应商通常向客户提供一个实用程序来更新固件,并提供最新版本二进制文件的链接,这个实用程序可以运行一个暴露的USB/USIF接口从移动模块到主机更新固件
这些工具使用一个特有协议,步骤如下:
下面是由Ghidra检索的一个反汇编实用程序的伪代码中的一个步骤示例:
[...]
if (pcVar3 == (char *)0x0) {
dbg_print(1,"Current firmware is up to date. Nothing to do.\n");
close(fdStream);
destroyDevice(dev);
/* WARNING: Subroutine does not return */
exit(0);
}
}
}
if (boot_delay != 0) {
setBootDelay(dev,boot_delay);
dbg_print(1,"Forced boot delay %d ms\n",boot_delay);
}
if ((0 < deviceSpeed) && (usb_flag == 0)) {
setDeviceSpeed(dev,(uint8_t)deviceSpeed);
dbg_print(1,"Setting device speed %d\n",deviceSpeed);
}
if (restart_needed != 0) {
if (atDevice[0] == '\0') {
manage_failure(&fdStream,"No at channel found for restarting the modem\n");
}
cmd = (char *)(*dev->_vptr.Device[4])();
if (cmd == (char *)0x0) {
manage_failure(&fdStream,"*** Device does not support shutdown\n");
}
dbg_print(1,"*** Restart device: %s\n",atDevice);
fd = open_device(atDevice);
if (fd == -1) {
manage_failure(&fdStream,"*** unable to open the device for restart\n");
}
cmd = (char *)send_verify(fd,cmd,"OK",read_buffer,0x100);
if ((int)cmd < 1) {
manage_failure(&fdStream,"*** error response to AT command\n");
}
close(fd);
}
uVar4 = (*dev->_vptr.Device[1])(cmd,deviceName);
if (((uVar4 ^ 1) & 0xff) != 0) {
manage_failure(&fdStream,"*** Error entering boot mode\n");
}
uVar4 = (*dev->_vptr.Device[2])();
if (((uVar4 ^ 1) & 0xff) != 0) {
manage_failure(&fdStream,"*** Error uploading stream\n");
}
tVar5 = time((time_t *)0x0);
dbg_print(1,"Elapsed time: %lu seconds\n",tVar5 - tVar2);
cmd = getStreamSwVersion(dev);
dbg_print(1,"*** Stream uploaded successfully, installed version %s\n",cmd);
供应商使用的协议允许上传,但也可以实现下载或读取功能,可能会泄露当前固件
在线更新
无线更新固件,即FOTA更新,是一种被许多嵌入式设备用于远程(无线)更新的方法,在嵌入式移动模块的情况下,设备使用的移动网络GPRS/3G/4G或5G取决于可用的移动堆栈
FOTA更新通常以delta差分包的形式出现,它是由FOTA更新生成器生成的,生成器创建一个设备映像及其文件系统,其中有:
生成的增量软件包仅包含源固件版本和目标固件版本之间的差量更改,从而确保了下载高效更新
Osmocom已经记录了增量软件包的格式:EC20 / EC25增量空中固件(DFOTA)升级页面,其中包含多个嵌套部分和指针/偏移量
P1 实际更新:
P2 FileNamesTable:
使用专用通信协议将delta包发送到不同的设备。通常使用OMA DM(开放移动联盟设备管理)标准从HTTP/HTTPS中的设备管理客户端提取固件,该协议应该提供包括密钥安全功能在内的软件更新过程的所有管理方面。此OMA DM协议中使用了不同的对象:
客户端发起的FOTA的服务流程示例如下:
FOTA更新进程(来源:Telit)
为了管理移动模块,供应商通常使用SaaS解决方案,该解决方案可以扩大请求更新的设备数量,还可以识别基本更改,并供这些不同模块开箱即用
OMA DM配置
在提取OMA DM配置时,我们已经能够识别出一些漏洞。实际上我们可以了解一些配置细节查看如何使用OMA DM客户端进行FOTA更新:
<node>
[...]
<name>FwUpdate</name>
<get/>
<acl>Add=*&Delete=*&Exec=*&Get=*&Replace=*</acl>
<node>
<name>Flash</name>
<add/><exec/><get/><replace/>
<type>urn:oma:mo:oma-fumo:1.0</type>
<leaf>
<name>State</name>
<get/><replace/>
<format>int</format>
<value>50</value>
</leaf>
<node>
<name>DownloadAndUpdate</name>
<exec/><get/>
<leaf>
<name>PkgURL</name>
<get/><replace/>
<format>chr</format>
<value></value>
</leaf>
[...]
其他部分还告诉我们有关同步的不同端点以及如何下载新的固件二进制文件:
<node>
<name>DMAcc</name>
<permanent/><get/>
<node>
<name>synchronica</name>
<add/><copy/><delete/><get/><replace/>
<node>
<name>AppAddr</name>
<add/><copy/><delete/><get/><replace/>
<node>
<name>APPSRV</name>
<add/><copy/><delete/><get/><replace/>
<leaf>
<name>Addr</name>
<copy/><delete/><get/><replace/>
<value>http://**********/****ml/dm</value>
</leaf>
<node>
<name>Port</name>
<add/><copy/><delete/><get/><replace/>
<node>
<name>Port</name>
<add/><copy/><delete/><get/><replace/>
<leaf>
<name>PortNbr</name>
<copy/><delete/><get/><replace/>
<value>80**</value>
</leaf>
</node>
</node>
<leaf>
<name>AddrType</name>
<copy/><delete/><get/><replace/>
<value>URI</value>
</leaf>
</node>
</node>
[...]
我们可以注意到这里使用的是HTTP而不是HTTPS。因此,我们可以快速想象如果启用此协议栈,这些请求可能会被伪GPRS站拦截。我们将不集中于对这些模块进行后门程序的拦截攻击,而将重点放在请求的端点上
此外,我们还可以按以下方式检索BASIC Auth,来进行同步或获取二进制文件:
<leaf>
<name>AAuthData</name>
<replace/>
<format>bin</format>
<value>q****************==</value>
</leaf>
<leaf>
<name>AAuthSecret</name>
<replace/>
<value>fota</value>
</leaf>
<leaf>
<name>AAuthType</name>
<copy/><delete/><get/><replace/>
<value>BASIC</value>
</leaf>
<leaf>
<name>AAuthName</name>
<copy/><delete/><get/><replace/>
<value>synchronica</value>
</leaf>
<leaf>
<name>AAuthLevel</name>
<copy/><delete/><get/><replace/>
<value>SRVCRED</value>
</leaf>
</node>
<node>
<name>CLIENT</name>
<add/><copy/><delete/><get/><replace/>
<leaf>
<name>AAuthData</name>
<copy/><delete/><get/><replace/>
<format>bin</format>
<value>e****************==</value>
</leaf>
更进一步,我们可以请求标识的端点URL来了解所使用的技术
端点为主要目标
通过简单地查询配置中标识的端点,我们可以获得多种含有缺陷的框架版本:
对SaaS端点应用程序的简单攻击模式
因此,通过针对这些端点,攻击者将能够对每个FOTA更新请求进行后门处理,并针对ECU进行如下配置:
<flashjobConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ecuName="SEAT_****" schemaVersion="1.0.0" xsi:noNamespaceSchemaLocation="config.xsd">
<config name="Development">
<variantPatterns>
<variantPattern>
<matchService>
<matchParameters>
<matchParameter value="0****"/>
</matchParameters>
</matchService>
</variantPattern>
</variantPatterns>
<swils>
<swil downloadSequence="0" logicalBlockId="0" startAddress="******" swilFile="Flash***.bin">
<crc>0x**, 0x**, 0x**, 0x**</crc>
</swil>
</swils>
<security>***********.pgp</security>
<usedSecurityElement>*******</usedSecurityElement>
<securityClass>NONE</securityClass>
<fblRevision>REV_***</fblRevision>
</config>
还应该注意,这些还取决于在这些端点上利用远程命令检索权限
总结
FOTA设备管理服务是想要同时对大量移动模块进行后门操作,而无需在无线电中进行任何移动拦截攻击。要执行攻击,仅需要获取这些端点的列表并利用与设备管理端点所使用的框架版本相关的公共漏洞即可
参考文章:
https://penthertz.com/blog/mobile-iot-modules-FOTA-backdooring-at-scale.html