通过利用CVE-2025-31710和sGSI间接实现给某个搭载安卓9的完全不可能利用下载模式(指FDL1和FDL2)的展讯方案学习机获取Root权限

Time

2025/6/25~30
Latest Edited:2025/10/12

Author

Github@KawaiiSparkle
Github@PurpleHang

Intro

众所周知,某品牌的学习机零售版目前最多人拥有的是搭载了紫光(Unisoc)芯片方案的那一类机型,而在这下面目前有 三种芯片1,分别为:

实验环境

因为我总不可能真的去搞一堆ud710-ad的机型回来(太容易坏了),所以等效一下就用了一台官解并解了BL锁的CB-C6s-STU(C1)机型来尝试使用该漏洞进行利用(感谢Github@PurpleHang提供平板并花了大概一周陪我搞实验),这样实验失败砖机时可以通过下载模式重置实验环境至初始状态
顺带一提,本机型的SELinux一直是Enforcing状态

探究如何利用CVE漏洞+分析public SELinux策略文件

使用CVE漏洞提取出vendor分区
尝试直接把precompiled_sepolicy相关部分删掉并刷回去,发现并没有什么变化
尝试使用早茶光给的方法进行system-root,寄
分别尝试直接给vendor_sepolicy.cil与plat_pub_versioned.cil文件的最底部加上全局宽容,刷回去,不开机了,说明这两个中某项改了可能有用。
另外在乱翻文件内容时发现plat_pub_versioned.cil中dev_type这个属性中有数个块设备,里面就有我提取不出来的boot/recovery/system_block_device_28_0。我又想到了系统在Recovery模式进行OTA阶段时,必定会进行对boot/system进行读写(差量更新),那表明Recovery模式下,SELinux肯定给了权限导致可以读写boot分区,那我或许可以把这个Recovery下的权限拿来一用。
我虽然完全看不懂SELinux上下文的具体内容,但我能搜索boot_block_device_28_0recovery_block_device_28_0并得到与这两个相关的行:

boot_block_device_28_0如下

(typeattributeset dev_type (device_28_0 alarm_device_28_0 ashmem_device_28_0 audio_device_28_0 audio_timer_device_28_0 audio_seq_device_28_0 binder_device_28_0 hwbinder_device_28_0 vndbinder_device_28_0 block_device_28_0 camera_device_28_0 dm_device_28_0 keychord_device_28_0 loop_control_device_28_0 loop_device_28_0 pmsg_device_28_0 radio_device_28_0 ram_device_28_0 rtc_device_28_0 vold_device_28_0 console_device_28_0 cpuctl_device_28_0 fscklogs_28_0 full_device_28_0 gpu_device_28_0 graphics_device_28_0 hw_random_device_28_0 input_device_28_0 kmem_device_28_0 port_device_28_0 lowpan_device_28_0 mtd_device_28_0 mtp_device_28_0 nfc_device_28_0 ptmx_device_28_0 kmsg_device_28_0 kmsg_debug_device_28_0 null_device_28_0 random_device_28_0 secure_element_device_28_0 sensors_device_28_0 serial_device_28_0 socket_device_28_0 owntty_device_28_0 tty_device_28_0 video_device_28_0 vcs_device_28_0 zero_device_28_0 fuse_device_28_0 iio_device_28_0 ion_device_28_0 qtaguid_device_28_0 watchdog_device_28_0 uhid_device_28_0 uio_device_28_0 tun_device_28_0 usbaccessory_device_28_0 usb_device_28_0 properties_device_28_0 properties_serial_28_0 property_info_28_0 i2c_device_28_0 hci_attach_dev_28_0 rpmsg_device_28_0 root_block_device_28_0 frp_block_device_28_0 system_block_device_28_0 recovery_block_device_28_0 boot_block_device_28_0 userdata_block_device_28_0 cache_block_device_28_0 swap_block_device_28_0 metadata_block_device_28_0 misc_block_device_28_0 ppp_device_28_0 tee_device_28_0))
(typeattribute boot_block_device_28_0)
(roletype object_r boot_block_device_28_0)
(neverallow fsck_28_0 boot_block_device_28_0 (blk_file (ioctl read write create setattr lock relabelfrom append unlink link rename open)))
(neverallow fsck_untrusted_28_0 boot_block_device_28_0 (blk_file (ioctl read write create setattr lock relabelfrom append unlink link rename open)))
(allow install_recovery_28_0 boot_block_device_28_0 (blk_file (ioctl read getattr lock map open)))
(allow update_engine_common boot_block_device_28_0 (blk_file (ioctl read write getattr lock append map open)))

recovery_block_device_28_0如下

(typeattributeset dev_type (device_28_0 alarm_device_28_0 ashmem_device_28_0 audio_device_28_0 audio_timer_device_28_0 audio_seq_device_28_0 binder_device_28_0 hwbinder_device_28_0 vndbinder_device_28_0 block_device_28_0 camera_device_28_0 dm_device_28_0 keychord_device_28_0 loop_control_device_28_0 loop_device_28_0 pmsg_device_28_0 radio_device_28_0 ram_device_28_0 rtc_device_28_0 vold_device_28_0 console_device_28_0 cpuctl_device_28_0 fscklogs_28_0 full_device_28_0 gpu_device_28_0 graphics_device_28_0 hw_random_device_28_0 input_device_28_0 kmem_device_28_0 port_device_28_0 lowpan_device_28_0 mtd_device_28_0 mtp_device_28_0 nfc_device_28_0 ptmx_device_28_0 kmsg_device_28_0 kmsg_debug_device_28_0 null_device_28_0 random_device_28_0 secure_element_device_28_0 sensors_device_28_0 serial_device_28_0 socket_device_28_0 owntty_device_28_0 tty_device_28_0 video_device_28_0 vcs_device_28_0 zero_device_28_0 fuse_device_28_0 iio_device_28_0 ion_device_28_0 qtaguid_device_28_0 watchdog_device_28_0 uhid_device_28_0 uio_device_28_0 tun_device_28_0 usbaccessory_device_28_0 usb_device_28_0 properties_device_28_0 properties_serial_28_0 property_info_28_0 i2c_device_28_0 hci_attach_dev_28_0 rpmsg_device_28_0 root_block_device_28_0 frp_block_device_28_0 system_block_device_28_0 recovery_block_device_28_0 boot_block_device_28_0 userdata_block_device_28_0 cache_block_device_28_0 swap_block_device_28_0 metadata_block_device_28_0 misc_block_device_28_0 ppp_device_28_0 tee_device_28_0))
(typeattribute recovery_block_device_28_0)
(roletype object_r recovery_block_device_28_0)
(neverallow base_typeattr_100_28_0 recovery_block_device_28_0 (blk_file (write append)))
(neverallow fsck_28_0 recovery_block_device_28_0 (blk_file (ioctl read write create setattr lock relabelfrom append unlink link rename open)))
(neverallow fsck_untrusted_28_0 recovery_block_device_28_0 (blk_file (ioctl read write create setattr lock relabelfrom append unlink link rename open)))
(allow init_28_0 recovery_block_device_28_0 (lnk_file (relabelto)))
(allow init_28_0 recovery_block_device_28_0 (blk_file (relabelto)))
(allow install_recovery_28_0 recovery_block_device_28_0 (blk_file (ioctl read write getattr lock append map open)))

很明显能通过上文发现,recovery_block_device_28_0 与boot_block_device_28_0 都allow了install_recovery_28_0这个对象(?)使用对它们进行块文件上的读写等功能,同时对于fsck_28_0、fsck_untrusted_28_0禁止了这部分的操作
再分析一下install_recovery_28_0有什么相关的条目

(typeattributeset domain (adbd_28_0 audioserver_28_0 blkid_28_0 blkid_untrusted_28_0 bluetooth_28_0 bootanim_28_0 bootstat_28_0 bufferhubd_28_0 cameraserver_28_0 charger_28_0 clatd_28_0 cppreopts_28_0 crash_dump_28_0 dex2oat_28_0 dhcp_28_0 dnsmasq_28_0 drmserver_28_0 dumpstate_28_0 e2fs_28_0 ephemeral_app_28_0 fingerprintd_28_0 fsck_28_0 fsck_untrusted_28_0 gatekeeperd_28_0 healthd_28_0 hwservicemanager_28_0 idmap_28_0 incident_28_0 incident_helper_28_0 incidentd_28_0 init_28_0 inputflinger_28_0 install_recovery_28_0 installd_28_0 isolated_app_28_0 kernel_28_0 keystore_28_0 lmkd_28_0 logd_28_0 logpersist_28_0 mdnsd_28_0 mediacodec_28_0 mediadrmserver_28_0 mediaextractor_28_0 mediametrics_28_0 mediaprovider_28_0 mediaserver_28_0 modprobe_28_0 mtp_28_0 netd_28_0 netutils_wrapper_28_0 nfc_28_0 otapreopt_chroot_28_0 otapreopt_slot_28_0 performanced_28_0 perfprofd_28_0 platform_app_28_0 postinstall_28_0 postinstall_dexopt_28_0 ppp_28_0 preopt2cachename_28_0 priv_app_28_0 profman_28_0 racoon_28_0 radio_28_0 recovery_28_0 recovery_persist_28_0 recovery_refresh_28_0 runas_28_0 sdcardd_28_0 secure_element_28_0 servicemanager_28_0 sgdisk_28_0 shared_relro_28_0 shell_28_0 slideshow_28_0 su_28_0 surfaceflinger_28_0 system_app_28_0 system_server_28_0 tee_28_0 thermalserviced_28_0 tombstoned_28_0 toolbox_28_0 traced_probes_28_0 traceur_app_28_0 tzdatacheck_28_0 ueventd_28_0 uncrypt_28_0 untrusted_app_28_0 untrusted_app_27_28_0 untrusted_app_25_28_0 untrusted_v2_app_28_0 update_engine_28_0 update_verifier_28_0 usbd_28_0 vdc_28_0 vendor_init_28_0 vendor_shell_28_0 virtual_touchpad_28_0 vndservicemanager_28_0 vold_28_0 vold_prepare_subdirs_28_0 vr_hwc_28_0 watchdogd_28_0 webview_zygote_28_0 wificond_28_0 wpantund_28_0 zygote_28_0 aprd_28_0 cndaemon_28_0 dataLogDaemon_28_0 fsmgr_28_0 ims_bridged_28_0 log_service_28_0 minidumpd_28_0 netbox_28_0 performancemanager_28_0 reboot_28_0 cmd_services_28_0 embmsd_28_0 modemlog_connmgr_service_28_0 slogmodem_28_0 ylog_28_0 zebu_28_0))

注:还在这个里面看到了漏洞利用到的cmd_services_28_0,那看来是程序运行时的SELinux上下文相关的

(typeattribute install_recovery_28_0)
(roletype object_r install_recovery_28_0)

(allow install_recovery_28_0 self (capability (dac_override dac_read_search)))
(allow install_recovery_28_0 self (cap_userns (dac_override dac_read_search)))
(allow install_recovery_28_0 shell_exec_28_0 (file (ioctl read getattr lock map execute execute_no_trans open)))
(allow install_recovery_28_0 system_file_28_0 (file (ioctl read getattr lock map execute execute_no_trans open)))
(allow install_recovery_28_0 toolbox_exec_28_0 (file (ioctl read getattr lock map execute execute_no_trans open)))
(allow install_recovery_28_0 block_device_28_0 (dir (search)))
(allow install_recovery_28_0 boot_block_device_28_0 (blk_file (ioctl read getattr lock map open)))
(allow install_recovery_28_0 recovery_block_device_28_0 (blk_file (ioctl read write getattr lock append map open)))
(allow install_recovery_28_0 cache_file_28_0 (dir (ioctl read write getattr lock add_name remove_name search open)))
(allow install_recovery_28_0 cache_file_28_0 (file (ioctl read write create getattr setattr lock append map unlink rename open)))
(allow install_recovery_28_0 proc_drop_caches_28_0 (file (write lock append map open)))

(typeattributeset base_typeattr_157_28_0 ((not (dnsmasq_28_0 dumpstate_28_0 init_28_0 install_recovery_28_0 installd_28_0 lmkd_28_0 netd_28_0 perfprofd_28_0 postinstall_dexopt_28_0 recovery_28_0 sdcardd_28_0 tee_28_0 traced_probes_28_0 ueventd_28_0 uncrypt_28_0 vendor_init_28_0 vold_28_0 vold_prepare_subdirs_28_0 zygote_28_0))))
(typeattributeset base_typeattr_156_28_0 ((not (dnsmasq_28_0 dumpstate_28_0 init_28_0 install_recovery_28_0 installd_28_0 lmkd_28_0 netd_28_0 perfprofd_28_0 postinstall_dexopt_28_0 recovery_28_0 sdcardd_28_0 tee_28_0 ueventd_28_0 uncrypt_28_0 vendor_init_28_0 vold_28_0 vold_prepare_subdirs_28_0 zygote_28_0))))

(typeattributeset base_typeattr_100_28_0 ((and (domain) ((not (install_recovery_28_0 recovery_28_0))))))

从上文的这些条目很明显能看出来,install_recovery_28_0是通过把自己排除出base_typeattr_156_28_0,base_typeattr_157_28_0,base_typeattr_100_28_0的同时,allow了一堆权限导致它能够读出boot和recovery分区的

实际操作

🤓👆,那为何不直接把这些权限和属性复制一份过去给cmd_services_28_0用呢
说干就干,直接在上面排除了install_recovery_28_0的属性里有样学样加上或者直接替换成cmd_services_28_0😋
然后把allow install_recovery_28_0那几行直接复制到文件内容的最后,把这边的install_recovery_28_0改成cmd_services_28_0,保存打包刷回去,成功启动就OK辣😋😋😋

然后就成功用cmd_services_28_0漏洞和这个美美提取出了boot和recovery,后面就是拿Tomking062大佬写的Github Actions版签名自动化工具跑一下提取出来的boot镜像然后再刷回去

一些有意思的

u1s1,这个漏洞好像只需要有一个内置了展讯EngineerMode调试工具的GSI就能跑(?)
但搞这个的前提还是得先解锁BL,但由于该厂商阉割掉了SPRD4模式,因此可以直接使用spd_dump/SPRDClient来在关机状态下kickto 1能把板子kick到一个特殊的Recovery模式,表现为黑屏但是此时是打开了ADB的,因此可以使用adb将其重启到Bootloader模式并使用某贼写的工具来进行展讯公钥解锁,从而进行后面的一系列操作。
如果某厂商不希望发生这个,可以把SPRD4模式加回来,但是这样就可以直接进SPRD4模式提取固件了😅
如果你是该厂商的员工,我还是建议您放弃处理这个“BUG”并去别处找BUG修🤣🤣

Footnotes

  1. https://github.com/TomKing062/CVE-2022-38694_unlock_bootloader/wiki/AddSupportToModel