PROWLER GROUPS, CHECKS, AND WHAT THEY MEAN, PART 3

As spoken prior in PROWLING WITH S.A.F.H. (OR THE HANGOVER.) Prowler is heavily based on the CIS benchmarks for AWS. Those benchmarks are broken into a series of groups:

  • Check11 to Check122 – From section 1 (Identity and Access Management)
  • Check21 to Check29 – From Section 2 (Logging)
  • Check31 to Check314 – From Section 3 (Monitoring)
  • Check41 to Check46 – From Section 4 (Networking)
  • Check71 to Check799 – From the InfoSec Community, GASSP-based checks are specific to the AWS environment.

Also, as spoken prior, If your security practitioner makes a suggestion, it is a recommendation based on his knowledge, experience, and the standards provided by various standards committees and the infosec community; again, NOT A SUBSTITUTE for advice from a compliance attorney.”

We will start a prowler run with my default profile, linked to a test account, and specify group 3. This maps to the CIS AWS Foundation benchmark, Monitoring.

I will invoke prowler from the prowler directory of my space heater server with the following command:

./prowler -g group3 -f "us-east-1"

This will start a prowler run, limiting it to the us-east-1 region and using only the checks from group 3.

We have the results as follows:

 Color code for results:
 -  INFO (Information)
 -  PASS (Recommended value)
 -  WARNING (Ignored by allowlist)
 -  FAIL (Fix required)

 This report is being generated using credentials below:

 AWS-CLI Profile: [default] AWS API Region: [us-east-1] AWS Filter Region: [us-east-1]
 AWS Account: [REDACTED] UserId: [REDACTED]
 Caller Identity ARN: [arn:aws:iam::REDACTED]

3.1 [check31] Ensure a log metric filter and alarm exist for unauthorized API calls - iam [Medium]
       FAIL! us-east-1: CloudWatch group c5-trail-watch found but no metric filters or alarms associated
3.2 [check32] Ensure a log metric filter and alarm exist for Management Console sign-in without MFA - iam [Medium]
       FAIL! us-east-1: CloudWatch group c5-trail-watch found but no metric filters or alarms associated
3.3 [check33] Ensure a log metric filter and alarm exist for usage of root account - iam [Medium]
       FAIL! us-east-1: CloudWatch group c5-trail-watch found but no metric filters or alarms associated
3.4 [check34] Ensure a log metric filter and alarm exist for IAM policy changes - iam [Medium]
       FAIL! us-east-1: CloudWatch group c5-trail-watch found but no metric filters or alarms associated
3.5 [check35] Ensure a log metric filter and alarm exist for CloudTrail configuration changes - cloudtrail [Medium]
       FAIL! us-east-1: CloudWatch group c5-trail-watch found but no metric filters or alarms associated
3.6 [check36] Ensure a log metric filter and alarm exist for AWS Management Console authentication failures - iam [Medium]
       FAIL! us-east-1: CloudWatch group c5-trail-watch found but no metric filters or alarms associated
3.7 [check37] Ensure a log metric filter and alarm exist for disabling or scheduled deletion of customer created KMS CMKs - kms [Medium]
       FAIL! us-east-1: CloudWatch group c5-trail-watch found but no metric filters or alarms associated
3.8 [check38] Ensure a log metric filter and alarm exist for S3 bucket policy changes - s3 [Medium]
       FAIL! us-east-1: CloudWatch group c5-trail-watch found but no metric filters or alarms associated
3.9 [check39] Ensure a log metric filter and alarm exist for AWS Config configuration changes - configservice [Medium]
       FAIL! us-east-1: CloudWatch group c5-trail-watch found but no metric filters or alarms associated
3.10 [check310] Ensure a log metric filter and alarm exist for security group changes - ec2 [Medium]
       FAIL! us-east-1: CloudWatch group c5-trail-watch found but no metric filters or alarms associated
3.11 [check311] Ensure a log metric filter and alarm exist for changes to Network Access Control Lists (NACL) - vpc [Medium]
       FAIL! us-east-1: CloudWatch group c5-trail-watch found but no metric filters or alarms associated
3.12 [check312] Ensure a log metric filter and alarm exist for changes to network gateways - vpc [Medium]
       FAIL! us-east-1: CloudWatch group c5-trail-watch found but no metric filters or alarms associated
3.13 [check313] Ensure a log metric filter and alarm exist for route table changes - vpc [Medium]
       FAIL! us-east-1: CloudWatch group c5-trail-watch found but no metric filters or alarms associated
3.14 [check314] Ensure a log metric filter and alarm exist for VPC changes - vpc [Medium]
       FAIL! us-east-1: CloudWatch group c5-trail-watch found but no metric filters or alarms associated

Hmmm, On the surface, it does seem that the fail-fairy has paid us an extended visit. But let us examine several of these to find the source of the failure, if there is one.

Examining the benchmark for check 3.1, we find :

The key phrase here is CloudWatch Logs and establishing corresponding metric filters and alarms. The CIS benchmark and prowler are looking for Cloudwatch Alarms to be in place similar to the ones described here.

As I use another set of tools (C4 and Wazuh) to filter my Cloudwatch logs and generate alerts, I do not have these items in place, thusly generating a massive failure in the vision of prowler.

A general discussion of the intent of the recommendations is in order, with the caveat that this is in MY HUMBLE OPINION and does not comprise legal or compliance advice. As always, review any code or examples as per O.P.C. Other People’s Code. As the 60’s automobile commercials always said, “Your mileage may vary.”

For check 31, Ensure a log metric filter and alarm exist for unauthorized API calls, I would filter my cloudtrail logs for any error code of UnauthorizedOperation or AccessDenied and set an action as defined by my compliance group. A single error may not necessitate an alert or a response; repetitive failures would warrant investigation. The number of repeated errors and time frame would be defined by the compliance group.

A SAMPLE Wazuh rule MIGHT resemble (from the Wazuh 0350-amazon-rules.xml file):

<!-- Events with errors -->
  <rule id="80250" level="5">
    <if_sid>80203</if_sid>
    <field name="aws.errorCode">AccessDenied</field>
    <options>no_full_log</options>
    <description>AWS Cloudtrail: $(aws.eventSource) - $(aws.eventName). Error: $(aws.errorCode).</description>
  </rule>

For check 32, Ensure a log metric filter and alarm exist for Management Console sign-in without MFA; I would filter my cloudtrails logs for event name “ConsoleLogin” and aws.additionalEventData.MFAUsed equaling “No”. Any event of a console login without MFA warrants investigation on a priority basis.

A SAMPLE Wazuh ruleset MIGHT resemble:

 Base rule to detect a login 
 <!-- Someone logged in, we do not care, but we will log it -->
  <rule id="150020" level="3">
    <if_sid>80202</if_sid>
    <field name="aws.eventName">ConsoleLogin</field>
    <options>no_full_log</options>
    <description>AWS Cloudtrail: Account: $(aws.aws_account_id) $(aws.eventSource) - $(aws.eventName) - User: $(aws.userIdentity.userName) login success.</description>
  </rule>
  
Chained rule to detect login without MFA
  <!-- Someone logged in without MFA - Log, Email and slack -->
    <rule id="150021" level="11">
    <if_sid>150020</if_sid>
    <field name="aws.additionalEventData.MFAUsed">No</field>
    <options>no_full_log</options>
    <description>AWS Cloudtrail: Account: $(aws.aws_account_id) $(aws.eventSource) - $(aws.eventName) - User: $(aws.userIdentity.userName) login No MFA.</description>
  </rule>

Check 3.3 Ensure a log metric filter and alarm exist for usage of the “root” account; similar to above, I would filter my cloudtrails events for the event name “ConsoleLogin” and userIdentity.Type equaling “Root.” Any event trapped by this should warrant immediate investigation.

A SAMPLE Wazuh ruleset MIGHT resemble:

BASIC RULE TO DETECT CONSOLE LOGIN 
<!-- Someone logged in, we do not care, but we will log it -->
  <rule id="150020" level="3">
    <if_sid>80202</if_sid>
    <field name="aws.eventName">ConsoleLogin</field>
    <options>no_full_log</options>
    <description>AWS Cloudtrail: Account: $(aws.aws_account_id) $(aws.eventSource) - $(aws.eventName) - User: $(aws.userIdentity.userName) login success.</description>
  </rule>
  
 
 CHAINED RULE TO DETECT ROOT LOGIN 
   <!-- ROOT logged in - Log, Email and slack -->
    <rule id="150022" level="11">
    <if_sid>150020</if_sid>
    <field name="aws.userIdentity.Type">Root</field>
    <options>no_full_log</options>
    <description>AWS Cloudtrail: Account: $(aws.aws_account_id) $(aws.eventSource) - $(aws.eventName) - $(aws.sourceIPAddress) - Root login.</description>
  </rule>

Check 3.4 Ensure a log metric filter and alarm exist for IAM policy changes; I would filter my cloudtrails logs for several events. The ones specified by the CIS Benchmark are as follows:

  • DeleteGroupPolicy
  • DeleteRolePolicy
  • DeleteUserPolicy
  • PutGroupPolicy
  • PutRolePolicy
  • PutUserPolicy
  • CreatePolicy
  • DeletePolicy
  • CreatePolicyVersion
  • DeletePolicyVersion
  • AttachRolePolicy
  • DetachRolePolicy
  • AttachUserPolicy
  • DetachUserPolicy
  • AttachGroupPolicy
  • DetachGroupPolicy

A SAMPLE TEMPLATE FOR A set of Wazuh rules MIGHT resemble:

  <!-- A SecurityGroup was created, we do not care, but we will log it -->
  <rule id="150050" level="3">
    <if_sid>80202</if_sid>
    <field name="aws.eventName">(INSERT_EVENT_NAME_HERE)</field>
    <options>no_full_log</options>
	<group>CIS_3,CIS_3.4,</group>
    <description>AWS Cloudtrail: Account: $(aws.aws_account_id) $(aws.eventSource) - $(aws.eventName) - User: $(aws.userIdentity.userName) <EVENT_NAME>.</description>
  </rule>

Note the level and any modifying rules (higher alert levels on repetition, filtering for specific permissions, etc.) are at the direction of the compliance group.

Check 3.5 Ensure a log metric filter and alarm exist for CloudTrail configuration changes; this is quite similar to check 3.4., the CIS Benchmark calls out the following events to filter for:

  • CreateTrail
  • UpdateTrail
  • DeleteTrail
  • StartLogging
  • StopLogging

I would treat the UpdateTrail, DeleteTrail, and StopLogging at a much higher alert level than the others; as such, those would elicit an immediate investigation. Sample Wazuh rules might follow the template above.

Check 3.6 Ensure a log metric filter and alarm exist for AWS Management Console authentication failures, similar to check 32. I would filter my cloudtrails logs for event name “ConsoleLogin” and aws.responseElements.ConsoleLogin equaling Failure. Any repeated event of a console login failure warrants investigation on a priority basis. The number of repetitions and time frame is at the discretion of the compliance group

A SAMPLE Wazuh ruleset MIGHT resemble:

Base rule to detect console login  
<!-- Someone logged in without MFA - Log, Email and slack -->
    <rule id="150021" level="11">
    <if_sid>150020</if_sid>
    <field name="aws.additionalEventData.MFAUsed">No</field>
    <options>no_full_log</options>
    <description>AWS Cloudtrail: Account: $(aws.aws_account_id) $(aws.eventSource) - $(aws.eventName) - User: $(aws.userIdentity.userName) login No MFA.</description>
  </rule>

Chained rule to detect failed logins
  <!-- Login Failure - Log -->
    <rule id="150030" level="5">
    <if_sid>80202</if_sid>
    <field name="aws.responseElements.ConsoleLogin">Failure</field>
    <options>no_full_log</options>
    <description>AWS Cloudtrail: Account: $(aws.aws_account_id) $(aws.eventSource) - $(aws.eventName) - $(aws.userIdentity.userName - User login failed.</description>
  </rule>

Chained Rule to detect Repeated Failures
  <!-- Multiple Login Failures - Log, Email, Slack -->  
    <rule id="150031" level="11" frequency="6" timeframe="360">
    <if_matched_sid>150030</if_matched_sid>
    <options>no_full_log</options>
    <description>AWS Cloudtrail: Account: $(aws.aws_account_id) $(aws.eventSource) - $(aws.eventName) - Possible break in attempt $(aws.userIdentity.userName.</description>
  </rule>
 

Check 3.7 Ensure a log metric filter and alarm exist for disabling or scheduled deletion of customer created CMKs; this is quite similar to check 3.4., the CIS Benchmark calls out the following events to filter for:

  • DisableKey
  • ScheduleKeyDeletion

Sample Wazuh rules might follow the template above in check 3.4.

Check 3.8 Ensure a log metric filter and alarm exist for S3 bucket policy changes; this is quite similar to check 3.4., the CIS Benchmark calls out the following events to filter for:

  • PutBucketAcl
  • PutBucketPolicy
  • PutBucketCors
  • PutBucketLifecycle
  • PutBucketReplication
  • DeleteBucketPolicy
  • DeleteBucketCors
  • DeleteBucketLifecycle
  • DeleteBucketReplication

Sample Wazuh rules might follow the template above in check 3.4.

Check 3.9 Ensure a log metric filter and alarm exist for AWS Config configuration changes; this is quite similar to check 3.4., the CIS Benchmark calls out the following events to filter for:

  • StopConfigurationRecorder
  • DeleteDeliveryChannel
  • PutDeliveryChannel
  • PutConfigurationRecorder

Sample Wazuh rules might follow the template above in check 3.4.

INTERMISSION: If you, the reader, are becoming bored with reading this, consider how tedious it is to write.

This is the life cycle of Information Security; we start out with a new environment and new requirements, creating new tools and expanding the knowledge corpus. Then it all becomes repetitious, solving similar requirements with the same tools, just minimal changes. Listening to a new standards committee say the same things differently, but all couched in vague one-size-fits-all, but-none-well language.

And back to CIS abuse (CIS Benchmark abuse, that is.)

Check 3.10 Ensure a log metric filter and alarm exist for security group changes; this is quite similar to check 3.4., the CIS Benchmark calls out the following events to filter for:

  • AuthorizeSecurityGroupIngress
  • AuthorizeSecurityGroupEgress
  • RevokeSecurityGroupIngress
  • RevokeSecurityGroupEgress
  • CreateSecurityGroup
  • DeleteSecurityGroup

On the surface, just applying the Wazuh Rule Template in check 3.4 with the list of event names would suffice, and it would suffice to check a box. But let’s examine this a bit more deeply. The real threat is not relly an outsider changing your security groups but someone inadvertently leaving a management port (22 or 3389) open to 0.0.0.0/0, exposing a critical resource to ongoing brute force attacks. (You are sending your system logs to a SIEM, RIGHT?)

So a SAMPLE Wazuh Ruleset MIGHT resemble:

Base Rule to capture INGRESS Security Group Rule Creation
  
  <!-- Chained Rule Searching for 0/0 as ingress with wide open for all ports, ssh, rdp -->
   <rule id="150051" level="3">
    <if_sid>80202</if_sid>
    <field name="aws.eventName">AuthorizeSecurityGroupIngress</field>
    <options>no_full_log</options>
    <description>AWS Cloudtrail: Account: $(aws.aws_account_id) $(aws.eventSource) - $(aws.eventName) - User: $(aws.userIdentity.userName) SecurityGroup Created.</description>
		<group>CIS_4,CIS_4.10,</group>
  </rule>
  
 Chained Rule to find 0/0 Allowed
  <!-- Filter for 0/0 -->
  <rule id="150053" level="7">
	<if_sid>150051</if_sid>
    <field name="aws.responseElements.securityGroupRuleSet.items.cidrIpv4">0.0.0.0/0</field>
    <options>no_full_log</options>
    <description>AWS Cloudtrail: Account: $(aws.aws_account_id) User: $(aws.userIdentity.userName) $(aws.requestParameters.groupId) SecurityGroup Created.</description>
	<group>CIS_4,CIS_4.10,</group>
  </rule>
  
Chained rule to find an ingress rule allowing ALL traffic from 0/0
  <!--  Winner, Winner We have an idiot - Check for Wide Open -->
   <rule id="150054" level="12">
	<if_sid>150053</if_sid>
    <field name="aws.requestParameters.ipPermissions.items.ipProtocol">-1</field>
    <options>no_full_log</options>
    <description>AWS Cloudtrail: Account: $(aws.aws_account_id) User: $(aws.userIdentity.userName) $(aws.requestParameters.groupId) ALL TRAFFIC WIDE OPEN !!</description>
	<group>CIS_4,CIS_4.10,</group>
  </rule>

Chained rule to find an ingress rule allowing ssh (port 22) Traffic from 0/0
  <!--  Winner, Winner We have an idiot - SSH Wide Open -->
   <rule id="150055" level="12">
	<if_sid>150053</if_sid>
    <field name="aws.responseElements.securityGroupRuleSet.items.fromPort">22</field>
    <options>no_full_log</options>
    <description>AWS Cloudtrail: Account: $(aws.aws_account_id) User: $(aws.userIdentity.userName) $(aws.requestParameters.groupId) SSH WIDE OPEN !!</description>
	<group>CIS_4,CIS_4.10,</group>
  </rule>

Note one can replicate the chained rule set in lines 32 – 40, incrementing the rule id and changing the port as necessary.

Ports that should also be checked for are :

  • SSH port 22
  • RDP port 3389
  • Oracle ports 1521 or 2483
  • MySQL port 3306
  • Postgres port 5432
  • MongoDB ports 27017 and 27018
  • Cassandra ports 7199 or 9160 or 8888
  • Memcached port 11211
  • FTP ports 20 or 21
  • Kafka port 9092
  • Telnet port 23
  • SQL Server ports 1433 or 1444
  • Redis port 6379
  • Elasticsearch/Kibana ports 9200 and 9300 or others as configured

These should trigger a critical alert and warrant immediate action.

Frankly, IN MY OPINION, only two ports may need to be open to 0/0. They are 80 and 443, and most times, I’m not sure about 80 being required.

Check 3.11 Ensure a log metric filter and alarm exist for changes to Network Access Control Lists (NACL); this is quite similar to check 3.4., the CIS Benchmark calls out the following events to filter for:

  • CreateNetworkAcl
  • CreateNetworkAclEntry
  • DeleteNetworkAcl
  • DeleteNetworkAclEntry
  • ReplaceNetworkAclEntry
  • ReplaceNetworkAclAssociation

Sample Wazuh rules might follow the template above in check 3.4. In my experience, NACLS do not change frequently, so any alerts for these should be reviewed promptly.

Check 3.12 Ensure a log metric filter and alarm exist for changes to network gateways; this is quite similar to check 3.4., the CIS Benchmark calls out the following events to filter for:

  • CreateCustomerGateway
  • DeleteCustomerGateway
  • AttachInternetGateway
  • CreateInternetGateway
  • DeleteInternetGateway
  • DetachInternetGateway

Sample Wazuh rules might follow the template above in check 3.4. In my experience, network gateways do not change frequently, so any alerts for these should be reviewed promptly.

Check 3.13 Ensure a log metric filter and alarm exist for route table changes; this is quite similar to check 3.4., the CIS Benchmark calls out the following events to filter for:

  • CreateRoute
  • CreateRouteTable
  • ReplaceRoute
  • ReplaceRouteTableAssociation
  • DeleteRouteTable
  • DeleteRoute
  • DisassociateRouteTable

Sample Wazuh rules might follow the template above in check 3.4. In my experience, route tables change infrequently, so any alerts for these should be reviewed promptly.

Check 3.14 Ensure a log metric filter and alarm exist for VPC changes; this is quite similar to check 3.4., the CIS Benchmark calls out the following events to filter for:

  • CreateVpc
  • DeleteVpc
  • ModifyVpcAttribute
  • AcceptVpcPeeringConnection
  • CreateVpcPeeringConnection
  • DeleteVpcPeeringConnection
  • RejectVpcPeeringConnection
  • AttachClassicLinkVpc
  • DetachClassicLinkVpc
  • DisableVpcClassicLink
  • EnableVpcClassicLink

Sample Wazuh rules might follow the template above in check 3.4. In my experience, VPCs change infrequently, so any alerts for these should be reviewed promptly.

The Wazuh Rule Template in check 34 is a fairly blunt instrument, and at some point (probably in a Wazuh Rules Post), we will discuss doing this more elegantly, but for now, this serves the need. (The Code Critics out there can stop laughing; otherwise, you might get pasta sauce on your monogrammed shirt.)

This little missive has been a bit longer than I had anticipated and a bit more annoying; I swear I could have put together an emacs macro to write 80% of this, but we did cover a lot of ground and start to introduce Wazuh basic rules and Wazuh chained rules, so it was well worth the time to write. And I hope it was well worth your time to read.

We’ll be back with part 4, part x, and a summary post to round up this series.