随着HKSP的发布,华为似乎涉足了内核自我保护游戏。补丁本身充满了错误和弱点,通常缺乏任何类型的威胁模型(使其缓解措施类似于LKRG中提供的缓解措施,在LKRG中,对缓解措施的了解足以绕过它)。目前尚不清楚发布的补丁程序集是华为的官方版本,还是该代码已经在任何华为设备上发布,但该补丁程序集在其名称中使用了华为,该补丁程序集的Github账户将华为列为该账户的组织。
我们今天在这篇简短的博客文章中的焦点将是HKSP补丁集如何引入一个由于完全缺乏防御性编程而容易被利用的漏洞。
在补丁中,创建了/proc/ksGuard/state条目。为了提示代码的审查级别,每次打开或关闭此条目时,都会将引用不存在的文件名的以下行输出到dmesg:open/proc/ksg_state_proc ok。
正如我们在补丁的下面一行中看到的,状态条目是使用全局RWX权限创建的,这是粗心大意的表现,因为条目不支持任何有意义的读取操作,并且在这样的条目上执行是没有意义的。
写入此条目的ksg_state_write处理程序如下所示:static ssize_t ksg_state_write(struct file*file,const char__user*buf,size_t len,loff_t*offset){U64value;char tmp[32];size_t n=0;if(copy_from_user(tmp,buf,len))return-1;value=simple_stroul(tmp,';\0。案例2:ksg_check_nf();BREAK;案例3:ksg_CHECK_POINTER();BREAK;案例4:KSG_CHECK_SCT();BREAK;DEFAULT:BREAK;}*OFFSET+=len;n+=len;Return len;}。
此函数存在许多问题。首先是返回-1,它应该返回一个正确的errno(通常是-EFAULT)。有一个n变量被赋值,但不用于任何东西。LEN的价值根本没有支票。这导致的第一个问题是充当有限的先知。通过将0字节写入条目,未初始化的tmp数组将尝试从中解析出一个数字,然后对其执行操作。同样,将完整的32个字节写入条目并不能NUL终止字符串将导致SIMPLE_STROUL越界访问,从而有可能作为相邻内存的部分预言进行操作。最重要的是,由于缺少对len的检查,并且假定tmp是一个简单的32字节堆栈数组,这会引入一个容易被利用的内核堆栈缓冲区溢出,任何非特权用户都可以执行。
为完整起见,下面提供一个简单的PoC:#include<;stdio.h>;#include<;unistd.h>;#include<;fcntl.h>;int main(Void){char buf[4096]={};int fd=open(";/proc/ksGuard/state";,O_WRONLY);if(fd>;=0){write(。
有效的安全防御需要明确、现实的威胁模型。内核中的防御应该是防御性的,并考虑到减少维护负担。可以有效地将内核视为系统中最大、最易受攻击的setuid root二进制文件。添加到系统的这个最高特权组件的新代码是潜在的新攻击面,需要严格检查,以免引入比最初试图解决的更严重的问题。