Lead Image © Dmitry Naumov, 123RF.com

Lead Image © Dmitry Naumov, 123RF.com

Prowling AWS

Snooping Around

Article from ADMIN 55/2020
By
Prowler is an AWS security best practices assessment, auditing, hardening, and forensics readiness tool.

Hearing that an external, independent organization has been commissioned to spend time actively attacking the cloud estate you have been tasked with helping to secure can be a little daunting – unless, of course, you are involved with a project at the seminal greenfield stage, and you have yet to learn what goes where and how it all fits together. To add to the complexity, if you are using Amazon Web Services (AWS), AWS Organizations can segregate departmental duties and, therefore, security controls between multiple accounts; commonly this might mean the use of 20 or more accounts. With these concerns and, if you blink a little too slowly, it's quite possible that you will miss a new AWS feature or service that needs to be understood and, once deployed, secured.

Fret not, however, because a few open source tools can help mitigate the pain before an external auditor or penetration tester receives permission to attack your precious cloud infrastructure. In this article, I show you how to install and run the highly sophisticated tool Prowler [1]. With the use of just a handful of its many features, you can test against the industry-consensus benchmarks from the Center for Internet Security (CIS) [2].

What Are You Lookin' At?

When you run Prowler against the overwhelmingly dominant cloud provider AWS, you get the chance to apply an impressive 49 test criteria of the AWS Foundations Benchmark. For some additional context, sections on the AWS Security Blog [3] are worth digging into further.

To bring more to the party, the sophisticated Prowler also stealthily prowls for issues in compliance with General Data Protection Regulation (GDPR) of the European Union and the Health Insurance Portability and Accountability Act (HIPAA) of the United States. Prowler refers to these 40 additional checks as "extras". Table 1 shows the type and number of checks that Prowler can run, and the right-hand column offers the group name you should use to get Prowler to test against specific sets of checks.

Table 1

Checks and Group Names

Description No./Type of Checks Group Name
Identity and access management 22 checks group 1
Logging 9 checks group 2
Monitoring 14 checks group 3
Networking 4 checks group 4
Critical priority CIS CIS Level 1 cislevel1
Critical and high-priority CIS CIS Level 2 cislevel2
Extras 39 checks extras
Forensics See README file [4] forensics-ready
GDPR See website [5] gdpr
HIPAA See website [6] hipaa

Porch Climbing

To start getting your hands dirty, install Prowler and see what it can do to help improve the visibility of your security issues. To begin, go to the GitHub page [1] held under author Toni de la Fuente's account; he also has a useful blogging site [7] that offers a number of useful insights into the vast landscape of security tools available to users these days and where to find them. I recommend a visit, whatever your level of experience.

The next step is cloning the repository with the git command [8] (Listing 1). As you can see at the beginning of the command's output, the prowler/ directory will hold the code.

Listing 1

Installing Prowler

$ git clone https://github.com/toniblyx/prowler.git
 **
Cloning into 'prowler'...
remote: Enumerating objects: 50, done.
remote: Counting objects: 100% (50/50), done.
remote: Compressing objects: 100% (41/41), done.
remote: Total 2955 (delta 6), reused 43 (delta 5), pack-reused 2905
Receiving objects: 100% (2955/2955), 971.57 KiB | 915.00 KiB/s, done.
Resolving deltas: 100% (1934/1934), done.

The README file recommends installing the ansi2html and detect-secrets packages with the pip Python package installer:

$ pip install awscli ansi2html detect-secrets

If you don't have pip installed, fret not: Use your package manager. For example, on Debian derivatives, use the apt command:

$ apt install python-pip

On Red Hat Enterprise Linux child distributions and others like openSUSE or Arch Linux, you can find instructions online [9] for help if you're not sure of the package names.

Now you're just about set to run Prowler from a local machine perspective. Before continuing, however, the other part of the process is configuring the correct AWS Identity and Access Management (IAM) permissions.

An Access Key and a Secret Key attached to a user is needed from AWS, with the correct permissions being made available to the user via a role. Don't worry, though: The permissions aren't giving away the crown jewels but reveal any potential holes in your security posture. Therefore, the results need to be stored somewhere with care, as do all access credentials to AWS.

You might call the List/Read/Describe actions "read-only" if you wanted to summarize succinctly the levels of access required by Prowler. You can either use the SecurityAudit policy permissions, which is provided by AWS directly, or the custom set of permissions in Listing 2 required by the role to be attached to the user in IAM, which opens up the DescribeTrustedAdvisorChecks, in addition to those offered by the SecurityAudit policy, according to the GitHub README file.

Listing 2

Permissions for IAM Role

{
  "Version": "2012-10-17",
  "Statement": [{
    "Action": [
      "acm:describecertificate",
      "acm:listcertificates",
      "apigateway:get",
      "autoscaling:describe*",
      "cloudformation:describestack*",
      "cloudformation:getstackpolicy",
      "cloudformation:gettemplate",
      "cloudformation:liststack*",
      "cloudfront:get*",
      "cloudfront:list*",
      "cloudtrail:describetrails",
      "cloudtrail:geteventselectors",
      "cloudtrail:gettrailstatus",
      "cloudtrail:listtags",
      "cloudwatch:describe*",
      "codecommit:batchgetrepositories",
      "codecommit:getbranch",
      "codecommit:getobjectidentifier",
      "codecommit:getrepository",
      "codecommit:list*",
      "codedeploy:batch*",
      "codedeploy:get*",
      "codedeploy:list*",
      "config:deliver*",
      "config:describe*",
      "config:get*",
      "datapipeline:describeobjects",
      "datapipeline:describepipelines",
      "datapipeline:evaluateexpression",
      "datapipeline:getpipelinedefinition",
      "datapipeline:listpipelines",
      "datapipeline:queryobjects",
      "datapipeline:validatepipelinedefinition",
      "directconnect:describe*",
      "dynamodb:listtables",
      "ec2:describe*",
      "ecr:describe*",
      "ecs:describe*",
      "ecs:list*",
      "elasticache:describe*",
      "elasticbeanstalk:describe*",
      "elasticloadbalancing:describe*",
      "elasticmapreduce:describejobflows",
      "elasticmapreduce:listclusters",
      "es:describeelasticsearchdomainconfig",
      "es:listdomainnames",
      "firehose:describe*",
      "firehose:list*",
      "glacier:listvaults",
      "guardduty:listdetectors",
      "iam:generatecredentialreport",
      "iam:get*",
      "iam:list*",
      "kms:describe*",
      "kms:get*",
      "kms:list*",
      "lambda:getpolicy",
      "lambda:listfunctions",
      "logs:DescribeLogGroups",
      "logs:DescribeMetricFilters",
      "rds:describe*",
      "rds:downloaddblogfileportion",
      "rds:listtagsforresource",
      "redshift:describe*",
      "route53:getchange",
      "route53:getcheckeripranges",
      "route53:getgeolocation",
      "route53:gethealthcheck",
      "route53:gethealthcheckcount",
      "route53:gethealthchecklastfailurereason",
      "route53:gethostedzone",
      "route53:gethostedzonecount",
      "route53:getreusabledelegationset",
      "route53:listgeolocations",
      "route53:listhealthchecks",
      "route53:listhostedzones",
      "route53:listhostedzonesbyname",
      "route53:listqueryloggingconfigs",
      "route53:listresourcerecordsets",
      "route53:listreusabledelegationsets",
      "route53:listtagsforresource",
      "route53:listtagsforresources",
      "route53domains:getdomaindetail",
      "route53domains:getoperationdetail",
      "route53domains:listdomains",
      "route53domains:listoperations",
      "route53domains:listtagsfordomain",
      "s3:getbucket*",
      "s3:getlifecycleconfiguration",
      "s3:getobjectacl",
      "s3:getobjectversionacl",
      "s3:listallmybuckets",
      "sdb:domainmetadata",
      "sdb:listdomains",
      "ses:getidentitydkimattributes",
      "ses:getidentityverificationattributes",
      "ses:listidentities",
      "ses:listverifiedemailaddresses",
      "ses:sendemail",
      "sns:gettopicattributes",
      "sns:listsubscriptionsbytopic",
      "sns:listtopics",
      "sqs:getqueueattributes",
      "sqs:listqueues",
      "support:describetrustedadvisorchecks",
      "tag:getresources",
      "tag:gettagkeys"
    ],
    "Effect": "Allow",
    "Resource": "*"
  }]
}

Have a close look at the permissions to make sure you're happy with them. As you can see, a lot of list and get actions cover a massive amount of AWS's ever-growing number of services. In a moment, I'll return to this policy after setting up the AWS configuration.

Gate Jumping

For those who aren't familiar with the process of setting up credentials for AWS, I'll zoom through them briefly. The obvious focus will be on Prowler in action.

In the redacted Figure 1, you can see the screen found in the IAM service under the Users | Security credentials tab. Because you're only shown the secret key once, you should click the Create access key button at the bottom and then safely store the details.

Figure 1: Creating the user's Access Key and Secret Key in AWS in the IAM service.

To make use of the Access Key and Secret Key you've just generated, return to the terminal and enter:

$ aws configure
AWS Access Key ID []:

The aws command became available when you installed the AWS command-line tool with the pip package manager.

As you will see from the questions asked by that command, you need to offer a few defaults, such as the preferred AWS region, the output format, and, most importantly, your Access Key and Secret Key, which you can enter with cut and paste. Once you've filled in those details, two files are created in plain text and stored in the ./aws directory: config and credentials. Because these keys are plain text, many developers use environment variables to populate their terminal with these details so they're ephemeral and not saved in a visible format. Wherever you keep them, you should encrypt them when stored – known as "data at rest" in security terms.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy ADMIN Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

comments powered by Disqus