渗透基础——Exchange 用户邮箱中的隐藏文件夹

发布于 2025-01-09 10:38:59 字数 19925 浏览 3 评论 0

0x00 前言

对于 Exchange 用户邮箱,可通过设置文件夹属性创建隐藏文件夹,用户使用 owa 网页登录和使用 Outlook 均无法查看隐藏文件夹中的内容。

站在渗透测试的角度,我们可以利用隐藏文件夹存储重要的信息,作为 C2 通信的数据通道。

本文将要介绍隐藏文件夹的使用方法,通过程序实现创建、访问和删除隐藏文件夹,结合利用思路给出防御建议。

0x01 简介

本文将要介绍以下内容:

  • 隐藏文件夹的创建原理
  • 隐藏文件夹的常用操作
  • 使用 EWS Managed API 的实现代码
  • 使用 EWS SOAP XML message 的实现代码
  • 开源代码
  • 防御检测

0x02 隐藏文件夹的创建原理

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

对于 Exchange 用户邮箱,将文件夹的扩展属性 PidTagAttributeHidden (0x10F4000B) 设置为 true 时,该文件夹对于用户不可见

默认配置下,Exchange 用户邮箱包括多个常用文件夹,例如收件箱、发件箱和草稿等,详细列表可参考: https://docs.microsoft.com/en-us/dotnet/api/microsoft.exchange.webservices.data.wellknownfoldername?view=exchange-ews-api

我们可以在根目录或者任一文件夹(例如收件箱) 下创建一个文件夹,将其扩展属性 PidTagAttributeHidden (0x10F4000B) 设置为 true,那么这个文件夹就是隐藏文件夹,对于用户不可见。同时,隐藏文件夹下的所有邮件对用户也是不可见的。更进一步,隐藏文件夹下的邮件内容和附件内容对用户同样不可见。但是我们只要知道了隐藏文件夹的 Id,就能够通过程序进行数据交互。

通过程序进行数据交互时,需要考虑以下操作: (这里以在 Inbox 下创建隐藏文件夹为例)

  • 在 Inbox 下创建文件夹
  • 查看 Inbox 下的文件夹列表
  • 在 Inbox 下创建隐藏文件夹
  • 查看 Inbox 下的隐藏文件夹列表
  • 查看指定文件夹(无论是否具有隐藏属性) 下的邮件列表
  • 在指定文件夹(无论是否具有隐藏属性) 下创建邮件
  • 删除指定文件夹
  • 为指定邮件添加附件

0x03 使用 EWS Managed API 的实现代码

1.在 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.查看 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.在 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.查看 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.查看指定文件夹(无论是否具有隐藏属性) 下的邮件列表

private static void ListMailofFolder(FolderId folderId, ExchangeService service)
{
                IdString = folderId;
                Folder Folders = Folder.Bind(service, IdString);
                FindItemsResults<Item> 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:<null>");
                    }

                    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.在指定文件夹(无论是否具有隐藏属性) 下创建邮件

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

7.为指定邮件添加附件

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.删除指定文件夹

EWS Managed API 不支持直接删除,需要构造 XML 格式的 SOAP 包

0x04 使用 EWS SOAP XML message 的实现代码

为了节省篇幅,只介绍 <soap:Body> 中的内容

1.在 Inbox 下创建文件夹

<m:CreateFolder>
  <m:ParentFolderId>
    <t:DistinguishedFolderId Id="inbox" />
  </m:ParentFolderId>
  <m:Folders>
    <t:Folder>
      <t:DisplayName>{name}</t:DisplayName>
    </t:Folder>
  </m:Folders>
</m:CreateFolder>

2.查看 Inbox 下的文件夹列表

<m:FindFolder Traversal="Deep">
  <m:FolderShape>
    <t:BaseShape>AllProperties</t:BaseShape>
  </m:FolderShape>
  <m:IndexedPageFolderView MaxEntriesReturned="2147483647" Offset="0" BasePoint="Beginning" />
  <m:ParentFolderIds>
    <t:DistinguishedFolderId Id="inbox" />
  </m:ParentFolderIds>
</m:FindFolder>

3.在 Inbox 下创建隐藏文件夹

这里需要发送三个数据包,依次为创建文件夹,添加隐藏属性和更新隐藏属性

创建文件夹:

   <m:CreateFolder>
      <m:ParentFolderId>
        <t:DistinguishedFolderId Id="inbox" />
      </m:ParentFolderId>
      <m:Folders>
        <t:Folder>
          <t:DisplayName>{name}</t:DisplayName>
        </t:Folder>
      </m:Folders>
    </m:CreateFolder>

添加隐藏属性:

<m:GetFolder>
  <m:FolderShape>
    <t:BaseShape>IdOnly</t:BaseShape>
    <t:AdditionalProperties>
      <t:ExtendedFieldURI PropertyTag="4340" PropertyType="Boolean" />
    </t:AdditionalProperties>
  </m:FolderShape>
  <m:FolderIds>
    <t:FolderId Id="{id}" ChangeKey="{key}" />
  </m:FolderIds>
</m:GetFolder>

更新隐藏属性:

   <m:UpdateFolder>
      <m:FolderChanges>
        <t:FolderChange>
          <t:FolderId Id="{id}" ChangeKey="{key}" />
          <t:Updates>
            <t:SetFolderField>
              <t:ExtendedFieldURI PropertyTag="4340" PropertyType="Boolean" />
              <t:Folder>
                <t:ExtendedProperty>
                  <t:ExtendedFieldURI PropertyTag="4340" PropertyType="Boolean" />
                  <t:Value>true</t:Value>
                </t:ExtendedProperty>
              </t:Folder>
            </t:SetFolderField>
          </t:Updates>
        </t:FolderChange>
      </m:FolderChanges>
    </m:UpdateFolder>

4.查看 Inbox 下的隐藏文件夹列表

   <m:FindFolder Traversal="Deep">
      <m:FolderShape>
        <t:BaseShape>IdOnly</t:BaseShape>
        <t:AdditionalProperties>
          <t:ExtendedFieldURI PropertyTag="4340" PropertyType="Boolean" />
          <t:FieldURI FieldURI="folder:DisplayName" />
        </t:AdditionalProperties>
      </m:FolderShape>
      <m:IndexedPageFolderView MaxEntriesReturned="100" Offset="0" BasePoint="Beginning" />
      <m:Restriction>
        <t:IsEqualTo>
          <t:ExtendedFieldURI PropertyTag="4340" PropertyType="Boolean" />
          <t:FieldURIOrConstant>
            <t:Constant Value="true" />
          </t:FieldURIOrConstant>
        </t:IsEqualTo>
      </m:Restriction>
      <m:ParentFolderIds>
        <t:DistinguishedFolderId Id="inbox" />
      </m:ParentFolderIds>
    </m:FindFolder>

5.查看指定文件夹(无论是否具有隐藏属性) 下的邮件列表

<m:FindItem Traversal="Shallow">
  <m:ItemShape>
    <t:BaseShape>AllProperties</t:BaseShape>
    <t:BodyType>Text</t:BodyType>
  </m:ItemShape>
  <m:IndexedPageItemView MaxEntriesReturned="2147483647" Offset="0" BasePoint="Beginning" />
  <m:ParentFolderIds>
    <t:FolderId Id="{id}" />
  </m:ParentFolderIds>
</m:FindItem>

6.在指定文件夹(无论是否具有隐藏属性) 下创建邮件

<m:CreateItem MessageDisposition="SaveOnly">
  <m:SavedItemFolderId>
    <t:FolderId Id="{id}" />
  </m:SavedItemFolderId>
  <m:Items>
    <t:Message>
      <t:Subject>test mail</t:Subject>
    </t:Message>
  </m:Items>
</m:CreateItem>

7.为指定邮件添加附件

<m:CreateAttachment>
  <m:ParentItemId Id="{id}" ChangeKey="{key}"/>
  <m:Attachments>
    <t:FileAttachment>
      <t:Name>{name}</t:Name>
      <t:Content>{data}</t:Content>
    </t:FileAttachment>
  </m:Attachments>
</m:CreateAttachment>

8.删除指定文件夹

<m:DeleteItem DeleteType="HardDelete" xmlns="https://schemas.microsoft.com/exchange/services/2006/messages">
  <m:ItemIds>
    <t:ItemId Id="{id}"/>
  </m:ItemIds>
</m:DeleteItem>

0x05 开源代码

1.使用 EWS Managed API

https://github.com/3gstudent/ewsManage

使用示例

(1) 在 Inbox 下创建隐藏文件夹 test1

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

获得文件夹对应的 FolderId: AAMkADc4YjRlNDc1LWI0YjctNDEzZi1hNTQ5LWZkYWY0ZGZhZDM0NgAuAAAAAABEBlGH6URWQp6Nlg9RxLmyAQA1ZCfAg9a0Sq75no2JOzsqAAAAA1FUAAA=

(2) 查看 Inbox 下的隐藏文件夹

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

(3) 在隐藏文件夹 test1 下创建测试邮件

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

(4) 查看隐藏文件夹 test1 下的所有邮件

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

获得测试邮件对应的 ItemId: AAMkADc4YjRlNDc1LWI0YjctNDEzZi1hNTQ5LWZkYWY0ZGZhZDM0NgBGAAAAAABEBlGH6URWQp6Nlg9RxLmyBwA1ZCfAg9a0Sq75no2JOzsqAAAAA1FUAAA1ZCfAg9a0Sq75no2JOzsqAAAAA1FVAAA=

(5) 向测试邮件添加附件

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) 读取测试邮件的内容

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

(7) 保存测试邮件中的附件

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

(8) 删除测试邮件

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

2.使用 EWS SOAP XML message

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

(1) 在 Inbox 下创建隐藏文件夹 test2

创建文件夹:

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

获得 Id: AAMkADc4YjRlNDc1LWI0YjctNDEzZi1hNTQ5LWZkYWY0ZGZhZDM0NgAuAAAAAABEBlGH6URWQp6Nlg9RxLmyAQA1ZCfAg9a0Sq75no2JOzsqAAAAA1U+AAA=,ChangeKey:AQAAABYAAAA1ZCfAg9a0Sq75no2JOzsqAAAAAGE/

添加隐藏属性:

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

更新隐藏属性:

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

(2) 查看 Inbox 下的隐藏文件夹

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

(3) 在隐藏文件夹 test1 下创建测试邮件

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

(4) 查看隐藏文件夹 test1 下的所有邮件

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

(5) 向测试邮件添加附件

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

(6) 读取测试邮件的内容

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

(7) 保存测试邮件中的附件

获得附件对应的 Id:

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

保存附件:

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

(8) 删除测试邮件

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

(9) 删除测试邮件隐藏文件夹 test1

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

0x06 防御检测

1.通过程序查看是否存在隐藏文件夹

例如:

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.查看邮件用户上次登录时间

使用 Exchange Server PowerShell:

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

3.查看 ews 访问日志

默认位置: C:\inetpub\logs\LogFiles\W3SVC1 ,搜索关键词 /EWS/Exchange.asmx

0x07 小结

本文介绍了 Exchange 用户邮箱隐藏文件夹的使用方法,分别介绍使用 EWS Managed API 和 EWS SOAP XML message 实现创建、访问和删除隐藏文件夹的方法,开源代码 ewsManageewsManage.py ,结合利用思路给出防御建议。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

向地狱狂奔

暂无简介

文章
评论
26 人气
更多

推荐作者

月下凄凉

文章 0 评论 0

toutuxuethreejs

文章 0 评论 0

回首观望

文章 0 评论 0

蓝戈者

文章 0 评论 0

zyxwd

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文