[Authenticated][Information Gathering] Automated Azure Active Directory enumeration using ROADtools

Description

ROADtools (Rogue Office 365 and Azure (active) Directory tools)

ROADtools is a framework to interact with Azure AD. It consists of a library (roadlib) with common components, the ROADrecon Azure AD exploration tool and the ROADtools Token eXchange (roadtx) tool.

ROADlib

ROADlib is a library that can be used to authenticate with Azure AD or to build tools that integrate with a database containing ROADrecon data. The database model in ROADlib is automatically generated based on the metadata definition of the Azure AD internal API. ROADlib lives in the ROADtools namespace, so to import it in your scripts use

  • from roadtools.roadlib import X

ROADrecon

ROADrecon is a tool for exploring information in Azure AD from both a Red Team and Blue Team perspective. In short, this is what it does:

  • Uses an automatically generated metadata model to create an SQLAlchemy backed database on disk.
  • Use asynchronous HTTP calls in Python to dump all available information in the Azure AD graph to this database.
  • Provide plugins to query this database and output it to a useful format.
  • Provide an extensive interface built in Angular that queries the offline database directly for its analysis.
  • ROADrecon uses async Python features and is only compatible with Python 3.7 and newer (development is done with Python 3.8, tests are run with versions up to Python 3.11).

Requirements

Authenticated Account

Installation

There are multiple ways to install ROADrecon:

Using a published version on PyPi

Stable versions can be installed with pip install roadrecon. This will automatically add the roadrecon command to your PATH.

Using a version from GitHub

Every commit to master is automatically built into a release version with Azure Pipelines. This ensures that you can install the latest version of the GUI without having to install npm and all it’s dependencies. You can download the roadlib and roadrecon build files from the Azure Pipelines artifacts (click on the button “1 Published”. The build output files are stored in ROADtools.zip. You can either install the .whl or .tar.gz files directly using pip or unzip both and install the folders in the correct order (roadlib first):

  • pip install roadlib/
  • pip install roadrecon/

You can also install them in development mode with pip install -e roadlib/.

Developing the front-end

If you want to make changes to the Angular front-end, you will need to have node and npm installed. Then install the components from git:

  • git clone https://github.com/dirkjanm/roadtools.git
  • pip install -e roadlib/
  • pip install -e roadrecon/
  • cd roadrecon/frontend/
  • npm install

You can run the Angular frontend with npm start or ng serve using the Angular CLI from the roadrecon/frontend/ directory. To build the JavaScript files into ROADrecon’s dist_gui directory, run npm build

How to use

1. You can also run the main script to run reoad recon

  • cd /roadtools/roadrecon/roadtools/roadrecon
  • python3 main.py -h

2. Display the argument options

  • python3 main.py auth -h

Start enumeration

Authentication

To authenticate use the auth module, this command will authenticate a create a token

  • roadrecon auth -u <azure_username> -p <password>

Gather information

Once authenticated we can proceed to gather information about Azure, it will save the results in a database

  • roadrecon gather

Start GUI

1. After the information has been gather, we can start the GUI

  • roadrecon gui

2. Connect to the GUI visiting http://127.0.0.1:5000/

Users

1. Enumerate users’ information such as username, account type, email, last password change, etc

2. If you click on a user you can verify the Groups, Roles, Owned Objects, Raw data

Groups

You can also enumerate groups and their details such as members and general information

Devices

Enumerate the devices name, status, OS, trust type

Roles

Enumerate rols Principal Name, type, userPrincipalName, status

Applications

Enumerate applications name, multitenant status, home page, authentication, owners

Service Principals

Enumerate Service principals name, type, publisher, status

Applications Roles

Enumerate application roles name, type, application, role, description

OAuth2

Enumerate OAuth2 Approval type, principal name, Source & target application, scope

References

https://github.com/dirkjanm/ROADtools

https://github.com/dirkjanm/ROADtools/wiki/Getting-started-with-ROADrecon

[Password Spray] Office Microsoft Online accounts (Azure/O365)

Description

A password spraying tool for Microsoft Online accounts (Azure/O365). The script logs if a user cred is valid, if MFA is enabled on the account, if a tenant doesn’t exist, if a user doesn’t exist, if the account is locked, or if the account is disabled.

BE VERY CAREFUL NOT TO LOCKOUT ACCOUNTS!

This tool not only is looking for valid passwords, but also the extremely verbose information Azure AD error codes give you. These error codes provide information relating to if MFA is enabled on the account, if a tenant doesn’t exist, if a user doesn’t exist, if the account is locked, if the account is disabled, if the password is expired and much more.

So this doubles, as not only a password spraying tool but also a Microsoft Online recon tool that will provide account/domain enumeration. In limited testing it appears that on valid login to the Microsoft Online OAuth2 endpoint it isn’t auto-triggering MFA texts/push notifications making this really useful for finding valid creds without alerting the target.

Requirements

  • Existing user account
  • List of password samples to spray

How to Use

1. Download the tool

  • git clone https://github.com/dafthack/MSOLSpray.git

2. Import the module into powershell

  • Import-Module .\MSOLSpray.ps1

3. Display help menu

  • Get-Help Invoke-MSOLSpray

This module will perform password spraying against Microsoft Online accounts (Azure/O365). The script logs if a user cred is valid, if MFA is enabled on the account, if a tenant doesn’t exist, if a user doesn’t exist, if the account is locked, or if the account is disabled.

Note: Invoke-MSOLSpray [[-OutFile] <String>] [[-UserList] <String>] [[-Password] <String>] [[-URL] <String>] [[-Force]] [<CommonParameters>]

4. Get full help description

  • Get-Help Invoke-MSOLSpray –Detailed

5. Invoke-MSOLSpray Options

  • UserList – UserList file filled with usernames one-per-line in the format “user@domain.com”
  • Password – A single password that will be used to perform the password spray.
  • OutFile – A file to output valid results to.
  • Force – Forces the spray to continue and not stop when multiple account lockouts are detected.
  • URL – The URL to spray against. Potentially useful if pointing at an API Gateway URL generated with something like FireProx to randomize the IP address you are authenticating from.

Exploitation

1. Spray a known password

  • Invoke-MSOLSpray -UserList <userlist.txt> -Password <password>

2. The URL to spray against. Potentially useful if pointing at an API Gateway URL generated with something like FireProx to randomize the IP address you are authenticating from.

  • Invoke-MSOLSpray -UserList <userlist.txt> -Password <password> -URL <url>

References

https://github.com/dafthack/MSOLSpray

[Unauthenticated][Information Gathering] OneDrive user enumeration

Description

OneDrive users have a file share URL with a known location:

https://acmecomputercompany-my.sharepoint.com/personal/lightmand_acmecomputercompany_com/_layouts/15/onedrive.aspx

In this instance, the username is ‘lightmand’ and the domain is ‘acmecomputercompany.com’. If a user has logged into OneDrive, this path will exist and return a 403 status code. If they have not, or the user is invalid, it will return a 404.

The results may vary depending on how widely used OneDrive is within an org. Currently it is the most reliable user-enumeration method that I’m aware of (office365userenum no longer works, and the others like UhOh365 are unreliable). Further, it does not attempt a login and is much more passive, and should be undetectable to the target org. Microsoft will see the hits, but the target org won’t.

Requirements

  • Tenant name
  • Username or user list <found usernames>
  • Domain name

How to Use

1. Download the tool

  • git clone https://github.com/nyxgeek/onedrive_user_enum.git

2. Install requirements

  • pip3 install -r requirements.txt

3. Display menu

  • python3 ./onedrive_enum.py -h

Exploitation

1. Run basic OneDrive user enumeration

  • python3 onedrive_enum.py -U <user_list> -d <domain.onmicrosoft.com> -v

2. example – basic usage

  • ./onedrive_enum.py -t microsoft -d microsoft.com -U USERNAMES/statistically-likely/jsmith.txt

3. example – mysql db logging

  • ./onedrive_enum.py -t microsoft -d microsoft.com -U USERNAMES/statistically-likely/jsmith.txt -m db.conf

4. Set Threads

  • python3 onedrive_enum.py -U <user_list> -d <domain.onmicrosoft.com> -v -T100

References

https://github.com/dafthack/MSOLSpray

https://trustedsec.com/blog/onedrive-to-enum-them-all

[Unauthenticated][Information Gathering] Enumerate public resources in Azure using Cloud_Enum

Description

Cloud_Enum is a multi-cloud OSINT tool, in this case we are going to use it to enumerate Microsoft Azure

Requirements

  • Company Name or domain

How to Use

1. Download the tool

  • git clone https://github.com/initstring/cloud_enum.git

2. Install the necessary modules

  • pip3 install -r requirements.txt

3. Display the menu

  • python3 cloud_enum.py -h

4. Select the regions you want the search to apply

  • vi enum_tools/azure_regions.py

Exploitation

1. Run the tool only for Azure

  • python3 cloud_enum.py -k <company name> –disable-aws –disable-gcp

2. Set threads

  • cloud_enum -k keyword -t 10

References

https://github.com/initstring/cloud_enum

[Unauthenticated][Information Gathering] Enumerate Azure OWA and EWS using MailSniper

Description

MailSniper is a penetration testing tool for searching through email in a Microsoft Exchange environment for specific terms (passwords, insider intel, network architecture information, etc.). It can be used as a non-administrative user to search their own email or by an Exchange administrator to search the mailboxes of every user in a domain.

MailSniper also includes additional modules for password spraying, enumerating users and domains, gathering the Global Address List (GAL) from OWA and EWS and checking mailbox permissions for every Exchange user at an organization.

For more information about the primary MailSniper functionality check out blog post.

For more information about additional MailSniper modules check out:

Download the MailSniper Field Manual to quickly reference various MailSniper functions.

How to Use

Two main functions in MailSniper.

These two functions are Invoke-GlobalMailSearch and Invoke-SelfSearch.

  • Invoke-GlobalMailSearch is a module that will connect to a Microsoft Exchange server and grant the “ApplicationImpersonation” role to a specified user. Having the “ApplicationImpersonation” role allows that user to search through all other domain user’s mailboxes.
  • After this role has been granted, the Invoke-GlobalMailSearch function creates a list of all mailboxes in the Exchange database. It then connects to Exchange Web Services (EWS) using the impersonation role to gather a number of emails from each mailbox and ultimately searches through them for specific terms. By default, the script searches for “*password*”,”*creds*”,”*credentials*”

Invoke-GlobalMailSearch Options

  • ImpersonationAccount – This user will be granted the ApplicationImpersonation role on the Exchange server.
  • ExchHostname – The hostname of the Exchange server to connect to (If $AutoDiscoverEmail is specified the server will be autodiscovered).
  • AutoDiscoverEmail – A valid email address that will be used to autodiscover where the Exchange server is located.
  • MailsPerUser – The total number of emails returned from each mailbox.
  • Terms – Specific search terms used to search through each email subject and body. By default, the script searches for “*password*”,”*creds*”,”*credentials*”.
  • OutputCsv – Outputs the results of the search to a CSV file.
  • ExchangeVersion – Specify the version of Exchange server to connect to. By default the script tries Exchange2010.
  • AdminUserName – The username of an Exchange administator (i.e. member of the “Exchange Organization Administrators” or “Organization Management” group) including the domain (i.e. domain\adminusername).
  • AdminPassword – The password to the Exchange administator (i.e. member of the “Exchange Organization Administrators” or “Organization Management” group) account specified with AdminUserName.
  • EmailList – A text file listing email addresses to search (one per line).
  • Folder – A specific folder within each mailbox to search. By default, the script only searches the “Inbox” folder. By specifying ‘all’, all folders and subfolders will be searched.
  • Regex – Use a regular expressions when performing searches. This will override the -Terms flag.
  • CheckAttachments – Attempts to search through the contents of email attachements in addition to the default body and subject. These attachments can be downloaded by specifying the -DownloadDir option. Searches for the following extensions: .bat, .htm, .msg, .pdf, .txt, .ps1, .doc and .xls.
  • DownloadDir – Download files to a specific location.

Invoke-SelfSearch Options

  • ExchHostname – The hostname of the Exchange server to connect to (If $Mailbox is specified the server will be autodiscovered).
  • Mailbox – Email address of the current user the PowerShell process is running as.
  • MailsPerUser – Number of emails to return.
  • Terms – Specific search terms used to search through each email subject and body. By default, the script searches for “*password*”,”*creds*”,”*credentials*”.
  • OutputCsv – Outputs the results of the search to a CSV file.
  • ExchangeVersion – Specify the version of Exchange server to connect to (default Exchange2010).
  • Remote – A new credential box will pop up for accessing a remote EWS service from the internet.
  • Folder – A specific folder within each mailbox to search. By default, the script only searches the “Inbox” folder. By specifying ‘all’, all folders and subfolders will be searched.
  • Regex – Use a regular expressions when performing searches. This will override the -Terms flag.
  • CheckAttachments – Attempts to search through the contents of email attachements in addition to the default body and subject. These attachments can be downloaded by specifying the -DownloadDir option. Searches for the following extensions: .bat, .htm, .msg, .pdf, .txt, .ps1, .doc and .xls.
  • DownloadDir – Download files to a specific location.
  • OtherUserMailbox – Use this flag when attempting to read emails from a different user’s mailbox
  • UsePrt – Uses the current user’s PRT to authenticate.
  • AccessToken – Use provided oauth access token to authenticate.

Invoke-GlobalO365MailSearch Options

  • UsePrtImperonsationAccount – Uses the current user’s PRT to authenticate ImperonsationAccount.
  • AccessTokenImpersonationAccount – Use provided oauth access token to authenticate ImperonsationAccount.
  • UsePrtAdminAccount – Uses the current user’s PRT to authenticate AdminAccount.
  • AccessTokenAdminAccount – Use provided oauth access token to authenticate ImperonsationAccount.

Additional MailSniper Modules

Get-GlobalAddressList

it will attempt to connect to an Outlook Web Access (OWA) portal and utilize the “FindPeople” method (only available in Exchange2013 and up) of gathering email addresses from the GAL. If this does not succeed the script will attempt to connect to EWS and attempt to gather the GAL.

  • Get-GlobalAddressList -ExchHostname mail.domain.com -UserName domain\username -Password Spring2021 -OutFile gal.txt

Get-MailboxFolders

it will connect to a Microsoft Exchange server using EWS and gather a list of folders from the current user’s mailbox.

  • Get-MailboxFolders -Mailbox current-user@domain.com

Invoke-PasswordSprayOWA

It will attempt to connect to an OWA portal and perform a password spraying attack using a userlist and a single password.

  • Invoke-PasswordSprayOWA -ExchHostname mail.domain.com -UserList .\userlist.txt -Password Spring2021 -Threads 15 -OutFile owa-sprayed-creds.txt

Invoke-PasswordSprayEWS

It will attempt to connect to an EWS portal and perform a password spraying attack using a userlist and a single password.

  • Invoke-PasswordSprayEWS -ExchHostname mail.domain.com -UserList .\userlist.txt -Password Spring2021 -Threads 15 -OutFile sprayed-ews-creds.txt

Invoke-PasswordSprayGmail

This module will first attempt to connect to a Gmail Authentication portal and perform a password spraying attack using a userlist and a single password.

  • Invoke-PasswordSprayGmail -UserList .\userlist.txt -Password Fall2016 -Threads 15 -OutFile gmail-sprayed-creds.txt

Invoke-DomainHarvestOWA

It will attempt to connect to an OWA portal and determine a valid domain name for logging into the portal from the WWW-Authenticate header returned in a web response from the server or based off of small timing differences in login attempts.

  • Invoke-DomainHarvestOWA -ExchHostname mail.domain.com

Invoke-UsernameHarvestOWA

It will attempt to connect to an OWA portal and harvest valid usernames based off of small timing differences in login attempts.

  • Invoke-UsernameHarvestOWA -ExchHostname mail.domain.com -UserList .\userlist.txt -Threads 1 -OutFile owa-valid-users.txt

Invoke-UsernameHarvestGmail

This is a module that will attempt to enumerate Google Apps user accounts and potentially identify user accounts that opt-out of implemented 2FA solutions.

  • Invoke-UsernameHarvestGmail -Account
  • Invoke-UsernameHarvestGmail -UserFile .\emails.txt
  • Invoke-UsernameHarvestGmail -UserFile .\emails.txt -ProxyHosts 10.0.0.5:8080,10.0.0.6:8080,10.0.0.10:443
  • Invoke-UsernameHarvestGmail -UserFile .\emails.txt -Detailed
  • Get-Content emails.txt | % { Invoke-UsernameHarvestGmail $_ }

Invoke-OpenInboxFinder

It will attempt to determine if the current user has access to the Inbox of each email address in a list of addresses.

  • Invoke-OpenInboxFinder -EmailList email-list.txt

Get-ADUsernameFromEWS

It will attempt to determine the Active Directory username for a single email address or a list of addresses. Use the Get-GlobalAddressList module to harvest a full list of email addresses to use with Get-ADUsernameFromEWS.

  • Get-ADUsernameFromEWS -EmailList email-list.txt

Send-EWSEmail

It will attempt to connect to EWS and send an email.

  • Send-EWSEmail –ExchHostname substrate.office.com -Recipient $targetEmail -Subject “Foo” -EmailBody “Bar” -AccessToken $Accesstoken

References

https://github.com/dafthack/MailSniper