Esempio n. 1
0
    def __init__(self, id: str):
        self.engagement_key = id

        self.eg_client: DgraphClient = DgraphClient(
            DgraphClientStub("alpha0.engagementgraphcluster.grapl:9080"))
        self.mg_client: DgraphClient = DgraphClient(
            DgraphClientStub("alpha0.mastergraphcluster.grapl:9080"))

        self.node_copier: NodeCopier = NodeCopier(id, self.mg_client,
                                                  self.eg_client)
Esempio n. 2
0
    def test_process_with_created_files(self) -> None:
        # Given: a process with a pid 100 & process_name word.exe,
        local_client = DgraphClient(DgraphClientStub("localhost:9080"))

        created_timestamp = int(time.time())

        parent_process = {
            "process_id": 100,
            "process_name": "word.exe",
            "created_timestamp": created_timestamp,
        }  # type: Dict[str, Property]

        parent_process_view = upsert(
            local_client,
            "Process",
            ProcessView,
            "763ddbda-8812-4a07-acfe-83402b92379d",
            parent_process,
        )

        created_file = {
            "file_path": "/folder/file.txt",
            "created_timestamp": created_timestamp + 1000,
        }  # type: Dict[str, Property]

        created_file_view = upsert(
            local_client,
            "File",
            FileView,
            "575f103e-1a11-4650-9f1b-5b72e44dfec3",
            created_file,
        )

        create_edge(
            local_client,
            parent_process_view.uid,
            "created_files",
            created_file_view.uid,
        )

        queried_process = (
            ProcessQuery()
            .with_node_key(eq="763ddbda-8812-4a07-acfe-83402b92379d")
            .with_process_id(eq=100)
            .with_process_name(contains="word")
            .with_created_timestamp(eq=created_timestamp)
            .with_created_files(
                FileQuery()
                .with_node_key(eq="575f103e-1a11-4650-9f1b-5b72e44dfec3")
                .with_file_path(eq="/folder/file.txt")
            )
            .query_first(local_client)
        )

        assert queried_process
        assert queried_process.process_id == 100

        assert len(queried_process.created_files) == 1
        created_file = queried_process.created_files[0]
        assert created_file.file_path == "/folder/file.txt"
Esempio n. 3
0
    def test_process_query_view_parity(self, process_props: ProcessProps):
        local_client = DgraphClient(DgraphClientStub("localhost:9080"))

        created_proc = get_or_create_process(self, local_client, process_props,)

        queried_proc = (
            ProcessQuery()
            .with_node_key(eq=created_proc.node_key)
            .query_first(local_client)
        )

        assert queried_proc

        assert process_props["node_key"] == queried_proc.node_key
        assert "Process" == queried_proc.get_node_type()
        assert process_props["process_id"] == queried_proc.get_process_id()
        assert process_props["arguments"] == escape_dgraph_str(
            queried_proc.get_arguments()
        )
        assert (
            process_props["created_timestamp"] == queried_proc.get_created_timestamp()
        )
        assert None == queried_proc.get_asset()
        assert process_props["terminate_time"] == queried_proc.get_terminate_time()
        assert process_props["image_name"] == escape_dgraph_str(
            queried_proc.get_image_name()
        )
        assert process_props["process_name"] == escape_dgraph_str(
            queried_proc.get_process_name()
        )
Esempio n. 4
0
    def test_process_query_view_miss(self, process_props: ProcessProps) -> None:
        local_client = DgraphClient(DgraphClientStub("localhost:9080"))

        created_proc = get_or_create_process(self, local_client, process_props)

        assert (
            created_proc.process_id is not None
            and created_proc.arguments is not None
            and created_proc.created_timestamp is not None
            and created_proc.terminate_time is not None
            and created_proc.image_name is not None
            and created_proc.process_name is not None
        )
        queried_proc = (
            ProcessQuery()
            .with_node_key(eq=created_proc.node_key)
            .with_process_id(eq=Not(created_proc.process_id))
            .with_arguments(eq=Not(created_proc.arguments))
            .with_created_timestamp(eq=Not(created_proc.created_timestamp))
            .with_terminate_time(eq=Not(created_proc.terminate_time))
            .with_image_name(eq=Not(created_proc.image_name))
            .with_process_name(eq=Not(created_proc.process_name))
            .query_first(local_client)
        )

        assert not queried_proc
    def test_with_wrote_files(self) -> None:
        # Given: a process with a pid 100 & process_name word.exe,
        local_client = DgraphClient(DgraphClientStub("localhost:9080"))

        created_timestamp = int(time.time())

        parent_process = {
            "process_id": 100,
            "process_name": "word.exe",
            "created_timestamp": created_timestamp,
        }  # type: Dict[str, Property]

        parent_process_view = upsert(
            local_client,
            "Process",
            ProcessView,
            "test_with_wrote_files-8f0761fb-2ffe-4d4b-ab38-68e5489f56dc",
            parent_process,
        )

        wrote_file = {
            "file_path": "/folder/file.txt",
            "created_timestamp": created_timestamp + 1000,
        }  # type: Dict[str, Property]

        wrote_file_view = upsert(
            local_client,
            "File",
            FileView,
            "test_with_wrote_files-2325c49a-95b4-423f-96d0-99539fe03833",
            wrote_file,
        )

        create_edge(
            local_client,
            parent_process_view.uid,
            "wrote_files",
            wrote_file_view.uid,
        )

        queried_process = (ProcessQuery().with_node_key(
            eq="test_with_wrote_files-8f0761fb-2ffe-4d4b-ab38-68e5489f56dc"
        ).with_process_id(eq=100).with_process_name(
            contains="word"
        ).with_created_timestamp(eq=created_timestamp).with_wrote_files(
            FileQuery().with_node_key(
                eq="test_with_wrote_files-2325c49a-95b4-423f-96d0-99539fe03833"
            ).with_file_path(eq="/folder/file.txt")).query_first(local_client))

        assert queried_process
        assert (queried_process.node_key ==
                "test_with_wrote_files-8f0761fb-2ffe-4d4b-ab38-68e5489f56dc")
        assert queried_process.process_id == 100
        assert queried_process.process_name == "word.exe"

        assert len(queried_process.wrote_files) == 1
        assert (queried_process.wrote_files[0].node_key ==
                "test_with_wrote_files-2325c49a-95b4-423f-96d0-99539fe03833")
        assert queried_process.wrote_files[0].file_path == "/folder/file.txt"
Esempio n. 6
0
def analyzer(graph: Subgraph, sender: Connection):
    try:
        print('analyzing')
        client = DgraphClient(DgraphClientStub('db.mastergraph:9080'))
        _analyzer(client, graph, sender)
    except Exception as e:
        print('analyzer failed: {}'.format(e))
        sender.send(None)
Esempio n. 7
0
def lambda_handler(events: Any, context: Any) -> None:
    # Parse sns message
    print("handling")
    print(events)
    print(context)

    alpha_names = os.environ["MG_ALPHAS"].split(",")

    client_stubs = [DgraphClientStub("{}:9080".format(name)) for name in alpha_names]
    client = DgraphClient(*client_stubs)

    s3 = get_s3_client()

    for event in events["Records"]:
        if not IS_LOCAL:
            event = json.loads(event['body'])['Records'][0]
        data = parse_s3_event(s3, event)

        message = json.loads(data)

        print(f'Executing Analyzer: {message["key"]}')
        analyzer = download_s3_file(s3, f"{os.environ['BUCKET_PREFIX']}-analyzers-bucket", message["key"])
        analyzer_name = message["key"].split("/")[-2]

        subgraph = SubgraphView.from_proto(client, bytes(message["subgraph"]))

        # TODO: Validate signature of S3 file
        print(f'event {event}')
        rx, tx = Pipe(duplex=False)  # type: Tuple[Connection, Connection]
        p = Process(target=execute_file, args=(analyzer_name, analyzer, subgraph, tx, ''))

        p.start()
        t = 0

        while True:
            p_res = rx.poll(timeout=5)
            if not p_res:
                t += 1
                print(f"Polled {analyzer_name} for {t * 5} seconds without result")
                continue
            result = rx.recv()  # type: Optional[Any]

            if isinstance(result, ExecutionComplete):
                print("execution complete")
                break

            # emit any hits to an S3 bucket
            if isinstance(result, ExecutionHit):
                print(f"emitting event for {analyzer_name} {result.analyzer_name} {result.root_node_key}")
                emit_event(s3, result)
                update_msg_cache(analyzer, result.root_node_key, message['key'])
                update_hit_cache(analyzer_name, result.root_node_key)

            assert not isinstance(
                result, ExecutionFailed
            ), f"Analyzer {analyzer_name} failed."

        p.join()
    def test_with_bin_file(self) -> None:
        # Given: a process with a pid 100 & process_name word.exe,
        local_client = DgraphClient(DgraphClientStub("localhost:9080"))

        created_timestamp = int(time.time())

        parent_process = {
            "process_id": 100,
            "process_name": "word.exe",
            "created_timestamp": created_timestamp,
        }  # type: Dict[str, Property]

        parent_process_view = upsert(
            local_client,
            "Process",
            ProcessView,
            "635952af-87f3-4a2a-a65d-3f1859db9525",
            parent_process,
        )

        bin_file = {
            "file_path": "/folder/file.txt",
            "created_timestamp": created_timestamp + 1000,
        }  # type: Dict[str, Property]

        bin_file_view = upsert(
            local_client,
            "File",
            FileView,
            "9f16e0c9-33c0-4d18-9878-ef686373570b",
            bin_file,
        )

        create_edge(
            local_client,
            parent_process_view.uid,
            "bin_file",
            bin_file_view.uid,
        )

        queried_process = (ProcessQuery().with_node_key(
            eq="635952af-87f3-4a2a-a65d-3f1859db9525"
        ).with_process_id(eq=100).with_process_name(
            contains="word").with_created_timestamp(
                eq=created_timestamp).with_bin_file(FileQuery().with_node_key(
                    eq="9f16e0c9-33c0-4d18-9878-ef686373570b").with_file_path(
                        eq="/folder/file.txt")).query_first(local_client))

        assert queried_process
        assert "635952af-87f3-4a2a-a65d-3f1859db9525"
        assert queried_process.process_id == 100
        assert queried_process.process_name == "word.exe"
        assert queried_process.created_timestamp == created_timestamp

        bin_file = queried_process.bin_file
        assert bin_file.node_key == "9f16e0c9-33c0-4d18-9878-ef686373570b"

        assert bin_file.file_path == "/folder/file.txt"
    def test_with_read_files(self) -> None:
        # Given: a process with a pid 100 & process_name word.exe,
        local_client = DgraphClient(DgraphClientStub("localhost:9080"))

        created_timestamp = int(time.time())

        parent_process = {
            "process_id": 100,
            "process_name": "word.exe",
            "created_timestamp": created_timestamp,
        }  # type: Dict[str, Property]

        parent_process_view = upsert(
            local_client,
            "Process",
            ProcessView,
            "test_with_read_files-669a3693-d960-401c-8d29-5d669ffcd660",
            parent_process,
        )

        read_file = {
            "file_path": "/folder/file.txt",
            "created_timestamp": created_timestamp + 1000,
        }  # type: Dict[str, Property]

        read_file_view = upsert(
            local_client,
            "File",
            FileView,
            "test_with_read_files-aa9248ec-36ee-4177-ba1a-999de735e682",
            read_file,
        )

        create_edge(
            local_client,
            parent_process_view.uid,
            "read_files",
            read_file_view.uid,
        )

        queried_process = (ProcessQuery().with_process_id(
            eq=100).with_process_name(contains="word").with_created_timestamp(
                eq=created_timestamp).with_read_files(
                    FileQuery().with_file_path(
                        eq="/folder/file.txt")).query_first(local_client))

        assert queried_process
        assert (queried_process.node_key ==
                "test_with_read_files-669a3693-d960-401c-8d29-5d669ffcd660")

        assert queried_process.process_id == 100
        assert queried_process.process_name == "word.exe"

        assert len(queried_process.read_files) == 1
        assert (queried_process.read_files[0].node_key ==
                "test_with_read_files-aa9248ec-36ee-4177-ba1a-999de735e682")
        assert queried_process.read_files[0].file_path == "/folder/file.txt"
Esempio n. 10
0
def main() -> None:
    local_client = DgraphClient(DgraphClientStub("localhost:9080"))

    test_ipc(local_client)

    parent = {
        "process_id": 100,
        "process_name": "word.exe",
    }  # type: Dict[str, Property]

    child = {
        "process_id": 1234,
        "process_name": "cmd.exe"
    }  # type: Dict[str, Property]

    external_ip = {
        "external_ip": "56.123.14.24",
    }  # type: Dict[str, Property]

    parent_view = upsert(local_client, ProcessView,
                         "ea75f056-61a1-479d-9ca2-f632d2c67205", parent)

    child_view = upsert(local_client, ProcessView,
                        "10f585c2-cf31-41e2-8ca5-d477e78be3ac", child)

    external_ip_view = upsert(
        local_client,
        ExternalIpView,
        "8bc20354-e8c5-49fc-a984-2927b24c1a29",
        external_ip,
    )

    create_edge(local_client, parent_view.uid, "children", child_view.uid)
    create_edge(local_client, child_view.uid, "created_connections",
                external_ip_view.uid)

    queried_child_0 = ProcessQuery().with_process_id(
        eq=1234).query_first(local_client)

    assert queried_child_0
    assert queried_child_0.node_key == child_view.node_key

    queried_child_1 = (ProcessQuery().with_process_id(eq=1234).query_first(
        local_client,
        contains_node_key="10f585c2-cf31-41e2-8ca5-d477e78be3ac"))

    assert queried_child_1
    assert queried_child_1.node_key == child_view.node_key
    assert queried_child_1.node_key == queried_child_0.node_key

    p = (ProcessQuery().with_process_name(
        eq="cmd.exe").with_parent().with_created_connection().query_first(
            local_client))  # type: Optional[ProcessView]

    assert p
Esempio n. 11
0
def execute_file(file: str, graph: SubgraphView, sender):
    print("executing analyzer")
    alpha_names = os.environ["MG_ALPHAS"].split(",")

    client_stubs = [DgraphClientStub("{}:9080".format(name)) for name in alpha_names]
    client = DgraphClient(*client_stubs)

    exec(file, globals())
    for node in graph.node_iter():
        # TODO: Check node + analyzer file hash in redis cache, avoid reprocess of hits
        print("File executed: {}".format(analyzer(client, node, sender)))  # type: ignore
Esempio n. 12
0
def main() -> None:
    local_client = DgraphClient(DgraphClientStub("localhost:9080"))

    parent = {
        "process_id": 100,
        "process_name": "word.exe",
    }  # type: Dict[str, Property]

    child = {"process_id": 1234, "process_name": "cmd.exe"}  # type: Dict[str, Property]

    parent_view = upsert(
        local_client,
        "Process",
        ProcessView,
        "ea75f056-61a1-479d-9ca2-f632d2c67205",
        parent,
    )

    child_view = upsert(
        local_client,
        "Process",
        ProcessView,
        "10f585c2-cf31-41e2-8ca5-d477e78be3ac",
        child,
    )

    create_edge(local_client, parent_view.uid, "children", child_view.uid)

    queried_child_0 = ProcessQuery().with_process_id(eq=1234).query_first(local_client)

    assert queried_child_0
    assert queried_child_0.node_key == child_view.node_key

    queried_child_1 = (
        ProcessQuery()
        .with_process_id(eq=1234)
        .query_first(
            local_client, contains_node_key="10f585c2-cf31-41e2-8ca5-d477e78be3ac"
        )
    )

    assert queried_child_1
    assert queried_child_1.node_key == child_view.node_key
    assert queried_child_1.node_key == queried_child_0.node_key

    p = (
        ProcessQuery().with_parent().query_first(local_client)
    )  # type: Optional[ProcessView]

    assert p

    p.get_parent()
Esempio n. 13
0
def execute_file(name: str, file: str, graph: SubgraphView, sender, msg_id):
    alpha_names = os.environ["MG_ALPHAS"].split(",")

    try:
        pool = ThreadPool(processes=4)

        exec(file, globals())
        client_stubs = [
            DgraphClientStub(f"{a_name}:9080") for a_name in alpha_names
        ]
        client = DgraphClient(*client_stubs)

        analyzers = get_analyzer_objects(client)
        if not analyzers:
            print(f'Got no analyzers for file: {name}')

        print(f'Executing analyzers: {[an for an in analyzers.keys()]}')

        chunk_size = 100

        if IS_RETRY == "True":
            chunk_size = 10

        for nodes in chunker([n for n in graph.node_iter()], chunk_size):
            print(f'Querying {len(nodes)} nodes')

            def exec_analyzer(nodes, sender):
                try:
                    exec_analyzers(client, file, msg_id, nodes, analyzers,
                                   sender)

                    return nodes
                except Exception as e:
                    print(traceback.format_exc())
                    print(f'Execution of {name} failed with {e} {e.args}')
                    sender.send(ExecutionFailed())
                    raise

            exec_analyzer(nodes, sender)
            pool.apply_async(exec_analyzer, args=(nodes, sender))

        pool.close()

        pool.join()

        sender.send(ExecutionComplete())

    except Exception as e:
        print(traceback.format_exc())
        print(f'Execution of {name} failed with {e} {e.args}')
        sender.send(ExecutionFailed())
        raise
Esempio n. 14
0
def main() -> None:
    local_client = DgraphClient(DgraphClientStub('localhost:9080'))

    test_ipc(local_client)

    parent = {
        'process_id': 100,
        'process_name': 'word.exe'
    }  # type: Dict[str, Property]

    child = {
        'process_id': 1234,
        'process_name': 'cmd.exe'
    }  # type: Dict[str, Property]

    external_ip = {
        'external_ip': '56.123.14.24',
    }  # type: Dict[str, Property]

    parent_view = upsert(local_client, ProcessView,
                         'ea75f056-61a1-479d-9ca2-f632d2c67205', parent)

    child_view = upsert(local_client, ProcessView,
                        '10f585c2-cf31-41e2-8ca5-d477e78be3ac', child)

    external_ip_view = upsert(local_client, ExternalIpView,
                              '8bc20354-e8c5-49fc-a984-2927b24c1a29',
                              external_ip)

    create_edge(local_client, parent_view.uid, 'children', child_view.uid)
    create_edge(local_client, child_view.uid, 'created_connections',
                external_ip_view.uid)

    queried_child_0 = ProcessQuery().with_process_id(
        eq=1234).query_first(local_client)

    assert queried_child_0
    assert queried_child_0.node_key == child_view.node_key

    queried_child_1 = (ProcessQuery().with_process_id(eq=1234).query_first(
        local_client,
        contains_node_key='10f585c2-cf31-41e2-8ca5-d477e78be3ac'))

    assert queried_child_1
    assert queried_child_1.node_key == child_view.node_key
    assert queried_child_1.node_key == queried_child_0.node_key

    p = (ProcessQuery().with_process_name(
        eq="cmd.exe").with_parent().with_created_connection().query_first(
            local_client))  # type: Optional[ProcessView]

    assert p
Esempio n. 15
0
def lambda_handler(events: Any, context: Any) -> None:
    # Parse sns message
    print("handling")
    print(events)
    print(context)

    alpha_names = os.environ["MG_ALPHAS"].split(",")

    client_stubs = [DgraphClientStub("{}:9080".format(name)) for name in alpha_names]
    client = DgraphClient(*client_stubs)

    for event in events["Records"]:
        data = parse_s3_event(event)

        message = json.loads(data)

        # TODO: Use env variable for s3 bucket
        analyzer = download_s3_file("grapl-analyzers-bucket", message["key"])
        subgraph = SubgraphView.from_proto(client, bytes(message["subgraph"]))

        # TODO: Validate signature of S3 file
        print("creating queue")
        rx, tx = Pipe(duplex=False)  # type: Tuple[Connection, Connection]
        print("creating process")
        p = Process(target=execute_file, args=(analyzer, subgraph, tx))
        print("running process")
        p.start()

        while True:
            print("waiting for results")
            p_res = rx.poll(timeout=5)
            if not p_res:
                print("Polled for 5 seconds without result")
                continue
            result = rx.recv()  # type: Optional[Any]

            if isinstance(result, ExecutionComplete):
                print("execution complete")
                # TODO: ACK Result
                break

            # emit any hits to an S3 bucket
            if isinstance(result, ExecutionHit):
                print("emitting event for result: {}".format(result))
                emit_event(result)

            assert not isinstance(
                result, ExecutionFailed
            ), "Result was none. Analyzer failed."

        p.join()
Esempio n. 16
0
    def test_with_deleted_files(self) -> None:
        # Given: a process with a pid 100 & process_name word.exe,
        local_client = DgraphClient(DgraphClientStub("localhost:9080"))

        created_timestamp = int(time.time())

        parent_process = {
            "process_id": 100,
            "process_name": "word.exe",
            "created_timestamp": created_timestamp,
        }  # type: Dict[str, Property]

        parent_process_view = upsert(
            local_client,
            "Process",
            ProcessView,
            "test_with_deleted_files-47527d73-22c4-4e0f-bf7d-184bf1f206e2",
            parent_process,
        )

        deleted_file = {
            "file_path": "/folder/file.txt",
            "created_timestamp": created_timestamp + 1000,
        }  # type: Dict[str, Property]

        deleted_file_view = upsert(
            local_client,
            "File",
            FileView,
            "test_with_deleted_files8b8364ea-9b47-476b-8cf0-0f724adff10f",
            deleted_file,
        )

        create_edge(
            local_client,
            parent_process_view.uid,
            "deleted_files",
            deleted_file_view.uid,
        )

        queried_process = (
            ProcessQuery()
            .with_process_id(eq=100)
            .with_process_name(contains="word")
            .with_created_timestamp(eq=created_timestamp)
            .with_deleted_files(FileQuery().with_file_path(eq="/folder/file.txt"))
            .query_first(local_client)
        )

        assert queried_process
        assert queried_process.process_id == 100
    def test_process_query_view_parity_contains(
        self,
        node_key,
        process_id,
        created_timestamp,
        asset_id,
        terminate_time,
        image_name,
        process_name,
        arguments,
    ):
        node_key = "test_process_query_view_parity_contains" + str(node_key)
        local_client = DgraphClient(DgraphClientStub("localhost:9080"))
        get_or_create_process_node(
            local_client,
            node_key,
            process_id,
            arguments,
            created_timestamp,
            asset_id,
            terminate_time,
            image_name,
            process_name,
        )

        query = ProcessQuery().with_node_key(eq=node_key)

        # Don't f**k with newlines due to a dgraph bug
        # https://github.com/dgraph-io/dgraph/issues/4694
        if len(arguments) > 3 and "\n" not in arguments:
            query.with_arguments(contains=arguments[:len(arguments) - 1])
        if len(asset_id) > 3 and "\n" not in asset_id:
            query.with_asset_id(contains=asset_id[:len(asset_id) - 1])
        if len(image_name) > 3 and "\n" not in image_name:
            query.with_image_name(contains=image_name[:len(image_name) - 1])
        if len(process_name) > 3 and "\n" not in process_name:
            query.with_process_name(contains=process_name[:len(process_name) -
                                                          1])

        queried_proc = query.query_first(local_client)

        assert queried_proc
        assert "Process" == queried_proc.get_node_type()
        assert process_id == queried_proc.get_process_id()
        assert node_key == queried_proc.node_key
        assert arguments == queried_proc.get_arguments()
        assert created_timestamp == queried_proc.get_created_timestamp()
        assert asset_id == queried_proc.get_asset_id()
        assert terminate_time == queried_proc.get_terminate_time()
        assert image_name == queried_proc.get_image_name()
        assert process_name == queried_proc.get_process_name()
Esempio n. 18
0
def execute_file(name: str, file: str, graph: SubgraphView, sender, msg_id):
    try:
        pool = ThreadPool(processes=4)

        exec(file, globals())
        client_stubs = (DgraphClientStub(f"{host}:{port}")
                        for host, port in mg_alphas())
        client = DgraphClient(*client_stubs)

        analyzers = get_analyzer_objects(client)
        if not analyzers:
            LOGGER.warning(f"Got no analyzers for file: {name}")

        LOGGER.info(f"Executing analyzers: {[an for an in analyzers.keys()]}")

        chunk_size = 100

        if IS_RETRY == "True":
            chunk_size = 10

        for nodes in chunker([n for n in graph.node_iter()], chunk_size):
            LOGGER.info(f"Querying {len(nodes)} nodes")

            def exec_analyzer(nodes, sender):
                try:
                    exec_analyzers(client, file, msg_id, nodes, analyzers,
                                   sender)

                    return nodes
                except Exception as e:
                    LOGGER.error(traceback.format_exc())
                    LOGGER.error(
                        f"Execution of {name} failed with {e} {e.args}")
                    sender.send(ExecutionFailed())
                    raise

            exec_analyzer(nodes, sender)
            pool.apply_async(exec_analyzer, args=(nodes, sender))

        pool.close()

        pool.join()

        sender.send(ExecutionComplete())

    except Exception as e:
        LOGGER.error(traceback.format_exc())
        LOGGER.error(f"Execution of {name} failed with {e} {e.args}")
        sender.send(ExecutionFailed())
        raise
Esempio n. 19
0
    def test_process_query_view_parity_contains(
        self,
        node_key,
        process_id,
        created_timestamp,
        terminate_time,
        image_name,
        process_name,
        arguments,
    ):
        node_key = "test_process_query_view_parity_contains" + str(node_key)
        local_client = DgraphClient(DgraphClientStub("localhost:9080"))
        get_or_create_process_node_deprecated(
            local_client,
            node_key,
            process_id,
            arguments,
            created_timestamp,
            terminate_time,
            image_name,
            process_name,
        )

        query = ProcessQuery().with_node_key(eq=node_key)

        # Don't f**k with newlines due to a dgraph bug
        # https://github.com/dgraph-io/dgraph/issues/4694
        for prop in [arguments, image_name, process_name]:
            hypothesis.assume(len(prop) > 3)
            hypothesis.assume("\n" not in prop)
            hypothesis.assume("\\" not in prop)

        # These fail because dgraph doesn't like the query
        # 	(regexp(process_name, /00\\//))
        query.with_arguments(contains=arguments[: len(arguments) - 1])
        query.with_image_name(contains=image_name[: len(image_name) - 1])
        query.with_process_name(contains=process_name[: len(process_name) - 1])

        queried_proc = query.query_first(local_client)

        assert queried_proc
        assert "Process" == queried_proc.get_node_type()
        assert process_id == queried_proc.get_process_id()
        assert node_key == queried_proc.node_key
        assert arguments == queried_proc.get_arguments()
        assert created_timestamp == queried_proc.get_created_timestamp()
        assert terminate_time == queried_proc.get_terminate_time()
        assert image_name == queried_proc.get_image_name()
        assert process_name == queried_proc.get_process_name()
Esempio n. 20
0
            def exec_analyzer(analyzer, node, sender):
                try:
                    client_stubs = [
                        DgraphClientStub(f"{a_name}:9080")
                        for a_name in alpha_names
                    ]
                    client = DgraphClient(*client_stubs)

                    analyzer(client, node, sender)
                    return node
                except Exception as e:
                    print(traceback.format_exc())
                    print(f'Execution of {name} failed with {e} {e.args}')
                    sender.send(ExecutionFailed())
                    raise
Esempio n. 21
0
def lambda_handler(events: Any, context: Any) -> None:
    mg_client = DgraphClient(DgraphClientStub('db.mastergraph:9080'))
    eg_client = DgraphClient(DgraphClientStub('db.engagementgraph:9080'))

    create_process_schema(eg_client)

    uid_map = {}
    for event in events['Records']:
        print('Copying engagement')
        data = parse_s3_event(event)
        incident_graph = json.loads(data)

        label = incident_graph['label'].encode('utf-8')
        node_refs = incident_graph['node_refs']
        edges = incident_graph['edges']

        engagement_key = get_engagement_key(label, [n['uid'] for n in node_refs])

        if should_throttle(engagement_key, eg_client):
            print('Throttling: {}'.format(engagement_key))
            continue

        print('Creating engagement: {}'.format(engagement_key))
        copier = NodeCopier(engagement_key, mg_client, eg_client)

        print('node_refs: {}'.format(node_refs))
        print('edges: {}'.format(edges))
        for node_ref in node_refs:
            new_uid = copier.copy_node(node_ref['uid'])
            uid_map[node_ref['uid']] = new_uid
            print('new_uid: {}'.format(new_uid))
        for edge in edges:
            copier.copy_edge(uid_map[edge[0]], edge[1], uid_map[edge[2]])
        print('Copied engagement successfully')

    print('Engagement creation was successful')
Esempio n. 22
0
    def test_process_query_view_parity_eq(
        self,
        node_key,
        process_id,
        created_timestamp,
        terminate_time,
        image_name,
        process_name,
        arguments,
    ):
        node_key = "test_process_query_view_parity_eq" + str(node_key)
        local_client = DgraphClient(DgraphClientStub("localhost:9080"))
        get_or_create_process_node_deprecated(
            local_client,
            node_key,
            process_id,
            arguments,
            created_timestamp,
            terminate_time,
            image_name,
            process_name,
        )

        queried_proc = (
            ProcessQuery()
            .with_node_key(eq=node_key)
            .with_process_id(eq=process_id)
            .with_arguments(eq=arguments)
            .with_created_timestamp(eq=created_timestamp)
            .with_terminate_time(eq=terminate_time)
            .with_image_name(eq=image_name)
            .with_process_name(eq=process_name)
            .query_first(local_client)
        )

        # assert process_view.process_id == queried_proc.get_process_id()
        assert node_key == queried_proc.node_key
        assert "Process" == queried_proc.get_node_type()
        assert process_id == queried_proc.get_process_id()

        assert arguments == queried_proc.get_arguments()
        assert created_timestamp == queried_proc.get_created_timestamp()
        assert terminate_time == queried_proc.get_terminate_time()
        assert image_name == queried_proc.get_image_name()
        assert process_name == queried_proc.get_process_name()
Esempio n. 23
0
def main() -> None:
    local_client = DgraphClient(DgraphClientStub('localhost:9080'))

    parent = {
        'process_id': 100,
        'process_name': 'word.exe'
    }  # type: Dict[str, Property]

    child = {
        'process_id': 1234,
        'process_name': 'cmd.exe'
    }  # type: Dict[str, Property]

    parent_view = upsert(local_client, 'Process', ProcessView,
                         'ea75f056-61a1-479d-9ca2-f632d2c67205', parent)

    child_view = upsert(local_client, 'Process', ProcessView,
                        '10f585c2-cf31-41e2-8ca5-d477e78be3ac', child)

    create_edge(local_client, parent_view.uid, 'children', child_view.uid)

    queried_child_0 = ProcessQuery().with_process_id(
        eq=1234).query_first(local_client)

    assert queried_child_0
    assert queried_child_0.node_key == child_view.node_key

    queried_child_1 = (ProcessQuery().with_process_id(eq=1234).query_first(
        local_client,
        contains_node_key='10f585c2-cf31-41e2-8ca5-d477e78be3ac'))

    assert queried_child_1
    assert queried_child_1.node_key == child_view.node_key
    assert queried_child_1.node_key == queried_child_0.node_key

    p = (ProcessQuery().with_parent().query_first(local_client)
         )  # type: Optional[ProcessView]

    assert p

    p.get_parent()
    def test_single_process_contains_key(
        self,
        node_key,
        process_id,
        created_timestamp,
        asset_id,
        terminate_time,
        image_name,
        process_name,
        arguments,
    ):
        node_key = "test_single_process_contains_key" + str(node_key)
        local_client = DgraphClient(DgraphClientStub("localhost:9080"))

        get_or_create_process_node(
            local_client,
            node_key,
            process_id,
            arguments,
            created_timestamp,
            asset_id,
            terminate_time,
            image_name,
            process_name,
        )

        queried_proc = ProcessQuery().query_first(local_client,
                                                  contains_node_key=node_key)

        # assert process_view.process_id == queried_proc.get_process_id()
        assert node_key == queried_proc.node_key
        assert "Process" == queried_proc.get_node_type()
        assert process_id == queried_proc.get_process_id()
        assert arguments == queried_proc.get_arguments()
        assert created_timestamp == queried_proc.get_created_timestamp()
        assert asset_id == queried_proc.get_asset_id()
        assert terminate_time == queried_proc.get_terminate_time()
        assert image_name == queried_proc.get_image_name()
        assert process_name == queried_proc.get_process_name()
Esempio n. 25
0
    def test_single_process_contains_key(self, process_props: ProcessProps) -> None:
        local_client = DgraphClient(DgraphClientStub("localhost:9080"))
        created_proc = get_or_create_process(self, local_client, process_props)

        # Setup complete, do some queries

        queried_proc = ProcessQuery().query_first(
            local_client, contains_node_key=created_proc.node_key
        )

        assert queried_proc
        assert created_proc.get_process_id() == queried_proc.get_process_id()
        assert created_proc.node_key == queried_proc.node_key
        assert "Process" == queried_proc.get_node_type()
        assert created_proc.get_arguments() == queried_proc.get_arguments()
        assert (
            created_proc.get_created_timestamp() == queried_proc.get_created_timestamp()
        )
        assert created_proc.get_terminate_time() == queried_proc.get_terminate_time()
        assert created_proc.get_image_name() == queried_proc.get_image_name()
        assert created_proc.get_process_name() == queried_proc.get_process_name()

        assert not queried_proc.get_asset()
    def test_process_query_view_miss(
        self,
        node_key,
        process_id,
        created_timestamp,
        asset_id,
        terminate_time,
        image_name,
        process_name,
        arguments,
    ):
        node_key = "test_process_query_view_miss" + str(node_key)
        local_client = DgraphClient(DgraphClientStub("localhost:9080"))
        process = {
            "process_id": process_id,
            "arguments": arguments,
            "created_timestamp": created_timestamp,
            "asset_id": asset_id,
            "terminate_time": terminate_time,
            "image_name": image_name,
            "process_name": process_name,
        }  # type: Dict[str, Property]

        process_view = cast(ProcessView,
                            upsert(local_client, "Process", ProcessView,
                                   node_key, process))  # type: ProcessView

        queried_proc = (ProcessQuery().with_node_key(
            eq=node_key).with_process_id(eq=Not(process_id)).with_arguments(
                eq=Not(arguments)).with_created_timestamp(
                    eq=Not(created_timestamp)).with_asset_id(
                        eq=Not(asset_id)).with_terminate_time(
                            eq=Not(terminate_time)).with_image_name(
                                eq=Not(image_name)).with_process_name(eq=Not(
                                    process_name)).query_first(local_client))

        assert not queried_proc
    def test__single_ip_addr_node__query_by_node_key(
        self,
        node_key,
        first_seen_timestamp,
        last_seen_timestamp,
        ip_address,
    ):
        # current function's name, but don't need to copy-paste replace
        node_key = node_key_for_test(self, node_key)
        local_client = DgraphClient(DgraphClientStub("localhost:9080"))

        created = get_or_create_ip_address_node(
            local_client=local_client,
            node_key=node_key,
            first_seen_timestamp=as_millis(first_seen_timestamp),
            last_seen_timestamp=as_millis(last_seen_timestamp),
            ip_address=str(ip_address),
        )

        queried_ip_address_node = (IpAddressQuery().with_ip_address(
        ).with_first_seen_timestamp().with_last_seen_timestamp().query_first(
            local_client, contains_node_key=node_key))

        assert_views_equal(expected=created, actual=queried_ip_address_node)
Esempio n. 28
0
    def test_single_process_connected_to_asset_node(
        self, asset_props: AssetProps, process_props: ProcessProps,
    ):
        local_client = DgraphClient(DgraphClientStub("localhost:9080"))

        created_asset = get_or_create_asset(self, local_client, asset_props)
        created_proc = get_or_create_process(self, local_client, process_props)

        create_edge(
            local_client, created_asset.uid, "asset_processes", created_proc.uid,
        )

        # Setup complete, do some queries

        queried_proc = (
            ProcessQuery()
            .with_asset(AssetQuery().with_hostname(created_asset.get_hostname()))
            .query_first(local_client, contains_node_key=created_proc.node_key)
        )
        assert queried_proc
        fetch_all_properties(queried_proc)
        assert_equal_props(created_proc, queried_proc)
        queried_asset = queried_proc.get_asset()
        assert_equal_identity(created_asset, queried_asset)
Esempio n. 29
0
    def test_parent_children_edge(self) -> None:
        # Given: a process with a pid 100 & process_name word.exe,
        local_client = DgraphClient(DgraphClientStub("localhost:9080"))

        created_timestamp = int(time.time())

        parent_process = {
            "process_id": 100,
            "process_name": "word.exe",
            "created_timestamp": created_timestamp,
        }  # type: Dict[str, Property]

        parent_process_view = upsert(
            local_client,
            "Process",
            ProcessView,
            "0e84f2ce-f711-46ce-bc9e-1b13c9ba6d6c",
            parent_process,
        )

        child_process = {
            "process_id": 110,
            "process_name": "malware.exe",
            "created_timestamp": created_timestamp + 1000,
        }  # type: Dict[str, Property]

        child_process_view = upsert(
            local_client,
            "Process",
            ProcessView,
            "46d2862f-cb58-4062-b35e-bb310b8d5b0d",
            child_process,
        )

        create_edge(
            local_client, parent_process_view.uid, "children", child_process_view.uid,
        )

        queried_process = (
            ProcessQuery()
            .with_node_key(eq="0e84f2ce-f711-46ce-bc9e-1b13c9ba6d6c")
            .with_process_id(eq=100)
            .with_process_name(contains="word")
            .with_created_timestamp(eq=created_timestamp)
            .with_children(
                ProcessQuery()
                .with_node_key(eq="46d2862f-cb58-4062-b35e-bb310b8d5b0d")
                .with_process_id(eq=110)
                .with_process_name(eq="malware.exe")
                .with_created_timestamp(eq=created_timestamp + 1000)
            )
            .query_first(local_client)
        )
        assert queried_process

        assert queried_process.node_key == "0e84f2ce-f711-46ce-bc9e-1b13c9ba6d6c"
        assert queried_process.process_id == 100
        assert queried_process.process_name == "word.exe"
        assert queried_process.created_timestamp == created_timestamp

        assert len(queried_process.children) == 1
        child = queried_process.children[0]
        assert child.node_key == "46d2862f-cb58-4062-b35e-bb310b8d5b0d"
        assert child.process_id == 110
        assert child.process_name == "malware.exe"
        assert child.created_timestamp == created_timestamp + 1000
Esempio n. 30
0
    def test_single_file_view_parity_eq(
        self,
        node_key,
        file_path,
        asset_id,
        file_extension,
        file_mime_type,
        file_size,
        file_version,
        file_description,
        file_product,
        file_company,
        file_directory,
        file_inode,
        file_hard_links,
        signed,
        signed_status,
        md5_hash,
        sha1_hash,
        sha256_hash,
    ):
        node_key = "test_single_file_view_parity_eq" + str(node_key)
        local_client = DgraphClient(DgraphClientStub("localhost:9080"))

        get_or_create_file_node(
            local_client,
            node_key,
            file_path,
            asset_id,
            file_extension,
            file_mime_type,
            file_size,
            file_version,
            file_description,
            file_product,
            file_company,
            file_directory,
            file_inode,
            file_hard_links,
            signed,
            signed_status,
            md5_hash,
            sha1_hash,
            sha256_hash,
        )

        queried_file = (FileQuery().with_node_key(eq=node_key).with_file_path(
            eq=file_path).with_asset_id(eq=asset_id).with_file_extension(
                eq=file_extension).with_file_mime_type(
                    eq=file_mime_type).with_file_size(
                        eq=file_size).with_file_version(
                            eq=file_version).with_file_description(
                                eq=file_description).with_file_product(
                                    eq=file_product).
                        with_file_company(eq=file_company).with_file_directory(
                            eq=file_directory).with_file_inode(
                                eq=file_inode).with_file_hard_links(
                                    eq=file_hard_links).with_signed(eq=signed).
                        with_signed_status(eq=signed_status).with_md5_hash(
                            eq=md5_hash).with_sha1_hash(
                                eq=sha1_hash).with_sha256_hash(
                                    eq=sha256_hash).query_first(local_client))

        assert node_key == queried_file.node_key

        assert file_path == queried_file.get_file_path()
        assert asset_id == queried_file.get_asset_id()
        assert file_extension == queried_file.get_file_extension()
        assert file_mime_type == queried_file.get_file_mime_type()
        assert file_size == queried_file.get_file_size()
        assert file_version == queried_file.get_file_version()
        assert file_description == queried_file.get_file_description()
        assert file_product == queried_file.get_file_product()
        assert file_company == queried_file.get_file_company()
        assert file_directory == queried_file.get_file_directory()
        assert file_inode == queried_file.get_file_inode()
        assert file_hard_links == queried_file.get_file_hard_links()
        assert signed == queried_file.get_signed()
        assert signed_status == queried_file.get_signed_status()
        assert md5_hash == queried_file.get_md5_hash()
        assert sha1_hash == queried_file.get_sha1_hash()
        assert sha256_hash == queried_file.get_sha256_hash()