# CVE-2020-1181: SharePoint Remote Code Execution Through Web Parts
June 17, 2020 | The ZDI Research Team
[SUBSCRIBE](https://www.zerodayinitiative.com/rss/)
Last week, Microsoft released a patch to correct
[CVE-2020-1181](https://portal.msrc.microsoft.com/en-US/security-
guidance/advisory/CVE-2020-1181) - a remote code execution bug in the
supported versions of Microsoft SharePoint Server. This bug was reported to
the ZDI program by an anonymous researcher and as is also known as
[ZDI-20-694](https://www.zerodayinitiative.com/advisories/ZDI-20-694/). This
blog takes a deeper look at the root cause of this vulnerability.
Before this patch being made available, SharePoint Server allowed an
authenticated user to execute arbitrary .NET code on the server in the context
and permissions of the service account of the SharePoint Web Application. For
an attack to succeed, the attacker should have **_Add and Customize Pages_**
permissions on the SharePoint site. However, the default configuration of
SharePoint allows authenticated users to create sites. When they do, the user
will be the owner of this site and will have all the necessary permissions.
**High-Level Description of The Vulnerability**
Microsoft SharePoint Server allows users to create web pages, but to prevent
abuse, it places strict limits on what components can appear on those pages.
The SharePoint server treats its "own" pages and user-defined pages in
different ways. SharePoint's "own" pages are stored on the file system and are
excluded from all restrictions. User pages are stored in a database and are
subject to restrictions. Some of these restrictions include the inability to
use code blocks or include files from the file system. They typically can use
only allowed web controls from a predefined list.
If a user creates a new page via upload, it will be restricted as usual.
However, if the new page is instead created by going through the SharePoint
web editor, it will be considered as "ghosted" and will be treated as a
trusted source. This makes sense, because the SharePoint web editor places
restrictions on what components can be added to a page, so the page can be run
safely in unrestricted mode.
The vulnerability occurs because one type of Web Part permitted by the editor
is a type called `WikiContentWebpart`, and this Web Part allows inclusion of
arbitrary ASP.NET markup. This provides a route for an attacker to have
arbitrary ASP.NET markup run in unrestricted mode, leading to remote code
execution.
**Examining the Vulnerable Code**
SharePoint uses `SPPageParserFilter` to block all dangerous content. Let's
review how `SPPageParserFilter` is initialized:
If we created our page by using the SharePoint Web Editor, it will have
`IsGhosted = true` and `_isAppWeb` will be set to `false`. Note that there is
an additional check to ensure there is no dependency file with a lower trust
level:
However, we have not added any such file, so we should be good here and pass
this check. As a result, `GetEffectivePageParserSettings()` will return
`PageParserSettings.GhostedPageDefaultSettings`:
As a result, our page will have `compilationmode=Always`,
`allowServerSideScript=true` and `allowUnsafeControls=true`. Now let's take a
closer look at `WikiContentWebpart`:
This means content from its parameters (`Directive` and `Content`) will be
parsed by `ParseControl(text2, false)`. The second parameter (`false`) will
force the use of `PageParserFilter`, but it will be used with
`PageParserSettings.GhostedPageDefaultSettings`.
Because the `ParseControl()` method never causes compilation, we cannot
specify .NET code directly. However, we can use dangerous controls from within
SharePoint to invoke arbitrary methods and get code execution. Here's an
example of a configuration of `WikiContentWebpart` that will run an arbitrary
OS command:
**Proof-of-Concept**
For our demonstration, we used a Microsoft SharePoint 2019 Server with all
default options installed on a Windows Server 2019 Datacenter edition system.
We assigned it the name sp2019.contoso.lab and made it a member of the
contoso.lab domain. Our domain controller is on a separate virtual machine.
Our target machine had all available patches installed as of February 2020,
which puts it at version 16.0.10355.20000.
Our attacker system simply needs any supported web browser. In the screenshots
below, we're using Mozilla Firefox 69.0.3. We'll also use a custom
`WikiContentWebpart` similar to the example above. We have named ours
**WikiContentRCE.xml** .
Let's visit our SharePoint Server and authenticate as a regular user. In this
example, it is **user2** :
View fullsize
![Picture1.png]()
View fullsize
![Picture2.png]()
Let's create a site so that we will be the owner and have full permissions.
Click on " **SharePoint** " on the top panel:
View fullsize
![Picture3.png]()
Click on the _"_ ** _\+ Create site_** _"_ link:
View fullsize
![Picture4.png]()
Choose **_Team Site_**. Now we need to pick a name for the new site. In this
example, it is **testsiteofuser2**.
View fullsize
![Picture5.png]()
Click " ** _Finish_** " and the new site will be created:
View fullsize
![Picture6.png]()
Now let's click on the " ** _Pages " _**link:
View fullsize
![Picture7.png]()
We need to switch to **Classic View**. To do this, just click on the "
**Return to classic SharePoint** " link on the bottom left corner:
View fullsize
![Picture8.png]()
Click on " ** _\+ New_** " and choose any name for our new page. In this
example, we called it **newpage1** :
View fullsize
![Picture9.png]()
Click on the **_Create_** button to confirm.
View fullsize
![Picture10.png]()
Now we need to choose **_Web Part_** on the **_INSERT_** tab:
View fullsize
![Picture11.png]()
In the dialog window, select the " **Upload Web Part** " link on the bottom
left corner and upload the crafted **WikiContentRCE.xml** file:
View fullsize
![Picture12.png]()
Click **_Upload_**. You may receive a pop-up warning stating, " _This page is
asking you to confirm that you want to leave - data you have entered may not
be saved_. " Just confirm by clicking on the " ** _Leave Page_** " button. We
then return to the main editing view:
View fullsize
![Picture13.png]()
We need to choose the **_Web Part_** widget on the **_INSERT_** tab again. It
will have our imported crafted Web Part:
View fullsize
![Picture14.png]()
Before we click on the **_Add_** button, let's go to the target SharePoint
server and open the **C:\windows\temp** folder:
View fullsize
![Picture15.png]()
Notice there is no **RCE_PoC.txt ** file.
Now let's go back to the attacker machine and add our imported Web Part to the
page:
View fullsize
![Picture16.png]()
Let's check the **C:\windows\temp** folder on our target server again:
View fullsize
![Picture17.png]()
In this way, our attacker can execute any OS command and compromise the
server. They just need to replace `echo pwned > c:/windows/temp/RCE_PoC.txt`
string in WikiContentRCE.xml file with their desired command.
**Conclusion**
In their patch documentation, Microsoft gave this vulnerability an Exploit
Index (XI) rating of 2, which means they felt exploitation of this bug is
unlikely. However, as demonstrated in our proof of concept section, the
exploitation of this bug is quite straightforward for any authenticated user.
Because of this, we recommend treating as an XI of 1, which indicates
exploitation is likely. According to Microsoft, they addressed this bug by
"correcting how Microsoft SharePoint Server handles processing of created
content." That does seem like a reasonable path to take in this instance.
SharePoint continues to be an attractive target for researchers and attackers
alike, and several SharePoint-related disclosures are currently in our
[Upcoming](https://www.zerodayinitiative.com/advisories/upcoming/) queue. Stay
tuned to this blog for details about those bugs once they are disclosed.
暂无评论