def run_scan_on_tags(subnets_info, tags, full_scan=True, debug=False): subnets = [] results = [] # Get a list of subnets to scan for tag in tags: subnets.append(subnets_info.get_subnets_by_tag(tag)) if debug == True: print "Subnets to scan: " + str(subnets) file_managment.logger("Subnets to scan: " + str(subnets)) if len(subnets) > 0: for subnet in subnets: if full_scan == True: log_text = "Full scan of " + str(subnet[0].subnet) else: log_text = "Top ports scan of " + str(subnet[0].subnet) if debug == True: print log_text file_managment.logger(log_text) scan_results = run_scan(subnet, full_scan, debug) results.append(scan_results) return results
def main(): global debug_script global send_email global email_from global email_pass global imap_username global nmap_location global script_directory global scan_directory global scan_history_file global hosts_directory global instance_number instance_number = randint(1000, 99999) file_managment.logger("Script started, instance number: " + str(instance_number)) # Script start script_directory = "/root/port-watcher/" # script_directory = "/home/azureuser/port-watcher/" config_options = file_managment.load_config_file(script_directory + "config.json") debug_script = config_options["debug_script"] send_email = config_options["send_email"] email_from = config_options["email_from"] email_pass = config_options["email_pass"] imap_username = config_options["imap_username"] nmap_location = config_options["nmap_location"] scan_directory = script_directory + "scans/" scan_history_file = script_directory + "scans/scan_history.txt" hosts_directory = script_directory + "hosts/" schedule_file = script_directory + "schedule.csv" try: # Load config and data files schedule_obj = file_managment.schedule(schedule_file) subnets_info = file_managment.load_subnets_file() all_hosts = file_managment.host_list() scan_history = file_managment.scan_history(scan_history_file) run_next_scan(subnets_info, schedule_obj, send_email, debug_script) if debug_script == True: print "Scans Completed" file_managment.logger("Pending scans completed.") file_managment.logger("Script complete.") except Exception, e: file_managment.logger("Error running script: " + str(e)) file_managment.logger("Traceback " + str(instance_number) + ": " + str(traceback.format_exc()))
def run_scan(subnets, full_scan=True, debug=False): hosts_arr = [] results = [] for subnet in subnets: # Detect hosts for subnets in group run_scan_for_hosts(subnet.subnet) # parse the hosts scan results hosts_arr.extend(parse_nmap_xml_for_hosts(scan_directory + "latest_hosts_scan.xml")) # Scan every port of detected hosts for host_entry in hosts_arr: if full_scan == True: log_text = "Running full scan on host: " + host_entry[0] else: log_text = "Running top ports scan on host: " + host_entry[0] file_managment.logger(log_text) run_scan_on_host(host_entry[0]) file_managment.logger("Parsing scan for host: " + host_entry[0]) scan_results = parse_nmap_xml(scan_directory + "latest_scan." + str(instance_number) + ".xml") results.append(scan_results) try: os.remove(scan_directory + "latest_scan." + str(instance_number) + ".xml") except Exception, e: if debug == True: print "Error deleting latest_scan.xml" + str(e) file_managment.logger("Error deleting latest_scan.xml" + str(e)) if debug == True: print scan_results
def run_group_scan(subnets_info, group_id, full_scan=True, debug=False): # Get a list of subnets to scan subnets = subnets_info.get_subnets_by_group(group_id) # Compile a String list of subnets subnet_str_list = "" for subnet in subnets: subnet_str_list = subnet_str_list + str(subnet.subnet) + " " # create log text if full_scan == True: log_text = "Group ID: " + group_id + " Full scan of subnets: " + str(subnet_str_list) else: log_text = "Group ID: " + group_id + " Top ports scan of subnets: " + str(subnet_str_list) if debug == True: print log_text file_managment.logger(log_text) results = run_scan(subnets, full_scan, debug) return results
def parse_nmap_xml(xml_doc, debug=False): scan_results = [] # Parse Scan Information try: doc = minidom.parse(xml_doc) for nmaprun_tag in doc.getElementsByTagName("nmaprun"): try: run_time_unix = int(nmaprun_tag.getAttribute("start")) except Exception as e: run_time_unix = int(time.time()) # Find all hosts from scan for host in doc.getElementsByTagName("host"): if debug == True: file_managment.logger("Getting address tag.") addr_element = host.getElementsByTagName("address")[0] ip = addr_element.getAttribute("addr") ip_ver = addr_element.getAttribute("addrtype") # see if host exists, create a new one if it does not new_host = file_managment.get_host(str(ip), ip_ver) # Open a new scan for the host new_host.open_new_scan(run_time_unix, True) # Parse ports from scan if debug == True: file_managment.logger("Getting ports tag.") ports_tag = host.getElementsByTagName("ports")[0] port_tags = ports_tag.getElementsByTagName("port") # Debug info for ports file_managment.logger("Scan found " + str(len(port_tags)) + " ports.") for port in port_tags: port_number = int(port.getAttribute("portid")) state_tag = port.getElementsByTagName("state")[0] port_status = state_tag.getAttribute("state") if port_status == "open": new_host.add_open_port_to_latest_scan(port_number) if debug == True: file_managment.logger("Port " + str(port_number) + " found to be open.") # Record if new host, or new ports are found port_changes = new_host.find_port_changes() if new_host.is_new == True: # Newly found host scan_results.append(["New Host", new_host.host_ip, port_changes]) all_hosts.add_host(str(new_host.host_ip)) else: # Port Changes found scan_results.append(["Port Changes", new_host.host_ip, port_changes]) # Ports loaded, save updates new_host.write_json() file_managment.logger("Host " + str(new_host.host_ip) + " JSON updated.") # Return results of this scan return scan_results except Exception as e: # Error parsing xml file_managment.logger("Error in script: " + str(e)) file_managment.logger("XML File: " + xml_doc) with open(xml_doc, "r") as content_file: file_managment.logger("XML File: " + content_file.read()) return scan_results
def run_next_scan(subnets_info, schedule_obj, send_email=True, debug=False): scanned_ips = [] host_count = 0 # get next scan and run it next_scan = schedule_obj.get_next_schedule_entry(debug) if next_scan != None: # record the start time scan_start_time = datetime.datetime.now() if debug == True: print str(next_scan) if len(next_scan.group) > 0: if debug == True: print "Scanning Group: " + next_scan.group file_managment.logger("Scanning Group: " + next_scan.group) for subnet in subnets_info.get_subnets_by_group(next_scan.group): scanned_ips.extend(subnet.get_ips()) group_results = run_group_scan(subnets_info, next_scan.group, next_scan.full_scan, debug) else: group_results = [] if len(next_scan.tags) > 0: if debug == True: print "Scanning Tags: " + str(next_scan.tags) file_managment.logger("Scanning Tags: " + str(next_scan.tags)) for tag in next_scan.tags: for subnet in subnets_info.get_subnets_by_tag(tag): scanned_ips.extend(subnet.get_ips()) tag_results = run_scan_on_tags(subnets_info, next_scan.tags, next_scan.full_scan, debug) else: tag_results = [] # record the end time scan_end_time = datetime.datetime.now() time_delta = (str(scan_end_time - scan_start_time).split("."))[0] if debug == True: print "Scanning completed, total time: " + str(time_delta) file_managment.logger("Scanning completed, total time: " + str(time_delta)) # update schedule entry last run time if debug == True: print "Updating scan schedule..." file_managment.logger("Updating scan schedule...") next_scan.last_scan = int(time.time()) schedule_obj.write_schedule() if debug == True: print "Scan schedule updated" file_managment.logger("Scan schedule updated") # Check for mising hosts if debug == True: print "Finding missing hosts..." file_managment.logger("Finding missing hosts...") existing_hosts = [] for scanned_ip in scanned_ips: json_file = hosts_directory + str(scanned_ip) + ".json" if os.path.exists(json_file): existing_hosts.append(str(scanned_ip)) try: # Get host object new_host = file_managment.get_host(str(scanned_ip), "IPv4") # Check to see if the last scan was blank latest_scans = new_host.get_latest_scans() if latest_scans[0] is None: existing_hosts.remove(str(scanned_ip)) file_managment.logger( "Removing missing host: " + str(scanned_ip) + " from list, because last scan did not exist." ) else: if len(latest_scans[0].open_ports) == 0: existing_hosts.remove(str(scanned_ip)) file_managment.logger( "Removing missing host: " + str(scanned_ip) + " from list, because last scan was empty." ) # Open a new scan, recording that the host was not found. new_host.open_new_scan(str(int(time.time())), False) # Record new scan, with host not being found. new_host.write_json() file_managment.logger("Host " + str(new_host.host_ip) + " JSON updated - Host Not Found.") except Exception, e: file_managment.logger("Error creating blank scan for missing host. " + str(e)) if send_email == True: send_email = False email_subject = "Port Watcher Scan For: " + next_scan.name email_body = email_subject + "\n" if next_scan.full_scan == True: email_body += "Type: Full port scan.\n" else: email_body += "Type: Top ports scan.\n" email_body += "Time elapsed: " + time_delta + "\n\n" if len(group_results) == 0 and len(tag_results[0]) == 0: email_body += "No changed found." # record no changes scan history_line = ( next_scan.name + " detected no changes and completed on " + datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") ) scan_history.append_entry(history_line) send_email = False for result in group_results: for host in result: if host[0] == "New Host": host_status = "New Host" else: host_status = "" try: host_name = str(socket.gethostbyaddr(str(host[1]))[0]) except Exception: host_name = "" host_info = str(host[1]) + " " + str(host_name) + " " + str(host_status) + "\n\t" if str(host[1]) in existing_hosts: existing_hosts.remove(str(host[1])) if len(host[2]["New Open Ports"]) > 0 or len(host[2]["New Closed Ports"]) > 0: host_info += "New Open Ports: " + str(host[2]["New Open Ports"]) + "\n\t" host_info += "New Closed Ports: " + str(host[2]["New Closed Ports"]) + "\n" email_body += host_info send_email = True host_count += 1 else: host_info += "No changes" for result in tag_results[0]: for host in result: if host[0] == "New Host": host_status = "New Host" else: host_status = "" try: host_name = str(socket.gethostbyaddr(str(host[1]))[0]) except Exception: host_name = "" host_info = str(host[1]) + " " + str(host_name) + " " + str(host_status) + "\n\t" if str(host[1]) in existing_hosts: existing_hosts.remove(str(host[1])) if len(host[2]["New Open Ports"]) > 0 or len(host[2]["New Closed Ports"]) > 0: host_info += "New Open Ports: " + str(host[2]["New Open Ports"]) + "\n\t" host_info += "New Closed Ports: " + str(host[2]["New Closed Ports"]) + "\n" email_body += host_info send_email = True host_count += 1 else: host_info += "No changes" # Output host found in previous scans, but not in latest if len(existing_hosts) > 0: email_body += "Missing Hosts:\n\t" send_email = True for host_ip in existing_hosts: email_body += host_ip + "\n\t" # Record a new blank scan since the host was not found new_missing_host = file_managment.get_host(str(host_ip), "IPv4") new_missing_host.open_new_scan(str(int(time.time())), False) new_missing_host.write_json() file_managment.logger( "Host " + str(new_missing_host.host_ip) + " JSON updated - Recorded blank scan for missing host." ) if host_count == 0: email_body += "No changes found.\n" # Send Email if send_email == True: au_email.send_email( "email.server.com", email_from, imap_username, email_pass, "*****@*****.**", email_subject, email_body, ) if debug == True: print "Email Sent." file_managment.logger("Email Sent.") else: if debug == True: print "No changes, not sending email." file_managment.logger("No changes.")
"*****@*****.**", email_subject, email_body, ) if debug == True: print "Email Sent." file_managment.logger("Email Sent.") else: if debug == True: print "No changes, not sending email." file_managment.logger("No changes.") else: if debug == True: print "No scans pending." file_managment.logger("No scans pending.") def run_scan(subnets, full_scan=True, debug=False): hosts_arr = [] results = [] for subnet in subnets: # Detect hosts for subnets in group run_scan_for_hosts(subnet.subnet) # parse the hosts scan results hosts_arr.extend(parse_nmap_xml_for_hosts(scan_directory + "latest_hosts_scan.xml")) # Scan every port of detected hosts for host_entry in hosts_arr: