diff --git a/bbot/core/helpers/dns/helpers.py b/bbot/core/helpers/dns/helpers.py index d7384934d1..c18a2c1620 100644 --- a/bbot/core/helpers/dns/helpers.py +++ b/bbot/core/helpers/dns/helpers.py @@ -6,6 +6,154 @@ log = logging.getLogger("bbot.core.helpers.dns") +# the following are the result of a 1-day internet survey to find the top SRV records +# the scan resulted in 36,282 SRV records. the count for each one is shown. +common_srvs = [ + "_sipfederationtls._tcp", # 6909 + "_sip._tls", # 6853 + "_autodiscover._tcp", # 4268 + "_xmpp-server._tcp", # 1437 + "_sip._tcp", # 1193 + "_sips._tcp", # 1183 + "_caldavs._tcp", # 1179 + "_carddavs._tcp", # 1132 + "_caldav._tcp", # 1035 + "_carddav._tcp", # 1024 + "_sip._udp", # 1007 + "_imaps._tcp", # 1007 + "_submission._tcp", # 906 + "_h323cs._tcp", # 846 + "_h323ls._udp", # 782 + "_xmpp-client._tcp", # 689 + "_pop3s._tcp", # 394 + "_jabber._tcp", # 277 + "_imap._tcp", # 267 + "_turn._udp", # 256 + "_pop3._tcp", # 221 + "_ldap._tcp", # 213 + "_smtps._tcp", # 195 + "_sipinternaltls._tcp", # 192 + "_vlmcs._tcp", # 165 + "_kerberos._udp", # 163 + "_kerberos._tcp", # 148 + "_kpasswd._udp", # 128 + "_kpasswd._tcp", # 100 + "_ntp._udp", # 90 + "_gc._tcp", # 73 + "_kerberos-master._udp", # 66 + "_ldap._tcp.dc._msdcs", # 63 + "_matrix._tcp", # 62 + "_smtp._tcp", # 61 + "_stun._udp", # 57 + "_kerberos._tcp.dc._msdcs", # 54 + "_ldap._tcp.gc._msdcs", # 49 + "_kerberos-adm._tcp", # 44 + "_ldap._tcp.pdc._msdcs", # 43 + "_kerberos-master._tcp", # 43 + "_http._tcp", # 37 + "_h323rs._tcp", # 36 + "_sipinternal._tcp", # 35 + "_turn._tcp", # 33 + "_stun._tcp", # 33 + "_h323ls._tcp", # 33 + "_x-puppet._tcp", # 30 + "_h323cs._udp", # 27 + "_stuns._tcp", # 26 + "_jabber-client._tcp", # 25 + "_x-puppet-ca._tcp", # 22 + "_ts3._udp", # 22 + "_minecraft._tcp", # 22 + "_turns._tcp", # 21 + "_ldaps._tcp", # 21 + "_xmpps-client._tcp", # 20 + "_https._tcp", # 19 + "_ftp._tcp", # 19 + "_xmpp-server._udp", # 18 + "_xmpp-client._udp", # 17 + "_jabber._udp", # 17 + "_jabber-client._udp", # 17 + "_xmpps-server._tcp", # 15 + "_finger._tcp", # 14 + "_stuns._udp", # 12 + "_hkp._tcp", # 12 + "_vlmcs._udp", # 11 + "_turns._udp", # 11 + "_tftp._udp", # 11 + "_ssh._tcp", # 11 + "_rtps._udp", # 11 + "_mysqlsrv._tcp", # 11 + "_hkps._tcp", # 11 + "_h323be._udp", # 11 + "_dns._tcp", # 11 + "_wss._tcp", # 10 + "_wpad._tcp", # 10 + "_whois._tcp", # 10 + "_webexconnect._tcp", # 10 + "_webexconnects._tcp", # 10 + "_vnc._tcp", # 10 + "_test._tcp", # 10 + "_telnet._tcp", # 10 + "_telnets._tcp", # 10 + "_teamspeak._tcp", # 10 + "_svns._tcp", # 10 + "_svcp._tcp", # 10 + "_smb._tcp", # 10 + "_sip-tls._tcp", # 10 + "_sftp._tcp", # 10 + "_secure-pop3._tcp", # 10 + "_secure-imap._tcp", # 10 + "_rtsp._tcp", # 10 + "_rtps._tcp", # 10 + "_rpc._tcp", # 10 + "_rfb._tcp", # 10 + "_raop._tcp", # 10 + "_pstn._tcp", # 10 + "_presence._tcp", # 10 + "_pkixrep._tcp", # 10 + "_pgprevokations._tcp", # 10 + "_pgpkeys._tcp", # 10 + "_ocsp._tcp", # 10 + "_nntp._tcp", # 10 + "_nfs._tcp", # 10 + "_netbios-ssn._tcp", # 10 + "_netbios-ns._tcp", # 10 + "_netbios-dgm._tcp", # 10 + "_mumble._tcp", # 10 + "_msrpc._tcp", # 10 + "_mqtts._tcp", # 10 + "_minecraft._udp", # 10 + "_iscsi._tcp", # 10 + "_ircs._tcp", # 10 + "_ipp._tcp", # 10 + "_ipps._tcp", # 10 + "_h323be._tcp", # 10 + "_gits._tcp", # 10 + "_ftps._tcp", # 10 + "_ftpes._tcp", # 10 + "_dnss._udp", # 10 + "_dnss._tcp", # 10 + "_diameter._tcp", # 10 + "_crl._tcp", # 10 + "_crls._tcp", # 10 + "_cmp._tcp", # 10 + "_certificates._tcp", # 10 + "_aix._tcp", # 10 + "_afpovertcp._tcp", # 10 + "_collab-edge._tls", # 6 + "_tcp", # 5 + "_client._smtp", # 3 + "_udp", # 2 + "_tls", # 2 + "_msdcs", # 2 + "_gc._msdcs", # 2 + "_ldaps._tcp.dc._msdcs", # 1 + "_kerberos._tcp.kdc._msdcs", # 1 + "_kerberos.tcp.dc._msdcs", # 1 + "_imap", # 1 + "_iax", # 1 +] + + def extract_targets(record): """ Extracts hostnames or IP addresses from a given DNS record. @@ -101,6 +249,20 @@ def service_record(host, rdtype=None): # we did not receive rdtype, so we'll have to inspect host name parts parts = str(host).split(".") + if not parts: + return False + + # DMARC TXT records, e.g. _dmarc.example.com + if parts[0] == "_dmarc": + return True + + # MTA-STS TXT records, e.g. _mta-sts.example.com + if parts[0] == "_mta-sts": + return True + + if len(parts) < 2: + return False + # classic SRV record names, e.g. _ldap._tcp.example.com if parts[1] == "_udp" or parts[1] == "_tcp": return True @@ -117,12 +279,4 @@ def service_record(host, rdtype=None): if parts[1] == "_domainkey": return True - # DMARC TXT records, e.g. _dmarc.example.com - if parts[0] == "_dmarc": - return True - - # MTA-STS TXT records, e.g. _mta-sts.example.com - if parts[0] == "_mta-sts": - return True - return False diff --git a/bbot/modules/dnscommonsrv.py b/bbot/modules/dnscommonsrv.py index 819e4967b9..5fb279b910 100644 --- a/bbot/modules/dnscommonsrv.py +++ b/bbot/modules/dnscommonsrv.py @@ -1,160 +1,12 @@ +from bbot.core.helpers.dns.helpers import common_srvs from bbot.modules.templates.subdomain_enum import subdomain_enum -# the following are the result of a 1-day internet survey to find the top SRV records -# the scan resulted in 36,282 SRV records. the count for each one is shown. -common_srvs = [ - "_sipfederationtls._tcp", # 6909 - "_sip._tls", # 6853 - "_autodiscover._tcp", # 4268 - "_xmpp-server._tcp", # 1437 - "_sip._tcp", # 1193 - "_sips._tcp", # 1183 - "_caldavs._tcp", # 1179 - "_carddavs._tcp", # 1132 - "_caldav._tcp", # 1035 - "_carddav._tcp", # 1024 - "_sip._udp", # 1007 - "_imaps._tcp", # 1007 - "_submission._tcp", # 906 - "_h323cs._tcp", # 846 - "_h323ls._udp", # 782 - "_xmpp-client._tcp", # 689 - "_pop3s._tcp", # 394 - "_jabber._tcp", # 277 - "_imap._tcp", # 267 - "_turn._udp", # 256 - "_pop3._tcp", # 221 - "_ldap._tcp", # 213 - "_smtps._tcp", # 195 - "_sipinternaltls._tcp", # 192 - "_vlmcs._tcp", # 165 - "_kerberos._udp", # 163 - "_kerberos._tcp", # 148 - "_kpasswd._udp", # 128 - "_kpasswd._tcp", # 100 - "_ntp._udp", # 90 - "_gc._tcp", # 73 - "_kerberos-master._udp", # 66 - "_ldap._tcp.dc._msdcs", # 63 - "_matrix._tcp", # 62 - "_smtp._tcp", # 61 - "_stun._udp", # 57 - "_kerberos._tcp.dc._msdcs", # 54 - "_ldap._tcp.gc._msdcs", # 49 - "_kerberos-adm._tcp", # 44 - "_ldap._tcp.pdc._msdcs", # 43 - "_kerberos-master._tcp", # 43 - "_http._tcp", # 37 - "_h323rs._tcp", # 36 - "_sipinternal._tcp", # 35 - "_turn._tcp", # 33 - "_stun._tcp", # 33 - "_h323ls._tcp", # 33 - "_x-puppet._tcp", # 30 - "_h323cs._udp", # 27 - "_stuns._tcp", # 26 - "_jabber-client._tcp", # 25 - "_x-puppet-ca._tcp", # 22 - "_ts3._udp", # 22 - "_minecraft._tcp", # 22 - "_turns._tcp", # 21 - "_ldaps._tcp", # 21 - "_xmpps-client._tcp", # 20 - "_https._tcp", # 19 - "_ftp._tcp", # 19 - "_xmpp-server._udp", # 18 - "_xmpp-client._udp", # 17 - "_jabber._udp", # 17 - "_jabber-client._udp", # 17 - "_xmpps-server._tcp", # 15 - "_finger._tcp", # 14 - "_stuns._udp", # 12 - "_hkp._tcp", # 12 - "_vlmcs._udp", # 11 - "_turns._udp", # 11 - "_tftp._udp", # 11 - "_ssh._tcp", # 11 - "_rtps._udp", # 11 - "_mysqlsrv._tcp", # 11 - "_hkps._tcp", # 11 - "_h323be._udp", # 11 - "_dns._tcp", # 11 - "_wss._tcp", # 10 - "_wpad._tcp", # 10 - "_whois._tcp", # 10 - "_webexconnect._tcp", # 10 - "_webexconnects._tcp", # 10 - "_vnc._tcp", # 10 - "_test._tcp", # 10 - "_telnet._tcp", # 10 - "_telnets._tcp", # 10 - "_teamspeak._tcp", # 10 - "_svns._tcp", # 10 - "_svcp._tcp", # 10 - "_smb._tcp", # 10 - "_sip-tls._tcp", # 10 - "_sftp._tcp", # 10 - "_secure-pop3._tcp", # 10 - "_secure-imap._tcp", # 10 - "_rtsp._tcp", # 10 - "_rtps._tcp", # 10 - "_rpc._tcp", # 10 - "_rfb._tcp", # 10 - "_raop._tcp", # 10 - "_pstn._tcp", # 10 - "_presence._tcp", # 10 - "_pkixrep._tcp", # 10 - "_pgprevokations._tcp", # 10 - "_pgpkeys._tcp", # 10 - "_ocsp._tcp", # 10 - "_nntp._tcp", # 10 - "_nfs._tcp", # 10 - "_netbios-ssn._tcp", # 10 - "_netbios-ns._tcp", # 10 - "_netbios-dgm._tcp", # 10 - "_mumble._tcp", # 10 - "_msrpc._tcp", # 10 - "_mqtts._tcp", # 10 - "_minecraft._udp", # 10 - "_iscsi._tcp", # 10 - "_ircs._tcp", # 10 - "_ipp._tcp", # 10 - "_ipps._tcp", # 10 - "_h323be._tcp", # 10 - "_gits._tcp", # 10 - "_ftps._tcp", # 10 - "_ftpes._tcp", # 10 - "_dnss._udp", # 10 - "_dnss._tcp", # 10 - "_diameter._tcp", # 10 - "_crl._tcp", # 10 - "_crls._tcp", # 10 - "_cmp._tcp", # 10 - "_certificates._tcp", # 10 - "_aix._tcp", # 10 - "_afpovertcp._tcp", # 10 - "_collab-edge._tls", # 6 - "_tcp", # 5 - "_wildcard", # 3 - "_client._smtp", # 3 - "_udp", # 2 - "_tls", # 2 - "_msdcs", # 2 - "_gc._msdcs", # 2 - "_ldaps._tcp.dc._msdcs", # 1 - "_kerberos._tcp.kdc._msdcs", # 1 - "_kerberos.tcp.dc._msdcs", # 1 - "_imap", # 1 - "_iax", # 1 -] -num_srvs = len(common_srvs) - class dnscommonsrv(subdomain_enum): watched_events = ["DNS_NAME"] produced_events = ["DNS_NAME"] flags = ["subdomain-enum", "passive", "safe"] - meta = {"description": "Check for common SRV records", "created_date": "2022-05-15", "author": "@TheTechromancer"} + meta = {"description": "", "created_date": "2022-05-15", "author": "@TheTechromancer"} dedup_strategy = "lowest_parent" options = {"max_depth": 2} @@ -162,6 +14,7 @@ class dnscommonsrv(subdomain_enum): async def setup(self): self.max_subdomain_depth = self.config.get("max_depth", 2) + self.num_srvs = len(common_srvs) return True async def filter_event(self, event): @@ -172,11 +25,11 @@ async def filter_event(self, event): async def handle_event(self, event): query = self.make_query(event) - self.verbose(f'Brute-forcing {num_srvs:,} SRV records for "{query}"') + self.verbose(f'Brute-forcing {self.num_srvs:,} SRV records for "{query}"') for hostname in await self.helpers.dns.brute(self, query, common_srvs, type="SRV"): await self.emit_event( hostname, "DNS_NAME", parent=event, - context=f'{{module}} tried {num_srvs:,} common SRV records against "{query}" and found {{event.type}}: {{event.data}}', + context=f'{{module}} tried {self.num_srvs:,} common SRV records against "{query}" and found {{event.type}}: {{event.data}}', ) diff --git a/bbot/test/test_step_1/test_dns.py b/bbot/test/test_step_1/test_dns.py index 5f98f49394..58e877b9f4 100644 --- a/bbot/test/test_step_1/test_dns.py +++ b/bbot/test/test_step_1/test_dns.py @@ -1,6 +1,6 @@ from ..bbot_fixtures import * -from bbot.core.helpers.dns.helpers import extract_targets +from bbot.core.helpers.dns.helpers import extract_targets, service_record, common_srvs mock_records = { @@ -438,6 +438,7 @@ async def handle_event(self, event): ) +<<<<<<< Updated upstream @pytest.mark.asyncio async def test_dns_graph_structure(bbot_scanner): scan = bbot_scanner("https://evilcorp.com", config={"dns": {"search_distance": 1, "minimal": False}}) @@ -464,3 +465,16 @@ async def test_dns_graph_structure(bbot_scanner): assert str(events_by_data["www.evilcorp.com"].module) == "CNAME" assert events_by_data["evilcorp.com"].parent.data == "https://evilcorp.com/" assert str(events_by_data["evilcorp.com"].module) == "host" +======= +def test_dns_helpers(): + assert service_record("") == False + assert service_record("localhost") == False + assert service_record("www.example.com") == False + assert service_record("www.example.com", "SRV") == True + assert service_record("_custom._service.example.com", "SRV") == True + assert service_record("_custom._service.example.com", "A") == False + # top 100 most common SRV records + for srv_record in common_srvs[:100]: + hostname = f"{srv_record}.example.com" + assert service_record(hostname) == True +>>>>>>> Stashed changes