0x00 Preface

---

In my previous articles "Exchange Web Service (EWS) Development Guide" and "Exchange Web Service (EWS) Development Guide 2 – SOAP XML Message", I detailed how to access Exchange resources using hash via SOAP XML messages.

Because it is a relatively low-level communication protocol, implementing functionality can be cumbersome. For example, to download email attachments, the following steps must be completed sequentially:

  • Read folder information to obtain the ItemId and ChangeKey corresponding to the email.
  • Read email information to obtain the ItemId of the attachment.
  • Use the attachment's ItemId to obtain the AttachmentId for each attachment.
  • Download the email content using the AttachmentId and decode the Base64 content to get the actual data.

To fully automate the process of downloading emails and extracting attachments, the original ewsManage.py requires some modifications.

Therefore, this article will introduce the implementation details for automating email downloads and attachment extraction, with the open-source code ewsManage_Downloader.

0x01 Introduction

---

This article will cover the following topics:

  • Design Approach
  • Development Details
  • Open Source Code

0x02 Design Approach

---

ewsManage_Downloader must meet the following requirements:

  • Support login with plaintext and NTLM Hash
  • Support keyword search
  • Support date-based search
  • Allow specifying the download quantity during download
  • Capable of automatically downloading emails and extracting attachments

During communication, each SOAP XML message request requires full NTLM authentication, preventing the use of session mechanisms to simplify the login process

Therefore, the original ewsManage.py code structure needs to be redesigned to reduce code redundancy.

0x03 Development Details

---

1. Fix the bug related to the Domain parameter for login users

The original ewsManage.py required specifying the Domain of the logged-in user as a parameter.

For example, if the logged-in user is test.com\administrator, the Domain parameter needs to be set to test.com.

However, if the logged-in user is administrator, then the Domain parameter cannot be specified.

This is an aspect I previously overlooked when using NTLM authentication. The solution is as follows:

Add parameter validation: if the Domain parameter is NULL, then do not specify the Domain parameter during NTLM authentication.

Code example:

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

2. Support keyword search

SOAP format to send:

?xml version="1.0" encoding="utf-8"?>







AllProperties





{querystring}


Where {querystring} is the search keyword, the returned results include the ItemId and ChangeKey of emails containing the specified keyword.

3. Supports date-based search

The SOAP format sent is the same as above, with the difference being the {querystring}.

Reference 1:

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

The date format in Reference 1 is MM/DD/YY, as shown in the example below:

The format corresponding to March 1, 2021 is 03/01/21

However, based on actual testing, the syntax for dates in {querystring} cannot follow the format in Reference 1.

Reference 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

The date format in Reference 2 is Year/Month/Day, as shown in the example below:

The format corresponding to March 1, 2021 is 2021/3/1

Regarding the date format, the correct syntax follows Reference 2.

In summary, the parameters for filtering emails sent between January 1, 2021, and December 30, 2021, are as follows:

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

Filter parameters with receipt time from January 1, 2021 to December 30, 2021 as follows:

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

4. Support length search

Normally, filter parameters with length less than 2000 as: size:<2000

But XML format escaping needs to be considered, the actual parameter content is: size:<2000

0x04 Open Source Code

---

Complete code has been uploaded to GitHub, address as follows:

An open source project

Supports login with plaintext and NTLM Hash, the code supports the following functions:

  • download, download emails and extract attachments, can specify mailbox folder and download quantity
  • findallpeople, export contact list
  • search, email search and download, supports syntax for keywords, time, length, etc.

When downloading emails, the email username is used as the parent folder, different operations create different subfolders. When creating subfolders using the search function, to avoid special characters (e.g., character >) that cannot be used as folder names, special characters are removed here

0x05 Summary

---

This article details the development of automated email downloading and attachment extraction, featuring the open-source code ewsManage_Downloader.py, which implements access to Exchange resources using hash.

Due to the use of lower-level communication protocols, the functional implementation is relatively cumbersome, but it aids in understanding communication protocol principles and vulnerability exploitation.