def Parse(self, pentest, file_opened, **_kwargs):
     """
     Parse a opened file to extract information
     Args:
         file_opened: the open file
         _kwargs: not used
     Returns:
         a tuple with 4 values (All set to None if Parsing wrong file): 
             0. notes: notes to be inserted in tool giving direct info to pentester
             1. tags: a list of tags to be added to tool 
             2. lvl: the level of the command executed to assign to given targets
             3. targets: a list of composed keys allowing retrieve/insert from/into database targerted objects.
     """
     notes = ""
     tags = []
     targets = {}
     result_socket = file_opened.read().decode("utf-8")
     domain, ip = parse_reverse_python(result_socket)
     if domain is None:
         return None, None, None, None
     ServerIp().initialize(domain).addInDb()
     ip_m = ServerIp().initialize(ip)
     insert_res = ip_m.addInDb()
     if not insert_res["res"]:
         ip_m = ServerIp.fetchObject(pentest, {"_id": insert_res["iid"]})
     existing_hostnames = ip_m.infos.get("hostname", [])
     if not isinstance(existing_hostnames, list):
         existing_hostnames = [existing_hostnames]
     hostnames = list(set(existing_hostnames + [domain]))
     ip_m.updateInfos({"hostname": hostnames})
     targets["ip"] = {"ip": ip}
     notes += "Domain found :" + domain + "\n"
     if notes == "":
         notes = "No domain found\n"
     return notes, tags, "ip", targets
Beispiel #2
0
    def Parse(self, pentest, file_opened, **_kwargs):
        """
        Parse a opened file to extract information
        Args:
            file_opened: the open file
            _kwargs: not used
        Returns:
            a tuple with 4 values (All set to None if Parsing wrong file): 
                0. notes: notes to be inserted in tool giving direct info to pentester
                1. tags: a list of tags to be added to tool 
                2. lvl: the level of the command executed to assign to given targets
                3. targets: a list of composed keys allowing retrieve/insert from/into database targerted objects.
        """
        parsed_by_hosts = parse(file_opened)
        if parsed_by_hosts is None:
            return None, None, None, None
        tags = ["todo"]
        cumulative_notes = []
        targets = {}
        for parsed_host in parsed_by_hosts:
            host = parsed_host
            findings = parsed_by_hosts[parsed_host]
            targets["ip"] = {"ip": host}
            notes = "host:" + str(host) + "\n"
            for finding in findings:
                notes += finding["info"]["name"] + " (" + finding["info"][
                    "severity"] + ") " + finding["info"].get(
                        "description", "") + "\n"
            for finding in findings:
                if finding["info"]["severity"] in [
                        "medium", "high", "critical"
                ]:
                    tags = ["Interesting"]
            ip_o = ServerIp().initialize(host, notes)
            inserted = ip_o.addInDb()
            if not inserted["res"]:
                ip_o = ServerIp.fetchObject(pentest, {"_id": inserted["iid"]})
                ip_o.notes += "\nNuclei:\n" + notes
                ip_o.update()
            cumulative_notes.append(notes + "\n")

        notes = "\n".join(cumulative_notes)

        return notes, tags, "ip", targets
Beispiel #3
0
    def Parse(self, pentest, file_opened, **_kwargs):
        """
        Parse a opened file to extract information

        foe.test.fr.	801	IN	A	18.19.20.21
        blog.test.fr.	10800	IN	CNAME	22.33.44.55
        Args:
            file_opened: the open file
            _kwargs: not used
        Returns:
            a tuple with 4 values (All set to None if Parsing wrong file): 
                0. notes: notes to be inserted in tool giving direct info to pentester
                1. tags: a list of tags to be added to tool 
                2. lvl: the level of the command executed to assign to given targets
                3. targets: a list of composed keys allowing retrieve/insert from/into database targerted objects.
        """
        notes = ""
        tags = []
        countInserted = 0
        for line in file_opened:
            line = line.decode("utf-8")
            domain, _record_type, ip = parse_crtsh_line(line)
            if domain is not None:
                # a domain has been found
                infosToAdd = {"hostname": ip}
                ip_m = ServerIp().initialize(domain, infos=infosToAdd)
                insert_ret = ip_m.addInDb()
                # failed, domain is out of scope
                if not insert_ret["res"]:
                    notes += domain+" exists but already added.\n"
                    ip_m = ServerIp.fetchObject(pentest, {"_id": insert_ret["iid"]})
                    hostname = ip_m.infos.get("hostname", [])
                    if not isinstance(hostname, list):
                        hostname = [hostname]
                    infosToAdd = {"hostname": list(set([ip] + hostname))}
                    ip_m.updateInfos(infosToAdd)
                else:
                    countInserted += 1
                    notes += domain+" inserted.\n"
        if notes.strip() == "":
            return None, None, None, None
        elif countInserted != 0:
            tags.append("todo")
        return notes, tags, "wave", {"wave": None}
Beispiel #4
0
def editScopeIPs(pentest, hostsInfos):
    """
    Add all the ips and theirs ports found after parsing the file to the scope object in database.
    Args:
        hostsInfos: the dictionnary with ips as keys and a list of dictionnary containing ports informations as value.
    """
    # Check if any ip has been found.
    if hostsInfos is not None:
        for infos in hostsInfos:
            tags = []

            infosToAdd = {}
            OS = infos.get("OS", "")
            if OS != "":
                infosToAdd["OS"] = OS
            creds = infos.get("creds", "")
            if creds != "":
                infosToAdd["creds"] = creds
            powned = infos.get("powned", False)
            if powned:
                infosToAdd["powned"] = "True"
            ip_m = ServerIp().initialize(str(infos["ip"]))
            insert_ret = ip_m.addInDb()
            if not insert_ret["res"]:
                ip_m = ServerIp.fetchObject(pentest,
                                            {"_id": insert_ret["iid"]})
            infosToAdd["hostname"] = list(
                set(ip_m.infos.get("hostname", []) + [infos["hostname"]]))
            ip_m.notes = "hostname:" + \
                infos["hostname"] + "\n"+infos.get("OS", "")
            if infos.get("powned", False):
                ip_m.addTag("P0wned!")
            port_m = ServerPort().initialize(str(infos["ip"]),
                                             str(infos["port"]), "tcp",
                                             "netbios-ssn")
            insert_ret = port_m.addInDb()
            if not insert_ret["res"]:
                port_m = ServerPort.fetchObject(pentest,
                                                {"_id": insert_ret["iid"]})
            port_m.updateInfos(infosToAdd)
            if infos.get("powned", False):
                port_m.addTag("P0wned!")
Beispiel #5
0
def getIpPortsNmap(pentest, nmapFile):
    """
    Read the given nmap .nmap file results and return a dictionnary with ips and a list of their open ports.
        Args:
            nmapFile:  the path to the .nmap file generated by an nmap scan

        Returns:
            notes about inseted ip and ports
    """
    notes = ""
    countOpen = 0
    all_text = nmapFile.read().decode("utf-8").strip()
    lines = all_text.split("\n")
    if len(lines) <= 3:
        # print("Not enough lines to be nmap")
        return None
    if not lines[0].startswith("# Nmap"):
        # print("Not starting with # Nmap")
        return None
    if "scan initiated" not in lines[0]:
        # print("Not scan initiated on first line")
        return None
    if "# Nmap done at" not in lines[-1]:
        # print("Not # Nmap done at at the end : "+str(lines[-1]))
        return None
    ipCIDR_m = None
    ipDom_m = None
    for line in lines:
        # Search ip in file
        # match an ip
        ip = re.search(
            r"^Nmap scan report for (\S+)(?: \(((?:[0-9]{1,3}\.){3}[0-9]{1,3})\))?$",
            line)
        if ip is not None:  # regex match
            lastIp = [
                ip.group(1),
                ip.group(2) if ip.group(2) is not None else ""
            ]
            notes_ip = "ip:" + \
                str(lastIp[1]) if lastIp[1] != "" and lastIp[1] is not None else ""
            ipCIDR_m = ServerIp(pentest).initialize(str(lastIp[0]),
                                                    notes=notes_ip)
            if lastIp[1].strip() != "" and lastIp[1] is not None:
                ipDom_m = ServerIp(pentest).initialize(str(lastIp[1]),
                                                       notes="domain:" +
                                                       str(lastIp[0]))

            else:
                ipDom_m = None
        if " open " in line:
            if ipCIDR_m is None:  # Probably a gnmap
                return None
            notes += line + "\n"
            # regex to find open ports in gnmap file
            port_search = re.search(
                r"^(\d+)\/(\S+)\s+open\s+(\S+)(?: +(.+))?$", line)
            if port_search is not None:
                port_number = str(port_search.group(1))
                proto = str(port_search.group(2))
                service = "unknown" if str(
                    port_search.group(3)) == "" else str(port_search.group(3))
                product = str(port_search.group(4))
                # a port unique key is its protocole/number.
                countOpen += 1
                validIps = []
                if ipCIDR_m is not None:
                    ipCIDR_m.addInDb()
                    validIps.append(ipCIDR_m.ip)
                    if ipDom_m is not None:
                        insert_res = ipDom_m.addInDb()
                        if not insert_res["res"]:
                            ipDom_m = ServerIp.fetchObject(
                                pentest, {"_id": insert_res["iid"]})
                        hostnames = ipDom_m.infos.get("hostname", [])
                        if isinstance(hostnames, str):
                            hostnames = [hostnames]
                        ipDom_m.updateInfos({
                            "hostname":
                            list(set(list(hostnames) + [str(ipCIDR_m.ip)]))
                        })
                        validIps.append(ipDom_m.ip)
                for ipFound in validIps:
                    if ip == "":
                        continue
                    port_o = ServerPort(pentest).initialize(
                        ipFound, port_number, proto, service, product)
                    insert_res = port_o.addInDb()
                    if not insert_res["res"]:
                        port_o = ServerPort.fetchObject(
                            pentest, {"_id": insert_res["iid"]})
                    port_o.service = service
                    port_o.update()

    notes = str(countOpen) + " open ports found\n" + notes
    return notes
Beispiel #6
0
    def Parse(self, pentest, file_opened, **_kwargs):
        """
        Parse a opened file to extract information
        Example:
[       
    {
        "arguments": "./dnsrecon.py -r 10.0.0.0/24 -j /home/barre/test.json",
        "date": "2020-01-06 11:43:37.701513",
        "type": "ScanInfo"
    },
    {
        "address": "10.0.0.1",
        "name": "_gateway",
        "type": "PTR"
    },
    {
        "address": "10.0.0.77",
        "name": "barre-ThinkPad-E480",
        "type": "PTR"
    },
    {
        "address": "10.0.0.77",
        "name": "barre-ThinkPad-E480.local",
        "type": "PTR"
    }
]
        Args:
            file_opened: the open file
            _kwargs: not used
        Returns:
            a tuple with 4 values (All set to None if Parsing wrong file): 
                0. notes: notes to be inserted in tool giving direct info to pentester
                1. tags: a list of tags to be added to tool 
                2. lvl: the level of the command executed to assign to given targets
                3. targets: a list of composed keys allowing retrieve/insert from/into database targerted objects.
        """
        notes = ""
        tags = []
        countInserted = 0
        try:
            dnsrecon_content = json.loads(file_opened.read().decode("utf-8"))
        except json.decoder.JSONDecodeError:
            return None, None, None, None
        if len(dnsrecon_content) == 0:
            return None, None, None, None
        if not isinstance(dnsrecon_content[0], dict):
            return None, None, None, None
        if dnsrecon_content[0].get("type", "") != "ScanInfo":
            return None, None, None, None
        if dnsrecon_content[0].get("date", "") == "":
            return None, None, None, None
        for record in dnsrecon_content[1:]:
            ip = record["address"]
            name = record["name"]
            infosToAdd = {"hostname": [name]}
            ip_m = ServerIp().initialize(ip, infos=infosToAdd)
            ip_m.addInDb()
            infosToAdd = {"ip": [ip]}
            ip_m = ServerIp().initialize(name, infos=infosToAdd)
            insert_ret = ip_m.addInDb()
            # failed, domain is out of scope
            if not insert_ret["res"]:
                notes += name + " exists but already added.\n"
                ip_m = ServerIp.fetchObject(pentest,
                                            {"_id": insert_ret["iid"]})
                existing_ips = ip_m.infos.get("ip", [])
                if not isinstance(existing_ips, list):
                    existing_ips = [existing_ips]
                infosToAdd = {"ip": list(set([ip] + existing_ips))}
                ip_m.updateInfos(infosToAdd)
            else:
                countInserted += 1
                notes += name + " inserted.\n"
        return notes, tags, "wave", {"wave": None}