欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

简单吐槽一下dirtyCow

简单吐槽一下dirtyCow

本来是来论坛看看有没有分享相关内容的,结果只看到了一个测试poc的帖子~~
来简单说说本人的分析。
这个漏洞涉及到的内核代码很复杂,如果没有相关基础的童鞋,建议还是放弃分析吧。
我是按照 https://github.com/dirtycow/dirtycow.github.io/wiki/VulnerabilityDetails 上的介绍,把相关流程看了一遍。简单介绍一下漏洞的触发流程。
1. 要写入的文件f必须可读,这样才能以read only模式打开文件f,并映射到内存空间
2. 把read only模式打开的文件映射到内存空间之后,以read write方式打开/proc/self/mem,这个文件就是本进程的内存,所以打开的mem是可写的。
3. 写mem,由于文件f是只读的,所以会触发Copy-On-Write,复制一份内存,复制完了之后,系统会认为新复制的内存页完全属于该进程,所以可以写。这时候会触发罪魁祸首的一段一代

1883				/*
1884				 * The VM_FAULT_WRITE bit tells us that
1885				 * do_wp_page has broken COW when necessary,
1886				 * even if maybe_mkwrite decided not to set
1887				 * pte_write. We can thus safely do subsequent
1888				 * page lookups as if they were reads. But only
1889				 * do so when looping for pte_write is futile:
1890				 * in some cases userspace may also be wanting
1891				 * to write to the gotten user page, which a
1892				 * read fault here might prevent (a readonly
1893				 * page might get reCOWed by userspace write).
1894				 */
1895				if ((ret & VM_FAULT_WRITE) &&
1896				    !(vma->vm_flags & VM_WRITE))
1897					foll_flags &= ~FOLL_WRITE;
1898
1899				cond_resched();

也就是把foll_flags里面的FOLL_WRITE标志去掉了。这个标志用来标识是否验证可写。
紧接着cond_resched()进行系统调度~如果在这个时候调用 madvise(map,100,MADV_DONTNEED);~~~
4. 调用madvise告诉系统,map的那一块内存不再需要了,可以进行释放。随后系统释放掉新复制出来的,完全属于本进程的内存。
5. 这时候重新回到COW线程,cond_resched()后继续之行。重新获取page,发现没有,因为已经被释放了。这时候会重新走原来的流程,应该进行COW的,因为原来有FOLL_WRITE标志,需要验证是否可写,不可写的话进行复制。但是在之前的操作过程中,已经去掉了FOLL_WRITE标志。系统就认为是以只读的形式获取page的,因为只读,所以不会COW,就直接把原始的映射着文件f的内存页(page)作为了get_user_pages函数的返回值。
6. get_user_pages是在write里面调用的,write获取了get_user_pages返回的页,直接进行写操作。所以就把原始的映射着文件f的内存写了。
漏洞大意就是如此。有描述不准确和模糊的地方莫要较真。随着漏洞的曝光,我会再看情况适当补充其他细节~
PS1:先说说root,这个漏洞要root,最直接的办法就是写带set-user-id标志位的文件,例如ubuntu上的/bin/ping文件
qever@Q-Lab:/bin$ ls -la | grep ping
-rwsr-xr-x  1 root root   44168    8  2014 ping
-rwsr-xr-x  1 root root   44680    8  2014 ping6

至于Android上的root,至少我还没发现合适的方案~
PS2: 有兴趣的可以仔细看看下面这段万恶的while循环
http://androidxref.com/kernel_3.14/xref/mm/memory.c#1807

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功