.Net Remoting 系列二:Solarwinds ARM 漏洞分析
字数 2272 2025-08-20 18:17:31

.NET Remoting 漏洞分析:SolarWinds ARM 漏洞深度解析

1. 漏洞概述

本教学文档将深入分析 SolarWinds Access Rights Manager (ARM) 中的 .NET Remoting 漏洞(CVE-2023-35187),这是一个允许远程攻击者在受影响系统上执行任意代码的高危漏洞。

关键漏洞信息

  • 漏洞编号:CVE-2023-35187
  • 影响组件:SolarWinds Access Rights Manager
  • 认证要求:无需认证即可利用
  • 漏洞位置:OpenClientUpdateFile 方法
  • 根本原因:使用用户提供的路径前缺乏适当验证
  • 影响范围:可在 SYSTEM 上下文中执行代码

2. 漏洞技术分析

2.1 漏洞代码分析

漏洞存在于 TattleImplementation 类中的 OpenClientUpdateFile 方法:

public class TattleImplementation : RemotingObject, ITattle, IPing {
    public Guid OpenClientUpdateFile(string fileName) {
        Guid guid2;
        using (MethodCall methodCall = new MethodCall(this)) {
            Guid guid = Guid.NewGuid();
            using (this.fileStreams.Lock()) {
                this.fileStreams.Add(guid, new FileStream(
                    Path.Combine(ApplicationPaths.Instance.InstallationPath, fileName),
                    FileMode.Open, 
                    FileAccess.Read));
            }
            guid2 = methodCall.SetResult(guid);
        }
        return guid2;
    }

    public byte[] ReadClientUpdateFile(Guid updateId, int maxBytes) {
        byte[] array = new byte[maxBytes];
        int num;
        using (this.fileStreams.Lock()) {
            num = this.fileStreams[updateId].Read(array, 0, maxBytes);
        }
        Array.Resize(ref array, num);
        return array;
    }
}

漏洞利用链

  1. 攻击者调用 OpenClientUpdateFile 方法,传入任意文件路径
  2. 方法返回一个 GUID
  3. 攻击者使用该 GUID 调用 ReadClientUpdateFile 方法
  4. 系统读取并返回指定文件的内容

2.2 Remoting 实现分析

TattleImplementation 继承自 RemotingObject,后者继承自 MarshalByRefObject

public abstract class RemotingObject : MarshalByRefObject, IDisposable, IPing {
    public override object InitializeLifetimeService() {
        return null; // 使对象永久存活
    }
    
    public string Ping(string packet) {
        return packet;
    }
    
    public void InstantiateInterface() {}
    
    public virtual void Dispose() {
        RemotingServices.Disconnect(this);
    }
}

3. GRPC 自定义 Channel 实现

SolarWinds ARM 使用自定义的 GrpcServerChannel 实现 .NET Remoting 功能:

3.1 Channel 注册

private int createGlobalServerChannelInternal(int port, bool selectServerPort) {
    string text = string.Format("port_{0}", port);
    object obj = this.channelAccess;
    lock (obj) {
        IDictionary dictionary = new Hashtable();
        dictionary["includeVersions"] = false;
        dictionary["typeFilterLevel"] = TypeFilterLevel.Full.ToString();
        
        IServerChannelSinkProvider serverChannelSinkProvider2;
        if (!this.applicationConfiguration.GetValue("network.dump.enabled", false)) {
            IServerChannelSinkProvider serverChannelSinkProvider = 
                new BinaryServerFormatterSinkProvider(dictionary, null);
            serverChannelSinkProvider2 = serverChannelSinkProvider;
            
            IChannelReceiver channelReceiver;
            if (selectServerPort || port > 0) {
                channelReceiver = new GrpcServerChannel(this.grpcManager, text, port, serverChannelSinkProvider3);
                ChannelServices.RegisterChannel(channelReceiver, false);
            }
        }
        return this.grpcManager.LocalPort;
    }
}

关键配置

  • typeFilterLevel 设置为 Full(允许反序列化所有类型)
  • 使用 BinaryServerFormatterSinkProvider 进行序列化

3.2 Sink Chain 结构

完整的 Sink Chain 如下:

GrpcRemotingService (GrpcRemotingService#send → GrpcRemotingService#HandelRequest) 
→ BinaryServerFormatterSink 
→ Dispatch

4. 漏洞利用方法

4.1 服务端点

以下是 SolarWinds ARM 中可用的 Remoting 服务端点:

URI Service 实现类
wusel WuselImplementation
pn.server gaffer
pn.gaffer tattle
pn.server update
pn.update tracerServer
pn.tracer farmServer
pn.server.farm tracerCenter
pn.tracer jobCenter
pn.jobs GenericGafferCredentialService
pn.connectors.generic.gaffer logService
pn.server ServerDebugger

4.2 利用步骤

  1. 构造 GrpcClientChannel 连接到 grpc://IP:5555/tattle
  2. 调用 OpenClientUpdateFile 方法获取文件句柄
  3. 使用返回的 GUID 调用 ReadClientUpdateFile 读取文件内容

升级到 RCE
可以利用 .erlang.cookie 文件(位于 C:\ProgramData\SolarWinds\Orion\RabbitMQ\.erlang.cookie)进行权限提升。

5. 代码审计关注点

在审计 .NET Remoting 实现时,应重点关注以下方面:

  1. TypeFilterLevel 设置

    • 检查是否设置为 Full(高风险)
    • 理想情况下应设置为 Low
  2. 自定义 Channel 实现

    • 检查传输协议实现(GRPC、UDP、WebSocket 等)
    • 分析 Sink Chain 结构
  3. MBR 类方法

    • 检查所有 MarshalByRefObject 派生类
    • 识别危险方法(文件操作、命令执行等)
  4. 认证与授权

    • 检查是否实现了适当的认证机制
    • 验证方法调用权限控制
  5. 输入验证

    • 检查所有用户提供的输入是否经过严格验证
    • 特别注意文件路径、命令参数等敏感输入

6. 防御建议

  1. 禁用不必要的 Remoting 服务
  2. 将 TypeFilterLevel 设置为 Low
  3. 实现强认证机制
  4. 对所有用户输入进行严格验证
  5. 使用网络隔离限制访问
  6. 及时应用安全补丁

通过深入理解这些漏洞原理和实现细节,安全研究人员可以更有效地发现和防御类似的 .NET Remoting 安全问题。

.NET Remoting 漏洞分析:SolarWinds ARM 漏洞深度解析 1. 漏洞概述 本教学文档将深入分析 SolarWinds Access Rights Manager (ARM) 中的 .NET Remoting 漏洞(CVE-2023-35187),这是一个允许远程攻击者在受影响系统上执行任意代码的高危漏洞。 关键漏洞信息 : 漏洞编号:CVE-2023-35187 影响组件:SolarWinds Access Rights Manager 认证要求:无需认证即可利用 漏洞位置: OpenClientUpdateFile 方法 根本原因:使用用户提供的路径前缺乏适当验证 影响范围:可在 SYSTEM 上下文中执行代码 2. 漏洞技术分析 2.1 漏洞代码分析 漏洞存在于 TattleImplementation 类中的 OpenClientUpdateFile 方法: 漏洞利用链 : 攻击者调用 OpenClientUpdateFile 方法,传入任意文件路径 方法返回一个 GUID 攻击者使用该 GUID 调用 ReadClientUpdateFile 方法 系统读取并返回指定文件的内容 2.2 Remoting 实现分析 TattleImplementation 继承自 RemotingObject ,后者继承自 MarshalByRefObject : 3. GRPC 自定义 Channel 实现 SolarWinds ARM 使用自定义的 GrpcServerChannel 实现 .NET Remoting 功能: 3.1 Channel 注册 关键配置 : typeFilterLevel 设置为 Full (允许反序列化所有类型) 使用 BinaryServerFormatterSinkProvider 进行序列化 3.2 Sink Chain 结构 完整的 Sink Chain 如下: 4. 漏洞利用方法 4.1 服务端点 以下是 SolarWinds ARM 中可用的 Remoting 服务端点: | URI Service | 实现类 | |-------------|--------| | wusel | WuselImplementation | | pn.server | gaffer | GafferImplementation | | pn.gaffer | tattle | TattleImplementation | | pn.server | update | UpdateSourceImplementation | | pn.update | tracerServer | TracerServerImplementation | | pn.tracer | farmServer | FarmServerImplementation | | pn.server.farm | tracerCenter | TracerCenterImplementation | | pn.tracer | jobCenter | JobCenterImplementation | | pn.jobs | GenericGafferCredentialService | GenericGafferCredentialServiceImplementation | | pn.connectors.generic.gaffer | logService | LogServiceImplementation | | pn.server | ServerDebugger | ServerDebuggerImplementation | 4.2 利用步骤 构造 GrpcClientChannel 连接到 grpc://IP:5555/tattle 调用 OpenClientUpdateFile 方法获取文件句柄 使用返回的 GUID 调用 ReadClientUpdateFile 读取文件内容 升级到 RCE : 可以利用 .erlang.cookie 文件(位于 C:\ProgramData\SolarWinds\Orion\RabbitMQ\.erlang.cookie )进行权限提升。 5. 代码审计关注点 在审计 .NET Remoting 实现时,应重点关注以下方面: TypeFilterLevel 设置 : 检查是否设置为 Full (高风险) 理想情况下应设置为 Low 自定义 Channel 实现 : 检查传输协议实现(GRPC、UDP、WebSocket 等) 分析 Sink Chain 结构 MBR 类方法 : 检查所有 MarshalByRefObject 派生类 识别危险方法(文件操作、命令执行等) 认证与授权 : 检查是否实现了适当的认证机制 验证方法调用权限控制 输入验证 : 检查所有用户提供的输入是否经过严格验证 特别注意文件路径、命令参数等敏感输入 6. 防御建议 禁用不必要的 Remoting 服务 将 TypeFilterLevel 设置为 Low 实现强认证机制 对所有用户输入进行严格验证 使用网络隔离限制访问 及时应用安全补丁 通过深入理解这些漏洞原理和实现细节,安全研究人员可以更有效地发现和防御类似的 .NET Remoting 安全问题。