CVE-2019-14287 sudo提权漏洞分析

一、本文目的

解释sudo提权漏洞
简要说明基础概念在安全领域的重要性

二、漏洞特点。

本漏洞是sudo在处理user id为-1和4294967295( 2 32 − 1 2^{32}-1 2321)即可,为什么呢?
下面做出解释。

三、漏洞分析
根据Linux Interface Programming的解释,首先我们要知道uid的类型:

struct passwd {
	char *pw_name; /* Login name (username) */
	char *pw_passwd; /* Encrypted password */
	uid_t pw_uid; /* User ID */
	gid_t pw_gid; /* Group ID */
	char *pw_gecos; /* Comment (user information) */
	char *pw_dir; /* Initial working (home) directory */
	char *pw_shell; /* Login shell */
};

uid_t呢?uid_t的类型是

typedef  unsigned int  kernel_uid32_t;

那么,我们就算算,正好 2 32 − 1 2^{32}-1 2321=4294967295,那现在回答一下-1。

让我们回顾一下,现在的机器的机器码对于负数都是用补码的形式表示的,因此-1的补码正好是全一。

但是,从int到unsigned int,在这种转换下-1就变成了4294967295。

四、程序验证

从CS APP(深入理解操作系统)第三版,英文版111页、中文版52页。大家可以用32位的编译方式验证一下。

我这里用Kali验证了一下:

#include 

int main(void)
{
    int x=-1;
    printf("x=%d, %u\n", x, x);
    return 0;
}

结果是
在这里插入图片描述

五、漏洞总结

这个问题是sudo在进行uid判断的时候,没有考虑这种边界情况,擅自改成了0。从而直接使用了root用户的uid,从而提权。

六、额外分析

有群友问了-0,-0的补码计算如下:

先算原码

10000000000000000000000000000000

取反码,保留符号位

1111111111111111111111111111111111111

加一

00000000000000000000000000000000

即补码情况下,-0=0。

七、篇后语

《老子》:合抱之木,生于毫末;九层之台,起于垒土;千里之行,始于足下。

你可能感兴趣的:(Linux)