Why cloud privilege escalation is a different game
When I started testing cloud environments, I tried to use the same mindset as a traditional network test. I looked for open ports, weak passwords, and vulnerable services. I missed the real attack surface. In the cloud, the most valuable target is often an identity, not a port. A temporary credential, an overly permissive policy, or a metadata service can give me more access than any service vulnerability.
This post is my personal study note on cloud privilege escalation. I am writing it because the topic is broad and the cloud providers keep changing their APIs. The notes focus on the patterns that stay the same: metadata, credentials, storage, policies, and service accounts.
Start with the identity
Before I try to escalate privileges, I need to understand the identity that I control. The identity can be a user, a role, a service account, or an instance profile. It has a set of permissions, and the permissions determine what I can do.
The first step is enumerating the permissions. Cloud providers offer APIs that return the effective permissions for an identity. I use read-only calls to list the roles, policies, and attached services. The result is a map of what I can already do.
The identity also has a trust relationship. A role may be assumable by other users or services. The trust policy tells me who can assume the role and under what conditions. If I can modify the trust policy, I can often escalate to a more privileged role.
The metadata service
The metadata service is the classic cloud escalation target. It is available at addresses like http://169.254.169.254/ and provides information about the instance. The information includes the instance ID, the network configuration, and the temporary credentials for the attached role.
If an application has an SSRF vulnerability, the metadata service becomes an obvious target. I send a request to the metadata address and see whether the response contains credentials. If it does, I have obtained the instance role's temporary credentials.
The metadata service has changed over time. Some providers require a specific header or session token. Some have disabled the service by default. I check the provider documentation and adapt the request. The metadata service is not always the answer, but it is always worth checking.
Using temporary credentials
Once I have temporary credentials, I use them to call the cloud API. The first step is to identify the role and its permissions. I list the attached policies and the allowed actions. The list tells me which services I can access.
I use the credentials with the provider's command-line tool or SDK. The tool resolves the access key, secret, and session token, and sends signed requests to the API. I start with read-only calls to avoid causing damage.
The temporary credentials have an expiration. I record the expiration time and plan my work around it. If the role allows me to assume another role, I can obtain a new set of credentials and continue.
Storage and key management
Cloud storage is a common escalation path. A storage bucket may allow public listing, public write, or access by a specific role. If I have credentials, I can list the buckets that the identity can access and look for sensitive files.
The permission model matters. A bucket policy can grant access to a role that I control, or it can deny access to everyone else. I test the bucket permissions with read-only requests before I try to write anything.
Key management services are another target. If the identity can list, decrypt, or export keys, I can access encrypted data. The ability to export a key is often the difference between reading a few files and controlling an entire system.
Overly permissive policies
The most common cause of cloud privilege escalation is an overly permissive policy. A policy that grants * for actions and resources gives the identity full access to the service. The attacker does not need to bypass anything; the access is already there.
I look for policies that allow an identity to create, modify, or attach policies. If I can create a new role, attach an administrator policy, and assume the role, I have escalated to administrator. This is one of the most powerful escalation paths in the cloud.
I also look for policies that allow an identity to launch compute instances with an arbitrary instance profile. The new instance inherits the profile's role, which may have more permissions than my current identity. I can launch an instance, use its metadata service to get the credentials, and then control the role.
Service accounts and workloads
Containers and serverless functions have their own identities. A container might run with a service account that has broad permissions. If I compromise the container, I inherit those permissions. The boundary between the application and the cloud identity is often the escalation path.
The service account credentials can be stored in the pod, in the environment, or in the cloud metadata service. I look for credential files, environment variables, and mounted secrets. A single service account can grant access to multiple applications.
The workload identity can also be used to assume a role. If the identity is allowed to assume a more privileged role, I can use it to escalate. The trust policy is the key, and I always read it carefully.
Containers and the host
Container escape is a separate topic, but it is connected to cloud escalation. If I escape the container, I may reach the host, and the host may have access to the cloud metadata service. The host's role may be more privileged than the container's service account.
I test the container boundaries with simple checks. Can I read files outside the container? Can I access the Docker socket? Can I see the host processes? Each answer tells me how close I am to the host.
The host role is often the highest-value target because it may have broad cloud permissions. If I can access the metadata service from the host, I can obtain the host role's credentials and continue the escalation.
Auditing my own path
The escalation path should be documented as I go. I record every role, policy, and credential that I use. The record helps me explain the finding and helps the defender understand the path.
I also record the actions that I decided not to take. A destructive action, such as deleting a bucket or modifying a production policy, is usually outside the scope. I note the action and explain why I did not perform it.
The report should show the full chain, from the initial access to the final privilege. The chain is more useful than a list of individual permissions, because it shows the actual risk.
Prevention
The cloud provider's defense is the same as any other security program: least privilege, monitoring, and audit. Every identity should have the minimum permissions needed for its task. The permissions should be reviewed regularly and removed when they are no longer needed.
The metadata service should be restricted when possible. Some providers allow the service to be disabled or to require a session token. The restriction reduces the risk of SSRF leading to credential theft.
Audit logs are essential. The logs should record role assumptions, policy changes, and unusual API calls. A role that is assumed from an unexpected source, or a policy that is modified by an unfamiliar identity, should trigger an alert.
Cloud provider differences
The cloud providers have different names for similar concepts. AWS has IAM roles and instance profiles. Azure has managed identities. Google Cloud has service accounts. The underlying idea is the same: an identity with a set of permissions.
The metadata services also differ. AWS uses 169.254.169.254 and supports different versions of the metadata API. Azure uses a similar address with its own headers. Google Cloud has its own metadata server. I check the provider documentation before I send a request.
The policy language is different too. An AWS policy uses JSON with actions and resources. An Azure role definition uses a different format. The testing tools are also provider-specific.
The provider differences matter because a technique that works in one cloud may not work in another. I build the test plan around the provider, not around a generic cloud checklist.
The enumeration checklist
When I have a new identity, I run a small enumeration checklist. The list covers the basics: who am I, what can I do, which resources can I read, and which policies can I modify.
The first item is the identity information. I list the user, the role, the service account, and the attached policies. The second item is the permission enumeration. I list the allowed actions for the relevant services.
The third item is the resource enumeration. I list the storage buckets, the key vaults, the databases, and the compute instances that the identity can access. The fourth item is the trust relationship. I read the role trust policies and look for assumptions.
The checklist keeps the test focused. It also creates a record of the actions that I performed. The record is useful for the report and for the audit.
Reporting the escalation path
The escalation path is the most important part of the report. I describe the starting identity, the steps that I took, and the final identity. Each step includes the API call and the permission that made it possible.
The report should also include the root cause. The root cause is usually a policy that is too broad, a trust relationship that is too open, or a metadata service that is not protected. The root cause tells the defender what to fix.
The remediation should be specific. Instead of saying "review the policies", I recommend the exact policy change and the exact service that should be restricted. The recommendation should be tested in a non-production environment.
The report should also mention the monitoring. The escalation path should have generated alerts. If it did not, the monitoring has a gap.
One more thought
The cloud environment changes fast. A permission that was safe last month can become dangerous after a new service is introduced. The escalation path that I find today may not work next month, and a new path may appear. That is why I keep the permission map fresh and why I check the provider documentation before every test. The goal is not to memorize a fixed list of attacks. It is to understand the identity model well enough to find the next path when the old one is fixed.
Common mistakes I make
My biggest mistake is treating the metadata service as the only escalation path. The policies and the trust relationships are often more important. My second mistake is using a new credential before reading the attached policies. The policy tells me what I can safely do. My third mistake is performing a destructive action without confirming the scope.
The fourth mistake is forgetting to record the expiration time of temporary credentials. The credentials can disappear in the middle of a test. The fifth mistake is ignoring the service accounts and workload identities, which are often more accessible than the cloud user.
My quick checklist
- Enumerate the current identity and its permissions.
- Check the metadata service for temporary credentials.
- Read the role and trust policies before using a new credential.
- List storage buckets and key management resources.
- Look for policies that allow creating or attaching new policies.
- Check containers, service accounts, and workload identities.
- Document the escalation path with every role and credential.
- Report the chain and the prevention controls.
What I would do next time
Next time I want to build a permission map before I try to escalate. The map shows me which paths are available and which are blocked. I also want to spend more time reading trust policies, because that is where the most interesting escalation paths hide. Cloud privilege escalation is not about breaking into a server. It is about finding an identity that can do more than it should.