openraven/security-rules

Ransomware Policy

kickroot opened this issue · 11 comments

Sources:

https://github.com/awslabs/aws-security-assessment-solution

  • AWS Core security services enabled (GuardDuty, SecurityHub)
  • Checks for EBS volumes with no snapshot
  • Checks for S3 bucket replication JobStatus
  • Checks for EC2 instances that can not be managed with SSM
  • Checks for Stale IAM roles that have been granted S3 access but have not used them in the last 60 days
  • Checks for S3 deny public access enablement

Discussed with Jason to check the MFA Delete flags on the S3 buckets
Rule which check if MFA Delete is disabled (violation)

As discussed with Jason:

  1. Check if there any assets in region there should be GuardDuty, SecurityHub enabled for that region

GuardDuty configuration on Jason stack

AWS::GuardDuty::Detector | ap-northeast-1
AWS::GuardDuty::Detector | ap-northeast-2
AWS::GuardDuty::Detector | ap-south-1
AWS::GuardDuty::Detector | ap-southeast-1
AWS::GuardDuty::Detector | ap-southeast-2
AWS::GuardDuty::Detector | ca-central-1
AWS::GuardDuty::Detector | eu-central-1
AWS::GuardDuty::Detector | eu-north-1
AWS::GuardDuty::Detector | eu-west-1
AWS::GuardDuty::Detector | eu-west-2
AWS::GuardDuty::Detector | eu-west-3
AWS::GuardDuty::Detector | sa-east-1
AWS::GuardDuty::Detector | us-east-1-fips
AWS::GuardDuty::Detector | us-east-2-fips
AWS::GuardDuty::Detector | us-west-1-fips
AWS::GuardDuty::Detector | us-west-2-fips

Checks for S3 bucket replication JobStatus
If Im not mistaken the Replication status is an Object level attribute describing replication state for chosen object:
https://docs.aws.amazon.com/AmazonS3/latest/userguide/replication-status.html
Assuming that we would need to grab metadata of all object in all buckets for specified region.
Screenshot 2021-07-30 at 16 09 34

On the bucket level it just the configuration for replication rule, for example surprise-bucket:

"replicationConfiguration": {
    "role": "arn:aws:iam::723176279592:role/jason-test-moped-MasterIamRole-JWNLPBPWH90W",
    "rules": [
      {
        "id": "test-rule-id",
        "filter": {
          "and": null,
          "tag": null,
          "prefix": null
        },
        "prefix": null,
        "status": "Enabled",
        "priority": 0,
        "destination": {
          "bucket": "arn:aws:s3:::gutenberg-project-saved-texts",
          "account": null,
          "metrics": null,
          "storageClass": null,
          "replicationTime": null,
          "encryptionConfiguration": null,
          "accessControlTranslation": null
        },
        "deleteMarkerReplication": {
          "status": "Disabled"
        },
        "sourceSelectionCriteria": null,
        "existingObjectReplication": null
      }
    ]
  },

As discussed with @kickroot we will create another policy AWS-Ransomware-Policy and link existing rules there

@kickroot FYI
Checks for Stale IAM roles that have been granted S3 access but have not used them in the last 60 days

Queries are ready for this role processing but we have problem with AWS Java SDK v2.
IAMClient.listRolesPaginator doesn't return the roleLastUsed data for each role in request
On the other hand direct request to getRole(..) return that data.
Same here discussed: boto/boto3#2297 (comment)

The only solution for us will be to request role data directly by its name for each encountered roles from listRolesPaginator response.
Benchmarks: for 55 Roles on your account we are dropping down by additional 10 seconds to get data for each role

Below simple test verify this behaviour:

  @Test
  public void testS3Discovery() {
    System.getProperties().setProperty("aws.accessKeyId", "<replace me>");
    System.getProperties().setProperty("aws.secretAccessKey", "<remplace me>/");

    // when
    IamClient client = AWSUtils.configure(IamClient.builder(), BASE_REGION);
    client.listRolesPaginator().roles().forEach(listedRole -> {
      Role role = client.getRole(builder -> builder.roleName(listedRole.roleName()).build()).role();

      assertNull(listedRole.roleLastUsed()); // <-- listed has no last access data
      assertNotNull(role.roleLastUsed()); // <-- direct request return complete role data WITH lastUsed data
      
      System.out.println("Role name: " + role.arn() + " rolelastUsed: " + role.roleLastUsed());
    });
  }

Role configuration asset (roleLastUsed - null)

{
   "arn":"arn:aws:iam::723176279592:role/GitLabInfrastructure",
   "path":"/",
   "tags":null,
   "roleId":"AROA2QYFKJYULIM52RUPV",
   "roleName":"GitLabInfrastructure",
   "createDate":"2020-09-23T20:54:20Z",
   "description":"",
   "roleLastUsed":null,
   "maxSessionDuration":3600,
   "permissionsBoundary":null,
   "assumeRolePolicyDocument":"%7B%22Version%22%3A%222012-10-17%22%2C%22Statement%22%3A%5B%7B%22Effect%22%3A%22Allow%22%2C%22Principal%22%3A%7B%22AWS%22%3A%22arn%3Aaws%3Aiam%3A%3A487193801865%3Aroot%22%7D%2C%22Action%22%3A%22sts%3AAssumeRole%22%7D%5D%7D"
}

Thanks Maksym. Go ahead and make the getRole() call.

Checks for EBS volumes with no snapshot - done

Checks for EC2 instances that can not be managed with SSM
Will be delivered in terms of the separate PR @kickroot