Skip to content

Query Reference

ncc-erik-steringer edited this page Jan 25, 2022 · 5 revisions

This page details the "plain-English" inputs you can make when calling the query command from the PMapper CLI.

Basics

PMapper takes queries in three different forms:

  • can <Principal> do <Action> [with <Resource> [when <Condition_A> [and <Condition_B> ...]]]
  • who can do <Action> [with <Resource> [when <ConditionA> [and <ConditionB>...]]]
  • preset <arguments>

When entering this via Bash prompts or the like, make sure to use single-quotes to surround the query and avoid any instances of dollar-signs or asterisks (*) from being interpreted incorrectly.

Authorization Queries

The first two forms check the authorization one or more principals to make a specific AWS API call. They not only check the principal's authorization, but also look at ways that principals can pivot to other principals and whether or not those other principals are authorized.

The first two forms are nearly the same, but the first runs against a specific user or role (specified by ARN, user/<user name>, or role/<role name>). You have to supply the name of a given action such as ec2:RunInstances or lambda:CreateFunction. If there's a specific resource, you can give that ARN. Otherwise, you can drop that part of the query (defaults to wildcard, *) or specify the wildcard * to include conditions. Conditions are separated by and and are of the form <key>=<value> where the key is a condition context key like aws:MultiFactorAuthPresent and the value is the string equivalent of the expected value (true/false for that particular key).

One example looks like:

who can do s3:GetObject with * when aws:SourceIp=128.223.0.1

This looks at all principals in the account, seeing who can call s3:GetObject for the resource * (all objects), when the caller's request comes from a given IP address.

Preset Queries

PMapper supports a series of "preset" queries. These presets do more extensive analysis beyond authorization checks. They can be invoked via query or argquery, and take special parameters.

privesc

This preset prints a list of which principals in an account are either admins or can escalate privileges by accessing an admin. Note that passing the --skip-admin flag will work here to skip printing which principals are admins and only shows the privilege escalation vectors.

# print all privilege escalation risks
$ pmapper --account 000000000000 query -s 'preset privesc *'

# check a specific user for privilege escalation
$ pmapper --account 000000000000 query 'preset privesc user/not-an-admin'

This can also be used via argquery

# print all privilege escalation risks
$ pmapper --account 000000000000 argquery -s --preset privesc --principal '*'

# check a specific user for privilege escalation
$ pmapper --account 000000000000 argquery --preset privesc --principal user/not-an-admin

connected

This preset lists which principals can access each other. For example:

# list who user A can access
$ pmapper --account 000000000000 query 'preset connected user/A *'

# list who can access user A
$ pmapper --account 000000000000 query 'preset connected * user/A'

# list if user A can access user B
$ pmapper --account 000000000000 query 'preset connected user/A user/B'

# list all connections
$ pmapper --account 000000000000 query 'preset connected * *'

With argquery, the source/destination is specified using the --principal and --resource parameters:

# list who can access user A
$ pmapper --account 000000000000 argquery --preset connected --principal '*' --resource 'user/A'

clusters

This preset query clusters IAM Users/Roles by looking at their tags, and reports when principals in one cluster can access principals in another cluster. If you cordon off users from resources via conditions working off of aws:PrincipalTag/*, this helps verify that isolation.

# identify clusters based on a given tag key "type"
$ pmapper --account 000000000000 query 'preset clusters type'

And again with argquery:

# identify clusters with the tag key "department"
$ pmapper --account 000000000000 argquery --preset clusters --resource 'department'

endgame

Another person theorized and implemented an attack known as "Endgame", where an attacker abuses resource policies to open up resources to global read/write access from any other AWS account (S3 buckets/objects, SQS queues, KMS keys, etc.). The endgame preset query identifies which users open up resources for global access. It also accepts the -s|--skip-admin flag to exclude admin users/roles from being included in the reporting.

This preset takes one argument, the services to check for resources, which are the services that PMapper caches resource policies for (KMS, SNS, SQS, S3). This can also be set to an asterisk (*) to include all of them.

# check for principals that can do an endgame attack against S3 (including admins)
$ pmapper --account 000000000000 query 'preset endgame s3'

And again with argquery:

# check for principals that can do an endgame attack against all services supported by PMapper
$ pmapper --account 000000000000 argquery --preset endgame --resource '*'

serviceaccess

IAM Roles have trust policies that control who can assume the role. The serviceaccess preset query runs through all the IAM Roles in the account and lists out services that can assume roles in the account, along with the roles they can assume.

# check which services can assume which roles
$ pmapper --account 000000000000 query 'preset serviceaccess'
$ pmapper --account 000000000000 argquery --preset serviceaccess

wrongadmin

Users and Roles may be classified as "admin" in PMapper based on if they can call all actions or resources, or grant themselves that permission directly (i.e. without pivoting to other principals). The wrongadmin preset query looks at all admin principals, then checks their managed/inline policies. If the admin does not have the AdministratorAccess or an equivalent inline policy attached, this tool reports the principal and why they are marked as an admin.

# check for potentially unwanted admins
$ pmapper --account 000000000000 query 'preset wrongadmin'
$ pmapper --account 000000000000 argquery --preset wrongadmin