渗透技巧——获得 Exchange GlobalAddressList 的方法
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 操作
这里需要注意,FindPeople 操作时必须指定搜索条件,无法通过通配符直接获取所有结果
变通的解决方法:
遍历 26 个字母 a-z,以此作为搜索条件,能够覆盖所有结果
对于 Exchange2010 及更低版本,只能使用 ResolveName 操作
这里需要注意,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
结果如下图
从图中可以获得 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
结果如下图
4.通过 Offline Address Book (OAB)
流程如下:
(1) 读取 Autodiscover 配置信息
访问的 URL: https://<domain>/autodiscover/autodiscover.xml
注:需要发送特定的 POST 包,详情可参考文章《渗透基础——Exchange Autodiscover 的使用》
从配置信息中获得 OABUrl
(2) 读取 OAB 文件列表
访问的 URL: OABUrl/oab.xml
返回结果中包括多个 OAB 文件的列表,如下图
找到其中 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
结果如下图
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:
如下图
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
如下图
Windows 系统通过 C#实现:
通过调用命名空间 System.DirectoryServices 能够很容易实现相同的操作,代码已上传至 github,地址如下:https://github.com/3gstudent/Homework-of-C-Sharp/blob/master/ListUserMailbyLDAP.cs
如下图
(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
如下图
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 操作
只能在 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
,如下图
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 技术交流群。
上一篇: 渗透基础——Exchange 用户邮箱中的隐藏文件夹
下一篇: Jvm 常量池
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论