导语:最近CrowdStrike在Office 365中发现了一项功能,此功能可以对所有用户默认活动的邮箱活动记录系统进行访问,本文就详细介绍了CrowdStrike关于Office 365的日志功能。
前言
商务电子邮件攻击(Business email compromises ,BECs)是目前电子邮件攻击中的重灾区。就在2018年的6月初,美国联邦调查局(FBI)参加了一项多国联合打击的商务电子邮件攻击的清除活动,这次活动在美国,尼日利亚,加拿大,毛里求斯和波兰攻逮捕了74人。早在2016年,美国网络犯罪投诉中心(Internet Crime Complaint Center,IC3)就做了一个统计,由BEC造成的损失大约为31亿美元,并预计到2018年,由此造成的损失将超过90亿美元。2018年5月,加纳警方的情报组逮捕了42名尼日利亚人和两名加纳人,原因就是与BEC活动有关。当然,绝大多数BEC事件得到了必要的惩罚,比如逮捕和定罪,因为阻碍执法结果的很大一个原因就是,执法人员对对电子邮件的攻击行为无法进行准确的调查取证。
不过最近在网络安全初创公司CrowdStrike针对BEC进行调查的过程中,他们在Office 365中发现了一项功能,可以检索Outlook邮箱活动日志,这些日志远远超过现有的已记录的Office 365日志源提供的统一审计日志。此功能可以对所有用户默认活动的邮箱活动记录系统进行访问,本文就详细介绍了CrowdStrike关于Office 365的日志功能。
Office 365的Web API功能
此功能由使用Exchange Web Services (EWS)检索Office 365 Outlook邮箱活动的Web API组成,任何知道API端点和特定HTTP标头的人都可以访问该API,且所有用户的活动都可以被记录下来并被保留六个月。记录的范围非常广,包含许多活动类型,比如登录,邮件传递,邮件阅读和邮箱搜索,另外你也可以获取特定时间范围和活动类型的邮箱活动。 不过,Web API有一些缺点,例如明显无法将活动直接链接到客户端会话。尽管如此,在大多数情况下,API仍然提供足够的调查细节,以便执法人员快速识别攻击者的活动。
注:目前,CrowdStrike已经发布了一个Python模块,该模块包含了Activities API的基本功能,有关Python模块的完整信息,请参阅下面的Python模块部分。
诸如尼日利亚帮会等组织所实施的电子邮件入侵,经常会用到相同的技术和手法,这种情况下的攻击行为,Office 365是很容易发现的。最初的电子邮件入侵途径通常包含网络钓鱼电子邮件,这些邮件中包含凭证窃取程序的链接,这些链接要么是对受害者进行重定向,要么是利用键盘记录程序捕获凭证。盗取凭证后,这些攻击者使用被盗的凭证登录到受害者的邮箱,并通过发出搜索查询命令和阅读电子邮件来开始收集情报。攻击者通常会从这些信息中,判断哪些人是高管,哪些业务与金融交易有关,一旦确认了攻击目标,攻击者就会开始监控,时间长达数周甚至数月。
一旦攻击者摸清了邮件的运作规律,他们会将自己伪装成交流的另一方进行欺诈。通常情况下,他们都会要求受骗方先汇款到某个账户上,不过一开始金额较小,如果受害者没有起疑,则金额不断增大。CrowdStrike发现,这些诈骗金额从数千美元到高达1500万美元都有。当然以上只是BEC诈骗的方法之一,还有其他方式,例如针对公司的人员工资单做文章,将一份假的工资名单发给会计部门;对个人退休金账户以及医疗储蓄账户做文章。正如你将看到的,通过分析从这个强大的Office 365 API返回的数据,研究人员可以发现这些攻击者使用的技术、策略和过程(TTPs)。
访问API
在Outlook REST API中,有一个没有记录的的API子集,研究人员将它称为“Activities”。目前Outlook REST API的三个版本(v1.0,v2.0和beta)中,都包含有API子集。本文主要关注v2.0的是API子集在Outlook REST API 2.0版本中的实现。与其他子集一样,对Activities API的调用必须使用受支持的方法进行身份验证,比如OAuth 2.0或基本身份验证(Basic Authentication)。
请注意,微软已决定从2018年11月1日起,不再支持Outlook REST API中的基本身份验证。
如果你打算使用OAuth 2.0进行身份验证,则可以使用任何版本的Outlook REST API访问Activities API。本文中的所有示例均在以下端点使用Outlook REST API v2.0:
https://outlook.office.com/api/v2.0/{user_context}/Activities
如果你打算使用基本身份验证方法进行身份验证,则可以在以下端点使用Outlook REST API v1.0访问API:
https://outlook.office365.com/api/v1.0/{user_context}/Activities
对Activities API的所有请求均通过HTTP GET方法发出,并且必须包含以下HTTP标头。未经此标头发送的请求将导致HTTP 400错误请求响应。
Prefer: exchange.behavior=”ActivityAccess”
对Activities API的所有请求都必须包含授权标头,不包含有效凭证的请求将导致HTTP 403未经授权的响应。
对于OAuth 2.0来说,请使用Bearer认证。
Authorization: Bearer <access token>
Bearer认证,其核心便是BEARER_TOKEN,而最流行的Token编码方式便是:JSON WEB TOKEN。Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准(RFC 7519)。该令牌被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该令牌也可直接被用于认证,也可被加密。
出于测试目的,你可以在Outlook开发人员中心的OAuth沙箱中生成OAuth 2.0访问令牌。然后使用有效的Office 365凭据授权应用,继续获取令牌。你可以使用获取的访问令牌并使用下面的示例。 请注意,此访问令牌的有效期将为60分钟。请注意,Activities API操作的最低要求范围(minimum required scope)为https://outlook.office.com/Mail.Read。
如果你使用的是基本身份验证,请按照基本方案提供base64编码的用户名和密码。
Authorization: Basic <encoded username:password>
注意,对于基本的身份验证,如果所调用的用户启用了多因素身份验证,则需要生成并提供一个应用密码来替代帐户密码。
建议包含带有MIME类型的application / json和odata.metadata格式参数的Accept标头,本文中讨论的所有示例使用的都是以下标题。
Accept: application/json; odata.metadata=none
最后,应该注意的是,Activities API受制于对Outlook REST API中所有其他子集的请求响应限制。在撰写本文时,该限制包括每个应用的每个目标用户的每10分钟窗口的10000个请求许可。超过此限制的发出请求将导致HTTP 429的请求响应过多,你可以解析这些响应的标题,以检索有关限制状态的附加信息。
检索方法
对Activities API的最简单调用不包含参数,并使用“me”用户上下文快捷方式,下面的请求将返回一个响应,该响应包含调用用户的最近10个邮箱活动。
GET https://outlook.office.com/api/v2.0/me/Activities
这个请求可以使用curl来发布,如以下看到的使OAuth 2.0的情况。
curl -H ‘Prefer: exchange.behavior=”ActivityAccess”‘ -H ‘Authorization: Bearer <access token>’ -H ‘Accept: application/json; odata.metadata=none’ https://outlook.office.com/api/v2.0/me/Activities
在基本身份验证的1.0版本中,情况如下所示。
curl -H ‘Prefer: exchange.behavior=”ActivityAccess”‘ -H ‘Accept: application/json; odata.metadata=none’ -u <username> https://outlook.office365.com/api/v1.0/me/Activities
也可以通过使用Outlook开发人员中心 – OAuth沙箱中的“编辑查询”功能来发出此请求。如果使用此方法,请确保提供适当的标题。
以下是来自API的示例JSON响应,注意并非所有属性均显示在这里。
{ “value”: [ { “Id”:”WOGVSAiPKrfJ4apAPcBksT2en7whzDz4NIbUs3==”, “ActivityCreationTime”:”2010-04-01T12:34:56.789Z”, “ActivityIdType”:”ReadingPaneDisplayStart”, “AppIdType”:”Outlook”, “ClientVersion”:”15.00.0000.000″, “ClientSessionId”:”679126f3-02de-3513-e336-0eac1294b120″, “ActivityItemId”:”NjKG5m6OmaCjGKq6WlbjIzvp94czUDg30qGopD==”, “TimeStamp”:”2010-04-01T12:34:56.789Z”, “TenantId”:”679126f3-02de-3513-e336-0eac1294b120″, } ] }
鉴于此API可以在事件响应中发挥的作用,执法人员通常会希望检索到那些不属于调用用户的邮箱活动。幸运的是,Activities API只允许指定的目标用户来使用该功能,如果要为其他用户检索邮箱活动,就必须修改用户的上下文,如下所示。
GET https://outlook.office.com/api/v2.0/Users(‘[email protected]’)/Activities
可以通过以下两种方式之一获取为其他用户提供检索邮箱活动所需的权限:
1.共享邮箱权限方法;
2.共享应用权限方法;
共享邮箱的方法
使用此方法,执行查询的应用应配置为请求Mail.Read.Shared授权的用户权限。如果你正在使用基本身份验证,则不需要此操作。此外,应该授予调用用户对目标邮箱的完全访问权限。通过为所需用户分配“读取和管理”权限或连接到Exchange Online并运行以下PowerShell cmdlet,就可以在Office 365管理中心应用此权限。
Add-MailboxPermission -Identity [email protected] -User [email protected] -AccessRights FullAccess -InheritanceType All -AutoMapping:$false
此方法将与使用OAuth沙箱获取的令牌一起使用,因为沙箱应用在请求的作用域列表中包含Mail.ReadWrite.Shared,该范围是读取共享邮箱所需的最小范围的超集。
注意:权限分配的结果不会马上出现,可能需要几分钟甚至几小时才能使权限更改生效。当提供有效凭据,但却没有对目标邮箱分配足够权限时,API可能会返回一个HTTP 404 Not Found的响应,并显示错误消息“在存储中找不到指定的对象,默认文件夹ActivityLogs找不到”。如果在正确授予完全访问权限后返回此错误,你可能需要等一段时间才能让权限更改生效。
共享应用权限的方法
使用此方法,执行查询的应用应配置为请求Mail.Read应用权限。如果全局管理员要同意此请求,则无需修改邮箱权限就可以检索其中所有用户的活动。请注意,OAuth 沙箱不能与此方法结合使用。因为采用这种方法是需要开发一个Web应用的,实现受支持的OAuth流程,并向管理员请求是否同意。
请求参数
Activities API支持以下请求参数,参数说明如下:
1.$orderby-通过指定的表达式对结果进行排序;
2.$filter-按时间戳或活动类型筛选结果;
3.$select-选择要返回的属性列表;
4.top-指定要返回的最大活动数;
5.$skip-指定要在返回的结果中跳过的活动数量
API返回的结果顺序标准并不总是一致的,通常情况下,都是按时间戳的排序来排序的,但是某些$filter表达式可以更改该行为。为了保证返回结果的顺序,就必须使用$orderby参数指定属性名和排序顺序,例如,发出以下查询命令,就可以以时间戳安排返回结果(最早的结果优先)。
GET https://outlook.office.com/api/v2.0/Users('[email protected]')/Activities?$orderby=TimeStamp+asc
注意:对于$orderby和$filter参数的同时使用,目前还是有一些限制的。https://dev.office.com/blogs/update-to-filtering-and-sorting-rest-api
$filter参数允许提供一个表达式,该表达式会将结果限制为一系列时间戳或活动类型列表。例如,为了请求在2018年1月发生的活动,你可以发出以下查询命令。
GET https://outlook.office.com/api/v2.0/Users('[email protected]')/Activities?$filter=(TimeStamp ge 2018-01-01T00:00:00Z and TimeStamp le 2018-01-31T23:59:59Z)
时间戳以ISO 8601格式(2018-01-01T00:00:00Z)为准。
默认情况下,在默认属性集中,API将返回每个活动类型的所有属性。可以使用$select参数指定要返回的属性子集,例如,要仅为每个活动返回TimeStamp和ActivityIdType属性,请发出以下查询。
GET https://outlook.office.com/api/v2.0/Users('[email protected]')/Activities?$select=TimeStamp,ActivityIdType
如果没有指定$top值,则API将返回最多10个活动。要更改默认行为,请在1到1000的范围内指定$top值,不过Activities API每次请求不会返回超过1000个结果。例如,要检索邮箱中最近发生的500个活动,请发出以下查询命令。
GET https://outlook.office.com/api/v2.0/Users('[email protected]')/Activities?$top=500
该API还支持分页查询结果,如果特定查询所生成的结果数超过$top值指定的结果数,需要发出多个请求才能检索完整个集。构建连续请求时,必须跳过先前请求中已检索的活动数量。这可以通过设置$skip参数的值来完成,如下面的第二个和第三个请求所示。
第一次请求:
GET https://outlook.office.com/api/v2.0/Users('[email protected]')/Activities?$top=1000
第二个请求:
GET https://outlook.office.com/api/v2.0/Users('[email protected]')/Activities?$top=1000&$skip=1000
第三个要求:
GET https://outlook.office.com/api/v2.0/Users('[email protected]')/Activities?$top=1000&$skip=2000
下一篇文章中,我将介绍检索过程中所用到的一些标准属性、活动类型。