From bf0e4c9018d83b6a2a42c6b7c6412ae201e711cf Mon Sep 17 00:00:00 2001 From: Dong Liu Date: Tue, 22 Sep 2020 17:41:46 -0700 Subject: [PATCH 1/5] wip --- cloud-inquisitor/aws_cloudfront_resource.go | 92 ++++++++++++++++++- cloud-inquisitor/graph/schema.resolvers.go | 79 ++++++++++++++++ .../patterns/cloudfront_dns_hijacks.json | 1 + 3 files changed, 171 insertions(+), 1 deletion(-) diff --git a/cloud-inquisitor/aws_cloudfront_resource.go b/cloud-inquisitor/aws_cloudfront_resource.go index 59fb227..0f0baeb 100644 --- a/cloud-inquisitor/aws_cloudfront_resource.go +++ b/cloud-inquisitor/aws_cloudfront_resource.go @@ -181,6 +181,58 @@ func (cf *AWSCloudFrontDistributionResource) createDistributionEntries() error { return nil } +func (cf *AWSCloudFrontDistributionResource) deleteDistributionEntries() error { + db, err := database.NewDBConnection() + defer db.Close() + if err != nil { + cf.logger.WithFields(cf.GetMetadata()).Error(err.Error()) + return err + } + + // get account + account := model.Account{AccountID: cf.AccountID} + err = db.FirstOrCreate(&account, account).Error + if err != nil { + cf.logger.WithFields(cf.GetMetadata()).Error(err.Error()) + return err + } + cf.logger.WithFields(cf.GetMetadata()).Debugf("account: %#v", account) + + distro := model.Distribution{DistributionID: cf.DistributionID, Domain: cf.DomainName, AccountID: account.ID} + err = db.Delete(&distro).Error + if err != nil { + cf.logger.WithFields(cf.GetMetadata()).Error(err.Error()) + return err + } + + // delete origins + for _, cfOrigin := range cf.Origins { + origin := model.Origin{ + OriginID: cfOrigin.ID, + Domain: cfOrigin.Domain, + DistributionID: distro.ID, + } + err = db.Delete(&origin).Error + if err != nil { + cf.logger.WithFields(cf.GetMetadata()).Error(err.Error()) + return err + } + + // delete origin groups + for _, cfGroup := range cf.OriginGroups { + group := model.OriginGroup{ + GroupID: cfGroup.ID, + DistributionID: distro.ID, + } + err = db.Delete(&group).Error + if err != nil { + cf.logger.WithFields(cf.GetMetadata()).Error(err.Error()) + return err + } + + return nil +} + func (cf *AWSCloudFrontDistributionResource) updateDistributionEntries() error { db, err := database.NewDBConnection() defer db.Close() @@ -496,6 +548,8 @@ func (cf *AWSCloudFrontDistributionHijackableResource) PublishState() error { switch cf.EventName { case "CreateDistribution": return cf.createDistributionEntries() + case "DeleteDistribution": + return cf.deleteDistributionEntries() case "UpdateDistribution": return cf.updateDistributionEntries() default: @@ -506,5 +560,41 @@ func (cf *AWSCloudFrontDistributionHijackableResource) PublishState() error { } func (cf *AWSCloudFrontDistributionHijackableResource) AnalyzeForHijack() (*model.HijackableResourceChain, error) { - return &model.HijackableResourceChain{}, nil + switch cf.EventName { + case "DeleteDistribution": + return cf.analyzedeleteDistributionEntries() + default: + return &model.HijackableResourceChain{}, nil + } } + +func (cf *AWSCloudFrontDistributionHijackableResourc) analyzedeleteDistributionEntries(*model.HijackableResourceChain, error) { + resolver, err := graph.NewResolver() + if err != nil { + cf.GetLogger().Errorf("error creating a new resolver to evaluate cloudfront hijacks: %v", err.Error()) + return &model.HijackableResourceChain{}, err + } + + domains := make([]string, len(cf.Origins)) + for i, ori := range cf.Origins { + domain[i] = ori.Domain + } + + ctx := context.Background() + chain, err := resolver.Query().HijackChainByDomain( + ctx, + fmt.Sprintf( + "cloudfront-%s-%s-%s", + cf.AccountID, + cf.DistributionID, + cf.DomainName, + ), + domains, + model.TypeDistribution, + ) + if err != nil { + eb.GetLogger().Errorf("error querying graph for cloudfront hijack analysis: %v", err.Error()) + } + + return chain, err +} \ No newline at end of file diff --git a/cloud-inquisitor/graph/schema.resolvers.go b/cloud-inquisitor/graph/schema.resolvers.go index e161db2..7db54ba 100644 --- a/cloud-inquisitor/graph/schema.resolvers.go +++ b/cloud-inquisitor/graph/schema.resolvers.go @@ -461,6 +461,51 @@ func (r *queryResolver) ElasticbeanstalkByEndpoint(ctx context.Context, endpoint return &beanstalk, err } +func (r *queryResolver) GetCloudFrontUpstreamHijack(ctx context.Context, domains []string) ([]*model.HijackableResource, error) { + hijackChain := []*model.HijackableResource{} + + // 1. check origins + for _, domain := range domains { + origins, err := r.Query().PointedAtByOrigin(ctx, domain) + if err != nil { + log.Errorf("error looking up domain %s", domain) + continue + } + + for _, origin := range origins { + completeOrigin, err := r.Query().Origin(ctx, origin.OriginID) + if err != nil { + log.Errorf("error looking up origin with id %v", origin.OriginID) + continue + } + + var account model.Account + err = r.DB.First(&account, origin.OriginID).Error + if err != nil { + log.Errorf("unable to get account for origin %#v", *completeOrigin) + continue + } + hijackChain = append(hijackChain, &model.HijackableResource{ + ID: completeOrigin.OriginID, + Type: model.TypeDistribution, + Account: account.AccountID, + Value: &model.Value{ + ValueID: completeOrigin.Domain, + }, + }) + } + } + + if log.GetLevel() == log.DebugLevel { + log.Debugf("found hijack chain for endpoints: %#v", domains) + for idx, chainElement := range hijackChain { + log.Debugf("%v: %#v", idx, *chainElement) + } + } + + return hijackChain, nil +} + func (r *queryResolver) GetElasticbeanstalkUpstreamHijack(ctx context.Context, endpoints []string) ([]*model.HijackableResource, error) { // elasticbeanstalks are endpoints are only fronted by other resources hijackChain := []*model.HijackableResource{} @@ -554,6 +599,40 @@ func (r *queryResolver) GetElasticbeanstalkUpstreamHijack(ctx context.Context, e func (r *queryResolver) HijackChainByDomain(ctx context.Context, id string, domains []string, typeArg model.Type) (*model.HijackableResourceChain, error) { switch typeArg { + case model.TypeDistribution: + cf, err := r.Query().Distribution(ctx, id) + if err != nil { + log.Errorf("error getting cloudfront: %v", err.Error()) + return nil, err + } + + var account *model.Account = nil + err = r.DB.Find(account, cf.AccountID).Error + if err != nil { + log.Errorf("unable to find account for cloudfront distribution: %#v", *cf) + return nil, err + } + + chain, err := r.Query().GetCloudFrontUpstreamHijack(ctx, domains) + if err != nil { + log.Errorf("recieved error when querying for cloudfront distribution hijacks: %v", err.Error()) + return nil, err + } + + return &model.HijackableResourceChain{ + ID: id, + Resource: &model.HijackableResource{ + ID: id, + Account: account.AccountID, + Type: model.TypeElasticbeanstalk, + Value: &model.Value{ + ValueID: cf.Domain, + }, + }, + Upstream: chain, + Downstream: []*model.HijackableResource{}, + }, err + case model.TypeElasticbeanstalk: /* ID string `json:"id"` diff --git a/terraform_modules/event_rule/patterns/cloudfront_dns_hijacks.json b/terraform_modules/event_rule/patterns/cloudfront_dns_hijacks.json index d69ef29..88e7094 100644 --- a/terraform_modules/event_rule/patterns/cloudfront_dns_hijacks.json +++ b/terraform_modules/event_rule/patterns/cloudfront_dns_hijacks.json @@ -11,6 +11,7 @@ ], "eventName": [ "CreateDistribution", + "DeleteDistribution", "UpdateDistribution" ] } From cbf4cb1f4ea25ab53d3f17dda669b412e2401c91 Mon Sep 17 00:00:00 2001 From: Dong Liu Date: Tue, 29 Sep 2020 23:45:40 -0700 Subject: [PATCH 2/5] wip --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 50d6977..f6fbc56 100644 --- a/.gitignore +++ b/.gitignore @@ -689,3 +689,4 @@ settings.json main.tf builds/** cinqctl +.scratch \ No newline at end of file From abf15436df78cfbdd82d6ff0ebab7951e19c22e5 Mon Sep 17 00:00:00 2001 From: Dong Liu Date: Wed, 30 Sep 2020 13:39:36 -0700 Subject: [PATCH 3/5] wip --- cloud-inquisitor/aws_cloudfront_resource.go | 24 +++++--- cloud-inquisitor/graph/model/models_gen.go | 8 +-- cloud-inquisitor/notification/templates.go | 68 +++------------------ 3 files changed, 30 insertions(+), 70 deletions(-) diff --git a/cloud-inquisitor/aws_cloudfront_resource.go b/cloud-inquisitor/aws_cloudfront_resource.go index 0f0baeb..278b277 100644 --- a/cloud-inquisitor/aws_cloudfront_resource.go +++ b/cloud-inquisitor/aws_cloudfront_resource.go @@ -559,20 +559,26 @@ func (cf *AWSCloudFrontDistributionHijackableResource) PublishState() error { return nil } -func (cf *AWSCloudFrontDistributionHijackableResource) AnalyzeForHijack() (*model.HijackableResourceChain, error) { +func (cf *AWSCloudFrontDistributionHijackableResource) AnalyzeForHijack() (*model.HijackableResourceRoot, error) { switch cf.EventName { + case "CreateDistribution": + return cf.analyzeCreateDistributionEntries() case "DeleteDistribution": - return cf.analyzedeleteDistributionEntries() + return cf.analyzeDeleteDistributionEntries() default: - return &model.HijackableResourceChain{}, nil + return &model.HijackableResourceRoot{}, nil } } -func (cf *AWSCloudFrontDistributionHijackableResourc) analyzedeleteDistributionEntries(*model.HijackableResourceChain, error) { +func (cf *AWSCloudFrontDistributionHijackableResource) analyzeDeleteDistributionEntries(*model.HijackableResourceRoot, error) { + return cf.analyzeDeleteDistributionEntries() +} + +func (cf *AWSCloudFrontDistributionHijackableResource) analyzeDeleteDistributionEntries(*model.HijackableResourceRoot, error) { resolver, err := graph.NewResolver() if err != nil { cf.GetLogger().Errorf("error creating a new resolver to evaluate cloudfront hijacks: %v", err.Error()) - return &model.HijackableResourceChain{}, err + return &model.HijackableResourceRoot{}, err } domains := make([]string, len(cf.Origins)) @@ -581,20 +587,22 @@ func (cf *AWSCloudFrontDistributionHijackableResourc) analyzedeleteDistributionE } ctx := context.Background() - chain, err := resolver.Query().HijackChainByDomain( + root, err := resolver.Query().GetHijackMapWithResourceIDAndDomainsAndTypeAndDirectionThenFlattened( ctx, fmt.Sprintf( "cloudfront-%s-%s-%s", cf.AccountID, cf.DistributionID, cf.DomainName, - ), + ), + cf.DistributionID, domains, model.TypeDistribution, + model.DirectionDownstream, ) if err != nil { eb.GetLogger().Errorf("error querying graph for cloudfront hijack analysis: %v", err.Error()) } - return chain, err + return root, err } \ No newline at end of file diff --git a/cloud-inquisitor/graph/model/models_gen.go b/cloud-inquisitor/graph/model/models_gen.go index d810173..51341c3 100644 --- a/cloud-inquisitor/graph/model/models_gen.go +++ b/cloud-inquisitor/graph/model/models_gen.go @@ -22,10 +22,10 @@ type HijackableResourceMap struct { } type HijackableResourceRoot struct { - ID string `json:"id"` - RootResourceID string `json:"rootResourceID"` - Direction Direction `json:"direction"` - Maps []*HijackableResourceMap `json:"maps"` + ID string `json:"id"` + RootResource *HijackableResource `json:"rootResourceID"` + Direction Direction `json:"direction"` + Maps []*HijackableResourceMap `json:"maps"` } type Direction string diff --git a/cloud-inquisitor/notification/templates.go b/cloud-inquisitor/notification/templates.go index 9279038..ca11387 100644 --- a/cloud-inquisitor/notification/templates.go +++ b/cloud-inquisitor/notification/templates.go @@ -29,72 +29,24 @@ type HijackNotificationContent struct { HijackChain []HijackChainElement } -func GenerateContent(rawChain *model.HijackableResourceChain) HijackNotificationContent { +func GenerateContent(root *model.HijackableResourceRoot) HijackNotificationContent { content := HijackNotificationContent{ - PrimaryResource: rawChain.Resource.ID, - PrimaryAccountId: rawChain.Resource.Account, - PrimaryResourceType: rawChain.Resource.Type.String(), + PrimaryResource: root.RootResource.Account, + PrimaryAccountId: root.RootResource.Account, + PrimaryResourceType: root.RootResource.Type.String(), } chain := []HijackChainElement{} - for idx, resource := range rawChain.Upstream { - if idx == len(rawChain.Upstream)-1 { - chain = append(chain, HijackChainElement{ - AccountId: resource.Account, - Resource: resource.ID, - ResourceType: resource.Type.String(), - ResourceReferenced: rawChain.Resource.ID, - ResourceReferencedType: rawChain.Resource.Type.String(), - }) - } else { - chain = append(chain, HijackChainElement{ - AccountId: resource.Account, - Resource: resource.ID, - ResourceType: resource.Type.String(), - ResourceReferenced: rawChain.Upstream[idx+1].ID, - ResourceReferencedType: rawChain.Upstream[idx+1].Type.String(), - }) - } - } - - if len(rawChain.Downstream) == 0 { - chain = append(chain, HijackChainElement{ - AccountId: rawChain.Resource.Account, - Resource: rawChain.Resource.ID, - ResourceType: rawChain.Resource.Type.String(), - ResourceReferenced: "not applicable", - ResourceReferencedType: "not applicable", - }) - } else { + for _, element := range root.Maps { chain = append(chain, HijackChainElement{ - AccountId: rawChain.Resource.Account, - Resource: rawChain.Resource.ID, - ResourceType: rawChain.Resource.Type.String(), - ResourceReferenced: rawChain.Downstream[0].ID, - ResourceReferencedType: rawChain.Downstream[0].Type.String(), + AccountId: element.Resource.Account, + Resource: element.Resource.ID, + ResourceType: element.Resource.Type.String(), + ResourceReferenced: root.RootResource.ID, + ResourceReferencedType: root.RootResource.Type.String(), }) } - for idx, resource := range rawChain.Downstream { - if idx == len(rawChain.Downstream)-1 { - chain = append(chain, HijackChainElement{ - AccountId: resource.Account, - Resource: resource.ID, - ResourceType: resource.Type.String(), - ResourceReferenced: "not applicable", - ResourceReferencedType: "not applicable", - }) - } else { - chain = append(chain, HijackChainElement{ - AccountId: resource.Account, - Resource: resource.ID, - ResourceType: resource.Type.String(), - ResourceReferenced: rawChain.Downstream[idx+1].ID, - ResourceReferencedType: rawChain.Downstream[idx+1].Type.String(), - }) - } - } - content.HijackChain = chain return content From 7d64ad2d014dad289a9b1f75142b0132f3b3f85a Mon Sep 17 00:00:00 2001 From: Dong Liu Date: Tue, 6 Oct 2020 10:21:46 -0700 Subject: [PATCH 4/5] wip --- cloud-inquisitor/graph/schema.graphqls | 2 +- cloud-inquisitor/notification/templates.go | 34 ++++---- .../templates/hijack_template.html | 81 +++++++++---------- .../templates/hijack_template.txt | 21 +++-- .../notification/templates_func_test.go | 2 - .../notification/templates_test.go | 70 +++++++--------- .../test_html/hijack_test_no_chain.html | 9 +-- .../test_html/hijack_test_with_chain.html | 21 +---- .../test_text/hijack_test_no_chain.txt | 6 +- .../test_text/hijack_test_with_chain.txt | 14 ++-- 10 files changed, 112 insertions(+), 148 deletions(-) diff --git a/cloud-inquisitor/graph/schema.graphqls b/cloud-inquisitor/graph/schema.graphqls index 6e84867..a9d9f3c 100644 --- a/cloud-inquisitor/graph/schema.graphqls +++ b/cloud-inquisitor/graph/schema.graphqls @@ -84,7 +84,7 @@ type HijackableResource { type HijackableResourceRoot { id: ID! - rootResourceID: ID! + rootResource: HijackableResource! direction: Direction! maps: [HijackableResourceMap!]! } diff --git a/cloud-inquisitor/notification/templates.go b/cloud-inquisitor/notification/templates.go index ca11387..065775b 100644 --- a/cloud-inquisitor/notification/templates.go +++ b/cloud-inquisitor/notification/templates.go @@ -15,39 +15,39 @@ func init() { } type HijackChainElement struct { - AccountId string - Resource string - ResourceType string - ResourceReferenced string - ResourceReferencedType string + AccountId string + Resource string + ResourceType string } type HijackNotificationContent struct { PrimaryResource string PrimaryResourceType string PrimaryAccountId string - HijackChain []HijackChainElement + HijackChains [][]HijackChainElement } func GenerateContent(root *model.HijackableResourceRoot) HijackNotificationContent { content := HijackNotificationContent{ - PrimaryResource: root.RootResource.Account, + PrimaryResource: root.RootResource.ID, PrimaryAccountId: root.RootResource.Account, PrimaryResourceType: root.RootResource.Type.String(), } - chain := []HijackChainElement{} - for _, element := range root.Maps { - chain = append(chain, HijackChainElement{ - AccountId: element.Resource.Account, - Resource: element.Resource.ID, - ResourceType: element.Resource.Type.String(), - ResourceReferenced: root.RootResource.ID, - ResourceReferencedType: root.RootResource.Type.String(), - }) + var hijackChains [][]HijackChainElement + for _, chain := range root.Maps { + hijackChain := []HijackChainElement{} + for _, element := range chain.Contains { + hijackChain = append(hijackChain, HijackChainElement{ + AccountId: element.Resource.Account, + Resource: element.Resource.ID, + ResourceType: element.Resource.Type.String(), + }) + } + hijackChains = append(hijackChains, hijackChain) } - content.HijackChain = chain + content.HijackChains = hijackChains return content } diff --git a/cloud-inquisitor/notification/templates/hijack_template.html b/cloud-inquisitor/notification/templates/hijack_template.html index 59ac00f..2a09b97 100644 --- a/cloud-inquisitor/notification/templates/hijack_template.html +++ b/cloud-inquisitor/notification/templates/hijack_template.html @@ -41,53 +41,46 @@

Potential Domain Hijack Found

Deleting resource {{ .PrimaryResourceType }}:{{ .PrimaryResource }} in AWS account {{ .PrimaryAccountId }} has resulted in a potential domain hijack; there is a DNS record pointing to a resource not owned or no longer owned by us.

-

The following table includes all resources in the chain that would lead to a potential domain hijack.

+

The following tables includes all resources in the chain that would lead to a potential domain hijack.

- - - - - - - - - - - - {{- with .HijackChain }} - {{- range $i, $elem := . }} - {{ if isEven $i }}{{- else }}{{- end }} - - - - - + {{- with .HijackChains }} + {{- range $j, $singlechain := . }} +

Chain {{ $j }}

+
- Account ID - - Resource - - Resource Type - - Resource Referenced - - Resource Referenced Type -
- {{ $elem.AccountId }} - - {{ $elem.Resource }} - - {{ $elem.ResourceType }} - - {{ $elem.ResourceReferenced }} - - {{ $elem.ResourceReferencedType }} -
+ + + + + - {{- end }} - {{- end }} - -
+ Account ID + + Resource + + Resource Type +
+ + + {{- with $singlechain }} + {{- range $i, $elem := . }} + {{ if isEven $i }}{{- else }}{{- end }} + + {{ $elem.AccountId }} + + + {{ $elem.Resource }} + + + {{ $elem.ResourceType }} + + + {{- end }} + {{- end }} + + + {{- end }} + {{- end }}
\ No newline at end of file diff --git a/cloud-inquisitor/notification/templates/hijack_template.txt b/cloud-inquisitor/notification/templates/hijack_template.txt index 50bb55f..fe10062 100644 --- a/cloud-inquisitor/notification/templates/hijack_template.txt +++ b/cloud-inquisitor/notification/templates/hijack_template.txt @@ -1,17 +1,22 @@ Potential Domain Hijack Found -Deleting resource {{ .PrimaryResourceType }}:{{ .PrimaryResource }} in AWS account {{ .PrimaryAccountId }} has resulted in a potential domain hijack; - there is a DNS record pointing to a resource not owned or no longer owned by us. +Deleting resource {{ .PrimaryResourceType }}:{{ .PrimaryResource }} in AWS account {{ .PrimaryAccountId }} has resulted in a potential security risk. +By claiming the corresponding resource an attacker will be able to make Players and Rioters believe they represent part of Riot and do harm to them. -The following table includes all resources in the chain that would lead to a potential domain hijack. +The following table includes all resources in the chain that would lead to a potential hijack. -{{ with .HijackChain }} -{{ range $i, $elem := . }} +{{ with .HijackChains }} +{{ range $j, $singlechain := . }} +============== +Hijack Chain {{ $j }} +============== + {{ with $singlechain }} + {{ range $i, $elem := . }} Resource {{ $i }}: Account ID: {{ $elem.AccountId }} Resource: {{ $elem.Resource }} Resource Type: {{ $elem.ResourceType }} - Resource Referenced: {{ $elem.ResourceReferenced }} - Resource Referenced Type: {{ $elem.ResourceReferencedType }} + {{ end }} + {{ end }} +{{ end }} {{ end }} -{{ end }} \ No newline at end of file diff --git a/cloud-inquisitor/notification/templates_func_test.go b/cloud-inquisitor/notification/templates_func_test.go index 06646ce..9a6176e 100644 --- a/cloud-inquisitor/notification/templates_func_test.go +++ b/cloud-inquisitor/notification/templates_func_test.go @@ -26,8 +26,6 @@ func TestAWSSES(t *testing.T) { AccountId: "123456789012", Resource: "public.test.bucket.com", ResourceType: "route53", - ResourceReferenced: "test.bucket.com", - ResourceReferencedType: "S3 Bucket", }, }, } diff --git a/cloud-inquisitor/notification/templates_test.go b/cloud-inquisitor/notification/templates_test.go index 8e8941a..8476c38 100644 --- a/cloud-inquisitor/notification/templates_test.go +++ b/cloud-inquisitor/notification/templates_test.go @@ -25,7 +25,7 @@ func TestHijackHTMLNoChain(t *testing.T) { PrimaryResource: "test.bucket.com", PrimaryResourceType: "S3 Bucket", PrimaryAccountId: "123456789012", - HijackChain: []HijackChainElement{}, + HijackChains: [][]HijackChainElement{}, } html, err := NewHijackHTML(content) @@ -54,20 +54,18 @@ func TestHijackHTMLWithChain(t *testing.T) { PrimaryResource: "test.bucket.com", PrimaryResourceType: "S3 Bucket", PrimaryAccountId: "123456789012", - HijackChain: []HijackChainElement{ - HijackChainElement{ - AccountId: "123456789012", - Resource: "public.test.bucket.com", - ResourceType: "route53", - ResourceReferenced: "test.bucket.com", - ResourceReferencedType: "S3 Bucket", - }, - HijackChainElement{ - AccountId: "123456789012", - Resource: "public.test.bucket.com", - ResourceType: "route53", - ResourceReferenced: "test.bucket.com", - ResourceReferencedType: "S3 Bucket", + HijackChains: [][]HijackChainElement{ + []HijackChainElement{ + HijackChainElement{ + AccountId: "123456789012", + Resource: "public.test.bucket.com", + ResourceType: "route53", + }, + HijackChainElement{ + AccountId: "123456789012", + Resource: "public.test.bucket.com", + ResourceType: "route53", + }, }, }, } @@ -98,7 +96,7 @@ func TestHijackTextNoChain(t *testing.T) { PrimaryResource: "test.bucket.com", PrimaryResourceType: "S3 Bucket", PrimaryAccountId: "123456789012", - HijackChain: []HijackChainElement{}, + HijackChains: [][]HijackChainElement{}, } text, err := NewHijackText(content) @@ -127,20 +125,18 @@ func TestHijackTextWithChain(t *testing.T) { PrimaryResource: "test.bucket.com", PrimaryResourceType: "S3 Bucket", PrimaryAccountId: "123456789012", - HijackChain: []HijackChainElement{ - HijackChainElement{ - AccountId: "123456789012", - Resource: "public.test.bucket.com", - ResourceType: "route53", - ResourceReferenced: "test.bucket.com", - ResourceReferencedType: "S3 Bucket", - }, - HijackChainElement{ - AccountId: "123456789012", - Resource: "public.test.bucket.com", - ResourceType: "route53", - ResourceReferenced: "test.bucket.com", - ResourceReferencedType: "S3 Bucket", + HijackChains: [][]HijackChainElement{ + []HijackChainElement{ + HijackChainElement{ + AccountId: "123456789012", + Resource: "public.test.bucket.com", + ResourceType: "route53", + }, + HijackChainElement{ + AccountId: "123456789012", + Resource: "public.test.bucket.com", + ResourceType: "route53", + }, }, }, } @@ -174,21 +170,15 @@ AccountId: rawChain.Resource.Account, ResourceReferencedType: "", */ func TestGenerateContent(t *testing.T) { - chain := &model.HijackableResourceChain{ + chain := &model.HijackableResourceRoot{ ID: "testID", - Resource: &model.HijackableResource{ + RootResource: &model.HijackableResource{ ID: "test root resource", Account: "test root account", Type: model.TypeElasticbeanstalk, }, - Upstream: []*model.HijackableResource{ - &model.HijackableResource{ - ID: "test upstream ", - Account: "test upstream account", - Type: model.TypeElasticbeanstalk, - }, - }, - Downstream: []*model.HijackableResource{ + Direction: model.DirectionDownstream, + Maps: []*model.HijackableResource{ &model.HijackableResource{ ID: "test downstream", Account: "test downstream account", diff --git a/cloud-inquisitor/notification/test_html/hijack_test_no_chain.html b/cloud-inquisitor/notification/test_html/hijack_test_no_chain.html index 593409f..874a723 100755 --- a/cloud-inquisitor/notification/test_html/hijack_test_no_chain.html +++ b/cloud-inquisitor/notification/test_html/hijack_test_no_chain.html @@ -41,9 +41,10 @@

Potential Domain Hijack Found

Deleting resource S3 Bucket:test.bucket.com in AWS account 123456789012 has resulted in a potential domain hijack; there is a DNS record pointing to a resource not owned or no longer owned by us.

-

The following table includes all resources in the chain that would lead to a potential domain hijack.

+

The following tables includes all resources in the chain that would lead to a potential domain hijack.

+

Chain 0

@@ -56,12 +57,6 @@

Deleting resource S3 Bucket:test.bucket.com in AWS account 123456789012 has

- - diff --git a/cloud-inquisitor/notification/test_html/hijack_test_with_chain.html b/cloud-inquisitor/notification/test_html/hijack_test_with_chain.html index fd8d0c0..8db7fba 100755 --- a/cloud-inquisitor/notification/test_html/hijack_test_with_chain.html +++ b/cloud-inquisitor/notification/test_html/hijack_test_with_chain.html @@ -41,9 +41,10 @@

Potential Domain Hijack Found

Deleting resource S3 Bucket:test.bucket.com in AWS account 123456789012 has resulted in a potential domain hijack; there is a DNS record pointing to a resource not owned or no longer owned by us.

-

The following table includes all resources in the chain that would lead to a potential domain hijack.

+

The following tables includes all resources in the chain that would lead to a potential domain hijack.

+

Chain 0

Resource Type - Resource Referenced - - Resource Referenced Type -
@@ -56,12 +57,6 @@

Deleting resource S3 Bucket:test.bucket.com in AWS account 123456789012 has

- - @@ -75,12 +70,6 @@

Deleting resource S3 Bucket:test.bucket.com in AWS account 123456789012 has

- - - -
Resource Type - Resource Referenced - - Resource Referenced Type -
route53 - test.bucket.com - - S3 Bucket -
@@ -92,12 +81,6 @@

Deleting resource S3 Bucket:test.bucket.com in AWS account 123456789012 has

route53 - test.bucket.com - - S3 Bucket -
diff --git a/cloud-inquisitor/notification/test_text/hijack_test_no_chain.txt b/cloud-inquisitor/notification/test_text/hijack_test_no_chain.txt index b018db8..2072c24 100755 --- a/cloud-inquisitor/notification/test_text/hijack_test_no_chain.txt +++ b/cloud-inquisitor/notification/test_text/hijack_test_no_chain.txt @@ -1,8 +1,8 @@ Potential Domain Hijack Found -Deleting resource S3 Bucket:test.bucket.com in AWS account 123456789012 has resulted in a potential domain hijack; - there is a DNS record pointing to a resource not owned or no longer owned by us. +Deleting resource S3 Bucket:test.bucket.com in AWS account 123456789012 has resulted in a potential security risk. +By claiming the corresponding resource an attacker will be able to make Players and Rioters believe they represent part of Riot and do harm to them. -The following table includes all resources in the chain that would lead to a potential domain hijack. +The following table includes all resources in the chain that would lead to a potential hijack. \ No newline at end of file diff --git a/cloud-inquisitor/notification/test_text/hijack_test_with_chain.txt b/cloud-inquisitor/notification/test_text/hijack_test_with_chain.txt index d605588..2b3644e 100755 --- a/cloud-inquisitor/notification/test_text/hijack_test_with_chain.txt +++ b/cloud-inquisitor/notification/test_text/hijack_test_with_chain.txt @@ -1,24 +1,24 @@ Potential Domain Hijack Found -Deleting resource S3 Bucket:test.bucket.com in AWS account 123456789012 has resulted in a potential domain hijack; - there is a DNS record pointing to a resource not owned or no longer owned by us. +Deleting resource S3 Bucket:test.bucket.com in AWS account 123456789012 has resulted in a potential security risk. +By claiming the corresponding resource an attacker will be able to make Players and Rioters believe they represent part of Riot and do harm to them. -The following table includes all resources in the chain that would lead to a potential domain hijack. +The following table includes all resources in the chain that would lead to a potential hijack. +============== +Hijack Chain 0 +============== + Resource 0: Account ID: 123456789012 Resource: public.test.bucket.com Resource Type: route53 - Resource Referenced: test.bucket.com - Resource Referenced Type: S3 Bucket Resource 1: Account ID: 123456789012 Resource: public.test.bucket.com Resource Type: route53 - Resource Referenced: test.bucket.com - Resource Referenced Type: S3 Bucket \ No newline at end of file From af4bb172e86514741be6bdcc884240d1a6aa4658 Mon Sep 17 00:00:00 2001 From: Dong Liu Date: Tue, 6 Oct 2020 11:17:05 -0700 Subject: [PATCH 5/5] wip --- .../notification/templates_func_test.go | 12 +++++++----- cloud-inquisitor/notification/templates_test.go | 14 +++++++++----- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/cloud-inquisitor/notification/templates_func_test.go b/cloud-inquisitor/notification/templates_func_test.go index 9a6176e..4cb84d8 100644 --- a/cloud-inquisitor/notification/templates_func_test.go +++ b/cloud-inquisitor/notification/templates_func_test.go @@ -21,11 +21,13 @@ func TestAWSSES(t *testing.T) { PrimaryResource: "test.bucket.com", PrimaryResourceType: "S3 Bucket", PrimaryAccountId: "123456789012", - HijackChain: []HijackChainElement{ - HijackChainElement{ - AccountId: "123456789012", - Resource: "public.test.bucket.com", - ResourceType: "route53", + HijackChains: [][]HijackChainElement{ + []HijackChainElement{ + HijackChainElement{ + AccountId: "123456789012", + Resource: "public.test.bucket.com", + ResourceType: "route53", + }, }, }, } diff --git a/cloud-inquisitor/notification/templates_test.go b/cloud-inquisitor/notification/templates_test.go index 8476c38..868f96e 100644 --- a/cloud-inquisitor/notification/templates_test.go +++ b/cloud-inquisitor/notification/templates_test.go @@ -178,11 +178,15 @@ func TestGenerateContent(t *testing.T) { Type: model.TypeElasticbeanstalk, }, Direction: model.DirectionDownstream, - Maps: []*model.HijackableResource{ - &model.HijackableResource{ - ID: "test downstream", - Account: "test downstream account", - Type: model.TypeElasticbeanstalk, + Maps: []*model.HijackableResourceMap{ + &model.HijackableResourceMap{ + Resource: &model.HijackableResource{ + ID: "test downstream", + Account: "test downstream account", + Type: model.TypeElasticbeanstalk, + }, + Direction: model.DirectionDownstream, + Contains: []*model.HijackableResourceMap{}, }, }, }