selinux与kernel 0day

kernel NULL pointer的利用需要把shellcode映射到内存0处, 大家在测试exp的时候,总能发现一个规律, 开着selinux就能溢出成功, 关闭就不能溢出成功了。 看了下内核源码,终于搞清楚了: mmap在做匿名映射的时候,会经过LSM层来做安全验证, LSM初始化的时候,会将selinux作为它的第一验证模块, capablity作为它的第2验证模块。这2个模块在做mmap映射的时候,都指向了dummy_file_mmap_addr这个函数:
usr/src/debug/kernel-2.6.18/linux-2.6.18.i686/security/dummy.c:

static int dummy_file_mmap_addr (struct file *file, unsigned long reqprot,
unsigned long prot,
unsigned long flags,
unsigned long addr,
unsigned long addr_only)
{
if ((addr < mmap_min_addr) && !capable(CAP_SYS_RAWIO))
return -EACCES;
return 0;
}
mmap_min_addr代表了用户能映射的最小内存地址, 它在/proc/sys/vm/mmap_min_addr进行设置。这里还要对当前进程的CAP_SYS_RAWIO能力做个判断, 就是说如果进程有这个能力的话, 不管mmap_min_addr的值是多大,都可以满足用户的需求, 当然就可以映射0地址了。 那么这跟selinux有什么关系呢?  进程在被执行的时候,尤其是调用了execve这个函数, 进程的权能是需要重新来计算的,在selinux开启的时候, selinux是LSM的第一验证模块, 看下它是怎么计算进程在被execve后的权能的:
void cap_bprm_apply_creds (struct linux_binprm *bprm, int unsafe)
{
/* Derived from fs/exec.c:compute_creds. */
kernel_cap_t new_permitted, working;

new_permitted = cap_intersect (bprm->cap_permitted, cap_bset);
working = cap_intersect (bprm->cap_inheritable,
current->cap_inheritable);
new_permitted = cap_combine (new_permitted, working);

if (bprm->e_uid != current->uid || bprm->e_gid != current->gid ||
!cap_issubset (new_permitted, current->cap_permitted)) {
current->mm->dumpable = suid_dumpable;

if (unsafe & ~LSM_UNSAFE_PTRACE_CAP) {
if (!capable(CAP_SETUID)) {
bprm->e_uid = current->uid;
bprm->e_gid = current->gid;
}
if (!capable (CAP_SETPCAP)) {
new_permitted = cap_intersect (new_permitted,
current->cap_permitted);
}
}
}

current->suid = current->euid = current->fsuid = bprm->e_uid;
current->sgid = current->egid = current->fsgid = bprm->e_gid;

/* For init, we want to retain the capabilities set
* in the init_task struct. Thus we skip the usual
* capability rules */
if (current->pid != 1) {
current->cap_permitted = new_permitted;
current->cap_effective =
cap_intersect (new_permitted, bprm->cap_effective);
}

/* AUD: Audit candidate if current->cap_effective is set */

current->keep_capabilities = 0;
}
我们看到如果当前进程不是init进程的话, 权能还是会被继承下来的。

在selinux关闭的时候, capabiliy模块成为了LSM的第一验证模块, 看下它是怎么计算的:
static void dummy_bprm_apply_creds (struct linux_binprm *bprm, int unsafe)
{
if (bprm->e_uid != current->uid || bprm->e_gid != current->gid) {
current->mm->dumpable = suid_dumpable;

if ((unsafe & ~LSM_UNSAFE_PTRACE_CAP) && !capable(CAP_SETUID)) {
bprm->e_uid = current->uid;
bprm->e_gid = current->gid;
}
}

current->suid = current->euid = current->fsuid = bprm->e_uid;
current->sgid = current->egid = current->fsgid = bprm->e_gid;

dummy_capget(current, &current->cap_effective, &current->cap_inheritable, &current->cap_permitted);
}

static int dummy_capget (struct task_struct *target, kernel_cap_t * effective,
kernel_cap_t * inheritable, kernel_cap_t * permitted)
{
*effective = *inheritable = *permitted = 0;
if (!issecure(SECURE_NOROOT)) {
if (target->euid == 0) {
*permitted |= (~0 & ~CAP_FS_MASK);
*effective |= (~0 & ~CAP_TO_MASK(CAP_SETPCAP) & ~CAP_FS_MASK);
}
if (target->fsuid == 0) {
*permitted |= CAP_FS_MASK;
*effective |= CAP_FS_MASK;
}
}
return 0;
}
注意看这行:
*effective = *inheritable = *permitted = 0;
selinux将当前进程的权能全部清0了, 所以excve后的普通进程是没有任何权能的。 也就没有了CAP_SYS_RAWIO权能,也就不能映射0内存了。 所以想阻止NULL pointer kernel 0day的攻击,最好把selinux关掉,或升级到最新的内核版本。 同时把mmap_min_addr的值设为大于4096。

selinux与kernel 0day的更多相关文章

  1. SELinux深入理解

    ps:今天在远程给服务器配置https的时候,一直乱码,以前做系统的系统第一件事情,就是关闭selinx,今天忘记了,然后就悲剧了... 弄了半天才弄好,镇定思痛,好好的来看下selinux 1. 简 ...

  2. 深入理解SELinux

      目录(?)[+]   1. 简介 SELinux带给Linux的主要价值是:提供了一个灵活的,可配置的MAC机制. Security-Enhanced Linux (SELinux)由以下两部分组 ...

  3. SElinux解决web网站无法访问

    SElinux解决web网站无法访问工具/原料centos 6.5系统httpd web服务器 SELinux 设置为enforcing:强制模式,代表 SELinux 运作中 方法/步骤1. 1se ...

  4. SELINUX工作原理

    SELinux工作原理 1. 简介 SELinux带给Linux的主要价值是:提供了一个灵活的,可配置的MAC机制. Security-Enhanced Linux (SELinux)由以下两部分组成 ...

  5. selinux权限问题【转】

    本文转载自:https://blog.csdn.net/u011386173/article/details/83339770 版权声明:本文为博主原创文章,未经博主允许不得转载. https://b ...

  6. SELinux简介

    Security-Enhanced Linux (SELinux)由以下两部分组成: 1) Kernel SELinux模块(/kernel/security/selinux) 2) 用户态工具 SE ...

  7. 零基础学习云计算及大数据DBA集群架构师【Linux系统配置及网络配置2015年12月30日周三】

    /Mon *************摘要************** 计划任务 )一次性计划任务 服务:atd 命令:at 服务存放文件:/etc/init.d/atd 系统配置文件:/etc/at. ...

  8. Linux进程管理(3):总结

    7. exit与_exit的差异    为了理解这两个系统调用的差异,先来讨论文件内存缓存区的问题. 在linux中,标准输入输出(I/O)函数都是作为文件来处理.对应于打开的每个文件,在内存中都有对 ...

  9. ANALYSIS AND EXPLOITATION OF A LINUX KERNEL VULNERABILITY (CVE-2016-0728)

    ANALYSIS AND EXPLOITATION OF A LINUX KERNEL VULNERABILITY (CVE-2016-0728) By Perception Point Resear ...

随机推荐

  1. 使用systemctl管理服务

    系统服务,开机不需要登录就能运行的程序(相当于开机自启)/usr/lib/systemd/system 用户服务,需要登录后才能运行的程序/usr/lib/systemd/user 目录下又存在两种类 ...

  2. 任正非:5G技术只独家卖给美国!不卖给韩国、日本、欧洲

    https://v.qq.com/x/page/g3001d0xvxe.html 我只转个标题,细节不管了. 呃,实际上就是说,老任头也决定向美国低头了,对不. 不过,也确实没办法. 该起床吃钙片了.

  3. 一、@Html.DropDownList

    一.Html.DropDownList 通过linq 将datatable转换下拉列表 //查询城市 string CityId = WebCommon.Public.GetAdminCityId() ...

  4. C++ 虚函数和多重继承的内存布局初探

    C++ 对象的内存布局 一切以事实说话: 代码: 1: #include <stdio.h> 2:  3: class A { 4: public: 5: int a; 6: int b; ...

  5. SVN连接不上仓库,问题之一

    如果之前用过SVN,在新的地址上用,发现一直连不上,报错.有可能是因为默认使用了之前的地址,所以没弹出输账号和密码的弹框. 解决方法就是:把之前的链接地址全部清除掉. 右键找到SVN里面的  Sett ...

  6. css实现文本溢出用...显示

    文本溢出省略号显示,要实现这个必须 要有四个条件: 1.须有容器宽度:width:value 2.强制文本在一行内显示:white-space:nowrap: 3.溢出内容隐藏:overflow:hi ...

  7. php time()函数 语法

    php time()函数 语法 time()函数怎么用? php time()函数用来返回当前时间的unix时间戳.语法是time(),返回自从 Unix 纪元(格林威治时间 1970 年 1 月 1 ...

  8. webpack 兼容低版本浏览器,转换ES6 ES7语法

    ES6,ES7真的太棒了,async +await+Promise,让我阅读代码的时候不用再从左拉到右了(异步太多,一层套一层真的太头痛) 但是有个问题,打包后低版本浏览器运行不了,还有我用了一些混淆 ...

  9. 《NULL-2019团队》第一次作业:OUC二手交易平台

    前言 项目名称:OUC二手交易平台 项目简介:针对在校大学生的二手交易平台,相对于现在市面已有的二手APP,将其使用的普遍性范围缩小,针对在校大学生,这样可以有效的保证交易的真实性和公平性.   NA ...

  10. thinkcmf5 pc切换手机

    1.在simplewind\cmf\common.php 里找到“获取当前主题名”添加 if(cmf_is_mobile()){ $theme = config('cmf_mobile_default ...