4/24 KPMG + Permiso LUCR-3 (Scattered Spider) Threat Briefing

REGISTER NOW
Illustration Cloud

How Using Deprecated Policies Creates Overprivileged Permissions - AmazonEC2RoleforSSM vs AmazonSSMManagedInstanceCore

Managed policies help AWS users simplify the way permissions are assigned. Periodically, AWS will add new permissions to active policies, which offer a new set of permissions to users. Because these are new permissions to an existing set of policies, users aren't impacted these changes and it doesn't remove any features or capabilities.

In the event that AWS would introduce a change to existing policies that could have adverse impacts on their users such as removing a certain set of permissions from a policy that IAM users, applications or services that leverage those policies, AWS will create a new policy, and deprecate the old legacy on in order to avoid service interruptions. These policies are also sometimes deprecated because they have overprivileged permissions that present security threats to their organization.

Once a policy is deprecated, it will continue to work for all existing users, groups and roles attached to it, but it cannot be attached to any NEW user, group or role. You would see warning informing you that the policy will soon be deprecated.

Aws Deprecated Policy Warning

At Permiso, we often observe environments that leverage overprivileged, deprecated policies. These policies are initially used because they were recommended by tutorials, blogs, vlogs or other articles that are now as dated as the policies themselves. None the less, overprivileged policies can lead to over-privileged identities and they present a significant threat to your organization's security.

In this post, we will compare two policies - AmazonEC2RoleforSSM, a deprecated version of the now recommended AmazonSSMManagedInstaceCore. We'll break down why AWS likely deprecated the original policy and how organizations leave themselves vulnerable by continuing to use these deprecated policies.

Diff-ing Policies

If you compare both policies side by side, you will notice that the deprecated policy (AmazonEC2RoleforSSM) has significantly more privileges attached to it than its counterpart. While AmazonSSMManagedInstanceCore has an extra Permission in ssm:GetParameters, it also removes all the permissions from CloudWatch, EC2, DS, Logs, S3 with changes highlighted below:

AmazonEC2RoleforSSM

The comparison above makes it apparent why the role has been deprecated. By default AmazonEC2RoleforSSM affects a total of eight AWS services that include:

  • SSM

  • SSMMessages

  • EC2Messages

  • CloudWatch

  • EC2

  • DS

  • Logs

  • S3

What is more problematic is the fact that the resource is defined as “*”, meaning all resources on these services will be affected by the policy:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ssm:DescribeAssociation",
                "ssm:GetDeployablePatchSnapshotForInstance",
                "ssm:GetDocument",
                "ssm:DescribeDocument",
                "ssm:GetManifest",
                "ssm:GetParameters",
                "ssm:ListAssociations",
                "ssm:ListInstanceAssociations",
                "ssm:PutInventory",
                "ssm:PutComplianceItems",
                "ssm:PutConfigurePackageResult",
                "ssm:UpdateAssociationStatus",
                "ssm:UpdateInstanceAssociationStatus",
                "ssm:UpdateInstanceInformation"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "ssmmessages:CreateControlChannel",
                "ssmmessages:CreateDataChannel",
                "ssmmessages:OpenControlChannel",
                "ssmmessages:OpenDataChannel"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "ec2messages:AcknowledgeMessage",
                "ec2messages:DeleteMessage",
                "ec2messages:FailMessage",
                "ec2messages:GetEndpoint",
                "ec2messages:GetMessages",
                "ec2messages:SendReply"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "cloudwatch:PutMetricData"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeInstanceStatus"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "ds:CreateComputer",
                "ds:DescribeDirectories"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:DescribeLogGroups",
                "logs:DescribeLogStreams",
                "logs:PutLogEvents"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetBucketLocation",
                "s3:PutObject",
                "s3:GetObject",
                "s3:GetEncryptionConfiguration",
                "s3:AbortMultipartUpload",
                "s3:ListMultipartUploadParts",
                "s3:ListBucket",
                "s3:ListBucketMultipartUploads"
            ],
            "Resource": "*"
        }
    ]
}


While AmazonSSMManagedInstanceCore only affects three AWS services, the impact on all resources within those services remains:

  • SSM

  • SSMMessages

  • EC2Messages

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ssm:DescribeAssociation",
                "ssm:GetDeployablePatchSnapshotForInstance",
                "ssm:GetDocument",
                "ssm:DescribeDocument",
                "ssm:GetManifest",
                "ssm:GetParameter",
                "ssm:GetParameters",
                "ssm:ListAssociations",
                "ssm:ListInstanceAssociations",
                "ssm:PutInventory",
                "ssm:PutComplianceItems",
                "ssm:PutConfigurePackageResult",
                "ssm:UpdateAssociationStatus",
                "ssm:UpdateInstanceAssociationStatus",
                "ssm:UpdateInstanceInformation"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "ssmmessages:CreateControlChannel",
                "ssmmessages:CreateDataChannel",
                "ssmmessages:OpenControlChannel",
                "ssmmessages:OpenDataChannel"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "ec2messages:AcknowledgeMessage",
                "ec2messages:DeleteMessage",
                "ec2messages:FailMessage",
                "ec2messages:GetEndpoint",
                "ec2messages:GetMessages",
                "ec2messages:SendReply"
            ],
            "Resource": "*"
        }
    ]
}

AmazonEC2RoleforSSM S3 Privileges

When we were testing some SSM related activities at Permiso, S3 Privileges on AmazonEC2RoleforSSM always troubled us. This policy gives a potential attacker almost all of the permissions and access needed to abuse S3 Buckets as they see fit, with the exception of listing bucket names (ListBuckets), although any threat actors could utilize different techniques to find the bucket names.

Using this Policy, an Identity can:

  • List Objects using ListBucket (not to be confused with ListBuckets which lists bucket names)

  • Download or Upload Objects with GetObject and PutObject

  • Get Bucket Encryption Configuration (using GetEncryptionConfiguration)

  • Get Bucket Location using GetBucketLocation (this can be easily found by fuzzing the bucket-name on any regions the bucket service is available on)

  • List/Abort Multipart Download Processes and each part of them using ListBucketMultipartUploads, ListMultipartUploadParts, AbortMultipartUpload

How Attackers Leverage These Permissions

So what does all this mean for bad actors that are looking to make lateral moves across a network? Let's walk through some use cases where threat actors can leverage these outdated permissions to access sensitive data.

Case Study #1: SSRF on Instances with Meta-Data v1 to All Buckets compromise

Assume that we found an SSRF (server-side request forgery) on an instance with IMDSv1, meaning a simple HTTP request can give us the credentials of an instance profile. Also, let's assume that during reconnaissance, we were able to find a bucket name “testbucketpermiso” on “eu-west-3”. This bucket is a private one.

SSRF On Instance

We get access as the IP with a name that looks like an SSM related IP:

SSM-related-IP

We assume this identity has AmazonEC2RoleforSSM attached to it and start looking at the Bucket’s objects.

S3 has two versions of APIs that it it accesses. This is also apparent on awscli, where you use s3 or s3api as services. s3:ListBucket is the permission that enables the usage of aws s3 ls:

aws s3 ls s3://bucketname

We’ll use this to list the bucket’s objects instead of s3:ListObjects, which is the permission that allows bucket listing on the new API (adding —recursive will give all the objects, not just the primary directory objects). It should be noted that s3:ListObjects and s3:ListObjectsv2 also work:

S3ListObjects

Let’s try to check if the bucket is encrypted:

check-bucket-encrypted


No encryption found. Let’s grab one of the files using GetObject (using both s3 and s3api as services):

GetObject-grab-files-1 GetObject-grab-files-2

This way we can get sensitive information from S3 Buckets like configuration files, databases, logs or other sensitive information:

S3 Buckets Sensitive Information

AmazonEC2RoleforSSM Directory Services Privileges

Directory Service is an AWS Managed AD Service. We can federate AD Environments using AD Connect-or.

The Permissions granted on Directory Service include:

  • List and gather information from Directory Services (AWS Managed and Federated ones from AD Connector) using DescribeDirectories

  • Create a Computer Account on a Directory using CreateComputer

Again, these permissions are granted for all resources within the service.

Case Study #2: Domain Joined EC2 Instance on AWS Directory Service with IMDSv1

In this scenario, we have an EC2 Instance that is domain joined on AWS DS Service with IMDSv1 and AmazonEC2RoleforSSM Role Attached to the Instance Profile.

Aws

After getting the credentials we start testing Directory Service. We start with Enumerating Directories using DescribeDirectories:

Directory-Service-DescribeDirectories


With this, we can get the DirectoryID (which we will need later), AD Domain (Name), AD DNS IPs, AD VPCs, Subnets and Regions covered, SSO, OS of Domain Controllers and whether it’s active or not.

Also, we can create machine accounts on AD using CreateComputer. This privilege is added so that the instance connected can automatically create the Machine Account in AD without requiring an administrator to do it. It's likely the reason those privileges were automatically added was so that Instances could be Domain Joined too.

AD CreateComputer TestMachine

And on the Directory:

TestMachine-in-Directory

This can help with RBCD too, without having to create a machine account from PowerShell. We didn't check to see if it worked when ms-ds-machineaccountquota was 0, because when you create a Directory, it gives you an OU and a user (Admin) that can manage only that OU. RBCD on Domain does not work since AccountNotDelegated is True, meaning it cannot be delegated.

Instance and Status Enumeration

Case Study Nr.3: Enumerating Instance State using DescribeInstanceStatus

EC2:DescribeInstanceStatus is a Privilege that allows an identity to get the state of one or all the instances running on a region. You can get all the instances that are pending, running, shutting-down, terminated, stopping, stopped. This provides insight on what Instance and instance turnover rate an account has.

DescribeInstanceStatus-Enumerating-Instance-State

This doesn't provide other info like OS, IP, Hostname, Domain Joined or not, but you get the idea. Additionally, this info can also be used when trying other enumeration techniques.

Service Enumeration through CloudWatch Log Groups

One interesting enumeration technique we've observed is using CloudWatch Log Groups to enumerate Services being used. You can choose to collect logs for a specific object like a single Instance or a single Lambda Function, then collect all of them into a Log Group. Log Group itself can be the service, as a form of grouping, but it can be anything. Since the most important services are the ones that are usually monitored, this can give an attacker a picture of the services being used.

AWSEC2RoleforSSM has both DescribeLogGroups and DescribeLogStreams, meaning you can list all Log Groups and the Streams inside them to understand what services are being used on an account.

AWSEC2RoleforSSM

And for each Group we can check its streams:

Check Streams

From this we see that there are at least 4 Services Being used:

  • Lambda

  • EC2

  • DS

  • Kube

And some service IDs:

  • Lambda Function Name: testDecryptionFunctionName

  • AWS DS IDs: d-8067298a1d and d-806729ebdd

  • EC2 Instance ID: i-02c1c36eaf8a15bd4

  • Kube Cluster: kubeCluster01

Conclusion

In these examples, we were able to:

  • List Instances and their status in an account

  • Get an idea on the services being used on an account

  • List Directory Services and almost pulled together a Resource Based Constrained Delegation

  • Got access to List, Download and Upload objects of any bucket in the account that we had the name for.

In conclusion, it’s a lot better to use AmazonSSMManagedInstanceCore instead of AmazonEC2RoleforSSM. It goes without saying that AmazonSSMManagedInstanceCore has some potentially dangerous privileges too, which we'll cover in our next article in this series. For now, make sure to modify the Instance Profile’s Role Policy and break some stuff in the process.

Illustration Cloud

Related Articles

Introducing Cloud Console Cartographer: An Open-Source Tool To Help Security Teams Easily Understand Log Events Generated by AWS Console Activity

Introduction While most cloud CLI tools provide a one-to-one correlation between an API being invoked and a single corresponding API event being generated in cloud log telemetry, browser-based interactive console sessions differ profoundly across

An Adversary Adventure with Cloud Administration Command

Introduction As the cybersecurity landscape rapidly evolves, organizations are implementing multi-cloud solutions to advance their digital transformation initiatives. On the other hand, threat actors are unrelenting in developing sophisticated

Introducing CloudGrappler: A Powerful Open-Source Threat Detection Tool for Cloud Environments

IntroductionWith the increased activity of threat actor groups like LUCR-3 (Scattered Spider) over the last year, being able to detect the presence of these threat groups in cloud environments continues to present a significant challenge to most

View more posts