I have been working with Amazon Web Services (AWS) a lot in my new role with Stride. I love every minute of it. I said a long time ago in several podcast episodes that cloud is not only the future–it’s here. And, it’s here to stay. One thing I have learned during my time working with AWS services is there is often a best tool for a specific job.
Sometimes it is faster to login and use the AWS Console, or Graphical User Interface (GUI), and sometimes it is easier to use the AWS Command Line Interface (CLI) to find what is needed. Sometimes it is easier to create a Python script with the Boto3 library, when one needs to be even more specific in one’s selection and output. The great part about AWS is the fact that one can use all three to do what one needs and is not limited to one specific method!
I have found that the AWS CLI is very powerful and can work around some of the limitations of the AWS Console. I have been a fanboy of command line interfaces in general for some time now. I have been learning Linux for years and a lot of things in Linux are better done in the command line. So, let’s discuss some powerful commands in the AWS CLI that have helped me in the past.
Note
I will not be covering any pre-requisites in this article. I will be assuming anyone following along knows how to install the AWS CLI tools in one’s favorite environment and how to generally use the AWS CLI it to pull information from an AWS account.
AWS Config
The AWS Config service is an immensely powerful tool for helping security teams discover resources that are non-compliant. It is capable of aggregating all resources across all accounts in an organization. This service provides a single place for one to go to get a full view of everything in one’s cloud environment.
List Aggregate Discovered Resources by Resource Type
There are times when one must list all resources of a certain resource type across all of one’s accounts. This is the command that makes that happen. This requires an aggregation point be configured in Config.
aws configservice list-aggregate-discovered-resources --region='<regionName>' --configuration-aggregator-name '<configuredAggregatorName>' --resource-type '<resourceType>' | grep '<propertyName>' | sed -e 's/"<propertyName>": "//g' -e 's/"//g' -e 's/^[ /t]*//' > file.csv
This command must be ran against the account where the AWS Config aggregator exists. There is a lot to break down here, so I will take it step-by-step.
aws configservice list-aggregate-discovered-resources --region '<regionName>' --configuration-aggregator-name '<configuredAggregatorName>' --resource-type '<resourceType>'
- Call
aws configservice
and use thelist-aggregate-discovered-resource
function - Provide a region name in the
--region '<regionName>'
field- eg. ‘us-east-1’
- Provide a Config aggregator name in the
--configuration-aggregator-name '<configuredAggregatorName>'
field- The Config aggregator name can be enumerated with the
describe-configuration-aggregators
command - eg. ‘Organization-Config-Aggregator’
- The Config aggregator name can be enumerated with the
- Provide a resource type in the
--resource-type '<resourceType>'
field- eg. ‘AWS::EC2::Instance’
| grep '<propertyName>'
- Pipe this JSON output into
grep
and provide it a property name on which to match- The property name is going to vary depending on which service one queries in the
--resource-type '<resourceType>'
field
- The property name is going to vary depending on which service one queries in the
| sed -e 's/"<propertyName>": "//g' \
-e 's/"//g' \
-e 's/^[ /t]*//'
- Pipe this output through
sed
and provide it some substitution strings-e 's/"<propertyName>: "//g/'
replace ‘propertyName’ with the property name from thegrep
command above-e 's/"//g'
eliminates any unnecessary quote marks-e 's/^[ /t]*//'
eliminates any unnecessary spaces
- For more information on sed, please click here
> file.csv
- Send the output to a CSV file, since all of the output will be separated by commas
EC2
The Elastic Compute Cloud (EC2) service is a fundamental AWS service on which everything is built. Unlike a traditional datacenter, it allows one to quickly spin-up or spin-down resources quickly, dynamically, and all with code. An EC2 instance is a virtual server that can use Intel, AMD, or Arm-based processors with Windows, Linux, macOS, or Arm-based operating systems installed on top. An EC2 is associated with a Security Group, which can act as a traditional firewall, protecting the resource from external exposure.
List EC2 Instances Associated With a Security Group
aws ec2 describe-network-interfaces --region 'regionName' --filters Name=group-id,Values=<securityGroupId> --output table --query NetworkInterfaces[*].Attachment.InstanceId
This command must be ran against the account in which the EC2 instances and Security Groups exist. Now, to the breakdown.
- Call
aws ec2
service and use thedescribe-network-interface
- Provide a region name in the
--region '<regionName>'
field- eg. ‘us-east-1’
- Provide a security group ID in the
--filters Name=group-id,Vaues=<securityGroupId>
field- eg. ‘sg-3fad834asdfgeedfs’
- Use
--output table
to define the CLI output format as a ‘table’, as compared to ‘text’ or ‘json’ - Use
--query NetworkInterfaces[*].Attachment.InstanceId
to use advanced filtering and dot notation to filter the output down to theInstanceId
associated with the Security Group
Security Hub
Security Hub centralizes cloud security posture management that allows for easy best practices checks, aggregate alerts, and provides mechanisms for automated remediation. It can help organizations align with popular frameworks such as Payment Card Industry Data Security Standards (PCI DSS) and Center for Internet Security (CIS) AWS Foundations Benchmarks.
Get Findings by Account ID
aws securityhub get-findings --region 'regionName' --filters '{AwsAccountId": [{"Value": "<accountNumber>","Comparison":"EQUALS"}]}' > file.txt
This command must be ran against the account in which the Security Hub service exist. Now, let’s walk through this.
aws securityhub get-findings --region 'regionName' --filters '{AwsAccountId": [{"Value": "<accountNumber>","Comparison":"EQUALS"}]}'
- Call
aws securityhub
service and use theget-findings
function - Provide a region name in the
--region '<regionName>'
field- eg. ‘us-east-1’
- Provide an account number in the
--filters '{"AwsAccountId": [{"Value": "<AccountNumber>","Comparison":"EQUALS"}]}'
- This is nested parsing of JSON output. It is complicated at first, but gets easier with time. Just put it in like you see it for now.
> file.txt
- Send the output to a text file
Organizations
AWS Organizations helps with central management and governance across all AWS accounts. Many companies use multiple AWS accounts and the Organizations service allows them to be configured, audited, and governed from one central location.
List All Accounts in Organizations
aws organizations list-accounts | grep 'Email' | sed -e 's/"Email": "//g -e 's/",//g' -e 's/"//g' -e 's/^[ \t]*//' > file.txt
This command must be ran against the account in which the Organization service is managed. Now, let’s walk through this.
aws organizations list-accounts
- Call
aws organizations
and use thelist-accounts
function
| grep 'Email'
- Pipe this JSON output into
grep
and provide it a property name on which to match- Match on ‘Email’
| sed -e 's/"Email": "//g -e 's/",//g' \
-e 's/"//g' \
-e 's/^[ \t]*//'
- Pipe this output through
sed
and provide it some substitution strings-e 's/"Email: "//g/'
eliminates the unnecessary, leading ‘Email: ‘ string-e 's/"//g'
eliminates any unnecessary quote marks-e 's/^[ /t]*//'
eliminates any unnecessary spaces
- For more information on sed, please click here
> file.txt
- Send the output to a text file
These are all four of the commands that I have had to create to get the information I needed in a timely manner.