0x00 Preface

---

For Exchange user mailboxes, hidden folders can be created by setting folder properties. Users cannot view the contents of hidden folders when logging in via OWA web pages or using Outlook.

From a penetration testing perspective, we can utilize hidden folders to store important information, serving as a data channel for C2 communication.

This article will introduce the usage of hidden folders, implement the creation, access, and deletion of hidden folders through programs, and provide defense recommendations based on exploitation ideas.

0x01 Introduction

---

This article will cover the following topics:

  • Principles of creating hidden folders
  • Common operations for hidden folders
  • Implementation code using EWS Managed API
  • Implementation code using EWS SOAP XML messages
  • Open-source code
  • Defense and detection

0x02 Principles of Creating Hidden Folders

---

References:

https://docs.microsoft.com/en-us/exchange/client-developer/exchange-web-services/how-to-work-with-hidden-folders-by-using-ews-in-exchange

For Exchange user mailboxes, when the extended property PidTagAttributeHidden (0x10F4000B) of a folder is set to true, the folder becomes invisible to the user.

By default, an Exchange user mailbox includes several common folders, such as Inbox, Outbox, and Drafts. For a detailed list, refer to: https://docs.microsoft.com/en-us/dotnet/api/microsoft.exchange.webservices.data.wellknownfoldername?view=exchange-ews-api#Microsoft_Exchange_WebServices_Data_WellKnownFolderName_MsgFolderRoot

We can create a folder under the root directory or any folder (e.g., Inbox), set its extended property PidTagAttributeHidden (0x10F4000B) to true, making it a hidden folder that is invisible to the user. Additionally, all emails within the hidden folder are also invisible to the user. Furthermore, the content of emails and attachments within the hidden folder remains invisible to the user. However, as long as we know the ID of the hidden folder, we can interact with the data programmatically.

When interacting with data programmatically, the following operations need to be considered:

(Here, taking the creation of a hidden folder under Inbox as an example)

  • Create a folder under Inbox
  • View the list of folders under Inbox
  • Create a hidden folder under Inbox
  • View the list of hidden folders under Inbox
  • View the list of emails under a specified folder (regardless of hidden attribute)
  • Create an email under a specified folder (regardless of hidden attribute)
  • Delete specified folder
  • Add attachment to specified email

0x03 Implementation code using EWS Managed API

---

1. Create folder under Inbox

private static void CreateFolderofInbox(ExchangeService service)
{
Folder folder = new Folder(service);
folder.DisplayName = "Custom Folder";
folder.Save(WellKnownFolderName.Inbox);
Console.WriteLine("[*] FolderId:" + folder.Id);
}

2. View folder list under Inbox

private static void ListFolderofInbox(ExchangeService service)
{
FindFoldersResults findResults = null;
FolderView view = new FolderView(int.MaxValue) { Traversal = FolderTraversal.Deep };
findResults = service.FindFolders(WellKnownFolderName.Inbox, view);
foreach (Folder folder in findResults.Folders)
{
Console.WriteLine("\r\n");
Console.WriteLine("[*]DisplayName:{0}", folder.DisplayName);
Console.WriteLine("[*]Id:{0}", folder.Id);
Console.WriteLine("[*]TotalCount:{0}", folder.TotalCount);
}
}

3. Create hidden folder under Inbox

private static void CreateHiddenFolderofInbox(ExchangeService service)
{
Folder folder = new Folder(service);
folder.DisplayName = "Custom Hidden Folder";
folder.Save(WellKnownFolderName.Inbox);
Console.WriteLine("[*] Hidden FolderId:" + folder.Id);

// Create an extended property definition for the PidTagAttributeHidden property.
ExtendedPropertyDefinition isHiddenProp = new ExtendedPropertyDefinition(0x10f4, MapiPropertyType.Boolean);
PropertySet propSet = new PropertySet(isHiddenProp);
// Bind to a folder and retrieve the PidTagAttributeHidden property.
Folder folderhidden = Folder.Bind(service, folder.Id, propSet);
// Set the PidTagAttributeHidden property to true.
folderhidden.SetExtendedProperty(isHiddenProp, true);
// Save the changes.
folderhidden.Update();
}

4. View hidden folder list under Inbox

private static void ListHiddenFolderofInbox(ExchangeService service)
{
// Create an extended property definition for the PidTagAttributeHidden property.
ExtendedPropertyDefinition isHiddenProp = new ExtendedPropertyDefinition(0x10f4, MapiPropertyType.Boolean);
// Create a folder view to retrieve up to 100 folders and
// retrieve only the PidTagAttributeHidden and the display name.
FolderView folderView = new FolderView(100);
folderView.PropertySet = new PropertySet(isHiddenProp, FolderSchema.DisplayName);
// Indicate a Traversal value of Deep, so that all subfolders are retrieved.
folderView.Traversal = FolderTraversal.Deep;
// Find all hidden folders under the MsgFolderRoot.
// This call results in a FindFolder call to EWS.
FindFoldersResults findFolder = service.FindFolders(WellKnownFolderName.Inbox,
new SearchFilter.IsEqualTo(isHiddenProp, true), folderView);
// Display the folder ID and display name of each hidden folder.
foreach (Folder folder in findFolder)
{
Console.WriteLine("[*] DisplayName: {0}", folder.DisplayName);
Console.WriteLine("[*] FolderId: {0}", folder.Id);
Console.WriteLine("\r\n");
}
}

5. View email list in specified folder (regardless of hidden attributes)

private static void ListMailofFolder(FolderId folderId, ExchangeService service)
{
IdString = folderId;
Folder Folders = Folder.Bind(service, IdString);
FindItemsResults findResults = null;
ItemView view = new ItemView(int.MaxValue);
PropertySet itempropertyset = new PropertySet(BasePropertySet.FirstClassProperties);
itempropertyset.RequestedBodyType = BodyType.Text;
view.PropertySet = itempropertyset;
findResults = Folders.FindItems(view);
foreach (Item item in findResults.Items)
{
Console.WriteLine("\r\n");
if (item.Subject != null)
{
Console.WriteLine("[*]Subject:{0}", item.Subject);
}
else
{
Console.WriteLine("[*]Subject:");
}

Console.WriteLine("[*]HasAttachments:{0}", item.HasAttachments);
if (item.HasAttachments)
{
EmailMessage message = EmailMessage.Bind(service, item.Id, new PropertySet(ItemSchema.Attachments));
foreach (Attachment attachment in message.Attachments)
{
FileAttachment fileAttachment = attachment as FileAttachment;
fileAttachment.Load();
Console.WriteLine(" - Attachments:{0}", fileAttachment.Name);
}
}
Console.WriteLine("[*]ItemId:{0}", item.Id);
Console.WriteLine("[*]DateTimeCreated:{0}", item.DateTimeCreated);
Console.WriteLine("[*]DateTimeReceived:{0}", item.DateTimeReceived);
Console.WriteLine("[*]DateTimeSent:{0}", item.DateTimeSent);
Console.WriteLine("[*]DisplayCc:{0}", item.DisplayCc);
Console.WriteLine("[*]DisplayTo:{0}", item.DisplayTo);
Console.WriteLine("[*]InReplyTo:{0}", item.InReplyTo);
Console.WriteLine("[*]Size:{0}", item.Size);
item.Load(itempropertyset);
if (item.Body.ToString().Length > 100)
{
item.Body = item.Body.ToString().Substring(0, 100);
Console.WriteLine("[*]MessageBody(too big,only output 100):{0}", item.Body);
}
else
{
Console.WriteLine("[*]MessageBody:{0}", item.Body);
}
}
}

6. Create an email in the specified folder (regardless of hidden attributes)

private static void CreateMail(FolderId folderId, ExchangeService service)
{
EmailMessage msg = new EmailMessage(service);
msg.Subject = "test mail";
msg.Save(folderId);
}

7. Add attachments to specified emails

private static void AddFileAttachment(ItemId id, string fileName, ExchangeService service)
{
EmailMessage message = EmailMessage.Bind(service, id);
message.Attachments.AddFileAttachment(fileName);
message.Update(ConflictResolutionMode.AlwaysOverwrite);
Console.WriteLine("\r\n[+]AddAttachment success");
}

8. Delete specified folder

EWS Managed API does not support direct deletion; it requires constructing SOAP packets in XML format

0x04 Implementation code using EWS SOAP XML messages

---

To save space, only the content within is introduced

1. Create a folder under Inbox







{name}


2. View the folder list under Inbox



AllProperties





3. Create a hidden folder under Inbox

Three data packets need to be sent here, in order: create folder, add hidden attribute, and update hidden attribute

Create folder:







{name}


Add hidden attribute:



IdOnly







Update hidden property:











true






4. View the list of hidden folders under Inbox



IdOnly

















5. View the list of emails in the specified folder (regardless of hidden attributes)



AllProperties
Text





6. Create an email in the specified folder (regardless of hidden attributes)







test mail


7. Add attachments to the specified email





{name}
{data}


8. Delete specified folder





0x05 Open source code

---

1. Using EWS Managed API

An open source project

Usage example

(1) Create hidden folder test1 under Inbox

ewsManage.exe -CerValidation No -ExchangeVersion Exchange2013_SP1 -u test1 -p test123! -ewsPath https://test.com/ews/Exchange.asmx -Mode CreateHiddenFolderofInbox -Name test1

Obtain the FolderId corresponding to the folder: AAMkADc4YjRlNDc1LWI0YjctNDEzZi1hNTQ5LWZkYWY0ZGZhZDM0NgAuAAAAAABEBlGH6URWQp6Nlg9RxLmyAQA1ZCfAg9a0Sq75no2JOzsqAAAAA1FUAAA=

(2) View hidden folders under Inbox

ewsManage.exe -CerValidation No -ExchangeVersion Exchange2013_SP1 -u test1 -p test123! -ewsPath https://test.com/ews/Exchange.asmx -Mode ListHiddenFolder -Folder Inbox

(3) Create a test email in the hidden folder test1

ewsManage.exe -CerValidation No -ExchangeVersion Exchange2013_SP1 -u test1 -p test123! -ewsPath https://test.com/ews/Exchange.asmx -Mode CreateTestMail -Id AAMkADc4YjRlNDc1LWI0YjctNDEzZi1hNTQ5LWZkYWY0ZGZhZDM0NgAuAAAAAABEBlGH6URWQp6Nlg9RxLmyAQA1ZCfAg9a0Sq75no2JOzsqAAAAA1FUAAA=

(4) View all emails in the hidden folder test1

ewsManage.exe -CerValidation No -ExchangeVersion Exchange2013_SP1 -u test1 -p test123! -ewsPath https://test.com/ews/Exchange.asmx -Mode ListMailofFolder -Id AAMkADc4YjRlNDc1LWI0YjctNDEzZi1hNTQ5LWZkYWY0ZGZhZDM0NgAuAAAAAABEBlGH6URWQp6Nlg9RxLmyAQA1ZCfAg9a0Sq75no2JOzsqAAAAA1FUAAA=

Obtain the ItemId corresponding to the test email: AAMkADc4YjRlNDc1LWI0YjctNDEzZi1hNTQ5LWZkYWY0ZGZhZDM0NgBGAAAAAABEBlGH6URWQp6Nlg9RxLmyBwA1ZCfAg9a0Sq75no2JOzsqAAAAA1FUAAA1ZCfAg9a0Sq75no2JOzsqAAAAA1FVAAA=

(5) Add an attachment to the test email

ewsManage.exe -CerValidation No -ExchangeVersion Exchange2013_SP1 -u test1 -p test123! -ewsPath https://test.com/ews/Exchange.asmx -Mode AddAttachment -Id AAMkADc4YjRlNDc1LWI0YjctNDEzZi1hNTQ5LWZkYWY0ZGZhZDM0NgAuAAAAAABEBlGH6URWQp6Nlg9RxLmyAQA1ZCfAg9a0Sq75no2JOzsqAAAAA1FUAAA= -AttachmentFile c:\test\1.exe

(6) Read the content of the test email

ewsManage.exe -CerValidation No -ExchangeVersion Exchange2013_SP1 -u test1 -p test123! -ewsPath https://test.com/ews/Exchange.asmx -Mode ViewMail -Id AAMkADc4YjRlNDc1LWI0YjctNDEzZi1hNTQ5LWZkYWY0ZGZhZDM0NgAuAAAAAABEBlGH6URWQp6Nlg9RxLmyAQA1ZCfAg9a0Sq75no2JOzsqAAAAA1FUAAA=

(7) Save attachments from the test email

ewsManage.exe -CerValidation No -ExchangeVersion Exchange2013_SP1 -u test1 -p test123! -ewsPath https://test.com/ews/Exchange.asmx -Mode SaveAttachment -Id AAMkADc4YjRlNDc1LWI0YjctNDEzZi1hNTQ5LWZkYWY0ZGZhZDM0NgAuAAAAAABEBlGH6URWQp6Nlg9RxLmyAQA1ZCfAg9a0Sq75no2JOzsqAAAAA1FUAAA=

(8) Delete test email

ewsManage.exe -CerValidation No -ExchangeVersion Exchange2013_SP1 -u test1 -p test123! -ewsPath https://test.com/ews/Exchange.asmx -Mode DeleteMail -Id AAMkADc4YjRlNDc1LWI0YjctNDEzZi1hNTQ5LWZkYWY0ZGZhZDM0NgAuAAAAAABEBlGH6URWQp6Nlg9RxLmyAQA1ZCfAg9a0Sq75no2JOzsqAAAAA1FUAAA=

2. Using EWS SOAP XML message

An open-source project

(1) Create hidden folder test2 under Inbox

Create folder:

ewsManage.py 192.168.1.1 443 plaintext test.com user1 password1 createfolderofinbox

Obtain Id: AAMkADc4YjRlNDc1LWI0YjctNDEzZi1hNTQ5LWZkYWY0ZGZhZDM0NgAuAAAAAABEBlGH6URWQp6Nlg9RxLmyAQA1ZCfAg9a0Sq75no2JOzsqAAAAA1U+AAA=, ChangeKey: AQAAABYAAAA1ZCfAg9a0Sq75no2JOzsqAAAAAGE/

Add hidden property:

ewsManage.py 192.168.1.1 443 plaintext test.com user1 password1 SetHiddenPropertyType

Update hidden property:

ewsManage.py 192.168.1.1 443 plaintext test.com user1 password1 UpdateHiddenPropertyType

(2) View hidden folders under Inbox

ewsManage.py 192.168.1.1 443 plaintext test.com user1 password1 listhiddenfolderofinbox

(3) Create test email under hidden folder test1

ewsManage.py 192.168.1.1 443 plaintext test.com user1 password1 createtestmail

(4) View all emails in hidden folder test1

ewsManage.py 192.168.1.1 443 plaintext test.com user1 password1 listmailoffolder

(5) Add attachment to test email

ewsManage.py 192.168.1.1 443 plaintext test.com user1 password1 createattachment

(6) Read test email content

ewsManage.py 192.168.1.1 443 plaintext test.com user1 password1 getmail

(7) Save attachments from test email

Obtain attachment ID:

ewsManage.py 192.168.1.1 443 plaintext test.com user1 password1 getattachment

Save attachment:

ewsManage.py 192.168.1.1 443 plaintext test.com user1 password1 saveattachment

(8) Delete test email

ewsManage.py 192.168.1.1 443 plaintext test.com user1 password1 deletemail

(9) Delete hidden folder test1 for test email

ewsManage.py 192.168.1.1 443 plaintext test.com user1 password1 deletefolder

0x06 Defense Detection

---

1. Check for hidden folders via program

For example:

ewsManage.exe -CerValidation No -ExchangeVersion Exchange2013_SP1 -u test1 -p test123! -ewsPath https://test.com/ews/Exchange.asmx -Mode ListHiddenFolder -Folder Inbox

ewsManage.py 192.168.1.1 443 plaintext test.com user1 password1 listhiddenfolderofinbox

2. Check the last login time of email users

Using Exchange Server PowerShell:

Get-MailboxDatabase | Get-MailboxStatistics |fl DisplayName,LastLogonTime

3. Check EWS access logs

Default location: C:\inetpub\logs\LogFiles\W3SVC1, search for keyword /EWS/Exchange.asmx

0x07 Summary

---

This article introduces the usage of hidden folders in Exchange user mailboxes, detailing methods for creating, accessing, and deleting hidden folders using EWS Managed API and EWS SOAP XML messages, along with the open-source tools ewsManage and ewsManage.py, and provides defense recommendations based on exploitation techniques.