渗透技巧——获得 Exchange GlobalAddressList 的方法

发布于 2024-11-30 19:09:42 字数 11299 浏览 26 评论 0

0x00 前言

Exchange GlobalAddressList(全局地址列表) 包含 Exchange 组织中所有邮箱用户的邮件地址,只要获得 Exchange 组织内任一邮箱用户的凭据,就能够通过 GlobalAddressList 导出其他邮箱用户的邮件地址。

本文将要介绍在渗透测试中不同条件下获得 Exchange GlobalAddressList 的常用方法,分享程序实现的细节,最后介绍禁用 GlobalAddressList 的方法

0x01 简介

本文将要介绍以下内容:

  • 获得 Exchange GlobalAddressList 的方法
  • 程序实现
  • 禁用 GlobalAddressList 的方法

0x02 获得 Exchange GlobalAddressList 的方法

1.通过 Outlook Web Access(OWA)

需要获得邮件用户的明文口令,登录 OWA 后,选择联系人-> All Users

2.通过 Exchange Web Service(EWS)

对于 Exchange 2013 及更高版本,可以使用 FindPeople 操作

参考资料:https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/findpeople-operation?redirectedfrom=MSDN

这里需要注意,FindPeople 操作时必须指定搜索条件,无法通过通配符直接获取所有结果

变通的解决方法:

遍历 26 个字母 a-z,以此作为搜索条件,能够覆盖所有结果

对于 Exchange2010 及更低版本,只能使用 ResolveName 操作

参考资料:https://docs.microsoft.com/en-us/dotnet/api/microsoft.exchange.webservices.data.exchangeservice.resolvename?redirectedfrom=MSDN&view=exchange-ews-api

这里需要注意,ResolveName 操作每次最多只能获得 100 个结果,如果 GlobalAddressList 中的邮箱用户大于 100,那么无法直接获得完整结果

变通的解决方法:

使用 ResolveName 操作时加入搜索条件,确保每次获得的结果能够少于 100,接着通过多次搜索实现对全部结果的覆盖

通常使用的方法:

搜索条件为任意两个字母的组合,例如 aa、ab、ac....zz,总共搜索 26*26=676 次,一般情况下能够覆盖所有结果

3.通过 Outlook 客户端使用的协议(MAPI OVER HTTP 和 RPC over HTTP)

登录用户,选择 联系人 -> 通讯簿

Outlook 客户端通常使用的协议为 RPC、RPC over HTTP(也称作 Outlook Anywhere) 和 MAPI over HTTP

使用 ruler 能够通过 MAPI OVER HTTP(暂不支持 RPC over HTTP) 读取 GlobalAddressList

注:MAPI over HTTP 是 Exchange Server 2013 Service Pack 1 (SP1) 中实现的新传输协议,用来替代 RPC OVER HTTP(也称作 Outlook Anywhere)

  • Exchange2013 默认没有启用 MAPI OVER HTTP,而是使用的 RPC OVER HTTP,需要手动开启
  • Exchange2016 默认启用 MAPI OVER HTTP

通过 RPC over HTTP 读取 GlobalAddressList 可使用 ptswarm 的 Exchanger.py

参考资料:https://swarm.ptsecurity.com/attacking-ms-exchange-web-interfaces/

流程如下:

(1) 列出 AddressList

命令示例:

python exchanger.py 192.168.1.1/test1:DomainUser123!@test.com nspi list-tables

结果如下图

Alt text

从图中可以获得 All Users 对应的 guid 为 5cb80229-e2b4-4447-b224-dc2c12098835

(2) 读取 AddressList

命令示例:

python exchanger.py 192.168.1.1/test1:DomainUser123!@test.com nspi dump-tables -guid 5cb80229-e2b4-4447-b224-dc2c12098835

结果如下图

Alt text

4.通过 Offline Address Book (OAB)

流程如下:

(1) 读取 Autodiscover 配置信息

访问的 URL: https://<domain>/autodiscover/autodiscover.xml

注:需要发送特定的 POST 包,详情可参考文章《渗透基础——Exchange Autodiscover 的使用》

从配置信息中获得 OABUrl

(2) 读取 OAB 文件列表

访问的 URL: OABUrl/oab.xml

返回结果中包括多个 OAB 文件的列表,如下图

Alt text

找到其中 Default Global Address List 对应的 lzx 文件名称,lzx 文件名称为 4667c322-5c08-4cda-844a-253ff36b4a6a-data-5.lzx

(3) 下载 lzx 文件

访问的 URL: OABUrl/xx.lzx

对应上面的示例,lzx 文件的下载地址为: https://192.168.1.1/OAB/9e3fa457-ebf1-40e4-b265-21d09a62872b/4667c322-5c08-4cda-844a-253ff36b4a6a-data-5.lzx

(4) 对 lzx 文件解码,还原出 Default Global Address List

这里需要使用工具 oabextract

下载后需要进行安装

编译好可在 Kali 下直接使用的版本下载地址: http://x2100.icecube.wisc.edu/downloads/python/python2.6.Linux-x86_64.gcc-4.4.4/bin/oabextract

将 lzx 文件转换为 oab 文件的命令示例:

oabextract 4667c322-5c08-4cda-844a-253ff36b4a6a-data-5.lzx gal.oab

提取出 GAL 的命令示例:

strings gal.oab|grep SMTP

结果如下图

Alt text

5.通过 LDAP

需要能够访问域控制器的 LDAP 服务(389 端口)

通常 Exchange 邮箱用户同域用户存在对应关系,所以可以根据域用户的信息获得 Exchange 邮箱用户的信息

(1) 从域外进行查询

需要获得域用户的明文口令

Kali 系统通过 ldapsearch 获取所有用户邮件地址的命令示例:

ldapsearch -x -H ldap://192.168.1.1:389 -D "CN=testa,CN=Users,DC=test,DC=com" -w DomainUser123! -b "DC=test,DC=com" |grep mail:

如下图

Alt text

Windows 系统通过 PowerView 获取所有用户邮件地址的命令示例:

$uname="testa"                                                      
$pwd=ConvertTo-SecureString "DomainUser123!" -AsPlainText –Force                   
$cred=New-Object System.Management.Automation.PSCredential($uname,$pwd)        
Get-NetUser -Domain test.com -DomainController 192.168.1.1 -ADSpath "LDAP://DC=test,DC=com" -Credential $cred | fl mail

如下图

Alt text

Windows 系统通过 C#实现:

通过调用命名空间 System.DirectoryServices 能够很容易实现相同的操作,代码已上传至 github,地址如下:https://github.com/3gstudent/Homework-of-C-Sharp/blob/master/ListUserMailbyLDAP.cs

如下图

Alt text

(2) 从域内进行查询

从域外查询的方法均适用,此时不需要域用户的凭据

还可以使用 PSSession 连接 Exchange 服务器后,通过 Exchange Management Shell 进行查询

命令示例:

$User = "test\administrator"
$Pass = ConvertTo-SecureString -AsPlainText DomainAdmin123! -Force
$Credential = New-Object System.Management.Automation.PSCredential -ArgumentList $User,$Pass
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://Exchange01.test.com/PowerShell/ -Authentication Kerberos -Credential $Credential
Import-PSSession $Session -AllowClobber
Get-Mailbox|fl PrimarySmtpAddress
Remove-PSSession $Session

如下图

Alt text

0x03 通过 Exchange Web Service(EWS) 获得 GlobalAddressList 的实现代码

1.Powershell

需要明文口令

https://github.com/dafthack/MailSniper

需要 PowerShell version 3.0

支持 FindPeople 操作和 ResolveName 操作

注:

FindPeople 操作通过 owa 实现

ResolveName 操作通过 ews 实现

2.Python

需要明文口令或 NTLM hash

(1)FindPeople 操作

参考资料:https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/findpeople-operation?redirectedfrom=MSDN

只能在 Exchange Server 2013 或更高版本使用

XML 格式示例:

<?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:FindPeople>
         <m:IndexedPageItemView BasePoint="Beginning" MaxEntriesReturned="1000" Offset="0"/>
         <m:ParentFolderId>
            <t:DistinguishedFolderId Id="directory"/>
         </m:ParentFolderId>
         <m:QueryString>test</m:QueryString>
      </m:FindPeople>
  </soap:Body>
</soap:Envelope>

搜索字符串 test ,这里指定最大查询结果数量 1000

为了能够覆盖所有结果,搜索字符串需要遍历 26 个字母 a-z,获得返回结果后进行去重处理

完整的代码可参考我在 ewsManage 新增的 findallpeople 功能

(2)ResolveName 操作

XML 格式示例:

<?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:ResolveNames ReturnFullContactData="false" SearchScope="ContactsActiveDirectory">
      <m:UnresolvedEntry>test</m:UnresolvedEntry>
    </m:ResolveNames>
  </soap:Body>
</soap:Envelope>

搜索字符串 test ,这里返回的查询结果最多为 100

为了能够覆盖所有结果,搜索条件为任意两个字母的组合,例如 aa、ab、ac....zz,总共搜索 26*26=676 次,一般情况下能够覆盖所有结果,获得返回结果后进行去重处理

这里需要注意,如果某个搜索条件获得的返回结果为 100,代表这个搜索条件的结果可能不完整(实际大于 100,只获得了 100),需要再次进行划分,进行第三级的遍历。返回结果可通过读取返回内容的 TotalItemsInView 项获得

完整的代码可参考我在 ewsManage 新增的 resolveallname 功能

0x04 禁用 GlobalAddressList 的方法

可以选择指定用户是否在 GlobalAddressList 中隐藏

1.通过 Exchange admin center(EAC)

使用 Exchange 管理员登录 Exchange Control Panel(ECP)

选择指定用户,选择 general ,选中 Hide from address lists ,如下图

Alt text

2.通过 Exchange Management Shell

隐藏指定用户的命令:

Set-MailContact -HiddenFromAddressListsEnabled $true -Identity test1

隐藏所有用户的命令:

Get-MailContact | Set-MailContact -HiddenFromAddressListsEnabled $true

0x05 小结

本文介绍了不同条件下获得 Exchange GlobalAddressList 的常用方法,编写程序分别实现通过 ews 的 FindPeople 操作和 ResolveName 操作导出 GlobalAddressList,在最后介绍了禁用 GlobalAddressList 的方法。

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

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

发布评论

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

关于作者

文章
评论
492 人气
更多

推荐作者

月下凄凉

文章 0 评论 0

toutuxuethreejs

文章 0 评论 0

回首观望

文章 0 评论 0

蓝戈者

文章 0 评论 0

zyxwd

文章 0 评论 0

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