硬件探索
由于没有外壳与系统进行交互,也没有明文固件可供分析,我们不得不借助内存转储来进行任何工作。该型号内部由 2 块 PCB 组成,有屏蔽罩隐藏芯片组。拆除后,可以识别芯片组制造商和型号。SoC 是赛普拉斯(现为英飞凌)CYW43012,辅以 OA00804-B56G 视频处理器(最接近的文档是 0A00805-B56G-Z),使用南亚 NT5CC64M16GP-DI RAM 和华邦 W25Q256JW_DTR 串行闪存存储器。设备可以通过电源电缆(左侧连接器)、电池(右上方连接器)或 Micro-USB(顶部)供电。一款相对类似型号的拆解过程也由 iFixit 详细介绍。
由于屏蔽罩的原因,串行闪存存储器的一些引脚不容易访问,但很容易弯曲或移除。此外, W25Q256JW_DTR
封装是 WSON 类型,SOIC 夹子无法适配该封装,因此需要使用 PCBite 来访问 SPI 引脚。
尝试使用 1.8V SPI 转储内存,如数据表中所述,未收到任何响应。然而,使用 3.3V SPI 适配器成功转储。
$ sudo flashrom -p buspirate_spi:dev=/dev/ttyUSB0,spispeed=2Mhz-c W25Q256JW_DTR -r dump.bin
[...]
FoundWinbond flash chip "W25Q256JW_DTR"(32768 kB, SPI) on buspirate_spi.
Reading flash...done.
固件解剖
与更新二进制文件不同,固件以明文和字符串的形式存储在文件中,这些字符串确认了这是在 SoC 上运行的代码。然而,二进制转储文件并没有像原样加载到内存中,我们需要在分析代码之前了解二进制格式。
$ strings dump.bin
[...]
EasycamLiveview
OvSelectApp
Unable to write OvAppSelect
CamModePerm
CamModeTemp
sf_detect %s:%x(%x)
sflash found:%s
sf detect failed, readid:%x
error: g_sflash_fun_init.erase is NULL
error: g_sflash_fun_init.program is NULL
error: g_sflash_fun_init.read is NULL
error: data length is forbidden as0when read serial flash
EEROR:set qe bit error:%d
flash id not match, read:0x%x(0x%x)
ERROR:hardware haed magic num error,read:%x should be 0x4f565449
ERROR:para haeder magic num error,read:%x should be 0x4f565450
ERROR:fw haeder magic num error,read:%x should be 0x4f565442
para header error
para crc error
magic3 is broken, need do partitioin recover
[...]
错误字符串表示魔术值: 0x4f565449/"ITVO"
用于硬件头, 0x4f565442/"BTVO"
用于 fw header
, 0x4f565450/"PTVO"
用于 para header
(为了可读性已更正拼写错误)。CRC 实现是 CRC16 CCITT。
ITVO
ITVO
头部主要包含有关 Flash 存储器上区域的信息,地址和大小如下 uint32_t
:
-
kvstore
显然存储着敏感信息,但尚未进行调查。 -
fw
存储在 CPU 或外围 CPU 上执行的二进制文件,以BTVO
头开始。 -
para
存储设备的配置,从PTVO
头开始。 -
cali
显然存储加密信息,使用来自kvstore
的密钥,以CALI
头部开头。 -
logs
特别是在设备停止或重新启动时记录日志的地方。
PTVO
PTVO
头部描述配置区域。它以 YTVO
头部开始,对齐在 0x1000
内存页面上,主要包含其大小和 ID。然后是配置本身,也对齐在 0x1000
内存页面上,并以键/值对的文本格式存储,由 =
分隔,后跟 n
。
BTVO
BTVO
头部描述了固件二进制文件,按原样加载到内存中,由 CPU 执行或在第二步由需要的外围设备加载。该设备基于 RTOS,操作模式(设置、更新等)不是同一操作系统上的不同任务,而是在需要时加载到内存中的不同完整映像。这些完整映像对应于头部中的不同“文件”,索引用于寻址特定的操作模式。通过在内存中的加载地址加载文件并重新启动来执行模式切换。一些文件中存在 shell,因此很容易确定 ID 和模式之间的映射:
int __fastcall cmd_fw(int argc,char**argv){
int fw_id;// r0
if( argc <=1)
goto ERROR;
if(!strcmp(argv[1],"uploading")){
fw_id =2;
RELOAD_FW:
reload_fw(fw_id);
return0;
}
if(!strcmp(argv[1],"liveview")){
fw_id =4;
goto RELOAD_FW;
}
if(!strcmp(argv[1],"arlogw"))
goto RELOAD_ARLOGW;
if(!strcmp(argv[1],"calfw")){
fw_id =14;
goto RELOAD_FW;
}
if(!strcmp(argv[1],"upgrade")){
fw_id =9;
goto RELOAD_FW;
}
if(!strcmp(argv[1],"setup")){
fw_id =12;
goto RELOAD_FW;
}
if(!strcmp(argv[1],"setupqr")){
fw_id =15;
goto RELOAD_FW;
}
if(!strcmp(argv[1],"pjsip")){
RELOAD_ARLOGW:
fw_id =36;
goto RELOAD_FW;
}
ERROR:
printf("usage: fw [ uploading | liveview | arlogw | calfw | setup | setupqr | upgrade ]n");
return0;
}
setupqr
模式使用 QR 码处理设备设置,以获取 Wi-Fi 凭据。当设备正确设置并随着时间的推移吸收功能时, arlogw
模式似乎是名义模式,因为它嵌入了 pjsip
COTS 用于音频/视频流。一些模式使用两个文件,在这种情况下,第一个文件负责加载第二个文件,因此大多数二进制文件中存在类似但略有不同的文件加载例程。
upgrade
模式处理下载、验证和将更新写入 Flash 存储器。对该文件的分析足以理解(加密的)更新格式和流程。
更新
获取和解析
如前所述,更新过程首先检索一个 JSON 文件。然而,先前识别的 URL 与此模型的更新不匹配。正确的更新 URL 是 https://updates.arlo.com/arlo/fw/fw_deployed/production/updaterules/VMC4041P_UpdateRules.json
( VMC4041P
是 Arlo Pro4 的模型 ID)。这个 JSON 文档包含了二进制路径、版本和日期,以及二进制的 MD5 哈希值。
下载的二进制文件遵循这种格式:
-
用于识别格式的魔术字节,
cimg
。 -
格式版本,
1
在这种情况下但2
存在。 -
二进制文件的头部和总大小,头部大小为
0x178
,版本为1
。 -
包的 DSA 签名,(
s1
,s2
) 在 ASN.1 中。 -
一个加密的 AES 密钥。
-
评论字符串,在所有观察到的更新中为空。
-
硬件和固件修订,都在所有观察到的更新中
0
。 -
二进制时间戳以时代格式。
-
以下部分的数量。
部分格式如下:
-
魔法字节,
part
。 -
一种类型,要么
1
(rootfs
),要么 2 (generic
),要么3
(kernel
)。 -
数据的大小。
-
描述数据存储方式的标志,可以是
0
(存储),1
(压缩),2
(加密)或3
(压缩+加密)。 -
数据的 MD5 哈希。由于此相机型号不检查哈希的有效性,因此不清楚输入数据的确切内容是什么。
DSA 签名是在去除签名的整个文件上执行的。
解密
AES 密钥使用嵌入在加载文件中的 RSA 私钥进行解密。RSA 私钥使用加载文件中的 4 字节 XOR 密钥进行加密。
do{
rsa_priv_key[i]=~xor_key[i &3]^ rsa_priv_key_obf[i];
++i;
}while( i !=1193);
bio = BIO_new_mem_buf(rsa_priv_key,1193);
提供明文 AES 密钥给 EVP_BytesToKey
,并与加载文件中的固定盐一起,以便使用 IV 派生实际密钥。
由于 OpenSSL 在 3.0 版本之前的版本中使用,因此可以广泛使用 ERR_put_error(intlib,intfunc,intreason,constchar*file,intline)
进行功能识别:一旦识别出后者功能( file
参数对此很有帮助),就可以使用 lib
和 func
参数重命名调用它的函数。GitHub 存储库中的 openssl_err.py
脚本解析 openssl
包含目录中的 .h
文件以生成 Python 字典。然后在使用 Bip 插件重命名函数的 ossl_rename_ida.py
脚本中使用该字典。
关于缺少的名称,可以使用 ossl_assert
参数,因为它们包括文件路径和行号。例如, ossl_assert_int("/home/jenkins/agent/workspace/_VMC4041P_1.080.20.0_483_0f3935c/omnivision/make/../share/network/openssl/crypto/evp/digest.c",271,"ctx->digest->md_size <= EVP_MAX_MD_SIZE")
必须匹配 EVPDigestFinalex。
其他功能,例如 EVP_aes_256_cbc
和 EVP_sha1
,可以通过使用交叉引用到 NID 定义来识别算法,例如 #defineNID_aes_256_cbc427
和 #defineNID_sha164
:
DDR_CODE:201244C0 aes_256_cbc DCD 427,16,32,16,20482
DDR_CODE:201244D4 DCD aes_init_key
DDR_CODE:201244D8 DCD sub_200B3BF0
[...]
DDR_CODE:201245BC sha1 DCD 0x40,0x41,0x14,0xC
DDR_CODE:201245CC DCD sub_200B3D58
DDR_CODE:201245D0 DCD sub_200B3DB0
WTVO
一旦解密, part
的内容是一个 WTVO
头部,使用与其他头部相同的逻辑:
WTVO
标题包含有关更新内容的信息,类似于先前识别的内容:
-
fw
实际上是一个完整的BTVO
区域,它被原样复制到 Flash 存储器上。 -
最终
para
将作为原样复制到 Flash 存储器上的一个PTVO
区域,但未发现包含para
的更新。 -
一条评论字符串。
-
用 CRC 来验证头部。
密钥重用
下载更新的 URL 是使用 snprintf(dst,256,"%s/updaterules/%s_UpdateRules.json",update_url,base_model_id)
构建的,其中 update_url
是以下之一:
-
https://arloupdates.arlo.com/arlo/fw/fw_deployed/dev
-
https://arloupdates.arlo.com/arlo/fw/fw_deployed/qa
-
https://arloupdates.arlo.com/arlo/fw/fw_deployed/goldenft
-
https://updates.arlo.com/arlo/fw/fw_deployed/staging
-
https://updates.arlo.com/arlo/fw/fw_deployed/fieldtrial
-
https://updates.arlo.com/arlo/fw/fw_deployed/production
base_model_id
是 VMC4041P 适用于这个特定型号。可能的 base_model_id
列表可以在 Arlo 支持网站上找到。
URLs 对于每个环境和所有模型都是可访问的,这意味着我们可以下载当前所有可用的更新二进制文件!而且看起来 RSA 私钥与 cimg
格式的第 1 版相关联,而不是针对每个模型特定的,因此我们可以解密更多固件:
- Cameras
- Arlo Wire-Free
- NTGR_1.5.295_WiFi_upgrade.bin.enc cimg: version: 1 size: 0x18be78, date: 2021-08-31T21:07:27 / part: kernel, encrypted / OVTW: (v1.5.295)
- Arlo Pro
- VMC4030_1.092.1.0_9_120d8b7.bin.enc cimg: version: 1 size: 0x3076c8, date: 2021-08-25T07:36:52 / part: kernel, encrypted
- Arlo Pro 2
- VMC4030P_1.125.17.1_11_de8490d.bin.enc cimg: version: 1 size: 0x387788, date: 2021-09-04T01:39:52 / part: kernel, encrypted
- Arlo Pro 3
- http://updates.arlo.com/arlo/fw/fw_deployed/production/updaterules/VMC4040P_UpdateRules.json HTTP 404
- Arlo Pro 4 (VMC4050P)
- http://updates.arlo.com/arlo/fw/fw_deployed/production/updaterules/VMC4050P_UpdateRules.json HTTP 404
- Arlo Pro 4 (VMC4041P)
- VMC4041P_1.080.20.1_23_d50a19d.bin.enc cimg: version: 1 size: 0xc37248, date: 2023-08-08T00:27:03 / part: kernel, encrypted
- Arlo Pro 5S
- http://updates.arlo.com/arlo/fw/fw_deployed/production/updaterules/VMC4060P_UpdateRules.json HTTP 404
- Arlo Ultra / Ultra 2
...
其中一些更新不是 RTOS,而是带有 rootfs 的 Linux 内核,可以是 SquashFS 或 UBI。此外, cimg
版本 2 的密钥和格式不同,因此无法解密此类更新。
工具制造
本研究开发的工具可在我们的 GitHub 存储库上获得。已知时,输出包括用于在 IDA 中直接加载模式的脚本,例如 arlogw
,具有适当的加载地址和相关的二进制加载。
结论
您现在已经准备好启动自己的漏洞研究了,只要您能够自己找出 RSA 私钥,因为 Arlo 更喜欢这个私钥不被泄露。同时请记住,攻击面很小,除非您知道如何在 TLS 连接上执行中间人攻击!
如果你是一个车联网攻防的长期主义者,欢迎加入我的知识星球,我们一起往前走,每日都会更新,微信识别二维码付费即可加入,如不满意,72 小时内可在 App 内无条件自助退款。
免责声明
由于传播、利用本公众号渗透安全团队所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,公众号渗透安全团队及作者不为此承担任何责任,一旦造成后果请自行承担!如有侵权烦请告知,我们会立即删除并致歉。谢谢!
原文始发于微信公众号(车联网攻防日记):【车联网】车载可用摄像头漏洞研究(转载)
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论