A toolset for Office 365 content acquisition

In recent incident response investigations Northwave has experienced an increasing number of companies which use Office 365 as their e-mail environment. From a company’s point of view, Office 365 brings great improvements to end users, including ease of maintenance, high availability and collaboration. From the perspective of a forensic investigator however, cloud services such as Office 365 have their challenges when it comes to acquiring contents.

An obvious place to look for e-mail contents is by to use the Microsoft eDiscovery portal within Office365. The eDiscovery portal contains an easy-to-use frontend to perform search queries within Office365 environments. Although this suits most cases, there are some drawbacks, such as licensing requirements, search query adaptability and lead time of some search queries.

As an alternative to Microsoft eDiscovery, Northwave has developed a simple, low-level toolset to acquire contents from Office 365 in a targeted way. By speaking directly to the Office365 API, the toolset is able to acquire specific e-mail contents using pre/post-filtering. The toolset allows Office365 contents to be collected in an efficient way and can be easily adapted to new use cases.

In this blogpost we introduce the toolset by showing its building blocks and by explaining its use in Office 365 investigations. We start by showing how to prepare the toolset for acquisition by setting up an App Registration in Office 365. After that, we show how the toolset can be used by looking at different examples with varying options.

Office 365 API

The toolset developed by Northwave is programmed in Python and uses the Python Office 365 library python-o365, which provides communication with the Microsoft Graph API and the (now deprecated) Office 365 Rest API. In order to use the API’s within Office 365 for content acquisition, a custom App Registration must be setup first within the Office 365 Azure Active Directory. These App Registrations allow a third-party application (in this case the acquisition toolset) to communicate with the Office 365 API.

Setting up an App Registration

First of all, we need to enter the Azure Active Directory portal in order to create our custom App Registration. The App Registration section can be directory found within the main menu.

New App Registrations can be given an arbitrary name and are identified by a Tenant ID and a Client ID (shown below). At creation, a Client Secret (not shown below) is generated for the App Registration and is used for authentication.

For acquiring Office 365 contents, the App Registration requires the following API permissions:

Note that every API permission is either “delegated” or “application”. Choosing the option “delegated” is light-mode and means that in order to acquire contents from Office 365 accounts, every user has to give his consent by logging in. If the option “application” is chosen, it means that no user interaction is required to acquire contents from Office 365 accounts. The acquisition tools developed by Northwave support both types API permissions.

For more details on how to set up the App Registration within an Office 365 tenant, check the HOWTO page on the public repository on Github ( https://github.com/NorthwaveSecurity/o365-collect/blob/master/docs/HOWTO.md)

Acquiring contents

After having set up the App Registration, we can start acquiring contents. Using the obtained Tenant ID, Client ID and Client Secret from the App Registration, we can instruct the toolset to perform a customizable acquisition.

First, in its simplest form, all contacts within an Office 365 tenant can be acquired using the following snippet:

o365-acquire-contacts.py \
-t 815099a1-e306-4dd8-a3c1-6698a1e05d43 \
-i 9a181509-06e3-dd84-1a3c-8a1e05d43669 \
-s 'oy:[email protected]:[email protected]' > o365-contacts.txt

After having acquired the full contact list in a file called o365-contacts.txt, e-mail contents these contacts can be acquired in EML files using the following snippet:

o365-acquire-mail.py \
-t 815099a1-e306-4dd8-a3c1-6698a1e05d43 \
-i 9a181509-06e3-dd84-1a3c-8a1e05d43669 \
-s 'oy:[email protected]:[email protected]' \
-f o365-contacts.txt \
-o /path/to/output/dir

The above command will automatically create directories for each user in o365-contacts.txt and will store acquired e-mail contents in EML format in the directory /path/to/output/dir. Note that this command acquires full mailboxes for every user listed in o365-contacts.txt, which may be unnecessary and may cause overhead.

In order to perform a more targeted search, a couple of search filters can be supplied, which will in turn be passed to the Office 365 API. An example of a command supplying these filters is shown below:

o365-acquire-mail.py \
-t 815099a1-e306-4dd8-a3c1-6698a1e05d43 \
-i 9a181509-06e3-dd84-1a3c-8a1e05d43669 \
-s 'oy:[email protected]:[email protected]' \
-f o365-contacts.txt \
-o /path/to/output/dir \
-ha \
-df 2020-04-01 \
-dt 2020-04-30 \
-cs “malicious”

The above command stores e-mail contents similarly, but the search scope is limited to specific e-mail, i.e.:

  • e-mails that contain an attachments (-ha)
  • e-mails that were received in April 2020 (-df 2020-04-01 -dt 2020-04-30)
  • e-mails that contain the subject “malicious”


Northwave has developed two scripts that will help investigators to efficiently acquire e-mail contents from Office 365 environments. For suggestions or improvements regarding the toolset as well as more documentation, please refer to the public repository on Github: https://github.com/NorthwaveSecurity/o365-collect