o365spray: username enumeration and password spraying tool


o365spray a username enumeration and password spraying tool aimed at Microsoft Office 365 (O365). This tool reimplements a collection of enumeration and spray techniques researched and identified by those mentioned in Acknowledgments.

WARNING: The ActiveSync and oAuth2 modules for user enumeration are performed by submitting a single authentication attempt per user. If either module is run in conjunction with password spraying in a single execution, o365spray will automatically reset the account lockout timer prior to performing the password spray — if enumeration is run alone, the user should be aware of how many and when each authentication attempt was made and manually reset the lockout timer before performing any password spraying.

If any bugs/errors are encountered, please open an Issue with the details (or a Pull Request with the proposed fix). See the section below for more information about using previous versions.


git clone https://github.com/0xZDH/o365spray.git
cd o365spray
pip install -r requirements.txt


o365spray has been packaged to allow for use within automation scenarios. If domain validation, user enumeration, or password spraying is a part of your proposed attack/recon automation, see the below modules and import usage exmaples.


  • getuserrealm
  • openid-config — Currently Disabled

The validator can be imported and used via:

from o365spray.core import Validator
v = Validator()
valid, adfs_url = v.validate(‘domain.com’)


  • office
  • activesync
  • onedrive
    • This module relies on the target user(s) having previously logged into OneDrive. If a valid user has not yet used OneDrive, their account will show as ‘invalid’.
  • oauth2
  • autodiscover — Currently Disabled

The enumerator can be imported and used via:

from o365spray.core import Enumerator
loop = asyncio.get_event_loop()
e = Enumerator(loop, writer=False)
loop.run_until_complete( e.run( userlist, password, domain, module, )
list_of_valid_users = e.VALID_ACCOUNTS


  • activesync
  • autodiscover
  • msol
  • adfs

The sprayer can be imported and used via:

from o365spray.core import Sprayer
loop = asyncio.get_event_loop()
s = Sprayer(loop, writer=False)
loop.run_until_complete( s.run( password, domain, module, userlist, )
list_of_valid_creds = s.VALID_CREDENTIALS


Validate a domain is using O365:

o365spray –validate –domain test.com

Perform username enumeration against a given domain:

o365spray –enum -U usernames.txt –domain test.com

Perform password spraying against a given domain:

o365spray –spray -U usernames.txt -P passwords.txt –count 2 –lockout 5 –domain test.com

Copyright (C) 2021 0xZDH

Source: https://github.com/0xZDH/

Source: Penetration Testing

Leave a Reply