Skip to content

Commit

Permalink
Merge pull request #842 from blacklanternsecurity/tag-subdomain-mutat…
Browse files Browse the repository at this point in the history
…ions

Tag subdomain mutations
  • Loading branch information
TheTechromancer authored Nov 13, 2023
2 parents e51742e + fa748a6 commit 8cf284f
Showing 1 changed file with 17 additions and 2 deletions.
19 changes: 17 additions & 2 deletions bbot/modules/massdns.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ class massdns(subdomain_enum):
It uses massdns to brute-force subdomains.
At the end of a scan, it will leverage BBOT's word cloud to recursively discover target-specific subdomain mutations.
Each subdomain discovered via mutations is tagged with the "mutation" tag. This tag includes the depth at which
the mutations is found. I.e. the first mutation will be tagged "mutation-1". The second one (a mutation of a
mutation) will be "mutation-2". Mutations of mutations of mutations will be "mutation-3", etc.
This is especially use for bug bounties because it enables you to recognize distant/rare subdomains at a glance.
Subdomains with higher mutation levels are more likely to be distant/rare or never-before-seen.
"""

flags = ["subdomain-enum", "passive", "slow", "aggressive"]
Expand Down Expand Up @@ -90,6 +97,7 @@ async def setup(self):
cache_hrs=24 * 7,
)
self.devops_mutations = list(self.helpers.word_cloud.devops_mutations)
self._mutation_run = 1
return await super().setup()

async def filter_event(self, event):
Expand Down Expand Up @@ -119,9 +127,11 @@ def abort_if(self, event):
if "wildcard" in event.tags:
return True, "event is a wildcard"

def emit_result(self, result, source_event, query):
def emit_result(self, result, source_event, query, tags=None):
if not result == source_event:
kwargs = {"abort_if": self.abort_if}
if tags is not None:
kwargs["tags"] = tags
self.emit_event(result, "DNS_NAME", source_event, **kwargs)

def already_processed(self, hostname):
Expand Down Expand Up @@ -300,6 +310,7 @@ async def finish(self):
)

base_mutations = set()
found_mutations = False
try:
for i, (domain, subdomains) in enumerate(trimmed_found):
self.verbose(f"{domain} has {len(subdomains):,} subdomains")
Expand Down Expand Up @@ -369,13 +380,17 @@ def add_mutation(_domain_hash, m):
if source_event is None:
self.warning(f"Could not correlate source event from: {hostname}")
source_event = self.scan.root_event
self.emit_result(hostname, source_event, query)
self.emit_result(hostname, source_event, query, tags=[f"mutation-{self._mutation_run}"])
if results:
found_mutations = True
continue
break
except AssertionError as e:
self.warning(e)

if found_mutations:
self._mutation_run += 1

def add_found(self, host):
if not isinstance(host, str):
host = host.data
Expand Down

0 comments on commit 8cf284f

Please sign in to comment.