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

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

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

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

工具目录

分类

查看所有分类
Loading categories
PwnKit-Exploit — 基于C语言的概念验证漏洞利用程序,针对CVE-2021-4034(PwnKit),通过pkexec中的越界写入实现本地权限提升。包含构建说明和漏洞解析。 | Kitploit
工具/GitHubGitHub/luijait/pwnkit-exploit
权限提升漏洞分析漏洞利用渗透测试
GitHubluijait/pwnkit-exploit

PwnKit-Exploit

基于C语言的概念验证漏洞利用程序,针对CVE-2021-4034(PwnKit),通过pkexec中的越界写入实现本地权限提升。包含构建说明和漏洞解析。

查看仓库
98184年前Kitploit 审核通过

最受欢迎

查看全部 →

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

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

PwnKit-Exploit

CVE-2021-4034

PolKit

@c0br40x 帮助制作了README中的这一部分!

概念验证

Proof of Concept

root@kitploit:~
debian@debian:~/PwnKit-Exploit$ make
cc -Wall    exploit.c   -o exploit
debian@debian:~/PwnKit-Exploit$ whoami
debian
debian@debian:~/PwnKit-Exploit$ ./exploit
Current User before execute exploit
hacker@victim$whoami: debian
Exploit written by @luijait (0x6c75696a616974)
[+] Enjoy your root if exploit was completed succesfully
root@debian:/home/debian/PwnKit-Exploit# whoami
root
root@debian:/home/debian/PwnKit-Exploit# 

修复

命令用途
sudo chmod 0755 pkexec修复 CVE-2021-4034

安装与使用

git clone https://github.com/luijait/PwnKit-Exploit

cd PwnKit-Exploit

make

./exploit

whoami

命令功能
make clean清理构建以测试修改后的代码

说明

基于 blog.qualys.com

pkexec的main()函数开头处理命令行参数(第534-568行),并在路径不是绝对路径的情况下,在PATH环境变量指定的目录中搜索要执行的程序(第610-640行):

root@kitploit:~

435 main (int argc, char *argv[])
436 {
...
534   for (n = 1; n < (guint) argc; n++)
535     {
...
568     }
...
610   path = g_strdup (argv[n]);
...
629   if (path[0] != '/')
630     {
...
632       s = g_find_program_in_path (path);
...
639       argv[n] = path = s;
640     }

遗憾的是,如果命令行参数计数argc为0——意味着我们传递给execve()的参数列表argv是空的,即{NULL}——那么argv[0]就是NULL,即参数列表的终止符。因此:

  • 在第534行,整数n被永久设置为1;
  • 在第610行,指针path从argv[1]越界读取;
  • 在第639行,指针s被越界写入argv[1]。

那么,从越界的argv[1]中读取的到底是什么,写入的又是什么?

要回答这个问题,我们必须简短地绕个弯。当我们execve()一个新程序时,内核会将我们的参数、环境字符串及其指针(argv和envp)复制到新程序栈的末尾;例如:

root@kitploit:~
|---------+---------+-----+------------|---------+---------+-----+------------| 
| 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 

显然,由于argv和envp指针在内存中是连续的,如果argc为0,那么越界的argv[1]实际上就是envp[0],即指向我们第一个环境变量“value”的指针。因此:

  • 在第610行,要执行的程序的路径从argv[1](即envp[0])越界读取,指向“value”;
  • 在第632行,该路径“value”被传递给g_find_program_in_path()(因为“value”不以斜杠开头,见第629行);
  • 然后,g_find_program_in_path()在我们的PATH环境变量目录中搜索名为“value”的可执行文件;
  • 如果找到这样的可执行文件,其完整路径将被返回给pkexec的main()函数(第632行);
  • 最后,在第639行,该完整路径被越界写入argv[1](即envp[0]),从而覆盖了我们的第一个环境变量。

所以,更精确地说:

  • 如果我们的PATH环境变量是“PATH=name”,并且目录“name”存在(在当前工作目录中)且包含一个名为“value”的可执行文件,那么一个指向字符串“name/value”的指针会被越界写入envp[0];

  • 或者

  • 如果我们的PATH是“PATH=name=.”,并且目录“name=.”存在且包含一个名为“value”的可执行文件,那么一个指向字符串“name=./value”的指针会被越界写入envp[0]。

换句话说,这种越界写入允许我们向pkexec的环境中重新引入一个“不安全”的环境变量(例如LD_PRELOAD)。在main()函数被调用之前,ld.so通常会将SUID程序环境中的这些“不安全”变量移除。我们将在下一节利用这一强大的原语。

最后提醒:polkit也支持非Linux操作系统,如Solaris和*BSD,但我们尚未研究它们的可利用性。不过,我们注意到OpenBSD不可利用,因为其内核拒绝执行argc为0的程序。

下载工具