
BloodHound Attack Research Kit

BARK stands for BloodHound Attack Research Kit. It is a PowerShell script built to assist the BloodHound Enterprise team with researching and continuously validating abuse primitives. BARK currently focuses on Microsoft's Azure suite of products and services.
BARK requires no third party dependencies. BARK's functions are designed to be as simple and maintainable as possible. Most functions are very simple wrappers for making requests to various REST API endpoints. BARK's basic functions do not even require each other - you can pull almost any BARK function out of BARK and it will work perfectly as a standalone function in your own scripts.
Primary author: Andy Robbins @_wald0
Contributors:
There are many ways to import a PowerShell script. Here's one way:
First, download BARK.ps1 by cloning this repo or simply copy/pasting its raw contents from GitHub.
git clone https://github.com/BloodHoundAD/BARK
Now, cd into the directory where the PS1 is:
cd BARK
Finally, you can dot import the PS1 like this:
. .\BARK.ps1
Hit enter, and your PowerShell instance will now have access to all of BARK's functions.
With very few exceptions, Azure API endpoints require authentication to interact with. BARK comes with a few functions that will help you acquire the necessary tokens for interacting with the MS Graph and Azure REST APIs. Any BARK function that interacts with an Azure API that requires authentication will require you to supply a token.
Let's say you want to list all of the users in an Entra ID tenant. You first need to get a token scoped for MS Graph. There are many ways to get this token:
If you have a username/password combination for an Entra user in that tenant, you can first acquire a refresh token for the user using BARK's Get-EntraRefreshTokenWithUsernamePassword function:
$MyRefreshTokenRequest = Get-EntraRefreshTokenWithUsernamePassword -username "[email protected]" -password "MyVeryCoolPassword" -TenantID "contoso.onmicrosoft.com"
The resulting object you just created, $MyRefreshTokenRequest, will have as part of it a refresh token for your user. You can now request an MS Graph-scoped token using this refresh token:
$MyMSGraphToken = Get-MSGraphTokenWithRefreshToken -RefreshToken $MyRefreshTokenRequest.refresh_token -TenantID "contoso.onmicrosoft.com"
Now this new object, $MyMSGraphToken, will have as one of its property values an MS Graph-scoped JWT for your user. You are now ready to use this token to list all the users in the Entra tenant:
$MyUsers = Get-AllEntraUsers -Token $MyMSGraphToken.access_token -ShowProgress
Once finished, the $MyEntraUsers variable will be populated by objects representing all of the users in your Entra tenant.
Get-AzureKeyVaultTokenWithClientCredentials requests a token from STS with Azure Vault specified as the resource/intended audience using a client ID and secret.Get-AzureKeyVaultTokenWithUsernamePassword requests a token from STS with Azure Vault specified as the resource/intended audience using a user-supplied username and password.Get-AzurePortalTokenWithRefreshToken requests an Azure Portal Auth Refresh token with a user-supplied refresh token.Get-AzureRMTokenWithClientCredentials requests an AzureRM-scoped JWT with a client ID and secret. Useful for authenticating as an Entra service principal.Get-AzureRMTokenWithPortalAuthRefreshToken requests an AzureRM-scoped JWT with a user-supplied Azure Portal Auth Refresh token.Get-AzureRMTokenWithRefreshToken requests an AzureRM-scoped JWT with a user-supplied refresh token.Get-AzureRMTokenWithUsernamePassword requests an AzureRM-scoped JWT with a user-supplied username and password.Get-EntraRefreshTokenWithUsernamePassword requests a collection of tokens, including a refresh token, from login.microsoftonline.com with a user-supplied username and password. This will fail if the user has Multi-Factor Authentication requirements or is affected by a Conditional Access Policy.Get-MSGraphTokenWithClientCredentials requests an MS Graph-scoped JWT with a client ID and secret. Useful for authenticating as an Entra service principal.Get-MSGraphTokenWithPortalAuthRefreshToken requests an MS Graph-scoped JWT with a user-supplied Azure Portal Auth Refresh token.Get-MSGraphTokenWithRefreshToken requests an MS Graph-scoped JWT with a user-supplied refresh token.Get-MSGraphTokenWithUsernamePassword requests an MS Graph-scoped JWT with a user-supplied username and password.Parse-JWTToken will take a Base64 encoded JWT as input and parse it for you. Useful for verifying correct token audience and claims.The refresh token-based functions in BARK are based on functions in TokenTactics by Steve Borosh.
Get-AllEntraApps collects all Entra application registration objects.Get-AllEntraGroups collects all Entra groups.Get-AllEntraRoles collects all Entra admin roles.Get-AllEntraServicePrincipals collects all Entra service principal objects.Get-AllEntraUsers collects all Entra users.Get-EntraAppOwner collects owners of an Entra app registration.Get-EntraDeviceRegisteredUsers collects users of an Entra device.Get-EntraGroupMembers collects members of an Entra group.Get-EntraGroupOwner collects owners of an Entra group.Get-EntraRoleTemplates collects Entra admin role templates.Get-EntraServicePrincipal collects an Entra service principal.Get-EntraServicePrincipalOwner collects owners of an Entra service principal.Get-EntraTierZeroServicePrincipals collects Entra service principals that have a Tier Zero Entra Admin Role or Tier Zero MS Graph App Role assignment.Get-MGAppRoles collects the app roles made available by the MS Graph service principal.