利用FireFU破解FireTV Cube和Pendant
发布日期:2018年10月31日
作者:zenofex
分类:未分类
各位Exploitee.rs的读者们,万圣节快乐!今天我们很兴奋地为大家带来我们过去几个月一直在研究的东西——FireFU。FireFU是我们创建的一个漏洞利用链,允许用户解锁(并获取root权限)他们的FireTV Cube和FireTV Pendant设备。
警告
Exploitee.rs提醒用户,刷入非官方固件或使用提供的工具风险自负,很可能会使您的设备保修失效。
DFU模式
此漏洞利用链依赖于两个基本原语,第一个是通过可从Amlogic S905Z SoC访问的DFU模式获得的读/写原语。通过利用HDMI的I2C总线在启动期间向设备发送特定字符串(“boot@USB”),可以在这些设备上访问DFU模式。可以通过剪开HDMI线缆或直接购买HDMI接头制作适配器,然后将HDMI的适当I2C引脚连接到Arduino或兼容板上的I2C引脚。我们提供了一个Arduino"sketch",可以编译并加载到Arduino上,然后用于执行进入DFU模式的软件部分。
访问DFU模式后,我们可以读取和写入FireTV的部分内存。通过这一点,我们针对eMMC控制器的硬件寄存器,获得了能够读取和写入设备eMMC闪存的新原语。然而,由于两个设备都启用了安全启动,我们无法直接利用当前拥有的原语来运行未签名代码。但我们发现了另一个可以利用的漏洞。
U-Boot堆溢出
在安全启动环境中,启动过程的每个部分都会检查并设置后续部分——从SoC ROM一直到内核,在某些情况下甚至包括内核模块。为了运行未签名代码,需要在安全启动"信任链"的某个部分找到弱点。经过一些研究,我们偶然发现了一个可以利用来打破链条的完美漏洞。该漏洞包括在读取设备分区表中的RSV信息时触发的U-Boot中的堆溢出。可以在以下代码中看到此溢出:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
436 /* get ptbl from rsv area from emmc */
437 static int get_ptbl_rsv(struct mmc *mmc, struct _iptbl *rsv)
438 {
439 struct ptbl_rsv * ptbl_rsv = NULL;
440 uchar * buffer = NULL;
441 ulong size, offset;
442 int checksum, version, ret = 0;
443 struct virtual_partition *vpart = aml_get_virtual_partition_by_name(MMC_TABLE_NAME);
444
445 size = (sizeof(struct ptbl_rsv) + 511) / 512 * 512;
446 if (vpart->size < size) {
447 apt_err("too much partitons\n");
448 ret = -1;
449 goto _out;
450 }
451 buffer = malloc(size);
452 if (NULL == buffer) {
453 apt_err("no enough memory for ptbl rsv\n");
454 ret = -2;
455 goto _out;
456 }
457 /* read it from emmc. */
458 offset = _get_inherent_offset(MMC_RESERVED_NAME) + vpart->offset;
459 if (size != _mmc_rsv_read(mmc, offset, size, buffer)) {
460 apt_err("read ptbl from rsv failed\n");
461 ret = -3;
462 goto _out;
463 }
464
465 ptbl_rsv = (struct ptbl_rsv *) buffer;
466 apt_info("magic %s, version %s, checksum %x\n", ptbl_rsv->magic,
467 ptbl_rsv->version, ptbl_rsv->checksum);
468 /* fixme, check magic ?*/
469 if (strcmp(ptbl_rsv->magic, MMC_PARTITIONS_MAGIC)) {
470 apt_err("magic faild %s, %s\n", MMC_PARTITIONS_MAGIC, ptbl_rsv->magic);
471 ret = -4;
472 goto _out;
473 }
474 /* check version*/
475 version = _get_version(ptbl_rsv->version);
476 if (version < 0) {
477 apt_err("version faild %s, %s\n", MMC_PARTITIONS_MAGIC, ptbl_rsv->magic);
478 ret = -5;
479 goto _out;
480 }
481 /* check sum */
482 checksum = _calc_iptbl_check(ptbl_rsv->partitions, ptbl_rsv->count, version);
483 if (checksum != ptbl_rsv->checksum) {
484 apt_err("checksum faild 0x%x, 0x%x\n", ptbl_rsv->checksum, checksum);
485 ret = -6;
486 goto _out;
487 }
488
489 rsv->count = ptbl_rsv->count;
490 memcpy(rsv->partitions, ptbl_rsv->partitions, rsv->count * sizeof(struct partitions));
491
492 _out:
493 if (buffer)
494 free (buffer);
495 return ret;
496 }
|
具体来说,通过向RSV表中的条目数(第490行的rsv->count)提供足够高的值,我们能够溢出堆分配并获得新的写入原语。通过此原语(全部在漏洞利用的有效载荷内),我们修改了U-Boot内存中的值,欺骗设备使其认为已解锁并禁用所有签名验证。由于漏洞利用在每次启动时运行,U-Boot代码只需要在内存中打补丁。但是,由于漏洞利用现在存储在闪存中的原始RSV位置,我们必须将旧的RSV值移动到新区域,并修复指向先前位置的所有地址。重启并成功利用后,Fire TV设备将能够运行未签名代码。
Fastboot
为了简化新镜像的刷入,我们选择使用fastboot向设备刷入新的recovery和boot.img,这个新的recovery仅提供指向新RSV位置所需的修复。然而,boot.img包含了"magisk",一个流行的Android root应用程序,以方便向用户提供对设备的root访问权限。
技术细节和说明
漏洞利用链的技术细节可在我们的wiki上获得,以及使用说明、源代码和有关所需硬件/工具的信息。
视频演示
Exploitee.rs Wiki – FireFU漏洞利用
Hack The Planet
-Exploitee.rs
评论
max mustermann 在2018年11月4日下午7:18说:
这对FireTV第3代也有效吗?
Robin 在2018年11月6日上午7:34说:
请为亚马逊Show第1版制作root。固件太糟糕了。