Skip to content

Commit

Permalink
AWS provider login checks
Browse files Browse the repository at this point in the history
  • Loading branch information
christophetd committed Jan 13, 2022
1 parent 02a0c1b commit a4edbbf
Show file tree
Hide file tree
Showing 10 changed files with 66 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Detonation: Calls ModifySnapshotAttribute to share the snapshot.
}

func detonate(params map[string]string) error {
ec2Client := ec2.NewFromConfig(providers.GetAWSProvider())
ec2Client := ec2.NewFromConfig(providers.AWS().GetConnection())

// Find the snapshot to exfiltrate
ourSnapshotId := params["snapshot_id"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ terraform {
}
}
}
provider "aws" {
skip_region_validation = true
skip_credentials_validation = true
skip_get_ec2_platforms = true
skip_metadata_api_check = true
}

data "aws_availability_zones" "available" {
state = "available"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Detonation: Create the access key.
MitreAttackTactics: []mitreattack.Tactic{mitreattack.Persistence},
PrerequisitesTerraformCode: tf,
Detonate: func(terraformOutputs map[string]string) error {
iamClient := iam.NewFromConfig(providers.GetAWSProvider())
iamClient := iam.NewFromConfig(providers.AWS().GetConnection())
log.Println("Creating access key on legit IAM user to simulate backdoor")
result, err := iamClient.CreateAccessKey(context.Background(), &iam.CreateAccessKeyInput{UserName: aws.String("sample-legit-user")})
if err != nil {
Expand All @@ -37,7 +37,7 @@ Detonation: Create the access key.
return nil
},
Cleanup: func() error {
iamClient := iam.NewFromConfig(providers.GetAWSProvider())
iamClient := iam.NewFromConfig(providers.AWS().GetConnection())
log.Println("Removing access key from IAM user")
result, err := iamClient.ListAccessKeys(context.Background(), &iam.ListAccessKeysInput{UserName: aws.String("sample-legit-user")})
if err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ terraform {
}
}
}
provider "aws" {
skip_region_validation = true
skip_credentials_validation = true
skip_get_ec2_platforms = true
skip_metadata_api_check = true
}

resource "aws_iam_user" "legit-user" {
name = "sample-legit-user" # TODO parametrize
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Detonation: Updates the assume role policy of the IAM role to backdoor it.
MitreAttackTactics: []mitreattack.Tactic{mitreattack.Persistence},
PrerequisitesTerraformCode: tf,
Detonate: func(terraformOutputs map[string]string) error {
iamClient := iam.NewFromConfig(providers.GetAWSProvider())
iamClient := iam.NewFromConfig(providers.AWS().GetConnection())
log.Println("Backdooring IAM role by allowing sts:AssumeRole from an extenral AWS account")
_, err := iamClient.UpdateAssumeRolePolicy(context.Background(), &iam.UpdateAssumeRolePolicyInput{
RoleName: aws.String("sample-legit-role"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ terraform {
}
}
}
provider "aws" {
skip_region_validation = true
skip_credentials_validation = true
skip_get_ec2_platforms = true
skip_metadata_api_check = true
}

resource "aws_iam_role" "legit-role" {
name = "sample-legit-role" # TODO parametrize
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Detonation: Creates the IAM user and attached 'AdministratorAccess' to it.
Platform: stratus.AWS,
MitreAttackTactics: []mitreattack.Tactic{mitreattack.Persistence},
Detonate: func(terraformOutputs map[string]string) error {
iamClient := iam.NewFromConfig(providers.GetAWSProvider())
iamClient := iam.NewFromConfig(providers.AWS().GetConnection())
log.Println("Creating a malicious IAM user")
_, err := iamClient.CreateUser(context.TODO(), &iam.CreateUserInput{
UserName: userName,
Expand Down Expand Up @@ -61,7 +61,7 @@ Detonation: Creates the IAM user and attached 'AdministratorAccess' to it.
return nil
},
Cleanup: func() error {
iamClient := iam.NewFromConfig(providers.GetAWSProvider())
iamClient := iam.NewFromConfig(providers.AWS().GetConnection())
result, err := iamClient.ListAccessKeys(context.Background(), &iam.ListAccessKeysInput{UserName: userName})
if err != nil {
return errors.New("unable to clean up IAM user access keys: " + err.Error())
Expand Down
39 changes: 24 additions & 15 deletions internal/providers/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,35 @@ import (
"context"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/sts"
"log"
)

var isAuthenticated = false
var hasDeterminedIfAuthenticated = false
var awsProvider = AWSProvider{}

func init() {
/*aws, _ := config.LoadDefaultConfig(context.TODO())
stsClient := sts.NewFromConfig(aws)
_, err := stsClient.GetCallerIdentity(context.Background(), &sts.GetCallerIdentityInput{})
isAuthenticated = err == nil*/
func AWS() *AWSProvider {
return &awsProvider
}

type AWSProvider struct {
awsConfig *aws.Config
}

func GetAWSProvider() aws.Config {
/*if !isAuthenticated {
log.Fatal("You are not authenticated to AWS, or have not set your default AWS region.")
}*/
cfg, err := config.LoadDefaultConfig(context.TODO())
if err != nil {
log.Fatalf("unable to load SDK config, %v", err)
func (m *AWSProvider) GetConnection() aws.Config {
if m.awsConfig == nil {
cfg, err := config.LoadDefaultConfig(context.Background())
if err != nil {
log.Fatalf("unable to load AWS configuration, %v", err)
}
m.awsConfig = &cfg
}
return cfg

return *m.awsConfig
}

func (m *AWSProvider) IsAuthenticatedAgainstAWS() bool {
m.GetConnection()
stsClient := sts.NewFromConfig(m.GetConnection())
_, err := stsClient.GetCallerIdentity(context.Background(), &sts.GetCallerIdentityInput{})
return err == nil
}
19 changes: 18 additions & 1 deletion internal/runner/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package runner
import (
"encoding/json"
"errors"
"github.com/datadog/stratus-red-team/internal/providers"
"github.com/datadog/stratus-red-team/internal/utils"
"github.com/datadog/stratus-red-team/pkg/stratus"
"io/ioutil"
Expand All @@ -28,13 +29,20 @@ type Runner struct {

func NewRunner(technique *stratus.AttackTechnique, warmup bool, cleanup bool) Runner {
stateManager := NewStateManager()
return Runner{
runner := Runner{
Technique: technique,
ShouldWarmUp: warmup,
ShouldCleanup: cleanup,
TerraformManager: NewTerraformManager(path.Join(stateManager.GetRootDirectory(), "terraform")),
StateManager: stateManager,
}
runner.initialize()

return runner
}

func (m *Runner) initialize() {
m.ValidatePlatformRequirements()
}

// Utility function to extract the Terraform file of a technique
Expand Down Expand Up @@ -136,3 +144,12 @@ func (m *Runner) CleanUp() error {
return prerequisitesCleanupErr
}
}

func (m *Runner) ValidatePlatformRequirements() {
switch m.Technique.Platform {
case stratus.AWS:
if !providers.AWS().IsAuthenticatedAgainstAWS() {
log.Fatal("You are not authenticated against AWS, or you have not set your region.")
}
}
}
2 changes: 0 additions & 2 deletions internal/runner/terraform.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package runner
import (
"context"
"errors"
"fmt"
"github.com/datadog/stratus-red-team/internal/utils"
"github.com/hashicorp/go-version"
"github.com/hashicorp/hc-install/product"
Expand All @@ -22,7 +21,6 @@ type TerraformManager struct {
}

func NewTerraformManager(terraformBinaryPath string) *TerraformManager {
fmt.Println(terraformBinaryPath)
manager := TerraformManager{
terraformVersion: TerraformVersion,
terraformBinaryPath: terraformBinaryPath,
Expand Down

0 comments on commit a4edbbf

Please sign in to comment.