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
Exemple #2
0
#!/usr/bin/python

import datetime
import file_managment

# Print report header
print "Open Ports Report"
print "Report date: " + str(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
print "--------------------------------"
print ""
print ""

# Load all hosts
hosts_obj = file_managment.host_list()
all_hosts = hosts_obj.hosts_list

#Get all ports open on last scan
for host_ip in all_hosts:
    print host_ip
    host_obj = file_managment.get_host(host_ip, "ipv4")
    scan_timestamp = datetime.datetime.fromtimestamp(host_obj.get_latest_scans()[0].unix_time).strftime('%Y-%m-%d %H:%M:%S')
    print "Last Scan at " + str(scan_timestamp)
    print "Open Ports:"
    print host_obj.get_latest_scans()[0].open_ports
    print "--------------------------------"
    print ""
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.")