深入分析TIMA任意内核模块认证绕过漏洞

[[181702]]

前言

为了确保Android设备中Linux内核的完整性,三星推出了一个名为“lkmauth”的功能。该功能的最初目的是,确保只有三星核准的那些内核模块才可以加载到Linux内核中。

TIMA任意内核模块认证绕过漏洞分析

每当内核尝试载入内核模块时,系统就会用到“lkmauth”功能。在加载内核模块之前,内核首先会加载“lkmauth”的trustlet,并发送一个请求,来验证模块的完整性。

由于三星设备使用了两个不同的TEE,所以对于每个TEE都单独实现了相应的“lkmauth”功能。

在使用QSEE TEE(它使用了内核配置TIMA_ON_QSEE)的设备上,使用“tima_lkmauth”的trustlet来验证待加载的内核模块的完整性。当然,这个trustlet本身是相当简单的——它提供了一个硬编码的列表,来保存所有“可允许”的内核模块的SHA1哈希值。如果当前待加载的内核模块的SHA1没有出现在硬编码的列表中,那么它就会被拒绝。

对于使用MobiCore TEE(使用内核配置TIMA_ON_MC20)的设备而言,它们会通过“ffffffff00000000000000000000000b.tlbin”trustlet来验证待加载内核模块的完整性。然而,在这种情况下,其流程会稍微有点复杂,下面简单介绍加载模块的具体步骤:

  1. [如果trustlet尚未加载]:加载trustlet。
  2. [如果已批准的哈希值列表尚未加载]:向trustlet发送请求,以便加载已批准的SHA1哈希签名列表。
  3. 将存放内核模块的缓冲区传递给trustlet进行验证。如果该内核模块的SHA1哈希值不在先前加载的已批准哈希值列表中,则会被拒绝。

已经批准的模块的哈希值组成的列表,将作为设备固件的一部分,存储在文件“/system/lkm_sec_info”中。该文件的结构如下所示:

  1. <LIST_OF_APPROVED_SHA1_HASHES> || <RSA-SHA1(LIST_OF_APPROVED_HASHES)> 

RSA签名本身会使用PKCS#1 v1.5进行填充,其中BT = 1,PS是0xFF字节的常量字符串。

用于验证签名的公钥,我们可以通过静态分析方法从trustlet中找到。在trustlet的自身代码中,2048位的模数(N)是以反向字节顺序硬编码的形式存在的。经验证,在许多不同的设备和版本(如GT-I9300、SM-P600、SM-G925V等)中,都使用了相同的常量模量。这个模数本身是

  1. 23115949866714941391353337177289175219285878274139282906616665210063884406381659531323213685988661310147714551519208211866717752764819593136041821730036424774768373518089158559738346399417711215445691103520271683108620470478217421253901045241463596145712323679479119182170178158376677146612087823704797563128645982031650495998390419939015769566125776929249878666421780560391442439477189264423758971325406632562977618217815844688082799802924540355522191958147326121713251815752299744182840538928330568160188518794896256711464745438125835732128172016078553039694575936536720388879378619731459541542508235684590815108447 

这里使用的公钥指数为3。

发送到trustlet的请求缓冲区具有以下结构:

  1. /* Message types for the lkmauth command */ 
  2. typedef struct lkmauth_hash_s { 
  3. uint32_t cmd_id; 
  4. uint32_t hash_buf_start;/* starting address of buf for ko hashes */ 
  5. uint32_t hash_buf_len;/* length of hash buf, should be multiples of 20 bytes */ 
  6. uint8_t ko_num;/* total number ko */ 
  7. } __attribute__ ((packed)) lkmauth_hash_t; 

通过对trustlet中处理这个命令的代码进行逆向工程,得到了处理函数高级逻辑代码,具体如下所示:

  1. int load_hash_list(char* hash_buf_start, uint32_t hash_buf_len, uint8_t ko_num) { 
  2.   //Checking the signature of the hash buffer, without the length of the 
  3.   //public modulus (256 bytes = 2048 bits) 
  4.   uint32_t hash_list_length = hash_buf_len - 256; 
  5.   char* rsa_signature_blob = hash_buf_start + hash_list_length; 
  6.   if (verify_rsa_signature(hash_buf_start, hash_list_length, rsa_signature_blob)) 
  7.     return SIGNATURE_VERIFICATION_FAILURE; 
  8.   //Copying in the verified hashes into the trustlet 
  9.   //SHA1 hashes are 20 bytes long (160 bits) each 
  10.   //The maximal number of copied hashes is 0x23 
  11.   //g_hash_list is a list in the BSS section of the trustlet 
  12.   //g_num_hashes is also in the BSS section of the trustlet 
  13.   uint8_t i; 
  14.   for (i=0; i<ko_num && i<0x23; i++) { 
  15.     memcpy(g_hash_list + i*20, hash_buf_start + i*20, 20); 
  16.   } 
  17.   g_num_hashes = i
  18.   return SUCCESS; 

问题在于,上述代码包含了一个逻辑缺陷:没有对“ko_num”字段进行相应的验证,以确保其匹配哈希值列表的实际长度。这意味着攻击者能够欺骗trustlet来加载额外的“允许哈希值”,即使它们不是已经签名的blob的一部分。为此,可以在提供与哈希值列表的原始长度匹配的”hash_buf_len”的时候,通过提供一个大于实际哈希值数量的“ko_num”字段来达到这一目的。然后,攻击者可以在缓冲器中的签名blob之后提供任意的SHA1哈希值,从而导致这些额外的哈希值也会被复制到已经批准的可信哈希值列表中。

下面给出此类攻击的一个具体例子:

  1. hash_buf_start = <ORIGINAL_SIGNED_HASH_LIST> || 
  2.                    <RSA-SHA1(ORIGINAL_SIGNED_HASH_LIST)> || 
  3.                    <4 GARBAGE BYTES> || 
  4.                    <ATTACKER_CONTROLLED_SHA1_HASH> 
  5.   hash_buf_len = len(<ORIGINAL_SIGNED_HASH_LIST>) + 
  6.                  len(<RSA-SHA1(ORIGINAL_SIGNED_HASH_LIST)>
  7.   ko_num = (<ORIGINAL_SIGNED_HASH_LIST>/20) + ceil(256/20) + 1 

由于“/system/lkm_sec_info”中的原始哈希值列表长度总是很短(例如从来不超过8)的,因此表达式(( / 20)+ ceil(256/20)+1)的值永远不会大于22。但是它仍然小于0x23(35)个哈希值的硬编码下限,这意味着上面的代码能够正常执行所提供的命令。此后,已批准的哈希值列表将会变成如下所示的结构:

  1. original_approved_hash_1 
  2. original_approved_hash_2 
  3. ... 
  4. original_approved_hash_n 
  5. bytes_00_to_20_of_rsa_signature 
  6. bytes_20_to_40_of_rsa_signature 
  7. ... 
  8. bytes_240_to_256_of_rsa_signature || 4_garbage_bytes 
  9. attacker_controlled_sha1_hash 

实际上,这就将攻击者控制的SHA1哈希值插入到了已批准的哈希值列表中,从而成功绕过了签名验证。

该漏洞的一种利用方法是,控制一个可以加载内核模块的进程,然后将感染的哈希值列表请求发送给trustlet。例如,“system_server”进程就具有这种能力,同时还能够加载trustlet,并与之进行通信(我们已经在SM-G925V的默认SELinux策略中进行了相应的验证):

  1. allow system_server mobicore-user_device : chr_file { ioctl read write getattr lock append open } ;  
  2. allow system_server mobicoredaemon : unix_stream_socket connectto ;  
  3. allow system_server mobicore_device : chr_file { ioctl read write getattr lock append open } ; 

将受感染的哈希值列表加载到trustlet之后,攻击者就可以尝试加载与刚才插入到列表中的SHA1哈希值相匹配的内核模块了。需要注意的是,加载模块的第一次尝试将会失败,因为内核将尝试加载已批准的哈希值列表本身,但是trustlet将检测到此情况并返回错误代码RET_TL_TIMA_LKMAUTH_HASH_LOADED。这样的话,内核会做一个标记,指出列表已经加载好了——也就是说,下一次加载模块的时候,就不会重新加载这个列表了:

  1. ... 
  2. else if (krsp->ret == RET_TL_TIMA_LKMAUTH_HASH_LOADED) { 
  3.   pr_info("TIMA: lkmauth--lkm_sec_info already loaded\n"); 
  4.   ret = RET_LKMAUTH_FAIL
  5.   lkm_sec_info_loaded = 1
  6. ... 

之后,第二次尝试加载已经感染的模块的时候,就会成功了,因为它的哈希值已经位于已批准的哈希值列表中了。

文章来源网络,作者:运维,如若转载,请注明出处:https://shuyeidc.com/wp/140370.html<

(0)
运维的头像运维
上一篇2025-03-03 22:05
下一篇 2025-03-03 22:07

相关推荐

  • 个人主题怎么制作?

    制作个人主题是一个将个人风格、兴趣或专业领域转化为视觉化或结构化内容的过程,无论是用于个人博客、作品集、社交媒体账号还是品牌形象,核心都是围绕“个人特色”展开,以下从定位、内容规划、视觉设计、技术实现四个维度,详细拆解制作个人主题的完整流程,明确主题定位:找到个人特色的核心主题定位是所有工作的起点,需要先回答……

    2025-11-20
    0
  • 社群营销管理关键是什么?

    社群营销的核心在于通过建立有温度、有价值、有归属感的社群,实现用户留存、转化和品牌传播,其管理需贯穿“目标定位-内容运营-用户互动-数据驱动-风险控制”全流程,以下从五个维度展开详细说明:明确社群定位与目标社群管理的首要任务是精准定位,需明确社群的核心价值(如行业交流、产品使用指导、兴趣分享等)、目标用户画像……

    2025-11-20
    0
  • 香港公司网站备案需要什么材料?

    香港公司进行网站备案是一个涉及多部门协调、流程相对严谨的过程,尤其需兼顾中国内地与香港两地的监管要求,由于香港公司注册地与中国内地不同,其网站若主要服务内地用户或使用内地服务器,需根据服务器位置、网站内容性质等,选择对应的备案路径(如工信部ICP备案或公安备案),以下从备案主体资格、流程步骤、材料准备、注意事项……

    2025-11-20
    0
  • 如何企业上云推广

    企业上云已成为数字化转型的核心战略,但推广过程中需结合行业特性、企业痛点与市场需求,构建系统性、多维度的推广体系,以下从市场定位、策略设计、执行落地及效果优化四个维度,详细拆解企业上云推广的实践路径,精准定位:明确目标企业与核心价值企业上云并非“一刀切”的方案,需先锁定目标客户群体,提炼差异化价值主张,客户分层……

    2025-11-20
    0
  • PS设计搜索框的实用技巧有哪些?

    在PS中设计一个美观且功能性的搜索框需要结合创意构思、视觉设计和用户体验考量,以下从设计思路、制作步骤、细节优化及交互预览等方面详细说明,帮助打造符合需求的搜索框,设计前的规划明确使用场景:根据网站或APP的整体风格确定搜索框的调性,例如极简风适合细线条和纯色,科技感适合渐变和发光效果,电商类则可能需要突出搜索……

    2025-11-20
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注