Esempio n. 1
0
def execute(**kwargs):
    if handler.SIGINT:
        Output().warn("Aborted plugin: %s" % NAME, False)
        return None
    try:
        domain = kwargs['domain'].split('.')
        config = kwargs['config']
        subfuz = kwargs['subfuz']
        ms_targets = [
            domain[-2] + '.sharepoint.com', domain[-2] + '-my.sharepoint.com',
            domain[-2] + '-myfiles.sharepoint.com',
            domain[-2] + '-files.sharepoint.com',
            domain[-2] + '.onmicrosoft.com',
            '%s-%s.mail.protection.outlook.com' % (domain[-2], domain[-1]),
            'selector1-%s-%s._domainkey.%s.onmicrosoft.com' %
            (domain[-2], domain[-1], domain[-2]),
            'selector2-%s-%s._domainkey.%s.onmicrosoft.com' %
            (domain[-2], domain[-1], domain[-2])
        ]
        i = 0
        for ms in ms_targets:
            ans = lookup(ms, 'ANY', '8.8.8.8', 'UDP', subfuz.timeout)
            if ans:
                i += 1
                subfuz.parse_record(ans, ms)
        Output().neutral("%d subdomains found" % i, False)
    except:
        raise
Esempio n. 2
0
    def check_wildcard(self, domain_addr):
        try:
            wildcard = ''.join(random.choice(string.ascii_lowercase) for _ in range(15))
            ans = lookup( (wildcard + '.' + domain_addr), self.record, self.dns, self.protocol, self.timeout)
            if ans:
                wc = False
                d = domain_addr #.encode('utf-8')
                for r in ans:
                    if r.rdtype == 1:  # A RECORD
                        item = []
                        for x in r.items:
                            item.append(x.to_text())
                        self.a_wildcard += item
                        self.log.warn(self.f1.format("Wildcard A record found for %s: " % d) + ", ".join(item), True)
                        wc = True

                    if r.rdtype == 5:  # CNAME RECORD
                        item = []
                        for x in r.items:
                            item.append(x.to_text())
                        self.cname_wildcard += item
                        self.log.warn(self.f1.format("Wildcard CNAME record found for %s: " % d) + ", ".join(item), True)
                        wc = True

                    if r.rdtype == 16:  # TXT RECORD
                        item = []
                        for x in r.items:
                            item.append(x.to_text())
                        self.txt_wildcard += item
                        self.log.warn(self.f1.format("Wildcard TXT record found for %s: " % d) + ", ".join(item), True)
                        wc = True

                    if r.rdtype == 28:  # AAAA RECORD
                        item = []
                        for x in r.items:
                            item.append(x.to_text())
                        self.aaaa_wildcard += item
                        self.log.warn(self.f1.format("Wildcard AAAA record found for %s: " % d) + ", ".join(item), True)
                        wc = True

                    if r.rdtype == 15:  # MX RECORD
                        item = []
                        for x in r.items:
                            item.append(x.to_text())
                        self.mx_wildcard += item
                        self.log.warn(self.f1.format("Wildcard MX record found for %s: " % d) + ", ".join(item), True)
                        wc = True
                    if wc == True: return True
                #if not wc:
                #    return False
        except Exception as e:
            self.log.fatal(('Wildcard check on %s.' % domain_addr), False)
            print(traceback.print_exc())
            print (e)
        return False
Esempio n. 3
0
def execute(**kwargs):
    if handler.SIGINT:
        Output().warn("Aborted plugin: %s" % NAME, False)
        return None
    try:
        domain = kwargs['domain'].split('.')
        config = kwargs['config']
        subfuz = kwargs['subfuz']
        citrix_targets = [domain[-2] + '.sharefile.com']
        redirect = requests.get('https://' + citrix_targets[0])
        if 'secure.sharefile.com' not in redirect.url:
            authlogin = redirect.url.split('/')[2]
            ans = lookup(authlogin.encode('utf-8'), 'ANY', '8.8.8.8', 'UDP',
                         subfuz.timeout)
            if ans:
                subfuz.parse_record(ans, authlogin)
    except:
        raise
Esempio n. 4
0
def execute(**kwargs):
    if handler.SIGINT:
        Output().warn("Aborted plugin: %s" % NAME, False)
        return None
    try:
        subfuz = kwargs['subfuz']
        domain = kwargs['domain'].split('.')
        aws_target = [domain[-2] + '.s3.amazonaws.com'][0]
        query = requests.get('https://' + aws_target)
        if query.status_code == 404:
            return None
        elif query.status_code == 200:
            Output().good('Bucket %s is open' % aws_target,False)
        ans = lookup(aws_target, 'ANY', '8.8.8.8', 'UDP', subfuz.timeout)
        if ans:
            subfuz.parse_record(ans, aws_target)
            Output().neutral("AWS bucket found", False)
    except:
        raise
Esempio n. 5
0
def execute(**kwargs):
    if handler.SIGINT:
        Output().warn("Aborted plugin: %s" % NAME, False)
        return None
    try:
        domain = kwargs['domain'].split('.')
        config = kwargs['config']
        subfuz = kwargs['subfuz']
        ms_targets = [domain[-2] + '.sharepoint.com',
                      domain[-2] + '-my.sharepoint.com',
                      domain[-2] + '-myfiles.sharepoint.com',
                      domain[-2] + '-files.sharepoint.com',
                      domain[-2] + '.onmicrosoft.com',
                      '%s-%s.mail.protection.outlook.com' % (domain[-2], domain[-1])]
        for ms in ms_targets:
            ans = lookup(ms.encode('utf-8'), 'ANY', '8.8.8.8', 'UDP', subfuz.timeout)
            if ans:
                subfuz.parse_record(ans, ms)
    except:
        raise
Esempio n. 6
0
    def check_dns_server(self):
        # If dns override is not specified
        dns_servers = []
        if not self.args.dns:
            ns_record = lookup(self.domain, 'NS', self.config['config']['dns_fallback'], self.protocol, self.timeout)
            if not ns_record:
                ns_record = lookup(".".join(self.domain.split('.')[-2:]), 'NS', self.config['config']['dns_fallback'], self.protocol, self.timeout)
                # TODO very ugly way of doing it, https://publicsuffix.org/list/public_suffix_list.dat is on the to-do list
                # currently doesn't handle target domain inputs like subdomain.domain.co.uk or similar domains very well yet.
                if not ns_record:  # Exit early if ns_record is not found.
                    self.log.fatal('Unable to lookup NS server', True)
                    return False
            nameservers = [x for x in ns_record if x.rdtype == 2]
            if nameservers:
                self.log.normal('Name Servers:', True)
                # For every NS record found
                for y in nameservers[0]:
                    dns_server_name = y.target.to_text()
                    # get DNS server IP
                    try:
                        print(dns_server_name)
                        dns_servers.append(
                            [lookup(dns_server_name,'A', self.config['config']['dns_fallback'], self.protocol, self.timeout)[0][0].address,  y.target.to_text()])
                    except:
                        self.log.fatal(self.f4.format(dns_server_name) + '{:15}'.format('Unable to resolv DNS server'), True)
            else:
                self.log.warn('No Name Servers found for %s' % self.domain, True)
                return False
        else:
            dns_servers.append([self.args.dns, self.args.dns])
        # Zone transfer
        for dns_server in dns_servers:
            nameserver = gethostbyname_ex(dns_server[0].encode('idna'))[2][0]
            if self.zone:
                try:
                    z = dns.zone.from_xfr(dns.query.xfr(nameserver, self.domain, timeout=10, lifetime=10))
                    self.log.good(self.f4.format(dns_server[1]) + '{:15}'.format(dns_server[0]) + ' - Zone Transfer allowed.', True)
                    #names = z.nodes.keys()
                    #for n in names:
                    #    self.log.normal(z[n].to_text(n), True)
                except:
                    self.log.warn(
                        self.f4.format(dns_server[1]) + '{:15}'.format(dns_server[0]) + ' - Zone Transfer not allowed.', True)
            else:
                self.log.neutral(self.f4.format(dns_server[1]) + '{:15}'.format(dns_server[0]), True)

            # Testing for open TCP and UDP ports for DNS servers, and what type of records are permitted.
            # TCP - ANY
            dns_result = []
            start = time.time()
            tany = lookup(self.domain, 'ANY', dns_server[0], 'TCP', self.timeout)
            end = time.time()
            if tany:
                if [x for x in tany if x.rdtype == 1 or x.rdtype == 28 or x.rdtype == 5 or x.rdtype == 15 or x.rdtype == 16]:
                    dns_result.append(['TCP', dns_server[0], 'ANY', end - start])
            # TCP - A
            start = time.time()
            ta = lookup(self.domain, 'A', dns_server[0], 'TCP', self.timeout)
            end = time.time()
            if ta:
                if [x for x in ta if x.rdtype == 1]:
                    dns_result.append(['TCP', dns_server[0], 'A', end - start])
            # UDP - ANY
            start = time.time()
            uany = lookup(self.domain, 'ANY', dns_server[0], 'UDP', self.timeout)
            end = time.time()
            if uany:
                if [x for x in uany if x.rdtype == 1 or x.rdtype == 28 or x.rdtype == 5 or x.rdtype == 15 or x.rdtype == 16]:
                    dns_result.append(['UDP', dns_server[0], 'ANY', end - start])
            # UDP - A
            start = time.time()
            ua = lookup(self.domain, 'A', dns_server[0], 'UDP', self.timeout)
            end = time.time()
            if ua:
                if [x for x in ua if x.rdtype == 1]:
                    dns_result.append(['UDP', dns_server[0], 'A', end - start])


        # Figure out the best combination to use
        dns_result = sorted(dns_result, key=lambda x: (x[3], x[1], x[0], x[2]))
        a = [i for i in dns_result if i[0] == 'UDP' and i[2] == 'ANY']
        b = [i for i in dns_result if i[0] == 'TCP' and i[2] == 'ANY']
        c = [i for i in dns_result if i[0] == 'UDP' and i[2] == 'A']
        d = [i for i in dns_result if i[0] == 'TCP' and i[2] == 'A']

        if a:  # ANY + UDP
            self.dns, self.protocol, self.record, delay = a[0][1], a[0][0], a[0][2], a[0][3]
        elif b:  # ANY + TCP
            self.dns, self.protocol, self.record, delay = b[0][1], b[0][0], b[0][2], b[0][3]
        elif c:  # A + UDP
            self.dns, self.protocol, self.record, delay = c[0][1], c[0][0], c[0][2], c[0][3]
        elif d:  # A + TCP
            self.dns, self.protocol, self.record, delay = d[0][1], d[0][0], d[0][2], d[0][3]
        else: #fallback
            self.dns, self.protocol, self.record, delay = self.config['config']['dns_fallback'], self.config['config']['dns_fallback_protocol'], self.config['config']['dns_fallback_record'], 0
            self.log.warn('Unable to find information about %s, falling back to DNS %s, Proto %s, Type %s ' % (self.domain, self.dns, self.protocol, self.record), True)

        # Compensate for override
        override_dns = self.args.dns
        override_record = self.args.record
        override_protocol = self.args.protocol
        if override_record: self.record = override_record
        if override_dns: self.dns = override_dns
        if override_protocol: self.protocol = override_protocol
        self.log.neutral('Using nameserver %s, query type %s over %s with RTT of %.4f seconds' % (self.dns, self.record, self.protocol, delay), True)
        return True
Esempio n. 7
0
 def scan_worker(self):
     while True:
         if self.handler.SIGINT:
             return
         self.mutex.acquire()
         try:
             if self.record == 'PTR':
                 tests = ['PTR']
                 subdomain = self.sl.ptr_unscanned_ip.pop(0)
                 self.sl.ptr_scanned += 1
             else:
                 subdomain = self.sl.unscanned.pop(0)
                 #print(subdomain)
                 if self.args.record: tests = [self.record]
                 elif self.record == 'A':
                     if subdomain == '': tests = ['A', 'TXT', 'MX']
                     else: tests = ['A']
                 else: tests = ['ANY']
         except:
             if len(self.sl.unscanned) == 0:
                 return
         finally:
             self.mutex.release()
         time.sleep(self.throttle)
         # if domain already has been scanned (remove duplicates)
         # else, add domain to "scanned" list.
         if subdomain in self.sl.scanned:
             continue
         else:
             self.sl.scanned.append(subdomain)
         for t in tests:
             if self.record == 'PTR':
                 d = subdomain
             else:
                 d = (subdomain + u'.' + self.domain).lower().lstrip('.')
             try:
                 ans = lookup(d, t, self.dns, self.protocol, self.timeout)
                 if ans:
                     wildcard = self.parse_record(ans, d)
                     if ans and not wildcard and d != self.domain and self.record != 'PTR':
                         self.new_targets(d)
                         self.sl.found.append(d)
                 elif ans == False and self.record != 'PTR':
                     hit = [x for x in self.sl.scan_failed if x[0] == subdomain]
                     if hit:
                         z = self.sl.scan_failed.index(hit[0])
                         self.sl.scan_failed[z][1] += 1
                         if hit[0][1] > self.retry:
                             self.sl.failcounter += 1
                             if self.args.verbose:
                                 self.log.status('Failed lookup on %s' % d + ' ' * 20, False)
                             self.log.error_queue.append('Failed lookup on %s' % d )
                             continue
                     else:
                         self.sl.scan_failed.append([subdomain, 1])
                     self.sl.scanned.remove(subdomain)
                     self.sl.unscanned.insert(0,subdomain)
                 if ans != False and self.record != 'PTR' and ((t == 'ANY' or t == 'A') or t == self.args.record):
                     # basically don't count queries that's TXT or MX if querying a server doesn't respond to ANY
                     self.sl.n_scanned += 1
                     self.sl.n_unscanned -= 1
             except Exception as e:
                 try:
                     self.log.fatal(('Domain Query failed on %s.'  % d), False)
                 except:
                     pass
                 print(traceback.print_exc())
                 print (e)
Esempio n. 8
0
    def parse_record(self, ans, query):
        wildcard = False
        try:
            for r in ans:
                if r.rdtype == 1:  # A RECORD
                    d = r.name.to_text().rstrip('.').encode('utf-8').decode('idna')
                    for x in r.items:
                        item = x.to_text()
                        if item in self.a_wildcard:
                            wildcard = True
                        else:
                            self.sl.items.append([d, item])
                            self.log.log_queue.append(self.f1.format(d +' ') + self.f2.format('A') + self.f3.format(item))
                            self.log.csv_queue.append("%s,A,%s,%s,%s" % (d, item,item,self.domain))


                if r.rdtype == 5:  # CNAME RECORD
                    d = r.name.to_text().rstrip('.').encode('utf-8').decode('idna')
                    for x in r.items:
                        item = x.to_text()
                        if item in self.cname_wildcard:
                            wildcard = True
                        else:
                            self.sl.items.append([d, item])
                            self.log.log_queue.append(self.f1.format(d +' ') + self.f2.format('CNAME') + self.f3.format(item.rstrip('.')))
                            if self.csv:
                                cname_ans = lookup(d, 'A')
                                for line in cname_ans:
                                    if line.rdtype == 1:
                                        for dns_entry in line.items:
                                            self.log.csv_queue.append("%s,CNAME,%s,%s,%s" % (d, item.rstrip('.'), dns_entry.to_text(), self.domain))


                if r.rdtype == 12:  # PTR RECORD
                    #d = r.name.to_text().rstrip('.').decode('utf-8').decode('idna')
                    for x in r.items:
                        item = x.to_text()
                        if self.domain.split('.')[-2] in item:
                            if not [y for y in self.sl.items if item.rstrip('.') in y if query in y[1]]:
                                self.sl.items.append([item, query])
                                self.log.log_queue.append(self.f1.format(item.rstrip('.') +' ') + self.f2.format('PTR') + self.f3.format(query))
                                self.log.csv_queue.append("%s,PTR,%s,%s,%s" % (item.rstrip('.'), query,query,self.domain))
                            else:
                                wildcard = True

                if r.rdtype == 16:  # TXT RECORD
                    d = r.name.to_text().rstrip('.').encode('utf-8').decode('idna')
                    for x in r.items:
                        item = x.to_text()
                        if item in self.txt_wildcard:
                            wildcard = True
                        else:
                            if [t for t in self.config['config']['txt_record_search'] if t in item]:
                                self.sl.items.append([d, item])
                                self.log.log_queue.append(self.f1.format(d +' ') + self.f2.format('TXT') + self.f3.format(item))
                                self.log.csv_queue.append("%s,TXT,%s,,%s" % (d, item,self.domain))

                if r.rdtype == 28:  # AAAA RECORD
                    d = r.name.to_text().rstrip('.').encode('utf-8').decode('idna')
                    for x in r.items:
                        item = x.to_text()
                        if item in self.aaaa_wildcard:
                            wildcard = True
                        else:
                            self.sl.items.append([d, item])
                            self.log.log_queue.append(self.f1.format(d +' ') + self.f2.format('AAAA') + self.f3.format(item))
                            self.log.csv_queue.append("%s,AAAA,%s,%s,%s" % (d, item, item, self.domain))

                if r.rdtype == 15:  # MX RECORD
                    d = r.name.to_text().rstrip('.').encode('utf-8').decode('idna')
                    for x in r.items:
                        item = x.to_text()
                        if item in self.mx_wildcard:
                            wildcard = True
                        else:
                            self.sl.items.append([d, item])
                            self.log.log_queue.append(self.f1.format(d +' ') + self.f2.format('MX') + self.f3.format(item.split(' ')[1].rstrip('.')))
                            if self.csv:
                                mx_value = item.split(' ')[1].rstrip('.')
                                mx_ans = lookup(mx_value, 'A')
                                for line in mx_ans:
                                    if line.rdtype == 1:
                                        for dns_entry in line.items:
                                            self.log.csv_queue.append("%s,MX,%s,%s,%s" % (d, mx_value, dns_entry.to_text(), self.domain))

                            new = ['mail._domainkey', '_dmarc', 'default._domainkey', 'selector1._domainkey', 'selector2._domainkey', 's2._domainkey', 's2._domainkey']
                            for n in new:
                                if d == self.domain:
                                    self.append_target(n)
                                else:
                                    self.append_target(n + '.' + d.replace(self.domain, '').strip('.'))
        except Exception as e:
            self.log.fatal(('Parsing records for: %s with answer %s' % (query, ans)), False)
            print(traceback.print_exc())
            print (e)
        return wildcard