Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
o365enum — Перечисление валидных имен пользователей из Office 365 с помощью ActiveSync, Autodiscover v1 или страницы входа office.com. | Kitploit
Инструменты/GitHubGitHub/gremwell/o365enum
OSINT (Разведка открытых источников)РазведкаСбор информацииВеб-безопасность
GitHubgremwell/o365enum

o365enum

Перечисление валидных имен пользователей из Office 365 с помощью ActiveSync, Autodiscover v1 или страницы входа office.com.

Репозиторий
301432 лет назадПроверено Kitploit

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться
Сайт

Перечисление пользователей Office 365

Перечисление действительных имён пользователей Office 365 с помощью ActiveSync, Autodiscover или страницы входа office.com.

Использование

o365enum читает имена пользователей из файла, указанного в качестве первого параметра. Файл должен содержать одно имя пользователя на строку. Вывод основан на CSV для удобства парсинга. Статус valid может быть 0 (недействительный пользователь), 1 (действительный пользователь), 2 (действительный пользователь и действительный пароль).

root@kitploit:~
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            show this help message and exit
  -u USERLIST, --userlist USERLIST
                        username list one per line (default: None)
  -p PASSWORD, --password PASSWORD
                        password to try (default: Password1)
  -n NUM, --num NUM     # of reattempts to remove false negatives (default: 3)
  -v, --verbose         Enable verbose output at urllib level (default: False)
  -m {activesync,autodiscover,office.com}, --method {activesync,autodiscover,office.com}
                        method to use (default: activesync)

Пример запуска:

root@kitploit:~
./o365enum.py -u users.txt -p Password2 -n 1 -m activesync
username,valid
[email protected],0
[email protected],1

Методы перечисления

Перечисление через ActiveSync

Этот метод основан на методе grimhacker, который отправляет запросы базовой HTTP-аутентификации на конечную точку ActiveSync. Однако проверка кода состояния больше не работает, так как Office365 возвращает 401 независимо от того, существует пользователь или нет.

Вместо этого мы отправляем тот же запрос, но проверяем наличие пользовательского заголовка ответа HTTP (X-MailboxGuid), чтобы определить, действительно ли имя пользователя.

Существующая учётная запись

Приведённый ниже запрос содержит следующие учётные данные в кодировке Base64 в заголовке Authorization: [email protected]:Password1

root@kitploit:~
OPTIONS /Microsoft-Server-ActiveSync HTTP/1.1
Host: outlook.office365.com
Connection: close
MS-ASProtocolVersion: 14.0
Content-Length: 0
Authorization: Basic dmFsaWRfdXNlckBjb250b3NvLmNvbTpQYXNzd29yZDE=

Это вызывает следующий ответ («401 Unauthorized») с установленным заголовком X-MailboxGuid, указывающим, что имя пользователя действительно, но пароль нет:

root@kitploit:~
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--

Несуществующая учётная запись

Приведённый ниже запрос содержит следующие учётные данные в кодировке Base64 в заголовке Authorization: [email protected]:Password1

root@kitploit:~
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», но на этот раз без заголовка X-MailboxGuid, что указывает на недействительность имени пользователя).

root@kitploit:~
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, если пользователь не существует (если только перенаправление не выполняется на локальный сервер Exchange).

Существующий пользователь

root@kitploit:~
GET /autodiscover/autodiscover.json/v1.0/[email protected]?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
root@kitploit:~
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"}

Несуществующий пользователь

root@kitploit:~
GET /autodiscover/autodiscover.json/v1.0/[email protected]?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
root@kitploit:~
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&amp;Protocol=Autodiscoverv1&amp;RedirectCount=1">here</a>.</h2>
</body></html>

Перечисление через Office.com

ПРЕДУПРЕЖДЕНИЕ: Этот метод работает только для организаций, которые являются подписчиками Exchange Online и не имеют локального или гибридного развёртывания Exchange Server.

Для компаний, использующих локальные серверы Exchange или некоторые гибридные развёртывания, а также в зависимости от некоторых настроек, которые я пока не определил, сервер может возвращать значение, указывающее на существование пользователя, для любого имени пользователя.

Метод полезен, когда вы не хотите тратить попытку аутентификации с 'Password1' :)

Определение существования пользователя

Свойство IfExistsResult используется для описания того, существует ли учётная запись и каким образом. Как обсуждалось в этой статье блога RSM, значения следующие:

Существующий пользователь

Когда учётная запись существует, IfExistsResult устанавливается в одно из упомянутых выше целых чисел, обычно 1.

root@kitploit:~
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": "[email protected]",
    "forceotclogin": false
}
root@kitploit:~
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":"[email protected]",
    "Display":"[email protected]",
    "IfExistsResult":0,
    "ThrottleStatus":0,
    "Credentials":{
        "PrefCredential":1,
        "HasPassword":true,
        "RemoteNgcParams":null,
        "FidoParams":null,
        "SasParams":null
    },
    "EstsProperties":{
        "UserTenantBranding":null,
        "DomainType":3
    },
    "IsSignupDisallowed":true,
    "apiCanary":"--snip--"
}
Несуществующий пользователь

Когда учётная запись не существует, IfExistsResult устанавливается в 1.

root@kitploit:~
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": "[email protected]",
    "forceotclogin": false
}
root@kitploit:~
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": "[email protected]",
    "IfExistsResult": 1,
    "EstsProperties": {
        "UserTenantBranding": null,
        "DomainType": 3
    },
    "Credentials": {
        "PrefCredential": 1,
        "FidoParams": null,
        "RemoteNgcParams": null,
        "SasParams": null,
        "HasPassword": true
    },
    "IsSignupDisallowed": true,
    "Display": "[email protected]"
}

Авторы

  • @jenic — Разбор аргументов и уменьшение ложных отрицательных результатов.
  • @Mike-Crowley — Исправление описания IfExistsResult.
Скачать инструмент
ЭлементЗначение
-1Неизвестная ошибка
0Учётная запись существует и использует этот домен для аутентификации
1Учётная запись не существует
2Ответ регулируется
4Некоторая ошибка сервера
5Учётная запись существует, но настроена для аутентификации с помощью другого поставщика удостоверений. Это может указывать на то, что учётная запись используется только как личная
6Учётная запись существует и настроена на использование как домена, так и другого поставщика удостоверений