Skip to content

Commit e867ac7

Browse files
committed
domain apex to node relationships are now stored
1 parent f4d50bc commit e867ac7

File tree

1 file changed

+50
-0
lines changed

1 file changed

+50
-0
lines changed

enum/names.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ import (
1111
"github.com/caffix/pipeline"
1212
"github.com/caffix/stringset"
1313
"github.com/owasp-amass/amass/v4/requests"
14+
"github.com/owasp-amass/asset-db/types"
15+
oam "github.com/owasp-amass/open-asset-model"
16+
"github.com/owasp-amass/open-asset-model/domain"
1417
)
1518

1619
// subdomainTask handles newly discovered proper subdomain names in the enumeration.
@@ -20,6 +23,7 @@ type subdomainTask struct {
2023
withinWildcards *stringset.Set
2124
timesChan chan *timesReq
2225
done chan struct{}
26+
possibleApexes map[string]struct{}
2327
}
2428

2529
// newSubdomainTask returns an initialized SubdomainTask.
@@ -30,6 +34,7 @@ func newSubdomainTask(e *Enumeration) *subdomainTask {
3034
withinWildcards: stringset.New(),
3135
timesChan: make(chan *timesReq, 10),
3236
done: make(chan struct{}, 2),
37+
possibleApexes: make(map[string]struct{}),
3338
}
3439

3540
go r.timesManager()
@@ -41,6 +46,7 @@ func (r *subdomainTask) Stop() {
4146
close(r.done)
4247
r.cnames.Close()
4348
r.withinWildcards.Close()
49+
r.linkNodesToApexes()
4450
}
4551

4652
// Process implements the pipeline Task interface.
@@ -112,6 +118,7 @@ func (r *subdomainTask) checkForSubdomains(ctx context.Context, req *requests.DN
112118

113119
r.enum.sendRequests(subreq)
114120
if times == 1 {
121+
r.possibleApexes[sub] = struct{}{}
115122
pipeline.SendData(ctx, "root", subreq, tp)
116123
}
117124
return true
@@ -168,3 +175,46 @@ func (r *subdomainTask) timesManager() {
168175
}
169176
}
170177
}
178+
179+
func (r *subdomainTask) linkNodesToApexes() {
180+
apexes := make(map[string]*types.Asset)
181+
182+
for k := range r.possibleApexes {
183+
res, err := r.enum.graph.DB.FindByContent(domain.FQDN{Name: k}, r.enum.Config.CollectionStartTime)
184+
if err != nil || len(res) == 0 {
185+
continue
186+
}
187+
apex := res[0]
188+
189+
if rels, err := r.enum.graph.DB.OutgoingRelations(apex, r.enum.Config.CollectionStartTime, "ns_record"); err == nil && len(rels) > 0 {
190+
apexes[k] = apex
191+
}
192+
}
193+
194+
for _, d := range r.enum.Config.Domains() {
195+
names, err := r.enum.graph.DB.FindByScope([]oam.Asset{domain.FQDN{Name: d}}, r.enum.Config.CollectionStartTime)
196+
if err != nil || len(names) == 0 {
197+
continue
198+
}
199+
200+
for _, name := range names {
201+
n, ok := name.Asset.(domain.FQDN)
202+
if !ok {
203+
continue
204+
}
205+
// determine which domain apex this name is a node in
206+
best := len(n.Name)
207+
var apex *types.Asset
208+
for fqdn, a := range apexes {
209+
if idx := strings.Index(n.Name, fqdn); idx != -1 && idx != 0 && idx < best {
210+
best = idx
211+
apex = a
212+
}
213+
}
214+
215+
if apex != nil {
216+
_, _ = r.enum.graph.DB.Create(apex, "node", n)
217+
}
218+
}
219+
}
220+
}

0 commit comments

Comments
 (0)