统信UOS家庭版

从CVE漏洞分析到安全防护复盘

最近这几天CVE-2021-4034漏洞爆出来以后,大家都在紧急修复,验证、补丁、测试、上线、通知用户,过年之前的这段时间不免又忙碌了一阵。

现在补丁已经上线,而且被用户接收验证了,我们的心里当然是放下了一块石头,终于有时间在统信UOS上就这个漏洞做一些更细致的研究和确认了。 

统信安全应急响应中心第一时间发布了漏洞修复方案


本次漏洞利用的是polkit里的pkexec程序,而polkit是桌面环境里广泛使用的DBus进程间通讯机制所依赖的安全模块之一,因此这个漏洞的波及面确实还是挺大的。不过在桌面团队修洞的过程中,我们发现在缺省(未开启开发者模式)情况下,统信UOS是不受主流攻击方式所影响的。

原因其实也很简单,因为统信UOS的当前版本在缺省情况下就提供了应用软件的签名验证机制,也就是说,如果一个软件没有得到有效证书的签名,它实际上是无法上架到应用商店,而且即使被手工复制到了本地,也会因为文件没有有效证书的签名,无法被运行起来的,对应保护的文件不仅是可执行文件,也包括了动态链接库(即so文件)。

那为什么有了可执行文件与动态链接库的证书签名验证机制,CVE-2021-4034漏洞就难以被利用了呢?

这就要从CVE-2021-4034漏洞的利用原理分析一下了。

本漏洞主要被利用的包括以下几点:

pkexec为suid程序


当argc(命令行参数个数变量)为0时,pkexec会读取argv[1]变量,而由于Linux进程的内存布局中环境变量是紧接着命令行参数的,因此实际上会读取到第一个环境变量。


读取到argv[1]之后,若其不是以/开头的(即不是绝对路径),则pkexec会将其理解为相对路径,继而会在环境变量中查找PATH变量,将其转换为实际路径。


若PATH环境变量包含一个攻击者可控的路径,则pkexec转换后的实际路径将会是这个攻击者可控的路径下的一个子目录,则显然此实际路径也是攻击者可控的。


pkexec对argv[1]赋值,将其修改为上述得到的实际路径,但是我们知道argv[1]此时实际上指向的是pkexec的第一个环境变量,也就是说,pkexec将自己的第一个环境变量修改为这个实际路径了。


pkexec会在程序运行过程中调用g_printerr函数,这个函数会在运行的时候按需载入GCONV_PATH环境变量指向的路径下的gconv-modules文件中写明的外部动态链接库(so),并运行其中的初始化函数gconv_init

这样,攻击者只需要:

第一步:在自己可控的目录下生成一个gconv-modules文件,并将文件内容设置为指向某个so文件。

第二步:so文件实现gconv_init函数,此函数主要就是生成一个root shell(由于pkexec默认开启SUID),而在so库的此函数中,设置当前进程用户的uid为0,即可提权到root用户。

第三步:调用pkexec,而且在调用的时候通过命令行参数设置使得pkexec得到的argc为0,将环境变量中的第一个设置为非/开头的一个相对路径,将环境变量中的PATH变量的值设置为GCONV_PATH=开头的字符串,使得对应的路径指向上述存储gconv-modules文件的路径。

就可以最终获得一个root shell了。


其中第一步与第三步可以有多种方法实现,虽然常见的PoC给出的是可执行程序,但是也可以通过脚本施行攻击,但是第二步需要生成一个so文件,就是在这里,新生成的so文件因为没有有效证书签名,因此在缺省的统信UOS上无法被载入执行。


当然,除了使用gconv的外挂插件之外,从理论上来说,也可以思考如何利用环境变量从pkexec的外部载入程序,但是这个实施难度显然就更高了。


因此,我们也希望统信UOS的广大用户不要修改系统的缺省配置,因为统信UOS基于证书签名的应用治理机制确实能有效地保护系统的安全,规避安全风险。


内容来源:统信软件安全技术小组


相关文章

扫码添加官方运营
领取专属社群服务

回到顶部