Example #1
0
    def _run_inv_scan(self, widget, inv):
        """
        Run Inventory scan.
        """
        if self.daddy:
            inv_id = self.daddy.invdb.get_inventory_id_for_name(inv)
            if not inv_id:

                scan_args = self._get_command_from_schemas(inv)
                if not scan_args:
                    return

            else:
                scan_args = (
                    self.daddy.invdb.get_scan_args_for_inventory_id(inv_id))
                if not scan_args:
                    scan_args = self._get_command_from_schemas(inv)
                    if not scan_args:
                        return


            scan = NmapCommand(scan_args)
            scan.run_scan()

            if not self.running_scans:
                # no scans running, start timer for checking if some scan
                # finished
                self.scans_timer = gobject.timeout_add(4200, self._check_scans)

            self.running_scans[scan] = inv
            running_scans = len(self.running_scans)
            self.daddy._write_statusbar(("%d " % running_scans) +
                    append_s(_("scan"), running_scans) + _(" running"))
    def _run_inv_scan(self, widget, inv):
        """
        Run Inventory scan.
        """
        if self.daddy:
            inv_id = self.daddy.invdb.get_inventory_id_for_name(inv)
            if not inv_id:

                scan_args = self._get_command_from_schemas(inv)
                if not scan_args:
                    return

            else:
                scan_args = (
                    self.daddy.invdb.get_scan_args_for_inventory_id(inv_id))
                if not scan_args:
                    scan_args = self._get_command_from_schemas(inv)
                    if not scan_args:
                        return

            scan = NmapCommand(scan_args)
            scan.run_scan()

            if not self.running_scans:
                # no scans running, start timer for checking if some scan
                # finished
                self.scans_timer = gobject.timeout_add(4200, self._check_scans)

            self.running_scans[scan] = inv
            running_scans = len(self.running_scans)
            self.daddy._write_statusbar(("%d " % running_scans) +
                                        append_s(_("scan"), running_scans) +
                                        _(" running"))
 def run(self):
     self.scan_exec = NmapCommand('%s %s %s' % (self.nmap_path,
                                                self.command,
                                                self.host))
     
     try:
         self.scan_exec.run_scan()
     except OSError, msg:
         raise(msg)
    def run_scan(self, host, profile):
        if re.match(self.rgx_is_domain, host):

            commands = self.qs_data.get_profiles("profile_commands")
            try:
                nmap_option = commands[profile]
            except:
                nmap_option = "-T Aggressive -v -n"

            print "QuickScan: running scan: %s on %s" % (nmap_option, host)
            
            if Ipv6.is_ipv6(host):
            	namp_option = nmap_option + " -6"
            
            self.command_execution = NmapCommand('%s %s %s' % (Path.nmap_command_path,
                                                               nmap_option,
                                                               host))
            
            try:
                alive = self.command_execution.scan_state()
                if alive:
                    warn_dialog = HIGAlertDialog(
                    message_format="Scan has not finished yet",
                    secondary_text="Another scan is running in the background.",
                    type=gtk.MESSAGE_QUESTION, buttons=gtk.BUTTONS_OK_CANCEL)
                response = warn_dialog.run()
                warn_dialog.destroy()
                
                if response == gtk.RESPONSE_OK:
                    self.kill_scan()
                else:
                    return
            
            except:
                pass
                        
            try:
                self.command_execution.run_scan()
                self.status.set_scanning()
            except OSError, msg:
                warn_dialog = HIGAlertDialog(
                    message_format="Nmap couldn't be found",
                    secondary_text="Umit Quick Scan couldn't find Nmap. " 
                    "Please check your Nmap instalation.",
                    type=gtk.MESSAGE_ERROR)
                warn_dialog.run()
                warn_dialog.destroy()
            except Exception, msg:
                warn_dialog = HIGAlertDialog(
                    message_format="Command is missing!",
                    secondary_text="Please check your profile's command.",
                    type=gtk.MESSAGE_ERROR)
                warn_dialog.run()
                warn_dialog.destroy()
class Nmap(object):
    """
    Class to manipulate Nmap scans.
    """

    def __init__(self, nmap_path, command, host):
        Path.set_umit_conf(os.path.dirname(sys.argv[0]))
        Path.set_running_path(os.path.abspath(os.path.dirname(sys.argv[0])))
        self.nmap_path = nmap_path
        self.command = command
        #add option for ipv6 address by checking the host
        #
        #
        #check for ipv6 address and -6 to command option 

        
        if Ipv6.is_ipv6(host):
            	command = command +" -6"
        self.host = host
        #threading.Thread.__init__(self)
        
    def run(self):
        self.scan_exec = NmapCommand('%s %s %s' % (self.nmap_path,
                                                   self.command,
                                                   self.host))
        
        try:
            self.scan_exec.run_scan()
        except OSError, msg:
            raise(msg)
        
        try:
            while self.scan_exec.scan_state():
                print ">>>", self.scan_exec.get_normal_output()
        except Exception:
            print "Exception caught"
            
            
        from umit.core.UmitDB import Scans

        state = self.scan_exec.scan_state()
        if state == False:
            store = Scans(scan_name="Quick Scan on %s" % self.host,
                          nmap_xml_output=self.scan_exec.get_xml_output(),
                          date=datetime.now())
                
            return self.scan_exec.get_normal_output()
        
        return False
    def get_addresses(self, event):
        """
        Get hosts for network(s).
        """
        networks = []

        for entry in self.networks_box.get_children()[:-1]:
            text_entry = entry.get_text()
            wrong = alpha.search(text_entry)
            if wrong:
                self._error_invalid_network(text_entry)
                return
            elif text_entry:
                networks.append(text_entry)

        if not networks:
            dlg = HIGAlertDialog(self,
                                 message_format=_("No network."),
                                 secondary_text=_(
                                     "You need to specify at least "
                                     "one network to search for hosts."))
            dlg.run()
            dlg.destroy()
            return

        self.scans = {}
        self.scount = 0

        for n in networks:
            discovery = NmapCommand("%s -sP %s" % ('nmap', n))
            discovery.run_scan()

            self.scans[self.scount] = (discovery, n)
            self.scount += 1

        self.target_model.clear()
        self.hostdetect_btn.set_sensitive(False)
        self._adjust_target_label()
        gobject.timeout_add(500, self._check_scans)
Example #7
0
    def get_addresses(self, event):
        """
        Get hosts for network(s).
        """
        networks = []

        for entry in self.networks_box.get_children()[:-1]:
            text_entry = entry.get_text()
            wrong = alpha.search(text_entry)
            if wrong:
                self._error_invalid_network(text_entry)
                return
            elif text_entry:
                networks.append(text_entry)

        if not networks:
            dlg = HIGAlertDialog(self, message_format=_("No network."),
                secondary_text=_("You need to specify at least "
                    "one network to search for hosts."))
            dlg.run()
            dlg.destroy()
            return

        self.scans = { }
        self.scount = 0

        for n in networks:
            discovery = NmapCommand("%s -sP %s" % ('nmap', n))
            discovery.run_scan()

            self.scans[self.scount] = (discovery, n)
            self.scount += 1

        self.target_model.clear()
        self.hostdetect_btn.set_sensitive(False)
        self._adjust_target_label()
        gobject.timeout_add(500, self._check_scans)
Example #8
0
def run_scheduler(sched, winhndl=None):
    """
    Run scheduler forever.
    """
    next_time = calc_next_time()
    scount = 0  # number of scans running

    while 1:  # run forever and ever ;)
        current_time = time.time()

        if current_time < next_time:
            sleep_time = next_time - current_time + .1
            if winhndl:
                stopsignal = win32event.WaitForSingleObject(
                    winhndl, int(sleep_time * 1000))
                if stopsignal == win32event.WAIT_OBJECT_0:
                    break
            else:
                time.sleep(sleep_time)

        # check if time has changed by more than two minutes (clock changes)
        if abs(time.time() - next_time) > 120:
            # reset timer
            next_time = calc_next_time()

        sched.check_for_changes()

        for schema in sched.schemas:
            if schema.job_to_run():
                if not int(schema.enabled):  # schema disabled, neeexxt!
                    continue

                name = schema.schema_name
                log.info("Scheduled schema to run: %s" % name)

                if not schema.command:
                    log.warning("No command set for schema %s, \
skipping!" % name)
                    continue

                scan = NmapCommand(schema.command)
                scan.run_scan()

                running_scans[scount] = (scan, schema.saveto, schema.mailto,
                                         name, schema.addtoinv, schema.smtp)
                scount += 1  # more one scan running

        for running, opts in running_scans.items():
            scan = opts[0]

            try:
                scan_state = scan.scan_state()
            except Exception, err:
                log.critical("Scheduled schema '%s' failed to run. \
Reason: %s" % (schema.schema_name, err))
                continue

            if not scan_state:  # scan finished
                log.info("Scan finished: %s" % opts[3])

                if opts[1]:  # save xml output
                    saveto = decide_output(opts[1])
                    f = open(saveto, 'w')
                    f.write(open(scan.get_xml_output_file(), 'r').read())
                    f.close()
                    log.info("Scan output saved as: %s" % saveto)

                if opts[2]:  # mail output
                    recipients = opts[2].split(',')
                    log.info("Scan output will be mailed to: %s" % recipients)

                    smtp = load_smtp_profile(opts[5])

                    auth = int(smtp['auth'])
                    tls = int(smtp['tls'])
                    mailfrom = smtp['mailfrom']
                    user = smtp['user']
                    passwd = smtp['pass']
                    server = smtp['server']
                    port = smtp['port']
                    curr_time = format_asctime(datetime.now())
                    orig_output = scan.get_xml_output_file()
                    new_file_output = os.path.join(
                        os.path.dirname(orig_output),
                        "%s (%s).xml" % (curr_time, opts[3]))

                    fd_wcont = open(new_file_output, 'w')
                    for line in open(orig_output, 'r'):
                        fd_wcont.write(line)
                    fd_wcont.close()

                    email = Email(mailfrom, recipients, server, None, user,
                                  passwd, tls, port)
                    email.sendmail(
                        subject=(
                            _("UMIT: Status Report for scheduled schema") +
                            " %r " % opts[3]),
                        msg=(_("There was a scheduled job that just "
                               "finished:") + (" %s\n" % curr_time) +
                             _("Follows an attachment of the job output.")),
                        attach=new_file_output)
                    os.remove(new_file_output)

                if int(opts[4]):  # add to inventory
                    log.info("Scan result is being added to Inventory "
                             "%s" % opts[3])
                    xmlstore = XMLStore(Path.umitdb_ng, False)
                    try:
                        xmlstore.store(scan.get_xml_output_file(),
                                       inventory=opts[3])
                    finally:
                        xmlstore.close()  # close connection to the database
                    log.info("Scan finished insertion on Inventory "
                             "%s" % opts[3])

                scan.close()  # delete temporary files
                scount -= 1  # one scan finished
                del running_scans[running]

        next_time += 60
class EntryField(object):
    """
    This class is responsible by the main part of QS: the EntryField.
    All logic of completion, data handling and interface is here.
    """
    
    def __init__(self):
        self.qs_data = QSData()
        self.entry = HIGTextEntry()
        self.entry.set_visibility(True)
        self.status = Status()
        self.status.set_empty()
        self.scan_result = Result()
        self.b_text = ""
        self.rgx_is_domain = "^((ht|f)tp(s?)\:\/\/|~/|/)?([\w]+:\w+@)?([a-zA-Z]{1}"
        self.rgx_is_domain += "([\w\-]+\.)+([\w]{2,5}))(:[\d]{1,5})?((/?\w+/)+|/?)"
        self.rgx_is_domain += "(\w+\.[\w]{3,4})?((\?\w+=\w+)?(&\w+=\w+)*)?"
        
        self.completion = gtk.EntryCompletion()
        self.entry.set_max_length(1000)
        
        # add button to launch result in umit
        self.btn_umit = gtk.Button ("Open Result")
        
        self.results_opened = False
        self.nmap_output = None
        
        self.load_data(None)
         
        self.btn_umit.connect("clicked", self._launch_umit, None)
        
        self.entry.show()

        
    def show_results(self):
        """
        Show scan output
        """
        if not self.results_opened:
            self.nmap_output = NmapOutputViewer()
            # remove some buttons
            self.nmap_output.hbox_buttons.remove(self.nmap_output.btn_output_properties)
            self.nmap_output.hbox_buttons.remove(self.nmap_output.btn_refresh)
            self.nmap_output.hbox_buttons.pack_start(self.btn_umit)
            self.vbox.pack_end(self.nmap_output)
            self.vbox.show_all()
            self.results_opened = True
        
    def hide_results(self):
        """
        Hide scan output
        """
        if self.results_opened:
            self.nmap_output.hbox_buttons.remove(self.btn_umit)
            self.vbox.remove(self.nmap_output)
            self.results_opened = False
        
    def menu_to_umit(self, widget, button, time, data=None):
        """
        Here will be the small menu responsible to call Network Scanner.
        """
        if button == 3:
            data.show_all()
            
    def _launch_umit(self, widget, event):
        """
        Here will go the call to NetWork Scanner to display results previously
        loaded here.
        """
        nscanner_call = "umit -f %s" % self.command_execution.get_xml_output_file()
        args = shlex.split(nscanner_call)
        self.command_process = Popen(args, bufsize=1, stdin=PIPE,
                                         stdout=PIPE, stderr=PIPE)

    def load_data(self, option=None):
        """
        Load the data on gtk.ListStore, generate the model and set functions of
        match and signals.
        """
        liststore = gtk.ListStore(str)
            
        if option == "host":
            for _d in self.qs_data.get_target_list():
                liststore.append([_d])
        elif option == "profile":
            for _d in self.qs_data.get_profiles("profile_name"):
                liststore.append([_d])
        elif option == "nmap_options":
            for _d in self.qs_data.get_nmap_options():
                liststore.append([_d])
        else:
            for _d in self.qs_data.get_all().values():
                for _i in _d:
                    liststore.append([_i])
            
        self.completion.set_model(liststore)
        self.completion.set_match_func(self.match_func)
        self.completion.connect('match-selected', self.on_completion_match)
        self.entry.connect('activate', self.on_completion_not_match)
        self.entry.connect('backspace', self.on_backspace)
        self.entry.set_completion(self.completion)
        self.completion.set_text_column(0)

    
    #def load_if_not_complete(self, widget, event):
        #self.load_data("host")
        
  
    def match_func(self, completion, key, iter):
        """
        This function have the job to match and compare the words that was entered 
        on the entry field.
        """
        model = self.completion.get_model()
        modelstr = model[iter][0]
        
        if ' ' in key:
            last_word = " ".join(key.split()[1:])
            if last_word != "":
                return modelstr.lower().startswith(last_word.lower()) or modelstr.lower().startswith(key.lower())
        
        return modelstr.lower().startswith(key.lower())
    
    
    def on_completion_not_match(self, widget):
        """
        This method is called when the autocompletion don't match any result
        or user press Enter.
        """
        target_list = TargetList()

        entered_text = self.entry.get_text()

        # If has a profile
        if len(entered_text) > 1 and entered_text.find(" ") != -1:
            possible_host = entered_text.split(" ")[0]
            possible_profile = " ".join(entered_text.split(" ")[1:])
        else:
            # If is just a domain
            self.b_text = entered_text + " "
            self.entry.set_text(self.b_text)
            possible_host = entered_text
            possible_profile = None

        # Saving the target
        target_list.add_target(possible_host)
            
        self.entry.set_position(-1)
                        
#        if len(self.b_text.split(" ")) > 1:
#            host = self.b_text.split(" ")[0]
#            profile = " ".join(self.b_text.split(" ")[1:])
#        else:
#            host = entered_text
#            profile = None

            
        #Launch the scan
        self.run_scan(possible_host, possible_profile)
        
        #TODO: get the end of the scan here?
        try:
            alive = self.command_execution.scan_state()
            
            while alive:
                alive = self.command_execution.scan_state()

            file = self.command_execution.get_normal_output_file()
            self.show_results()
            self.nmap_output.show_nmap_output(file)
            self.nmap_output.refresh_output()
 
            
            #text_out = self.scan_result.set_nmap_output(possible_host, 
            #                        self.command_execution.get_normal_output(),
            #                        possible_profile)
                    
            #self.buffer.set_text(text_out)
            #self.vbox.pack_start(self.result_text, False, False, 0)
            #self.result_text.show()
        
            self.save_scan(possible_host)
            #del entered_text
        
            #self.load_data("profile")
        
            return True
        
        except:
            pass

        
    def on_completion_match(self, completion, model, iter):
        #get the text entered by the user
        entered_text = self.entry.get_text()
        
        if model[iter][0]:
            
            current_text = model[iter][0]
            # If has a profile
            if len(entered_text) > 1 and entered_text.find(" ") != -1:
                self.b_text = entered_text.split(" ")[0] + " " + current_text + " "
                self.entry.set_text(self.b_text)
                possible_host = entered_text.split(" ")[0]
                possible_profile = current_text
            #elif self.entry.get_text()
            else:
                # If is just a domain
                self.b_text = current_text + " "
                self.entry.set_text(self.b_text)
                possible_host = current_text
                possible_profile = None
                
            self.entry.set_position(-1)    
            data_from_db = self.qs_data.get_from_db()
            
            if current_text in data_from_db.keys():
                text_out = ""
                for _t in data_from_db[current_text]:
                    if _t[0] == "ports" or _t[0] == "stats":
                        pass
                    else:
                        text_out += "%s: %s\n" % (_t[0], _t[1])
                        
                #self.buffer.set_text(text_out)
                #self.vbox.pack_start(self.result_text, False, False, 0)
                #self.result_text.show()
                
    
            self.run_scan(possible_host, possible_profile)
            try:
                alive = self.command_execution.scan_state()
                
                while alive:
                    alive = self.command_execution.scan_state()
                    if not alive:
                        break
                    
                self.show_results()
                file = self.command_execution.get_normal_output_file()
                print "scan finished - %s" % file
                self.nmap_output.show_nmap_output(file)
                self.nmap_output.refresh_output()
                
                #text_out = self.scan_result.set_nmap_output(possible_host, 
                #                self.command_execution.get_normal_output(),
                #                possible_profile)
        
                #self.buffer.set_text(text_out)
                #self.vbox.pack_start(self.result_text, False, False, 0)
                #self.result_text.show()
        
                self.save_scan(possible_host)
        
                #self.load_data("profile")
        
                return True
        
            except:
                print("exception")
                traceback.print_exc(file=sys.stdout)
            
            del data_from_db
                        
            #self.load_data("profile")
            return True
            
    def on_backspace(self, entry):
        self.hide_results()
        self.resize(500,30)
        self.b_text = ""

    def disable_widgets(self):
        self.scan_result.set_sensitive(False)
    
    def enable_widgets(self):
        self.scan_result.set_sensitive(True)
    
    def kill_scan(self):
        try:
            self.command_execution.kill()
        except AttributeError:
            pass

        self.entry.set_text("")
        self.status.set_empty()
        self.disable_widgets()
    
    def run_scan(self, host, profile):
        if re.match(self.rgx_is_domain, host):

            commands = self.qs_data.get_profiles("profile_commands")
            try:
                nmap_option = commands[profile]
            except:
                nmap_option = "-T Aggressive -v -n"

            print "QuickScan: running scan: %s on %s" % (nmap_option, host)
            
            if Ipv6.is_ipv6(host):
            	namp_option = nmap_option + " -6"
            
            self.command_execution = NmapCommand('%s %s %s' % (Path.nmap_command_path,
                                                               nmap_option,
                                                               host))
            
            try:
                alive = self.command_execution.scan_state()
                if alive:
                    warn_dialog = HIGAlertDialog(
                    message_format="Scan has not finished yet",
                    secondary_text="Another scan is running in the background.",
                    type=gtk.MESSAGE_QUESTION, buttons=gtk.BUTTONS_OK_CANCEL)
                response = warn_dialog.run()
                warn_dialog.destroy()
                
                if response == gtk.RESPONSE_OK:
                    self.kill_scan()
                else:
                    return
            
            except:
                pass
                        
            try:
                self.command_execution.run_scan()
                self.status.set_scanning()
            except OSError, msg:
                warn_dialog = HIGAlertDialog(
                    message_format="Nmap couldn't be found",
                    secondary_text="Umit Quick Scan couldn't find Nmap. " 
                    "Please check your Nmap instalation.",
                    type=gtk.MESSAGE_ERROR)
                warn_dialog.run()
                warn_dialog.destroy()
            except Exception, msg:
                warn_dialog = HIGAlertDialog(
                    message_format="Command is missing!",
                    secondary_text="Please check your profile's command.",
                    type=gtk.MESSAGE_ERROR)
                warn_dialog.run()
                warn_dialog.destroy()
                
                
            self.verify_thread_timeout_id = gobject.timeout_add(2000, 
                self.verify_execution)
            
            return
Example #10
0
def run_scheduler(sched, winhndl=None):
    """
    Run scheduler forever.
    """
    next_time = calc_next_time()
    scount = 0 # number of scans running

    while 1: # run forever and ever ;)
        current_time = time.time()

        if current_time < next_time:
            sleep_time = next_time - current_time + .1
            if winhndl:
                stopsignal = win32event.WaitForSingleObject(winhndl,
                        int(sleep_time * 1000))
                if stopsignal == win32event.WAIT_OBJECT_0:
                    break
            else:
                time.sleep(sleep_time)

        # check if time has changed by more than two minutes (clock changes)
        if abs(time.time() - next_time) > 120:
            # reset timer
            next_time = calc_next_time()

        sched.check_for_changes()

        for schema in sched.schemas:
            if schema.job_to_run():
                if not int(schema.enabled): # schema disabled, neeexxt!
                    continue

                name = schema.schema_name
                log.info("Scheduled schema to run: %s" % name)

                if not schema.command:
                    log.warning("No command set for schema %s, \
skipping!" % name)
                    continue

                scan = NmapCommand(schema.command)
                scan.run_scan()

                running_scans[scount] = (scan, schema.saveto, schema.mailto,
                                         name, schema.addtoinv, schema.smtp)
                scount += 1 # more one scan running
        
        for running, opts in running_scans.items():
            scan = opts[0]

            try:
                scan_state = scan.scan_state()
            except Exception, err:
                log.critical("Scheduled schema '%s' failed to run. \
Reason: %s" % (schema.schema_name , err))
                continue

            if not scan_state: # scan finished
                log.info("Scan finished: %s" % opts[3])
            
                if opts[1]: # save xml output
                    saveto = decide_output(opts[1])
                    f = open(saveto, 'w')
                    f.write(open(scan.get_xml_output_file(), 'r').read())
                    f.close()
                    log.info("Scan output saved as: %s" % saveto)
                
                if opts[2]: # mail output
                    recipients = opts[2].split(',')
                    log.info("Scan output will be mailed to: %s" % recipients)

                    smtp = load_smtp_profile(opts[5])

                    auth = int(smtp['auth'])
                    tls = int(smtp['tls'])
                    mailfrom = smtp['mailfrom']
                    user = smtp['user']
                    passwd = smtp['pass']
                    server = smtp['server']
                    port = smtp['port']
                    curr_time = format_asctime(datetime.now())
                    orig_output = scan.get_xml_output_file()
                    new_file_output = os.path.join(
                            os.path.dirname(orig_output),
                            "%s (%s).xml" % (curr_time, opts[3]))

                    fd_wcont = open(new_file_output, 'w')
                    for line in open(orig_output, 'r'):
                        fd_wcont.write(line)
                    fd_wcont.close()

                    email = Email(mailfrom, recipients, server, None,
                                  user, passwd, tls, port)
                    email.sendmail(
                            subject=(
                                _("UMIT: Status Report for scheduled schema") +
                                " %r " % opts[3]),
                            msg=(
                                _("There was a scheduled job that just "
                                    "finished:") + (" %s\n" % curr_time) +
                                _("Follows an attachment of the job output.")),
                            attach=new_file_output)
                    os.remove(new_file_output)

                if int(opts[4]): # add to inventory
                    log.info("Scan result is being added to Inventory "
                            "%s" % opts[3])
                    xmlstore = XMLStore(Path.umitdb_ng, False)
                    try:
                        xmlstore.store(scan.get_xml_output_file(),
                                inventory=opts[3])
                    finally:
                        xmlstore.close() # close connection to the database
                    log.info("Scan finished insertion on Inventory "
                            "%s" % opts[3])

                scan.close() # delete temporary files
                scount -= 1 # one scan finished
                del running_scans[running]
            
        next_time += 60