Ejemplo n.º 1
0
    def run(self, ip, port=25):
        try:
            s = socket.socket()
            s.connect((ip, port))
            banner = s.recv(1024).rstrip('\r\n')
            if banner[:3] == '220':
                self.data.banner = banner[4:]
            s.send('EHLO test\n')
            ehlo = s.recv(1024).replace('\r', '').rstrip().split('\n')[1:]
            self.data.ehlo = map(lambda x: x[4:], ehlo)
        except Exception as e:
            cprint(str(e), 'error')
            self.clear()
            s.close()
            return None

        if 'STARTTLS' in self.data.ehlo:
            try:
                s.send("STARTTLS\n")
                resp = s.recv(1024)
                if resp[:3] == '220':
                    ss = ssl.wrap_socket(s)
                    cert = ss.getpeercert(True)
                    self.data.update(parse_der(cert))
            except Exception as e:
                cprint(str(e), 'error')
                self.clear()
                return None
            finally:
                s.close()

        ServicesInfo.add(ip, port, 'smtp', self.data)
        self.clear()
        return True
Ejemplo n.º 2
0
    def nouse_run(self, ipdir):
        """
        A wrapper for single_run_nmap.
        :param ipdir: dict. Using ip:ports as key:value.
        :return: dict. Further imformation about services on each host.
        """

        result = {}
        for ip in ipdir:
            tmp_res = self.single_run_nmap(ip, ipdir[ip])
            if tmp_res != None:
                result[ip] = tmp_res

        if self.error_list:
            cprint(
                'Scanning finished, but some error occurs while nmap scanning!',
                'error')
            with open('test.log', 'w') as f:
                for error in self.error_list:
                    f.write("{}\n".format(error))
        else:
            cprint('One ip range scanning finished with no error!', 'info')

        self.nmap_result = result
        NmapInfo.addWithJson(dumps(result))
Ejemplo n.º 3
0
    def single_run_zmap(self, port, ips):
        """
        Must run this function as root. Otherwise fail.
        :param ports: str. the port that zmap scans
        :param ips: str. ip addresses range in CIDR block notation
        """
        cprint("Run zmap on port {} of {}".format(port, ips), 'debug')
        os.seteuid(0)  # run as root.
        if not self.zmap_path:
            print 'Zmap is not installed!'
            exit()
        cmd = [self.zmap_path] + config.common.ZMAP_CMD + ["-p", port, ips]
        cprint("start process: " + str(cmd), "debug")
        p = subprocess.Popen(cmd,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE)
        out, err = p.communicate()
        if err:
            cprint(err, 'error')
            return

        if out:
            cprint("One zmap scanning finished!", "debug")
        else:
            cprint("No result found this time!", "warning")
            return

        for ip in out.strip().split('\n'):
            if self.zmap_result.has_key(ip):
                self.zmap_result[ip].append(port)
            else:
                self.zmap_result[ip] = [port]
Ejemplo n.º 4
0
 def _generate_all_tasks_for_goal(self, goal, max_depth=3):
     base_entities = [goal]
     intermediate_entities = set()
     cprint(DEBUG, f"Expanding tasks to goal {goal}")
     self._expand_tasks_to_goal(goal, max_depth, base_entities,
                                intermediate_entities)
     cprint(DEBUG, "Done.")
Ejemplo n.º 5
0
    def run(self, ip, port=25):
        try:
            s = socket.socket()
            s.connect((ip, port))
            banner = s.recv(1024).rstrip('\r\n')
            if banner[:3] == '220':
                self.data.banner = banner[4:]
            s.send('EHLO test\n')
            ehlo = s.recv(1024).replace('\r', '').rstrip().split('\n')[1:]
            self.data.ehlo = map(lambda x: x[4:], ehlo)
        except Exception as e:
            cprint(str(e), 'error')
            self.clear()
            return None

        if 'STARTTLS' in self.data.ehlo:
            try:
                s.send("STARTTLS\n")
                resp = s.recv(1024)
                if resp[:3] == '220':
                    ss = ssl.wrap_socket(s)
                    cert = ss.getpeercert(True)
                    self.data.update(parse_der(cert))
            except Exception as e:
                cprint(str(e), 'error')
                self.clear()
                return None
            finally:
                s.close()

        ServicesInfo.add(ip, port, 'smtp', self.data)
        self.clear()
        return True
Ejemplo n.º 6
0
    def run(self, ip, ports=config.common.PORTS):
        """
        Must run as root.
        Use nmap to get further imformation about the ip and ports
        scanned by zmap.
        :param ip: str. The target ip that zmap will scan.
        :param port: list. All open ports of the ip founded by zmap.
        :return: list. Further imformation about services on the host.
        """

        self.current_ip = ip
        filename = os.path.join(
            config.paths.logpath,
            '{}_{}.xml.log'.format(ip, '-'.join(map(str, ports))))
        # Save time while debugging by not scanning ip that has been scanned.
        if 0 and os.path.exists(filename):
            cprint(
                'Previous scan result exists for {}, just parse the xml.'.
                format(ip), 'info')
            return self.parse_nmap_xml(filename)

        # os.seteuid(0)  # run as root.
        cprint(
            'Start scanning {} on port {} with nmap'.format(
                ip, ','.join(ports)), 'info')
        cmd = [self.nmap_path] + config.common.NMAP_CMD + \
              [ip, '-p', ','.join(ports)]
        v6Scan = False
        if not isIPv4(ip):  # ipv6
            cmd.append('-6')
            v6Scan = True
        p = subprocess.Popen(cmd,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE)
        out, error = p.communicate()

        if error:
            cprint(error, 'error')

        cprint(
            'Nmap finished scanning {} on {}'.format(ip,
                                                     ','.join(map(str,
                                                                  ports))),
            'info')
        # store temporary xml file in logs dir.
        f = open(filename, 'w+')
        f.write(out)
        f.close()
        cprint('nmap result %s' % self.parse_nmap_xml(filename), 'debug')
        self.nmap_result[ip] = self.parse_nmap_xml(filename)
        if v6Scan:
            for port in self.nmap_result[ip]:
                ServicesInfo.add(
                    ip, port, self.nmap_result[ip][port]["name"], {
                        "version": self.nmap_result[ip][port]["version"],
                        "extrainfo": self.nmap_result[ip][port]["extrainfo"],
                        "product": self.nmap_result[ip][port]["product"],
                    })
        else:
            NmapInfo.addWithJson(dumps(self.nmap_result))
Ejemplo n.º 7
0
    def run(self, ip, port=110):
        try:
            s = socket.socket()
            s.connect((ip, port))
            banner = s.recv(1024).rstrip('\r\n')
            self.data.banner = banner
            if banner.startswith('+OK'):
                s.send('CAPA\r\n')
                capa = s.recv(1024).split('\r\n')[1:-2]
                self.data.capability_list = capa
        except Exception as e:
            cprint(str(e), 'error')
            self.clear()
            return None

        if 'STLS' in self.data.capability_list:
            try:
                s.send("STLS\r\n")
                resp = s.recv(1024)
                if resp[:3] == '+OK':
                    ss = ssl.wrap_socket(s)
                    cert = ss.getpeercert(True)
                    self.data.update(parse_der(cert))
            except Exception as e:
                cprint(str(e), 'error')
                self.clear()
                return None

        s.close()
        # from pprint import pprint
        # pprint(self.data)
        ServicesInfo.add(ip, port, 'pop3', self.data)
        self.clear()
        return True
Ejemplo n.º 8
0
    def run(self, ip, port=3306):
        try:
            s = socket.socket()
            s.connect((ip, port))
            s.recv(4)
            self.data.protocol_version = ord(s.recv(1))
            self.data.server_version = recv_str(s)
            self.data.connection_id = unpack('I', s.recv(4))[0]
            self.data.auth_data = recv_str(s)
            if self.data.protocol_version == 10:
                cflag1 = s.recv(2)
                self.data.character_set = ord(s.recv(1))
                self.data.status_flags = unpack('H', s.recv(2))[0]
                self.data.capability_flags = unpack('I', cflag1+s.recv(2))[0]
                auth_len = ord(s.recv(1))
                assert set(s.recv(10)) == set(['\x00'])
                self.data.auth_data += recv_str(s)
                if auth_len:
                    self.data.auth_name = s.recv(auth_len)
                    assert s.recv(1) == '\x00'
        except Exception as e:
            cprint(str(e), 'error')
            self.clear()
            return None

        ServicesInfo.add(ip, port, 'mysql', self.data)
        s.close()
        self.clear()
        return True
Ejemplo n.º 9
0
    def single_run_zmap(self, port, ips):
        """
        Must run this function as root. Otherwise fail.
        :param ports: str. the port that zmap scans
        :param ips: str. ip addresses range in CIDR block notation
        """
        cprint("Run zmap on port {} of {}".format(port, ips), 'debug')
        os.seteuid(0)  # run as root.
        if not self.zmap_path:
            print 'Zmap is not installed!'
            exit()
        cmd = [self.zmap_path] + config.common.ZMAP_CMD + ["-p", port, ips]
        cprint("start process: " + str(cmd), "debug")
        p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        out, err = p.communicate()
        if err:
            cprint(err, 'error')
            return

        if out:
            cprint("One zmap scanning finished!", "debug")
        else:
            cprint("No result found this time!", "warning")
            return

        for ip in out.strip().split('\n'):
            if self.zmap_result.has_key(ip):
                self.zmap_result[ip].append(port)
            else:
                self.zmap_result[ip] = [port]
Ejemplo n.º 10
0
 def __init__(self):
     """
     Initialize the zmap scanner.
     """
     super(ZmapScan, self).__init__()
     self.zmap_result = {}
     self.zmap_path = subprocess.check_output(['which', 'zmap']).rstrip('\n')
     if not self.zmap_path:
         cprint('Zmap is not installed!', 'error')
         exit()
Ejemplo n.º 11
0
 def __init__(self):
     """
     Initialize the zmap scanner.
     """
     super(ZmapScan, self).__init__()
     self.zmap_result = {}
     self.zmap_path = subprocess.check_output(['which',
                                               'zmap']).rstrip('\n')
     if not self.zmap_path:
         cprint('Zmap is not installed!', 'error')
         exit()
Ejemplo n.º 12
0
 def __init__(self):
     """
     Initialize the nmap scanner.
     """
     super(NmapScan, self).__init__()
     self.nmap_path = subprocess.check_output(['which', 'nmap']).rstrip('\n')
     if not self.nmap_path:
         cprint('Nmap is not installed!', 'error')
         exit()
     self.error_list = []
     self.nmap_result = {}
     self.current_ip = None
Ejemplo n.º 13
0
    def run(self, ips, ports=config.common.PORTS):
        """
        A wrapper for single_run_zmap.
        :param ports: list. the ports that zmap scans
        :param ips: str. ip addresses range in CIDR block notation
        """
        cprint("Start running zmap on port {} of {}".format(''.join(ports), ips), 'info')
        for port in ports:
            self.single_run_zmap(port, ips)

        cprint("All zmap scanning finished!", "info")
        ZmapInfo.addWithJson(dumps(self.zmap_result))
Ejemplo n.º 14
0
 def __init__(self):
     """
     Initialize the nmap scanner.
     """
     super(NmapScan, self).__init__()
     self.nmap_path = subprocess.check_output(['which',
                                               'nmap']).rstrip('\n')
     if not self.nmap_path:
         cprint('Nmap is not installed!', 'error')
         exit()
     self.error_list = []
     self.nmap_result = {}
     self.current_ip = None
Ejemplo n.º 15
0
    def run(self, ips, ports=config.common.PORTS):
        """
        A wrapper for single_run_zmap.
        :param ports: list. the ports that zmap scans
        :param ips: str. ip addresses range in CIDR block notation
        """
        cprint(
            "Start running zmap on port {} of {}".format(''.join(ports), ips),
            'info')
        for port in ports:
            self.single_run_zmap(port, ips)

        cprint("All zmap scanning finished!", "info")
        ZmapInfo.addWithJson(dumps(self.zmap_result))
Ejemplo n.º 16
0
 def run(self, ip, port=21, timeout=2):
     try:
         ftp = FTP()
         ftp.connect(ip, port, timeout=timeout)
         self.data.banner = ftp.getwelcome()
         ftp.login()
         self.data.anonymous = True
         flist = []
         ftp.retrlines('LIST', lambda i: flist.append(i))
         ftp.quit()
         self.data.flist = flist
         ServicesInfo.add(ip, port, 'ftp', self.data)
     except Exception, e:
         cprint(str(e), 'error')
         return None
Ejemplo n.º 17
0
    def run(self, ip, port=23):
        try:
            s = socket.socket()
            s.connect((ip, port))
            banner = s.recv(1024)
            if banner.endswith('login: '******'telnet', self.data)
        except Exception as e:
            cprint(str(e), 'error')
            return None
        finally:
            s.close()
            self.clear()

        return True
Ejemplo n.º 18
0
    def run(self, ip, port=23):
        try:
            s = socket.socket()
            s.connect((ip, port))
            banner = s.recv(1024)
            if banner.endswith('login: '******'telnet', self.data)
        except Exception as e:
            cprint(str(e), 'error')
            return None
        finally:
            s.close()
            self.clear()

        return True
Ejemplo n.º 19
0
    def _expand_tasks_to_goal(self, goal, max_depth=1, base_entities=[], intermediate_entities=set(), relevant_recipes=[]):
        """
        DFS expansion of recipes for an entity to generate new tasks
        """
        for b in base_entities:
            if b not in self.root_entities: # Can't expand if it's a root entity or cyclic
                if b != goal: intermediate_entities.add(b)
                next_base_entities = base_entities[:]
                next_base_entities.remove(b)

                cur_depth = len(intermediate_entities) + 1

                cprint(DEBUG,'--Expanding base entity', b)

                # Expand each recipe for each base entity
                for recipe in self.entity2recipes[b]:
                    cprint(DEBUG,f'----Trying recipe for {b}, {recipe}')
                    expanded_entities = [e for e in recipe if e not in next_base_entities]
                    is_cycle = False
                    for e in recipe:
                        if e in intermediate_entities or e == goal: 
                            cprint(DEBUG,f'------Cycle detected, skipping recipe {recipe}')
                            is_cycle = True
                            break
                    if is_cycle:
                        continue

                    old_base_entities = next_base_entities
                    next_base_entities = expanded_entities + next_base_entities

                    # Add task
                    relevant_recipes.append(recipe)
                    task = Task(goal, next_base_entities, intermediate_entities, relevant_recipes[:])
                    if task not in self.depth2task[cur_depth]: 
                        self.depth2task[cur_depth].add(task)
                        cprint(DEBUG,f'------Adding task {task}')

                    if cur_depth < max_depth:
                        cprint(DEBUG,f'current depth is {cur_depth}')
                        self._expand_tasks_to_goal(goal, max_depth, next_base_entities, intermediate_entities, relevant_recipes[:])

                    relevant_recipes.remove(recipe)
                    next_base_entities = old_base_entities

                if b != goal: intermediate_entities.remove(b)
Ejemplo n.º 20
0
    def run(self, ip, ports=config.common.PORTS):
        """
        Must run as root.
        Use nmap to get further imformation about the ip and ports
        scanned by zmap.
        :param ip: str. The target ip that zmap will scan.
        :param port: list. All open ports of the ip founded by zmap.
        :return: list. Further imformation about services on the host.
        """

        self.current_ip = ip
        filename = os.path.join(config.paths.logpath, '{}_{}.xml.log'.format(ip, '-'.join(map(str, ports))))
        # Save time while debugging by not scanning ip that has been scanned.
        if 0 and os.path.exists(filename):
            cprint('Previous scan result exists for {}, just parse the xml.'.format(ip), 'info')
            return self.parse_nmap_xml(filename)

        # os.seteuid(0)  # run as root.
        cprint('Start scanning {} on port {} with nmap'.format(ip, ','.join(ports)), 'info')
        cmd = [self.nmap_path] + config.common.NMAP_CMD + \
              [ip, '-p', ','.join(ports)]
        v6Scan = False
        if not isIPv4(ip):  # ipv6
            cmd.append('-6')
            v6Scan = True
        p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE)
        out, error = p.communicate()

        if error:
            cprint(error, 'error')

        cprint('Nmap finished scanning {} on {}'.format(
            ip, ','.join(map(str, ports))), 'info')
        # store temporary xml file in logs dir.
        f = open(filename.replace(":", "_"), 'w+')
        f.write(out)
        f.close()
        cprint('nmap result %s' % self.parse_nmap_xml(filename), 'debug')
        self.nmap_result[ip] = self.parse_nmap_xml(filename)
        if v6Scan:
            for port in self.nmap_result[ip]:
                ServicesInfo.add(ip, port, self.nmap_result[ip][port]["name"], self.nmap_result[ip][port])
        else:
            NmapInfo.addWithJson(dumps(self.nmap_result))
Ejemplo n.º 21
0
 def run(self, ip, port=80, ishttps=False):
     # WebPage
     port = int(port)
     if ishttps:
         url = "https://" + ip
         if port != 443:
             url += ":" + str(port)
     else:
         url = "http://" + ip
         if port != 80:
             url += ":" + str(port)
     try:
         webinfo = WebPage(url).info()
         ServicesInfo.add(ip, port, ["http", "https"][int(ishttps)], webinfo)
     except Exception as e:
         cprint(str(e), 'error')
         return None
     return True
Ejemplo n.º 22
0
    def run(self, ip, port=21, timeout=2):
        try:
            ftp = FTP()
            ftp.connect(ip, port, timeout=timeout)

            self.data.banner = ftp.getwelcome()

            ftp.login()
            self.data.anonymous = True

            flist = []
            ftp.retrlines('LIST', lambda i: flist.append(i))
            self.data.flist = flist
            ServicesInfo.add(ip, port, 'ftp', self.data)

        except Exception, e:
            cprint(str(e), 'error')
            return None
Ejemplo n.º 23
0
    def run(self, ip, port=22, timeout=2):

        try:
            socket.setdefaulttimeout(timeout)
            s = socket.socket()
            s.connect((ip, port))
            banner = s.recv(50).strip('\r\n').split(' ')

            try:
                self.data.version = banner[0]
                self.data.os = banner[1]
            except IndexError:
                pass

            s.send('{}\r\n'.format(banner[0]))
            self._raw_recv = s.recv(2048)

            s.close()
            self._parse_raw_data()

            # use paramiko to get hostkey because of lazyless...
            tran = Transport((ip, port))
            tran.start_client()
            pubkey = tran.get_remote_server_key()
            self.data.pubkey_name = pubkey.get_name()
            fp = pubkey.get_fingerprint()
            self.data.pubkey_fingerprint = ':'.join(
                map(lambda x: x.encode('hex'), fp))

            ServicesInfo.add(ip, port, 'ssh', self.data)

        except Exception as e:
            cprint(str(e), 'error')
            return None
        finally:
            tran.close()
            self.clear()

        return True
Ejemplo n.º 24
0
    def run(self, ip, port=22, timeout=2):

        try:
            socket.setdefaulttimeout(timeout)
            s = socket.socket()
            s.connect((ip, port))
            banner = s.recv(50).strip('\r\n').split(' ')

            try:
                self.data.version = banner[0]
                self.data.os = banner[1]
            except IndexError:
                pass

            s.send('{}\r\n'.format(banner[0]))
            self._raw_recv = s.recv(2048)

            s.close()
            self._parse_raw_data()

            # use paramiko to get hostkey because of lazyless...
            tran = Transport((ip, port))
            tran.start_client()
            pubkey = tran.get_remote_server_key()
            self.data.pubkey_name = pubkey.get_name()
            fp = pubkey.get_fingerprint()
            self.data.pubkey_fingerprint = ':'.join(map(lambda x:x.encode('hex'), fp))
            
            ServicesInfo.add(ip, port, 'ssh', self.data)

        except Exception as e:
            cprint(str(e), 'error')
            return None
        finally:
            tran.close()
            self.clear()

        return True
Ejemplo n.º 25
0
    def nouse_run(self, ipdir):
        """
        A wrapper for single_run_nmap.
        :param ipdir: dict. Using ip:ports as key:value.
        :return: dict. Further imformation about services on each host.
        """

        result = {}
        for ip in ipdir:
            tmp_res = self.single_run_nmap(ip, ipdir[ip])
            if tmp_res != None:
                result[ip] = tmp_res

        if self.error_list:
            cprint('Scanning finished, but some error occurs while nmap scanning!', 'error')
            with open('test.log', 'w') as f:
                for error in self.error_list:
                    f.write("{}\n".format(error))
        else:
            cprint('One ip range scanning finished with no error!', 'info')

        self.nmap_result = result
        NmapInfo.addWithJson(dumps(result))
Ejemplo n.º 26
0
    def parse_nmap_xml(self, nmap_xml):
        """
        Parse the xml file and extract the imforation of web services.
        Service info contains (name, version, extrainfo, product, devicetype, ostype...)
        :param nmap_xml: str. The name of the xml file to parse.
        :return: dict. Use open port number as key and concrete infomation of the web service as value.
        """

        try:
            tree = ET.parse(nmap_xml)
            root = tree.getroot()
            result = {}
            filter_flag = True
            for port in root.find('host').find('ports').findall('port'):
                if port.find('state').get('state') not in ('filtered',
                                                           'closed'):
                    filter_flag = False
                if port.find('state').get('state') == 'open':
                    service = port.find('service').attrib
                    service.pop('conf')
                    service.pop('method')
                    result[port.get('portid')] = service
        except Exception as e:
            cprint(e, 'error')
            self.error_list.append(self.current_ip)
            return None

        # What if we get nothing from the xml...
        if not result:
            if filter_flag:
                cprint(
                    'All open ports detected by zmap are actually filtered or closed!',
                    'warning')
            else:
                cprint('Failed to parse nmap xml!', 'error')
                self.error_list.append(self.current_ip)
            return None
        else:
            cprint('Nmap xml parsed!', 'debug')

        return result
Ejemplo n.º 27
0
    def parse_nmap_xml(self, nmap_xml):
        """
        Parse the xml file and extract the imforation of web services.
        Service info contains (name, version, extrainfo, product, devicetype, ostype...)
        :param nmap_xml: str. The name of the xml file to parse.
        :return: dict. Use open port number as key and concrete infomation of the web service as value.
        """

        try:
            tree = ET.parse(nmap_xml)
            root = tree.getroot()
            result = {}
            filter_flag = True
            for port in root.find('host').find('ports').findall('port'):
                if port.find('state').get('state') not in ('filtered', 'closed'):
                    filter_flag = False
                if port.find('state').get('state') == 'open':
                    service = port.find('service').attrib
                    service.pop('conf')
                    service.pop('method')
                    result[port.get('portid')] = service
        except Exception as e:
            cprint(e, 'error')
            self.error_list.append(self.current_ip)
            return None

        # What if we get nothing from the xml...
        if not result:
            if filter_flag:
                cprint('All open ports detected by zmap are actually filtered or closed!', 'warning')
            else:
                cprint('Failed to parse nmap xml!', 'error')
                self.error_list.append(self.current_ip)
            return None
        else:
            cprint('Nmap xml parsed!', 'debug')

        return result
Ejemplo n.º 28
0
    def run(self, ip, port=143):
        try:
            s = socket.socket()
            s.connect((ip, port))
            banner = s.recv(1024).rstrip('\r\n')
            self.data.banner = banner
            if banner.startswith('* OK'):
                s.send('A1 CAPABILITY\r\n')
                capa = s.recv(1024).split('\r\n')[0]
                self.data.capability_list = capa
        except Exception as e:
            cprint(str(e), 'error')
            self.clear()
            return None

        if 'ID ' in self.data.capability_list:
            try:
                s.send('A2 ID ("test" "test")\r\n')
                resp = s.recv(1024)
                mid = resp[6:resp.index(')')].split()
                iddict = {}
                for i in range(0, len(mid), 2):
                    iddict[mid[i].strip('"')] = mid[i+1].strip('"')
                self.data.id = iddict
            except Exception as e:
                cprint(str(e), 'error')
                self.clear()
                return None

        if 'STARTTLS' in self.data.capability_list:
            try:
                s.send("A3 STARTTLS\r\n")
                resp = s.recv(1024)
                if resp[:5] == 'A3 OK':
                    ss = ssl.wrap_socket(s)
                    cert = ss.getpeercert(True)
                    self.data.update(parse_der(cert))
            except Exception as e:
                cprint(str(e), 'error')
                self.clear()
                return None

        s.close()
        # from pprint import pprint
        # pprint(self.data)
        ServicesInfo.add(ip, port, 'imap', self.data)
        self.clear()
        return True