Ejemplo n.º 1
0
    def make_process(self, event: dict) -> Tuple[Process, File, Process, File]:
        """Accepts a process with the `EventTypes.PROCESS_LAUNCHED` event_type.

        For example::

            {
                FieldNames.PARENT_PROCESS_IMAGE: "cmd.exe",
                FieldNames.PARENT_PROCESS_IMAGE_PATH: "\\",
                FieldNames.PARENT_PROCESS_ID: "2568",
                FieldNames.PARENT_COMMAND_LINE: '/K name.exe"',
                FieldNames.PROCESS_IMAGE: "find.exe",
                FieldNames.PROCESS_IMAGE_PATH: "\\",
                FieldNames.COMMAND_LINE: 'find /i "svhost.exe"',
                FieldNames.PROCESS_ID: "3144",
                FieldNames.EVENT_TYPE: EventTypes.PROCESS_LAUNCHED,
            }

        Parameters
        ----------
        event : dict
            [description]

        Returns
        -------
        Tuple[Process, File, Process, File]
            [description]
        """

        parent = Process(
            process_image=event[FieldNames.PARENT_PROCESS_IMAGE],
            process_image_path=event[FieldNames.PARENT_PROCESS_IMAGE_PATH],
            process_id=int(event[FieldNames.PARENT_PROCESS_ID]),
            command_line=event[FieldNames.PARENT_COMMAND_LINE],
        )

        # Create the file node.
        # TODO: Integrate into the Process() init function?
        parent_file = parent.get_file_node()
        parent_file.file_of[parent]

        child = Process(
            process_image=event[FieldNames.PROCESS_IMAGE],
            process_image_path=event[FieldNames.PROCESS_IMAGE_PATH],
            process_id=int(event[FieldNames.PROCESS_ID]),
            command_line=event[FieldNames.COMMAND_LINE],
        )

        child_file = child.get_file_node()
        child_file.file_of[child]

        if FieldNames.TIMESTAMP in event:
            parent.launched[child].append(
                timestamp=int(event[FieldNames.TIMESTAMP]))
        else:
            parent.launched[child]

        return (parent, parent_file, child, child_file)
Ejemplo n.º 2
0
    def make_regkey_set_value(
            self, event: dict) -> Tuple[Process, File, RegistryKey]:

        process = Process(
            process_image=event[FieldNames.PROCESS_IMAGE],
            process_image_path=event[FieldNames.PROCESS_IMAGE_PATH],
            process_id=int(event[FieldNames.PROCESS_ID]),
            command_line=event[FieldNames.COMMAND_LINE],
        )

        proc_file = process.get_file_node()
        proc_file.file_of[process]

        # RegistryKey Node Creation
        reg_node = RegistryKey(
            hive=event[FieldNames.HIVE],
            key_path=event[FieldNames.REG_KEY_PATH],
            key=event[FieldNames.REG_KEY],
            value=event.get(FieldNames.REG_KEY_VALUE),
        )

        if reg_node.value:
            process.changed_value[reg_node].append(value=reg_node.value)
        else:
            process.changed_value[reg_node]

        return (process, proc_file, reg_node)
Ejemplo n.º 3
0
    def make_dnslookup(
        self, event: dict
    ) -> Union[Tuple[Process, File, Domain, IPAddress], Tuple[Process, File,
                                                              Domain]]:
        process = Process(
            process_image=event[FieldNames.PROCESS_IMAGE],
            process_image_path=event[FieldNames.PROCESS_IMAGE_PATH],
            process_id=int(event[FieldNames.PROCESS_ID]),
            command_line=event[FieldNames.COMMAND_LINE],
        )

        proc_file = process.get_file_node()
        proc_file.file_of[process]

        dom = Domain(event[FieldNames.HTTP_HOST])

        process.dns_query_for[dom]

        # Sometimes we don't know what the domain resolved to.
        if FieldNames.IP_ADDRESS in event:
            addr = IPAddress(ip_address=event[FieldNames.IP_ADDRESS])

            dom.resolves_to[addr]

            return (process, proc_file, dom, addr)
        else:
            return (process, proc_file, dom)
Ejemplo n.º 4
0
    def make_connection(self, event: dict) -> Tuple[Process, File, IPAddress]:
        process = Process(
            process_image=event[FieldNames.PROCESS_IMAGE],
            process_image_path=event[FieldNames.PROCESS_IMAGE_PATH],
            process_id=int(event[FieldNames.PROCESS_ID]),
            command_line=event[FieldNames.COMMAND_LINE],
        )

        proc_file = process.get_file_node()
        proc_file.file_of[process]

        addr = IPAddress(ip_address=event[FieldNames.IP_ADDRESS])

        if FieldNames.PORT in event and FieldNames.PROTOCOL in event:
            process.connected_to[addr].append(
                port=int(event[FieldNames.PORT]),
                protocol=event[FieldNames.PROTOCOL])
        elif FieldNames.PORT in event:
            process.connected_to[addr].append(port=int(event[FieldNames.PORT]))
        elif FieldNames.PROTOCOL in event:
            process.connected_to[addr].append(
                protocol=event[FieldNames.PROTOCOL])
        else:
            process.connected_to[addr]

        return (process, proc_file, addr)
Ejemplo n.º 5
0
    def make_http_req(
        self, event: dict
    ) -> Union[Tuple[Process, File, URI, Domain], Tuple[Process, File, URI,
                                                        Domain, IPAddress]]:
        process = Process(
            process_image=event[FieldNames.PROCESS_IMAGE],
            process_image_path=event[FieldNames.PROCESS_IMAGE_PATH],
            process_id=int(event[FieldNames.PROCESS_ID]),
            command_line=event[FieldNames.COMMAND_LINE],
        )

        proc_file = process.get_file_node()
        proc_file.file_of[process]

        dom = Domain(event[FieldNames.HTTP_HOST])
        uri = URI(uri=event[FieldNames.URI])

        uri.uri_of[dom]

        process.http_request_to[uri].append(
            method=event[FieldNames.HTTP_METHOD])

        if FieldNames.IP_ADDRESS in event:
            ip = IPAddress(event[FieldNames.IP_ADDRESS])
            dom.resolves_to[ip]
            process.connected_to[ip]
            return (process, proc_file, uri, dom, ip)
        else:
            return (process, proc_file, uri, dom)
Ejemplo n.º 6
0
    def make_file_copy(self, event: dict) -> Tuple[Process, File, File, File]:
        process = Process(
            process_image=event[FieldNames.PROCESS_IMAGE],
            process_image_path=event[FieldNames.PROCESS_IMAGE_PATH],
            process_id=int(event[FieldNames.PROCESS_ID]),
            command_line=event[FieldNames.COMMAND_LINE],
        )

        proc_file = process.get_file_node()
        proc_file.file_of[process]

        # Source file
        src_file = File(
            file_path=event[FieldNames.SRC_FILE][FieldNames.FILE_PATH],
            file_name=event[FieldNames.SRC_FILE][FieldNames.FILE_NAME],
            hashes=event[FieldNames.SRC_FILE].get(FieldNames.HASHES),
        )

        # Dest file
        src_file.set_extension()

        dest_file = File(
            file_path=event[FieldNames.DEST_FILE][FieldNames.FILE_PATH],
            file_name=event[FieldNames.DEST_FILE][FieldNames.FILE_NAME],
            hashes=event[FieldNames.DEST_FILE].get(FieldNames.HASHES),
        )

        dest_file.set_extension()

        src_file.copied_to[dest_file]

        process.copied[src_file]

        return (process, proc_file, src_file, dest_file)
Ejemplo n.º 7
0
    def process_create(self, event) -> Tuple[Process, File, Process]:

        pid = -1
        command_line = None
        match = re.match(r"PID: (\d*), Command line: (.*)", event["params"])
        if match:
            pid, command_line = match.groups()

        process_image, process_image_path = split_path(event["path"])

        proc = Process(
            process_id=int(pid),
            process_image=process_image,
            process_image_path=process_image_path,
            command_line=command_line,
        )
        proc_file = proc.get_file_node()
        proc_file.file_of[proc]

        parent = Process(process_id=int(event["process_id"]),
                         process_image=event["process_name"])

        parent.launched[proc].append(timestamp=event["event_time"])

        return (proc, proc_file, parent)
Ejemplo n.º 8
0
    def make_imageload(self,
                       event: dict) -> Optional[Tuple[File, Process, File]]:
        # Pull out the process fields.
        process = Process(
            process_image=event["process"],
            process_image_path=event["processPath"],
            process_id=int(event["pid"]),
            user=event.get("username", None),
        )

        # Pull out the image of the process
        file_node = process.get_file_node()

        # File - (File Of) -> Process
        file_node.file_of[process]

        # Add the drive where possible.
        if event.get("drive"):
            file_path = f"{event['drive']}:\\{event['filePath']}"
        else:
            file_path = event["filePath"]

        loaded_file = File(file_path=file_path, file_name=event["fileName"])

        loaded_file.set_extension()

        process.loaded[loaded_file].append(timestamp=event["event_time"])

        return (loaded_file, process, file_node)
Ejemplo n.º 9
0
    def make_basic_regkey(self,
                          event: dict) -> Tuple[Process, File, RegistryKey]:

        process = Process(
            process_image=event[FieldNames.PROCESS_IMAGE],
            process_image_path=event[FieldNames.PROCESS_IMAGE_PATH],
            process_id=int(event[FieldNames.PROCESS_ID]),
            command_line=event[FieldNames.COMMAND_LINE],
        )

        proc_file = process.get_file_node()
        proc_file.file_of[process]

        # RegistryKey Node Creation
        reg_node = RegistryKey(
            hive=event[FieldNames.HIVE],
            key_path=event[FieldNames.REG_KEY_PATH],
            key=event[FieldNames.REG_KEY],
        )

        if event["event_type"] == EventTypes.REG_KEY_OPENED:
            process.read_key[reg_node]
        else:
            process.deleted_key[reg_node]

        return (process, proc_file, reg_node)
Ejemplo n.º 10
0
    def make_file(self, event: dict) -> Optional[Tuple[File, Process, File]]:
        """Converts a fileWriteEvent to two nodes, a file and the process manipulated the file.
        Generates a process - (Wrote) -> File edge.

        Parameters
        ----------
        event : dict
            The fileWriteEvent event.

        Returns
        -------
        Optional[Tuple[File, Process, File]]
            Returns a tuple contaning the File that this event is focused on, and the process
            which manipulated the file. The process has a Wrote edge to the file. Also contains
            the file that the process belongs to.
        """

        if "filePath" not in event:
            return None

        # Add the drive where possible.
        if event.get("drive"):
            file_path = f"{event['drive']}:\\{event['filePath']}"
        else:
            file_path = event["filePath"]

        hashes: Dict[str, str] = {}
        if event.get("md5"):
            hashes = {"md5": event["md5"]}

        # Create the file node.
        file_node = File(file_path=file_path,
                         file_name=event["fileName"],
                         hashes=hashes)

        # Set the extension
        file_node.set_extension()

        # Set the process node
        process = Process(
            process_id=int(event["pid"]),
            process_image=event["process"],
            process_image_path=event["processPath"],
            user=event.get("username"),
        )

        # Add a wrote edge with the contents of the file write.
        process.wrote[file_node].append(
            timestamp=int(event["event_time"]),
            contents=event.get("textAtLowestOffset"))

        # Pull out the image of the process
        proc_file_node = process.get_file_node()

        # File - (File Of) -> Process
        proc_file_node.file_of[process]

        return (file_node, process, proc_file_node)
Ejemplo n.º 11
0
    def dns_events(
        self, event: dict
    ) -> Union[Tuple[Process, File, Domain], Tuple[Process, File, Domain,
                                                   IPAddress]]:
        """Transforms a single DNS event

        Example event::

            {
                "mode": "dns_query",
                "protocol_type": "udp",
                "hostname": "foobar",
                "qtype": "Host Address",
                "processinfo": {
                    "imagepath": "C:\\ProgramData\\bloop\\some_proc.exe",
                    "tainted": true,
                    "md5sum": "....",
                    "pid": 3020
                },
                "timestamp": 27648
            }

        Optionally, if the event is "dns_query_answer", we can also extract the response.

        Parameters
        ----------
        event : dict
            source dns_query event

        Returns
        -------
        Tuple[Process, File, Domain]
            Process and its image, and the domain looked up
        """
        proc_info = event["processinfo"]
        process_image, process_image_path = split_path(proc_info["imagepath"])

        proc = Process(
            process_id=int(proc_info["pid"]),
            process_image=process_image,
            process_image_path=process_image_path,
        )

        proc_file = proc.get_file_node()
        proc_file.file_of[proc]

        domain = Domain(event["hostname"])

        proc.dns_query_for[domain].append(timestamp=int(event["timestamp"]))

        if "ipaddress" in event:
            addr = IPAddress(event["ipaddress"])
            domain.resolves_to[addr].append(timestamp=int(event["timestamp"]))
            return (proc, proc_file, domain, addr)
        else:
            return (proc, proc_file, domain)
Ejemplo n.º 12
0
    def make_basic_file(self, event: dict) -> Tuple[Process, File, File]:
        """Transforms a file based event.

        Support events:

        1. EventTypes.FILE_DELETED

        2. EventTypes.FILE_OPENED

        3. EventTypes.FILE_WRITTEN

        4. EventTypes.LOADED_MODULE


        Parameters
        ----------
        event : dict
            [description]

        Returns
        -------
        Tuple[Process, File, File]
            [description]
        """

        process = Process(
            process_image=event[FieldNames.PROCESS_IMAGE],
            process_image_path=event[FieldNames.PROCESS_IMAGE_PATH],
            process_id=int(event[FieldNames.PROCESS_ID]),
            command_line=event[FieldNames.COMMAND_LINE],
        )

        proc_file = process.get_file_node()
        proc_file.file_of[process]

        file_node = File(
            file_path=event[FieldNames.FILE_PATH],
            file_name=event[FieldNames.FILE_NAME],
            hashes=event.get(FieldNames.HASHES),
        )

        file_node.set_extension()

        # Switch based on the event type
        event_type = event[FieldNames.EVENT_TYPE]

        if event_type == EventTypes.FILE_OPENED:
            process.accessed[file_node]
        elif event_type == EventTypes.FILE_WRITTEN:
            process.wrote[file_node]
        elif event_type == EventTypes.LOADED_MODULE:
            process.loaded[file_node]
        else:
            process.deleted[file_node]

        return (process, proc_file, file_node)
Ejemplo n.º 13
0
    def make_network(self,
                     event: dict) -> Optional[Tuple[IPAddress, Process, File]]:
        """Converts a network connection event into a Process, File and IP Address node.

        Nodes:

        1. IP Address communicated to.

        2. Process contacting IP.

        3. File process launched from.

        Edges:

        1. Process - (Connected To) -> IP Address

        2. File - (File Of) -> Process

        Parameters
        ----------
        event : dict
            The ipv4NetworkEvent

        Returns
        -------
        Optional[Tuple[IPAddress, Process, File]]
            The IP Address, Process, and Process's File object.
        """

        # Pull out the process fields.
        process = Process(
            process_image=event["process"],
            process_image_path=event["processPath"],
            process_id=int(event["pid"]),
            user=event.get("username", None),
        )

        # Pull out the image of the process
        file_node = process.get_file_node()

        # File - (File Of) -> Process
        file_node.file_of[process]

        # Create the network node
        ip_address = IPAddress(event["remoteIP"])

        # Create the connection edge
        # Process - (Connected To) -> IP Address
        process.connected_to[ip_address].append(timestamp=event["event_time"],
                                                protocol=event["protocol"],
                                                port=int(event["remotePort"]))

        return (ip_address, process, file_node)
Ejemplo n.º 14
0
    def process_creation(self, event: dict) -> Tuple[Process, File, Process]:
        """Transformers a process creation (event ID 4688) into a set of nodes.

        https://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventID=4688

        Parameters
        ----------
        event : dict
            [description]

        Returns
        -------
        Optional[Tuple[Process, File, Process, File]]
            [description]
        """

        # Get the parent PID
        parent_pid = int(event["data_name_processid"], 16)

        # Child PID
        child_pid = int(event["data_name_newprocessid"], 16)

        proc_name, proc_path = split_path(event["data_name_newprocessname"])

        child = Process(
            host=event["computer"],
            process_id=child_pid,
            user=event["data_name_subjectusername"],
            process_image=proc_name,
            process_image_path=proc_path,
            command_line=event.get("data_name_commandline"),
        )

        child_file = child.get_file_node()
        child_file.file_of[child]

        # Map the process for later
        self.seen_procs[child_pid] = child

        parent = self.seen_procs.get(parent_pid)

        if parent is None:
            # Create a dummy proc. If we haven't already seen the parent
            parent = Process(host=event["computer"], process_id=parent_pid)

        parent.launched[child].append(
            timestamp=event["timecreated_systemtime"])

        # Don't need to pull out the parent's file, as it will have always
        # been created before being put into seen_procs

        return (child, child_file, parent)
Ejemplo n.º 15
0
    def conn_events(self, event: dict) -> Tuple[Process, File, IPAddress]:
        """Transforms a single connection event

        Example event::

            {
                "mode": "connect",
                "protocol_type": "tcp",
                "ipaddress": "199.168.199.123",
                "destination_port": 3333,
                "processinfo": {
                    "imagepath": "C:\\ProgramData\\bloop\\some_proc.exe",
                    "tainted": true,
                    "md5sum": "....",
                    "pid": 3020
                },
                "timestamp": 27648
            }

        Parameters
        ----------
        event : dict
            source dns_query event

        Returns
        -------
        Tuple[Process, File, IPAddress]
            Process and its image, and the destination address
        """
        proc_info = event["processinfo"]
        process_image, process_image_path = split_path(proc_info["imagepath"])

        proc = Process(
            process_id=int(proc_info["pid"]),
            process_image=process_image,
            process_image_path=process_image_path,
        )

        proc_file = proc.get_file_node()
        proc_file.file_of[proc]

        addr = IPAddress(event["ipaddress"])

        proc.connected_to[addr].append(
            protocol=event["protocol_type"],
            timestamp=event["timestamp"],
            port=int(event["destination_port"]),
        )

        return (proc, proc_file, addr)
Ejemplo n.º 16
0
    def make_registry(
            self, event: dict) -> Optional[Tuple[RegistryKey, Process, File]]:
        # Pull out the process fields.
        process = Process(
            process_image=event["process"],
            process_image_path=event["processPath"],
            process_id=int(event["pid"]),
            user=event.get("username", None),
        )

        # Pull out the image of the process
        file_node = process.get_file_node()

        # File - (File Of) -> Process
        file_node.file_of[process]

        # RegistryKey Node Creation
        reg_node = RegistryKey(
            hive=event["hive"],
            key_path=event["keyPath"],
            key=event.get("valueName"),
            value=event.get("text"),
            value_type=event.get("valueType"),
        )

        # Space shuttle code for the edge setting
        #
        # EventType Mappings:
        #     1: Value Changed
        #     2: Value Deleted
        #     3: Key Created
        #     4: Key Deleted
        #
        reg_event_type = str(event["eventType"])
        if reg_event_type == "1":
            process.changed_value[reg_node].append(
                timestamp=event["event_time"])
        elif reg_event_type == "2":
            process.deleted_value[reg_node].append(
                timestamp=event["event_time"])
        elif reg_event_type == "3":
            process.created_key[reg_node].append(timestamp=event["event_time"])
        elif reg_event_type == "4":
            process.deleted_key[reg_node].append(timestamp=event["event_time"])
        else:
            logger.warn(
                f"Found a new registry event type with a value of {reg_event_type}: {event}"
            )

        return (reg_node, process, file_node)
Ejemplo n.º 17
0
    def make_dnslookup(self,
                       event: dict) -> Optional[Tuple[Domain, Process, File]]:
        """Converts a dnsLookupEvent into a Domain, Process, and Process's File node.

        Nodes:
        1. Domain looked up.

        2. Process performing the lookup.

        3. File the Process was launched from.

        Edges:

        1. Process - (DNS Lookup For) -> Domain.

        2. File - (FileOf) -> Process.

        Parameters
        ----------
        event : dict
            A dnsLookupEvent

        Returns
        -------
        Optional[Tuple[Domain, Process, File]]
            The Domain, Process, and File nodes.
        """

        # Pull out the process fields.
        process = Process(
            process_image=event["process"],
            process_image_path=event["processPath"],
            process_id=int(event["pid"]),
            user=event.get("username", None),
        )

        # Pull out the image of the process
        file_node = process.get_file_node()

        # File - (File Of) -> Process
        file_node.file_of[process]

        domain = Domain(event["hostname"])

        process.dns_query_for[domain].append(timestamp=event["event_time"])

        return (domain, process, file_node)
Ejemplo n.º 18
0
    def make_http_req(self, event: dict) -> Tuple[Process, File, URI, Domain]:
        process = Process(
            process_image=event[FieldNames.PROCESS_IMAGE],
            process_image_path=event[FieldNames.PROCESS_IMAGE_PATH],
            process_id=int(event[FieldNames.PROCESS_ID]),
            command_line=event[FieldNames.COMMAND_LINE],
        )

        proc_file = process.get_file_node()
        proc_file.file_of[process]

        dom = Domain(event[FieldNames.HTTP_HOST])
        uri = URI(uri=event[FieldNames.URI])

        uri.uri_of[dom]

        process.http_request_to[uri].append(
            method=event[FieldNames.HTTP_METHOD])

        return (process, proc_file, uri, dom)
Ejemplo n.º 19
0
    def make_process(
        self, event: dict
    ) -> Optional[Union[Tuple[Process, File], Tuple[Process, File, Process,
                                                    File]]]:
        """Converts a processEvent into either one Process node, or two Process nodes with a
        parent - (Launched) -> child relationship.
        Additionally, creats File nodes for the images of both of the Processe's identified.

        Parameters
        ----------
        event : dict
            The processEvent event

        Returns
        -------
        Optional[Union[Tuple[Process, File], Tuple[Process, File, Process, File]]]
            Returns either a single process node, or a (parent, child) tuple
            where the parent has a launched edge to the child.
        """

        # Only look at start or already running event types.
        if event["eventType"] not in ["start", "running"]:
            return None

        # Sometimes a process in a `running` state doens't properly identify the path
        # which causes a case where processPath == process.
        # For example {"process": "cmd.exe", "processPath": "cmd.exe"}

        # See: test_process_equal_processpath
        if event["processPath"] == event["process"]:
            return None

        process_image, process_image_path = split_path(event["processPath"])

        # Pull out the hashes
        hashes: Dict[str, str] = {}
        if event.get("md5"):
            hashes = {"md5": event["md5"]}

        # Create the "child" process. This is the process who this event
        # belongs to.
        child = Process(
            process_image=process_image,
            process_image_path=process_image_path,
            command_line=event.get("processCmdLine"),
            process_id=int(event["pid"]),
            hashes=hashes,
            user=event.get("username", None),
        )

        # Pull out the image of the child process
        child_proc_file_node = child.get_file_node()

        # File - (File Of) -> Process
        child_proc_file_node.file_of[child]

        # If there is no parent field, return just the child
        if "parentProcessPath" not in event:

            return (child, child_proc_file_node)

        parent_process_image, parent_process_image_path = split_path(
            event["parentProcessPath"])

        # Create the parent process
        parent = Process(
            process_id=int(event["parentPid"]),
            process_image=parent_process_image,
            process_image_path=parent_process_image_path,
        )

        # Create a parent - (launched) -> child edge.
        parent.launched[child].append(timestamp=event["event_time"])

        # Pull out the image of the parent process
        parent_proc_file_node = child.get_file_node()

        # File - (File Of) -> Process
        parent_proc_file_node.file_of[child]

        return (parent, parent_proc_file_node, child, child_proc_file_node)
Ejemplo n.º 20
0
    def http_requests(
        self, event: dict
    ) -> Union[Tuple[Process, File, IPAddress, URI, Domain], Tuple[
            Process, File, IPAddress, URI], Tuple[Process, File, IPAddress], ]:
        """Transforms a single `http_request` network event. A typical event looks like::

            {
                "mode": "http_request",
                "protocol_type": "tcp",
                "ipaddress": "199.168.199.1",
                "destination_port": 80,
                "processinfo": {
                    "imagepath": "c:\\Windows\\System32\\svchost.exe",
                    "tainted": false,
                    "md5sum": "1234",
                    "pid": 1292
                },
                "http_request": "GET /some_route.crl HTTP/1.1~~Cache-Control: max-age = 900~~User-Agent: Microsoft-CryptoAPI/10.0~~Host: crl.microsoft.com~~~~",
                "timestamp": 433750
            }


        Parameters
        ----------
        event : dict
            The source `network` event with mode `http_request`

        Returns
        -------
        Tuple[Node]
            [description]
        """

        proc_info = event["processinfo"]
        process_image, process_image_path = split_path(proc_info["imagepath"])

        proc = Process(
            process_id=int(proc_info["pid"]),
            process_image=process_image,
            process_image_path=process_image_path,
        )

        proc_file = proc.get_file_node()
        proc_file.file_of[proc]

        addr = IPAddress(event["ipaddress"])

        proc.connected_to[addr].append(
            timestamp=event["timestamp"],
            protocol=event["protocol_type"],
            port=event["destination_port"],
        )

        try:
            url, header = event["http_request"].split("~~", 1)

            method, uri_path, _ = url.split(" ")

            uri = URI(uri_path)

            headers = dict(
                email.message_from_string(header.replace("~~", "\n")).items())

            proc.http_request_to[uri].append(timestamp=event["timestamp"],
                                             method=method)

            if "Host" in headers:
                domain = Domain(headers["Host"])  # type: ignore

                domain.resolves_to[addr].append(timestamp=event["timestamp"])
                uri.uri_of[domain]

                return (proc, proc_file, addr, uri, domain)
            else:
                return (proc, proc_file, addr, uri)

        except (ValueError, KeyError):
            return (proc, proc_file, addr)
Ejemplo n.º 21
0
    def file_events(
        self, event: dict
    ) -> Union[Tuple[Process, File, File], Tuple[Process, File, File, File]]:
        """Transforms a file event

        Example file event::

            {
                "mode": "created",
                "fid": { "ads": "", "content": 2533274790555891 },
                "processinfo": {
                    "imagepath": "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
                    "md5sum": "eb32c070e658937aa9fa9f3ae629b2b8",
                    "pid": 2956
                },
                "ntstatus": "0x0",
                "value": "C:\\Users\\admin\\AppData\\Local\\Temp\\sy24ttkc.k25.ps1",
                "CreateOptions": "0x400064",
                "timestamp": 9494
            }

        In 8.2.0 the `value` field became a dictionary when the mode is `failed`::

            "values": {
                "value": "C:\\Users\\admin\\AppData\\Local\\Temp\\sy24ttkc.k25.ps1""
            }

        Parameters
        ----------
        event : dict
            The source event

        Returns
        -------
        Tuple[Process, File, File]
            The process, the process' image, and the file written.
        """

        proc_info = event["processinfo"]
        process_image, process_image_path = split_path(proc_info["imagepath"])

        proc = Process(
            process_id=int(proc_info["pid"]),
            process_image=process_image,
            process_image_path=process_image_path,
        )

        proc_file = proc.get_file_node()
        proc_file.file_of[proc]

        # 8.2.0 changes.
        if "values" in event:
            full_path = event["values"]["value"]
        else:
            full_path = event["value"]

        file_name, file_path = split_path(full_path)

        file_node = File(file_name=file_name, file_path=file_path)
        file_node.set_extension()

        if event["mode"] == "created":
            proc.wrote[file_node].append(timestamp=event["timestamp"])
        elif event["mode"] == "deleted":
            proc.deleted[file_node].append(timestamp=event["timestamp"])
        elif event["mode"] == "CopyFile":
            src_name, src_path = split_path(event["source"])
            src_file = File(file_name=src_name, file_path=src_path)
            src_file.set_extension()

            src_file.copied_to[file_node].append(timestamp=event["timestamp"])

            proc.copied[src_file].append(timestamp=event["timestamp"])

            return (proc, proc_file, file_node, src_file)
        else:
            proc.accessed[file_node].append(timestamp=event["timestamp"])

        return (proc, proc_file, file_node)
Ejemplo n.º 22
0
    def regkey_events(self, event: dict) -> Tuple[Process, File, RegistryKey]:
        """Transforms a single registry key event

        Example event::

            {
                "mode": "queryvalue",
                "processinfo": {
                    "imagepath": "C:\\Users\\admin\\AppData\\Local\\Temp\\bar.exe",
                    "tainted": True,
                    "md5sum": "....",
                    "pid": 1700,
                },
                "value": "\\REGISTRY\\USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\\"ProxyOverride\"",
                "timestamp": 6203
            },

        Parameters
        ----------
        event : dict
            source regkey event

        Returns
        -------
        Tuple[Process, File, RegistrKey]
            Process and its image, and the registry key.
        """
        proc_info = event["processinfo"]
        process_image, process_image_path = split_path(proc_info["imagepath"])

        proc = Process(
            process_id=int(proc_info["pid"]),
            process_image=process_image,
            process_image_path=process_image_path,
        )

        proc_file = proc.get_file_node()
        proc_file.file_of[proc]

        path, key_contents = re.match(r"(.*)\\\"(.*)",
                                      event["value"]).groups()  # type: ignore

        key_contents = key_contents[:-1]  # remove last quote.

        hive, reg_key_path = path.replace("\\REGISTRY\\", "").split("\\", 1)

        if '" = ' in key_contents:
            key, value = key_contents.split('" = ')
        else:
            key = key_contents
            value = None

        regkey = RegistryKey(hive=hive,
                             key=key,
                             key_path=reg_key_path,
                             value=value)

        if event["mode"] == "added":
            proc.created_key[regkey].append(timestamp=event["timestamp"],
                                            value=value)
        elif event["mode"] == "setval":
            proc.changed_value[regkey].append(timestamp=event["timestamp"],
                                              value=value)
        elif event["mode"] in ["deleteval", "deleted"]:
            proc.deleted_key[regkey].append(timestamp=event["timestamp"],
                                            value=value)
        else:
            proc.read_key[regkey].append(timestamp=event["timestamp"],
                                         value=value)

        return (proc, proc_file, regkey)
Ejemplo n.º 23
0
    def process_events(
            self,
            event: dict) -> Optional[Tuple[Process, File, Process, File]]:
        """Transformers events from the `process` entry.

        A single process entry looks like::

            {
                "mode": string,
                "fid": dict,
                "parentname": string,
                "cmdline": string,
                "sha1sum": "string,
                "md5sum": string,
                "sha256sum": string,
                "pid": int,
                "filesize": int,
                "value": string,
                "timestamp": int,
                "ppid": int
            },

        Parameters
        ----------
        event : dict
            The input event.

        Returns
        -------
        Optional[Tuple[Process, File, Process, File]]
            Parent and child processes, and the file nodes that represent their binaries.
        """

        if event.get("mode") != "started":
            return None

        process_image, process_image_path = split_path(event["value"])
        parent_image, parent_image_path = split_path(event["parentname"])

        hashes = {
            HashAlgos.MD5: event.get("md5sum"),
            HashAlgos.SHA1: event.get("sha1sum"),
            HashAlgos.SHA256: event.get("sha256sum"),
        }
        proc = Process(
            process_image=process_image,
            process_image_path=process_image_path,
            command_line=event["cmdline"],
            process_id=int(event["pid"]),
            hashes={h: k
                    for h, k in hashes.items() if k},
        )

        proc_file = proc.get_file_node()

        proc_file.file_of[proc]

        parent = Process(
            process_image=parent_image,
            process_image_path=parent_image_path,
            process_id=int(event["ppid"]),
        )

        parent_file = parent.get_file_node()

        parent_file.file_of[parent]

        parent.launched[proc].append(timestamp=int(event["timestamp"]))

        return (proc, proc_file, parent, parent_file)
Ejemplo n.º 24
0
    def make_url(
            self, event: dict
    ) -> Optional[Tuple[URI, Domain, Process, File, IPAddress]]:
        """Converts a URL access event and returns 5 nodes with 4 different relationships.

        Nodes created:

        1. URI Accessed (e.g /foobar)

        2. Domain Accessed (e.g omer.com)

        3. Process performing URL request.

        4. File object for the Process image.

        5. IP Address the domain resolves to.

        Relationships created:

        1. URI - (URI Of) -> Domain

        2. Domain - (Resolves To) -> IP Address

        3. Process - (`http method of event`) -> URI

        4. Process - (Connected To) -> IP Address

        5. File - (File Of) -> Process

        Parameters
        ----------
        event : dict
            The urlMonitorEvent events

        Returns
        -------
        Optional[Tuple[URI, Domain, Process, File, IPAddress]]
            5 tuple of the nodes pulled out of the event (see function description).
        """

        uri = URI(uri=event["requestUrl"])
        domain = Domain(domain=event["hostname"])
        ip_address = IPAddress(ip_address=event["remoteIpAddress"])

        # Pull out the process fields.
        process = Process(
            process_image=event["process"],
            process_image_path=event["processPath"],
            command_line=event.get("processCmdLine"),
            process_id=int(event["pid"]),
            user=event.get("username", None),
        )

        # Pull out the image of the process
        file_node = process.get_file_node()

        # File - (File Of) -> Process
        file_node.file_of[process]

        # Link up the URI and the domain
        # URI - (URI Of) -> Domain
        uri.uri_of[domain].append(timestamp=event["event_time"])

        # HTTP Request to the URL from the process
        # Proc - (HTTP Request) -> URI
        process.http_request_to[uri].append(
            method=event.get("urlMethod"),
            user_agent=event.get("userAgent"),
            header=event.get("httpHeader"),
            timestamp=event["event_time"],
        )

        # TCP Communication from process to IP of domain
        # Process - (Connected To) -> IP Address
        process.connected_to[ip_address].append(port=int(event["remotePort"]),
                                                protocol=Protocols.HTTP,
                                                timestamp=event["event_time"])

        # Domain resolving to that IP
        # Domain - (Resolves To) -> IP Address
        domain.resolves_to[ip_address].append(timestamp=event["event_time"])

        return (uri, domain, process, file_node, ip_address)