Beispiel #1
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)
    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)
Beispiel #3
0
def testEquals():
    file_node = File(file_path="c:/windows",
                     file_name="test.exe",
                     extension=".exe")

    file_node2 = File(file_path="c:/windows",
                      file_name="test.exe",
                      extension=".exe")

    assert file_node == file_node2
    assert hash(file_node) == hash(file_node2)
    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)
Beispiel #5
0
def test_add_nodes_no_overlap(nx):
    proc = Process(process_id=10,
                   process_image="test.exe",
                   command_line="test.exe /c foobar")
    other_proc = Process(process_id=12,
                         process_image="best.exe",
                         command_line="best.exe /c 123456")

    proc.launched[other_proc].append(timestamp=1)

    backend = NetworkX(consolidate_edges=True, nodes=[proc, other_proc])
    G = backend.graph()

    assert len(G.nodes()) == 2
    assert len(G.edges()) == 1

    # Add in a new pair of nodes.
    proc2 = Process(process_id=4,
                    process_image="malware.exe",
                    command_line="malware.exe /c foobar")
    f = File(file_name="foo", file_path="bar")
    proc2.wrote[f]

    G = backend.add_nodes([proc2, f])

    # Graph grew
    assert len(G.nodes()) == 4
    assert len(G.edges()) == 2
Beispiel #6
0
def test_file_of():
    file_node = File(file_path="c:/windows", file_name="test.exe", extension=".exe")
    proc = Process(process_id=0, process_image="test.exe", process_image_path="c:/windows/test.exe")

    file_node.file_of[proc]

    assert proc in file_node.file_of
Beispiel #7
0
def testNotFileOf():
    file_node = File(file_path="c:/windows",
                     file_name="test.exe",
                     extension=".exe")
    proc = Process(process_id=0,
                   process_image="best.exe",
                   process_image_path="c:/windows/best.exe")

    assert proc not in file_node.file_of
Beispiel #8
0
    def access_file(self, event) -> Tuple[Process, File]:
        proc = Process(process_id=int(event["process_id"]),
                       process_image=event["process_name"])

        file_name, file_path = split_path(event["path"])
        target_file = File(file_name=file_name, file_path=file_path)

        proc.accessed[target_file].append(timestamp=event["event_time"])

        return (proc, target_file)
Beispiel #9
0
    def file_created(self, event: dict) -> Tuple[Process, File, File]:

        process_image, process_path = split_path(event["EventData_Image"])

        proc = SysMonProc(
            host=event["Computer"],
            user=event.get("EventData_User"),
            process_guid=event["EventData_ProcessGuid"],
            process_id=int(event["EventData_ProcessId"]),
            process_image=process_image,
            process_image_path=process_path,
        )
        proc_file = proc.get_file_node()
        proc_file.file_of[proc]

        file_image, file_path = split_path(event["EventData_TargetFilename"])

        file_node = File(file_name=file_image, file_path=file_path)

        proc.accessed[file_node].append(timestamp=event["EventData_UtcTime"])

        return (proc, proc_file, file_node)
Beispiel #10
0
def test_add_node_overlaps_existing(nx):
    proc = Process(process_id=10,
                   process_image="test.exe",
                   command_line="test.exe /c foobar")
    other_proc = Process(process_id=12,
                         process_image="best.exe",
                         command_line="best.exe /c 123456")

    proc.launched[other_proc].append(timestamp=1)

    backend = NetworkX(consolidate_edges=True, nodes=[proc, other_proc])
    G = backend.graph()

    assert len(G.nodes()) == 2
    assert len(G.edges()) == 1

    # Add a new node that *overlaps* an existing node (note - not the same node object.)
    proc2 = Process(process_id=10,
                    process_image="test.exe",
                    command_line="test.exe /c foobar")
    f = File(file_name="foo", file_path="bar")
    proc2.wrote[f]

    G = backend.add_nodes([proc2, f])

    # Graph grew, but only 3 nodes.
    assert len(G.nodes()) == 3
    assert len(G.edges()) == 2

    # Process should have both write and launched edges.

    u = hash(proc2)
    v = hash(other_proc)
    v2 = hash(f)

    assert networkx.has_path(G, u, v)
    assert networkx.has_path(G, u, v2)
    assert "Launched" in G[u][v]
    assert "Wrote" in G[u][v2]
Beispiel #11
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)
Beispiel #12
0
def test_explicit_full_path_overrides():
    file_node = File(file_path="c:\\windows", file_name="test.exe", full_path="foobar")

    assert file_node.full_path == "foobar"
Beispiel #13
0
def test_create():
    file_node = File(file_path="c:/windows", file_name="test.exe", extension=".exe")
    assert type(file_node) == File
Beispiel #14
0
def test_set_full_path():
    file_node = File(file_path="c:\\windows", file_name="test.exe")

    assert file_node.full_path == "c:\\windows\\test.exe"
Beispiel #15
0
def test_set_extension():
    file_node = File(file_path="c:/windows", file_name="test.exe")

    file_node.set_extension()

    assert file_node.extension == "exe"