From 960e08d5aa6e01b1b7e66f5edd8a30db58ee3e68 Mon Sep 17 00:00:00 2001 From: "Alex (@enenumxela)" <62714471+enenumxela@users.noreply.github.com> Date: Wed, 11 Dec 2024 08:21:35 +0300 Subject: [PATCH] feat(sources): Add driftnet --- pkg/xsubfind3r/sources/driftnet/driftnet.go | 188 ++++++++++++++++++++ pkg/xsubfind3r/sources/sources.go | 3 + pkg/xsubfind3r/xsubfind3r.go | 3 + 3 files changed, 194 insertions(+) create mode 100644 pkg/xsubfind3r/sources/driftnet/driftnet.go diff --git a/pkg/xsubfind3r/sources/driftnet/driftnet.go b/pkg/xsubfind3r/sources/driftnet/driftnet.go new file mode 100644 index 0000000..2618d3e --- /dev/null +++ b/pkg/xsubfind3r/sources/driftnet/driftnet.go @@ -0,0 +1,188 @@ +package driftnet + +import ( + "encoding/json" + "fmt" + "strings" + + hqgohttp "github.com/hueristiq/hq-go-http" + "github.com/hueristiq/xsubfind3r/pkg/xsubfind3r/sources" +) + +type getResultsResponse struct { + Enrichments Enrichments `json:"enrichments"` + Observations Observations `json:"observations"` +} + +type Enrichments struct { + CVE RedactionReason `json:"cve"` + JA4XHash RedactionReason `json:"ja4x-hash"` + JarmFuzzyHash struct{} `json:"jarm-fuzzyhash"` + NucleiName RedactionReason `json:"nuclei-name"` + ObjMurmur3 struct{} `json:"obj-murmur3"` + ProductTag ProductTag `json:"product-tag"` +} + +type RedactionReason struct { + RedactionReason string `json:"redaction_reason"` +} + +type ProductTag struct { + Cardinality Cardinality `json:"cardinality"` + Other Cardinality `json:"other"` + Values ProductTagValues `json:"values"` +} + +type Cardinality struct { + Domains int `json:"domains"` + Protocols int `json:"protocols"` +} + +type ProductTagValues struct { + Domains map[string]int `json:"domains"` + Protocols map[string]int `json:"protocols"` +} + +type Observations struct { + ASN ObservationData `json:"asn"` + Entity ObservationData `json:"entity"` + GeoCountry ObservationData `json:"geo-country"` + Host HostData `json:"host"` + HTTPHeader HTTPHeaderData `json:"http-header"` + IP IPData `json:"ip"` + PortTCP PortData `json:"port-tcp"` + PortUDP struct{} `json:"port-udp"` + ServerBanner ServerBanner `json:"server-banner"` + SubjectCert SubjectCert `json:"subject;cert"` //nolint: staticcheck + TitleHTML TitleHTML `json:"title;html"` //nolint: staticcheck +} + +type ObservationData struct { + Cardinality Cardinality `json:"cardinality"` + Values map[string]map[string]int `json:"values"` +} + +type HostData struct { + Cardinality Cardinality `json:"cardinality"` + Other map[string]int `json:"other"` + Values map[string]map[string]int `json:"values"` +} + +type HTTPHeaderData struct { + Cardinality Cardinality `json:"cardinality"` + Other map[string]int `json:"other"` + Values map[string]map[string]interface{} `json:"values"` +} + +type IPData struct { + Cardinality Cardinality `json:"cardinality"` + Other map[string]int `json:"other"` + Values map[string]map[string]interface{} `json:"values"` +} + +type PortData struct { + Cardinality Cardinality `json:"cardinality"` + Values map[string]map[string]int `json:"values"` +} + +type ServerBanner struct { + Cardinality Cardinality `json:"cardinality"` + Values map[string]map[string]int `json:"values"` +} + +type SubjectCert struct { + Cardinality Cardinality `json:"cardinality"` + Values map[string]map[string]int `json:"values"` +} + +type TitleHTML struct { + Cardinality Cardinality `json:"cardinality"` + Values map[string]map[string]int `json:"values"` +} + +type Source struct{} + +func (source *Source) Run(config *sources.Configuration, domain string) <-chan sources.Result { + results := make(chan sources.Result) + + go func() { + defer close(results) + + getResultsReqURL := fmt.Sprintf("https://api.driftnet.io/v1/multi/summary?summary_limit=10&timeout=30&from=2024-12-01&to=2024-12-11&field=host:%s", domain) + + getResultsRes, err := hqgohttp.GET(getResultsReqURL).AddHeader("Authorization", "Bearer anon").Send() + if err != nil { + result := sources.Result{ + Type: sources.ResultError, + Source: source.Name(), + Error: err, + } + + results <- result + + return + } + + var getResultsResData getResultsResponse + + if err = json.NewDecoder(getResultsRes.Body).Decode(&getResultsResData); err != nil { + result := sources.Result{ + Type: sources.ResultError, + Source: source.Name(), + Error: err, + } + + results <- result + + getResultsRes.Body.Close() + + return + } + + getResultsRes.Body.Close() + + for _, v := range getResultsResData.Observations.Host.Values { + for subdomain := range v { + if subdomain != domain && !strings.HasSuffix(subdomain, "."+domain) { + continue + } + + result := sources.Result{ + Type: sources.ResultSubdomain, + Source: source.Name(), + Value: subdomain, + } + + results <- result + } + } + + for _, value := range getResultsResData.Observations.SubjectCert.Values { + for entry := range value { + subdomains := config.Extractor.FindAllString(entry, -1) + + for i := range subdomains { + subdomain := subdomains[i] + + if subdomain != domain && !strings.HasSuffix(subdomain, "."+domain) { + continue + } + + result := sources.Result{ + Type: sources.ResultSubdomain, + Source: source.Name(), + Value: subdomain, + } + + results <- result + } + } + } + }() + + return results +} + +func (source *Source) Name() string { + return sources.DRIFTNET +} diff --git a/pkg/xsubfind3r/sources/sources.go b/pkg/xsubfind3r/sources/sources.go index 95f0236..9b21274 100644 --- a/pkg/xsubfind3r/sources/sources.go +++ b/pkg/xsubfind3r/sources/sources.go @@ -47,6 +47,7 @@ type Source interface { // - CHAOS: ProjectDiscovery’s service for subdomain enumeration. // - COMMONCRAWL: Repository of open web data. // - CRTSH: Certificate transparency log search engine. +// - DRIFTNET // - FULLHUNT: Platform for attack surface monitoring. // - GITHUB: Searches code repositories for relevant data. // - HACKERTARGET: Offers security scanning and OSINT capabilities. @@ -69,6 +70,7 @@ const ( CHAOS = "chaos" COMMONCRAWL = "commoncrawl" CRTSH = "crtsh" + DRIFTNET = "driftnet" FULLHUNT = "fullhunt" GITHUB = "github" HACKERTARGET = "hackertarget" @@ -107,6 +109,7 @@ var List = []string{ CHAOS, COMMONCRAWL, CRTSH, + DRIFTNET, FULLHUNT, GITHUB, HACKERTARGET, diff --git a/pkg/xsubfind3r/xsubfind3r.go b/pkg/xsubfind3r/xsubfind3r.go index 5855ba1..587248e 100644 --- a/pkg/xsubfind3r/xsubfind3r.go +++ b/pkg/xsubfind3r/xsubfind3r.go @@ -15,6 +15,7 @@ import ( "github.com/hueristiq/xsubfind3r/pkg/xsubfind3r/sources/chaos" "github.com/hueristiq/xsubfind3r/pkg/xsubfind3r/sources/commoncrawl" "github.com/hueristiq/xsubfind3r/pkg/xsubfind3r/sources/crtsh" + "github.com/hueristiq/xsubfind3r/pkg/xsubfind3r/sources/driftnet" "github.com/hueristiq/xsubfind3r/pkg/xsubfind3r/sources/fullhunt" "github.com/hueristiq/xsubfind3r/pkg/xsubfind3r/sources/github" "github.com/hueristiq/xsubfind3r/pkg/xsubfind3r/sources/hackertarget" @@ -153,6 +154,8 @@ func New(cfg *Configuration) (finder *Finder, err error) { finder.sources[source] = &chaos.Source{} case sources.COMMONCRAWL: finder.sources[source] = &commoncrawl.Source{} + case sources.DRIFTNET: + finder.sources[source] = &driftnet.Source{} case sources.CRTSH: finder.sources[source] = &crtsh.Source{} case sources.FULLHUNT: