First cloud-focused engagement, and the plan going in looked like every internal AD assessment before it: get a foothold, dump some hashes, kerberoast a service account, walk the privilege escalation path to domain admin, write it up. Day one in an AWS account with that plan produced almost nothing, because there was no domain controller to enumerate, no hash to dump, and no ticket to crack. The environment wasn't hiding the familiar attack surface. It didn't have one.
Cloud privilege escalation runs on a different substrate entirely, and the mental shift that takes the longest to make is this: in AWS, Azure or GCP, identity and access management policy is the terrain. A misconfigured IAM policy does the same job a misconfigured ACL or an unquoted service path did on-prem, except it's declarative, text-based, and usually written by someone who has never once thought about it as an attack surface.
The pattern that catches this out most often is a permission called iam:PassRole. On its own it looks harmless: it lets a user hand off a role to a service, the kind of thing every deployment pipeline needs to function. Paired with permission to create or update a Lambda function, an EC2 instance, or almost any other service that can assume a role, it stops being harmless. Attach a role with broader permissions than the user's own to that new resource, let the resource run, and the code executing under that role now has whatever access the role was granted. The user never touched an admin credential directly. They just handed one to a service that would run code on their behalf.
The second pattern is worse because it's invisible if you're reading the wrong policy. Every IAM role has two policies attached to it: a permissions policy, which says what the role can do, and a trust policy, which says who is allowed to assume it. Pentesters trained to think in terms of "what can this account access" read permissions policies and stop there. The actual privilege escalation path is often sitting in the trust policy of a completely different role: an identity with no interesting permissions of its own but with sts:AssumeRole rights into a role that has everything. Enumerate permissions in isolation and that chain is invisible. Enumerate every trust relationship in the account and it's the first thing you find.
None of this maps cleanly onto an on-prem mental model, and treating a cloud engagement like an AD engagement with different tool names is how a pentester spends day one confirming that the old playbook doesn't apply, instead of spending it finding the actual path. Codelivly's Cloud Penetration Testing book is built around exactly that gap: 60-plus labs across AWS, Azure and GCP that teach IAM attack paths as their own discipline instead of assuming the AD instincts will transfer.
Top comments (0)