简介
ESET研究团队最近发现了一种新型的恶意软件,名为LightNeuron,专门针对Microsoft Exchange进行攻击。该恶意软件利用一种以前未被发现的持久性技术,即Transport Agent。
Transport Agent(传输代理)是一种用于邮件服务器的扩展性组件,它在邮件传输过程中介入,并可以对传入或传出的邮件进行自定义处理。它允许开发人员在邮件传输过程中添加自定义的逻辑和功能。
Transport Agent可以用于各种目的,包括但不限于以下几个方面:
- 内容筛选和过滤:Transport Agent可以检查邮件内容、附件或标头,并根据预定义的规则对邮件进行过滤或阻止。
- 加密和解密:Transport Agent可以对邮件进行加密或解密操作,以确保邮件的安全性和保密性。
- 病毒和垃圾邮件检测:TransportAgent可以与反病毒引擎和垃圾邮件过滤器集成,对传入或传出的邮件进行检测和过滤,以提高邮件安全性和减少垃圾邮件的传递。
- 邮件路由和重定向:Transport Agent可以根据特定的规则和条件,对邮件进行路由或重定向操作,以实现灵活的邮件转发和分发策略。
- 自定义通知和日志记录:Transport Agent可以在邮件传输过程中生成自定义的通知消息或记录相关信息,用于监控、审计或报告目的。
本文从技术研究的角度,介绍了Transport Agent的用途,并提供了编写代码实现不同功能的示例,同时结合利用思路给出了防御建议。
Transport Agent基础知识
参考资料:
1.https://docs.microsoft.com/en-us/previous-versions/office/developer/exchange-server-2010/dd877026(v=exchg.140)
2.https://github.com/MicrosoftDocs/office-developer-exchange-docs/blob/main/docs/transport-agents/agent.md
3.https://3gstudent.github.io/%E6%B8%97%E9%80%8F%E6%8A%80%E5%B7%A7-%E4%BD%BF%E7%94%A8Transport-Agent%E4%BD%9C%E4%B8%BAExchange%E5%90%8E%E9%97%A8
通过使用 Exchange 附带的程序集,您可以创建自己的自定义代理以根据组织的需要执行特定任务。例如,您可以使用 SmtpReceiveAgent 传输代理拦截通过 SMTP 协议接收的消息并处理消息以将正文格式转换为包含预格式化的文本。您可以使用 RoutingAgent 传输代理来记录通过服务器传递到另一台服务器的消息。您还可以创建使用多种类型代理的更复杂的功能。例如,要创建防病毒代理,您可以实现 SmtpReceiveAgent 和 RoutingAgent 代理。
创建传输代理的先决条件
传输代理类的以下程序集:
Microsoft.Exchange.Data.dll
Microsoft.Exchange.Data.Common.dll
Microsoft.Exchange.Transport.dll
- .NET 框架 4.5
dll可从Exchange服务器上获得,位置为%ExchangeInstallPath%Public,例如C:\Program Files\Microsoft\Exchange Server\V15\Public
传输代理派生自以下三个类之一:
1. SmtpReceiveAgent
2. RoutingAgent
3. DeliveryAgent
实现传输代理的方式是先注册某个事件,然后在该事件触发时执行操作。 这三种代理类型中的每一种都可以注册一组不同的事件。

当邮件进入传输管道时,从 SmtpReceiveAgent 类派生的传输代理可以在代理注册的任何 SMTP 事件期间对邮件进行操作。 派生自 RoutingAgent 类的代理可以对其注册的四个分类程序事件中的任何一个执行操作。 派生自 DeliveryAgent 类的代理可以在注册的任何传递事件期间对消息进行操作。
传输代理类
传输代理派生自的类确定代理可以注册的事件。 代理通常包含代理类、代理工厂、一个或多个事件处理程序,以及执行希望代理执行的操作的代码。
下表列出了要针对每种代理类型派生的类。
| 代理类型 | 工厂基类 | 代理基类 |
|---|---|---|
| SmtpReceiveAgent | SmtpReceiveAgentFactory | SmtpReceiveAgent |
| RoutingAgent | RoutingAgentFactory | RoutingAgent |
| DeliveryAgent | DeliveryAgentFactory | DeliveryAgent |
这些工厂和代理基类提供可用于访问传输事件和消息的属性和方法。 在代理中实现继承自这些类的类。 在代理工厂派生类中,重写 CreateAgent 方法,以便它返回代理类的新实例。
SmtpReceiveAgent 传输代理
SmtpReceiveAgent 类事件
| “事件” | 说明 |
|---|---|
| OnAuthCommand | 当代理需要仅在 SMTP AUTH 命令中提供的信息时使用,例如接受或拒绝基于所用身份验证方法类型的邮件传递尝试的代理。 |
| OnConnect | 当代理需要仅在通过 SMTP 打开到前端传输服务的连接时提供的信息,例如基于远程 SMTP 服务器的地址或域执行操作的代理时使用。 |
| OnDataCommand | 当代理需要 SMTP DATA 命令中提供的信息时,请使用此事件。 |
| OnDisconnect | 当代理需要断开连接时可用的信息(例如当前日期和时间)时使用,以便执行时间计算。 |
| OnEhloCommand | 当代理需要 SMTP EHLO 命令中提供的信息时使用;例如,如果代理根据 EHLO 命令中提供的标识接受或拒绝消息。 |
| OnEndOfAuthentication | 当代理需要远程服务器完成身份验证过程后可用的信息时使用;例如,对于基于远程 SMTP 服务器或客户端提供的身份验证信息对邮件执行操作的代理。 |
| OnEndOfData | 当代理必须基于消息中可用的数据执行操作时使用。 此事件不会在前端传输服务上触发。 如果传输代理必须使用此事件,则必须将其安装在邮箱服务器上。 |
| OnEndOfHeaders | 当代理必须根据提交的邮件标头中提供的信息执行操作时使用。 |
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Exchange.Data.Transport;
using Microsoft.Exchange.Data.Transport.Smtp;
namespace MyAgents
{
public sealed class MyAgentFactory : SmtpReceiveAgentFactory
{
public override SmtpReceiveAgent CreateAgent(SmtpServer server)
{
return new MyAgent();
}
}
public class MyAgent : SmtpReceiveAgent
{
public MyAgent()
{
this.OnEndOfData += new EndOfDataEventHandler(MyEndOfDataHandler);
}
private void MyEndOfDataHandler (ReceiveMessageEventSource source, EndOfDataEventArgs e)
{
e.MailItem.Message.Subject += " - this text appended by MyAgent";
}
}
}
编译生成MyAgent.dll
将MyAgent.dll复制到Exchange服务器,保存路径为C:\test\MyAgent.dll
使用Exchange Server PowerShell安装Transport Agent,需要重启服务MSExchangeTransport才能够生效,命令如下:
Install-TransportAgent -Name "MySpamFilterAgent" -TransportAgentFactory "MyAgents.MyAgentFactory" -AssemblyPath "C:\test\MyAgent.dll"("MyAgents.MyAgentFactory"命名空间.自定义工厂类)
Enable-TransportAgent MySpamFilterAgent
Restart-Service MSExchangeTransport
卸载Transport Agent的命令:
Uninstall-TransportAgent MySpamFilterAgent -Confirm:$false
Restart-Service MSExchangeTransport
查看所有Transport Agent的命令:
Get-TransportAgent |fl
Transport Agent安装成功后,使用任意用户发送邮件,邮件标题被修改,测试成功。在该传输代理中,还可以做到“监控邮件,监控附件,记录邮件信息(发件人、收件人、域名、时间等),修改邮件的发件人和主题等”,具体操作可以面向"chatGPT"编程。
RoutingAgent 传输代理
RoutingAgent 类事件
| “事件” | 说明 |
|---|---|
| OnCategorizedMessage | 在服务器执行内容转换后发生(如果需要)。 |
| OnResolvedMessage | 在已解决邮件的所有收件人之后,在确定路由之前发生。 |
| OnRoutedMessage | 在服务器将消息路由到下一跃点并执行内容转换(如果需要)之后发生。 服务器可能会使用比 OnSubmittedMessage 事件更多的资源来处理 OnRoutedMessage 事件中的每个消息,因为服务器在执行 OnRoutedMessage 事件处理程序中的代码之前,将执行任何必要的内容转换并确定消息路由中的下一跃点。 |
| OnSubmittedMessage | 在消息从提交队列中取出后发生。 如果 RoutingAgent 传输代理不需要内容转换、解析的收件人或路由数据,请使用 OnSubmittedMessage 事件。 |
using System.Diagnostics;
using System.Runtime.InteropServices;
using Microsoft.Exchange.Data.Transport;
using Microsoft.Exchange.Data.Transport.Routing;
namespace MyRoutingAgent
{
public sealed class RoutingAgenttFactory : RoutingAgentFactory
{
public override RoutingAgent CreateAgent(SmtpServer server)
{
return new RoutAgent(server);
}
}
public class RoutAgent : RoutingAgent
{
public RoutAgent(SmtpServer server)
{
this.OnSubmittedMessage += OnSubmittedMessageHandler;
this.OnRoutedMessage += OnRoutedMessageHandler;
}
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern uint GetCurrentThreadId();
private void OnSubmittedMessageHandler(SubmittedMessageEventSource source, QueuedMessageEventArgs args)
{
Trace.WriteLine("c# ===> OnSubmittedMessageHandler!");
Trace.WriteLine("c# ===> tid!" + GetCurrentThreadId().ToString());
Trace.WriteLine("c# ===> subject!" + args.MailItem.Message.Subject);
}
private void OnRoutedMessageHandler(RoutedMessageEventSource source, QueuedMessageEventArgs args)
{
Trace.WriteLine("c# ===> OnRoutedMessageHandler!");
Trace.WriteLine("c# ===> tid!" + GetCurrentThreadId().ToString());
Trace.WriteLine("c# ===> subject!" + args.MailItem.Message.Subject);
}
}
}
编译生成DLL文件后,安装和卸载该传输带代理和SmtpReceiveAgent 传输代理安装卸载步骤类似。
DeliveryAgent 传输代理
DeliveryAgent 类事件
| “事件” | 说明 |
|---|---|
| OnCloseConnection | 在传递最后一个邮件项目并关闭连接之后发生。 |
| OnDeliverMailItem | 在邮件项准备好送达时发生。 |
| OnOpenConnection | 在打开传递代理进行邮件传递时发生。 |
1.实现 DeliveryAgentFactory 类的派生类。
using Microsoft.Exchange.Data.Transport;
using Microsoft.Exchange.Data.Transport.Delivery;
public class MyDeliveryAgentFactory : DeliveryAgentFactory<MyDeliveryAgentFactory.MyDeliveryAgentManager>
{
static MyDeliveryAgentFactory()
{
}
public override DeliveryAgent CreateAgent(SmtpServer server)
{
return new MyDeliveryAgent(server);
}
public sealed class MyDeliveryAgentManager : DeliveryAgentManager
{
/// <summary>
/// Gets the supported delivery protocol.
/// </summary>
public override string SupportedDeliveryProtocol
{
get { return "SMTP"; }
}
}
}
此代码将实例化派生类并重写 CreateAgent 方法以创建新的自定义代理的实例。 此类中还可以重写其他方法(如 Close),以执行自定义代码。 将创建 DeliveryAgentManager 类来替代 SupportedDeliveryProtocol 属性并设置代理将使用的协议。
2.定义代理。
public class MyDeliveryAgent : DeliveryAgent
{
public MyDeliveryAgent(SmtpServer server)
{
this.OnCloseConnection += CloseConnection;
this.OnDeliverMailItem += DeliverMailItem;
this.OnOpenConnection += OpenConnection;
}
}
定义代理类后,可以添加自定义功能。 在此示例中, OnCloseConnection、 OnDeliverMailItem 和 OnOpenConnection 这三个事件重定向到自定义事件处理程序。
检测
1.查看Transport Agent配置
使用Exchange Server PowerShell,命令如下:
Get-TransportAgent
其他Powershell命令可参考:
https://docs.microsoft.com/en-us/powershell/module/exchange/?view=exchange-ps#mail-flow
2.查看服务日志
安装Transport Agent需要重启服务MSExchangeTransport
3.查看进程
使用Transport Agent后,进程EdgeTransport.exe将会加载对应的dll
可以查看进程EdgeTransport.exe是否加载可疑dll
2156

被折叠的 条评论
为什么被折叠?



