Good in study, attitude and health

Exchange Web Service(EWS)开发指南4——Auto Downloader

0x00 前言


我在之前的文章《Exchange Web Service(EWS)开发指南》《Exchange Web Service(EWS)开发指南2——SOAP XML message》详细介绍了通过SOAP XML message实现利用hash对Exchange资源的访问。

因为是较为底层的通信协议,在功能实现上相对繁琐,例如下载邮件附件的操作,需要依次完成以下操作:

  • 读取文件夹信息,获得邮件对应的ItemId和ChangeKey
  • 读取邮件信息,获得附件的ItemId
  • 通过附件的ItemId获得每个附件对应的AttachmentId
  • 通过AttachmentId下载邮件内容,将内容作Base64解码得到实际内容

如果想要完全自动化实现下载邮件和提取附件,原有的ewsManage.py需要作一些改动

因此,本文将要介绍自动化下载邮件和提取附件的实现细节,开源代码ewsManage_Downloader。

0x01 简介


本文将要介绍以下内容:

  • 设计思路
  • 开发细节
  • 开源代码

0x02 设计思路


ewsManage_Downloader需要满足以下功能:

  • 支持明文和NTLM Hash的登录
  • 支持关键词搜索
  • 支持日期搜索
  • 下载时可以指定下载数量
  • 能够自动下载邮件和提取附件

程序在通信过程中,每次SOAP XML message请求都需要完整的NTLM验证,无法借助Session机制简化登录流程

因此,原有的ewsManage.py代码结构需要重新设计,减少代码冗余。

0x03 开发细节


1.修复登录用户Domain参数的bug

原有的ewsManage.py,需要指定登录用户的Domain作为参数

例如登录用户为test.com\administrator,Domain参数需要设置为test.com

但是,如果登录用户为administrator,那么无法指定Domain参数

这是我之前在使用NTLM认证时没有考虑到的一个地方,解决方法如下:

添加参数判断,如果Domain参数为NULL,那么在NTML认证时不指定Domian参数

代码示例:

    if domain == "NULL":
        ntlm_nego = ntlm.getNTLMSSPType1(host)
    else:    
        ntlm_nego = ntlm.getNTLMSSPType1(host, domain)

2.支持关键词搜索

发送的SOAP格式:

?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Header>
    <t:RequestServerVersion Version="Exchange2013_SP1" />
  </soap:Header>
  <soap:Body>
    <m:FindItem Traversal='Shallow'>
      <m:ItemShape>
        <t:BaseShape>AllProperties</t:BaseShape>
      </m:ItemShape>
      <m:ParentFolderIds>
        <t:DistinguishedFolderId Id='{folderpath}'>
        </t:DistinguishedFolderId>
      </m:ParentFolderIds>
      <m:QueryString>{querystring}</m:QueryString>
    </m:FindItem>
  </soap:Body>
</soap:Envelope>

其中{querystring}为搜索的关键词,返回结果为带有指定关键词邮件对应的ItemId和ChangeKey

3.支持日期搜索

发送的SOAP格式同上,区别是{querystring}不同

参考资料1:

https://docs.microsoft.com/en-us/windows/win32/lwef/-search-2x-wds-aqsreference?redirectedfrom=MSDN

参考资料1中的时间格式为MM/DD/YY,示例如下:

2021年3月1日对应的格式为03/01/21

但是经过实际测试,{querystring}中关于时间的语法不能按照参考资料1的格式

参考资料2:

https://support.microsoft.com/en-us/office/learn-to-narrow-your-search-criteria-for-better-searches-in-outlook-d824d1e9-a255-4c8a-8553-276fb895a8da?ocmsassetid=ha010238831&correlationid=bf4cdcf9-abb8-4d43-930e-d0909de76728&ui=en-us&rs=en-us&ad=us

参考资料2中的时间格式为Year/Month/Day,示例如下:

2021年3月1日对应的格式为2021/3/1

在时间格式上面,正确的语法为参考资料2

综上,筛选出发送时间为2021年1月1日至2021年12月30日的参数如下:

sent:>=2021/1/1 AND sent:<=2021/12/30

筛选出接收时间为2021年1月1日至2021年12月30日的参数如下:

received:>=2021/1/1 AND received:<=2021/12/30

4.支持长度搜索

正常情况下,筛选出长度小于2000的参数为:size:<2000

但是需要考虑XML格式转义,实际的参数内容为:size:&lt;2000

0x04 开源代码


完整代码已上传至github,地址如下:

https://github.com/3gstudent/Homework-of-Python/blob/master/ewsManage_Downloader.py

支持明文和NTLM Hash的登录,代码支持以下功能:

  • download,下载邮件并提取附件,可指定邮箱文件夹和下载数量
  • findallpeople,导出联系人列表
  • search,邮件搜索并下载,支持关键词、时间、长度等语法

在下载邮件时,以邮件用户名作为父文件夹,不同操作会创建不同的子文件夹,在使用搜索功能创建子文件夹时,为了避免特殊字符(例如字符>)无法作为文件夹名称,这里会去掉特殊字符

0x05 小结


本文介绍了自动化下载邮件和提取附件的开发细节,开源代码ewsManage_Downloader.py,实现了利用hash对Exchange资源的访问。

由于采用了较为底层的通信协议,在功能实现上相对繁琐,但是有助于理解通信协议原理和漏洞利用。


LEAVE A REPLY