@@ -67,6 +67,9 @@ func (r *Runner) EnumerateSingleDomainWithCtx(ctx context.Context, domain string
6767 gologger .Warning ().Msgf ("Encountered an error with source %s: %s\n " , result .Source , result .Error )
6868 case subscraping .Subdomain :
6969 subdomain := replacer .Replace (result .Value )
70+ // check if this subdomain is actually a wildcard subdomain
71+ // that may have furthur subdomains associated with it
72+ isWildcard := strings .Contains (result .Value , "*." + subdomain )
7073
7174 // Validate the subdomain found and remove wildcards from
7275 if ! strings .HasSuffix (subdomain , "." + domain ) {
@@ -90,10 +93,20 @@ func (r *Runner) EnumerateSingleDomainWithCtx(ctx context.Context, domain string
9093 // send the subdomain for resolution.
9194 if _ , ok := uniqueMap [subdomain ]; ok {
9295 skippedCounts [result .Source ]++
96+ // even if it is duplicate if it was not marked as wildcard before but this source says it is wildcard
97+ // then we should mark it as wildcard
98+ if ! uniqueMap [subdomain ].WildcardCertificate && isWildcard {
99+ val := uniqueMap [subdomain ]
100+ val .WildcardCertificate = true
101+ uniqueMap [subdomain ] = val
102+ }
93103 continue
94104 }
95105
96- hostEntry := resolve.HostEntry {Domain : domain , Host : subdomain , Source : result .Source }
106+ hostEntry := resolve.HostEntry {Domain : domain , Host : subdomain , Source : result .Source , WildcardCertificate : isWildcard }
107+ if r .options .ResultCallback != nil && ! r .options .RemoveWildcard {
108+ r .options .ResultCallback (& hostEntry )
109+ }
97110
98111 uniqueMap [subdomain ] = hostEntry
99112 // If the user asked to remove wildcard then send on the resolve
@@ -109,6 +122,7 @@ func (r *Runner) EnumerateSingleDomainWithCtx(ctx context.Context, domain string
109122 if r .options .RemoveWildcard {
110123 close (resolutionPool .Tasks )
111124 }
125+
112126 wg .Done ()
113127 }()
114128
@@ -125,9 +139,22 @@ func (r *Runner) EnumerateSingleDomainWithCtx(ctx context.Context, domain string
125139 // Add the found subdomain to a map.
126140 if _ , ok := foundResults [result .Host ]; ! ok {
127141 foundResults [result .Host ] = result
142+ if r .options .ResultCallback != nil {
143+ r .options .ResultCallback (& resolve.HostEntry {Domain : domain , Host : result .Host , Source : result .Source , WildcardCertificate : result .WildcardCertificate })
144+ }
128145 }
129146 }
130147 }
148+
149+ // Merge wildcard certificate information from uniqueMap into foundResults
150+ // This handles cases where a later source marked a subdomain as wildcard
151+ // after it was already sent to the resolution pool
152+ for host , result := range foundResults {
153+ if entry , ok := uniqueMap [host ]; ok && entry .WildcardCertificate && ! result .WildcardCertificate {
154+ result .WildcardCertificate = true
155+ foundResults [host ] = result
156+ }
157+ }
131158 }
132159 wg .Wait ()
133160 outputWriter := NewOutputWriter (r .options .JSON )
@@ -162,17 +189,6 @@ func (r *Runner) EnumerateSingleDomainWithCtx(ctx context.Context, domain string
162189 numberOfSubDomains = len (uniqueMap )
163190 }
164191
165- if r .options .ResultCallback != nil {
166- if r .options .RemoveWildcard {
167- for host , result := range foundResults {
168- r .options .ResultCallback (& resolve.HostEntry {Domain : host , Host : result .Host , Source : result .Source })
169- }
170- } else {
171- for _ , v := range uniqueMap {
172- r .options .ResultCallback (& v )
173- }
174- }
175- }
176192 gologger .Info ().Msgf ("Found %d subdomains for %s in %s\n " , numberOfSubDomains , domain , duration )
177193
178194 if r .options .Statistics {
0 commit comments