def testRawGzchunkedMultipleClients(self):
        client_id_1 = db_test_utils.InitializeClient(data_store.REL_DB)
        client_id_2 = db_test_utils.InitializeClient(data_store.REL_DB)

        snapshot = rdf_objects.ClientSnapshot()
        snapshot.client_id = client_id_1
        snapshot.knowledge_base.fqdn = "foo.quux.com"
        data_store.REL_DB.WriteClientSnapshot(snapshot)

        snapshot = rdf_objects.ClientSnapshot()
        snapshot.client_id = client_id_2
        snapshot.knowledge_base.fqdn = "foo.norf.com"
        data_store.REL_DB.WriteClientSnapshot(snapshot)

        hunt_id = "A0B1D2C3E4"

        hunt_obj = rdf_hunt_objects.Hunt()
        hunt_obj.hunt_id = hunt_id
        hunt_obj.args.standard.client_ids = [client_id_1, client_id_2]
        hunt_obj.args.standard.flow_name = timeline.TimelineFlow.__name__
        hunt_obj.hunt_state = rdf_hunt_objects.Hunt.HuntState.PAUSED

        data_store.REL_DB.WriteHuntObject(hunt_obj)

        entry_1 = rdf_timeline.TimelineEntry()
        entry_1.path = "foo_1".encode("utf-8")
        entry_1.size = 13371

        entry_2 = rdf_timeline.TimelineEntry()
        entry_2.path = "foo_2".encode("utf-8")
        entry_2.size = 13372

        _WriteTimeline(client_id_1, [entry_1], hunt_id=hunt_id)
        _WriteTimeline(client_id_2, [entry_2], hunt_id=hunt_id)

        args = api_timeline.ApiGetCollectedHuntTimelinesArgs()
        args.hunt_id = hunt_id

        content = b"".join(self.handler.Handle(args).GenerateContent())
        buffer = io.BytesIO(content)

        with zipfile.ZipFile(buffer, mode="r") as archive:
            client_filename_1 = f"{client_id_1}_foo.quux.com.gzchunked"
            with archive.open(client_filename_1, mode="r") as file:
                chunks = chunked.ReadAll(file)
                entries = list(
                    rdf_timeline.TimelineEntry.DeserializeStream(chunks))
                self.assertEqual(entries, [entry_1])

            client_filename_2 = f"{client_id_2}_foo.norf.com.gzchunked"
            with archive.open(client_filename_2, mode="r") as file:
                chunks = chunked.ReadAll(file)
                entries = list(
                    rdf_timeline.TimelineEntry.DeserializeStream(chunks))
                self.assertEqual(entries, [entry_2])
Esempio n. 2
0
    def testBodyMultipleResults(self):
        client_id = db_test_utils.InitializeClient(data_store.REL_DB)
        flow_id = "ABCDEF42"

        flow_obj = rdf_flow_objects.Flow()
        flow_obj.client_id = client_id
        flow_obj.flow_id = flow_id
        flow_obj.flow_class_name = timeline.TimelineFlow.__name__
        flow_obj.create_time = rdfvalue.RDFDatetime.Now()
        data_store.REL_DB.WriteFlowObject(flow_obj)

        entry_1 = rdf_timeline.TimelineEntry()
        entry_1.path = "/foo".encode("utf-8")

        blobs_1 = list(
            rdf_timeline.TimelineEntry.SerializeStream(iter([entry_1])))
        (blob_id_1, ) = data_store.BLOBS.WriteBlobsWithUnknownHashes(blobs_1)

        result_1 = rdf_timeline.TimelineResult()
        result_1.entry_batch_blob_ids = [blob_id_1.AsBytes()]

        entry_2 = rdf_timeline.TimelineEntry()
        entry_2.path = "/bar".encode("utf-8")

        blobs_2 = list(
            rdf_timeline.TimelineEntry.SerializeStream(iter([entry_2])))
        (blob_id_2, ) = data_store.BLOBS.WriteBlobsWithUnknownHashes(blobs_2)

        result_2 = rdf_timeline.TimelineResult()
        result_2.entry_batch_blob_ids = [blob_id_2.AsBytes()]

        flow_result_1 = rdf_flow_objects.FlowResult()
        flow_result_1.client_id = client_id
        flow_result_1.flow_id = flow_id
        flow_result_1.payload = result_1

        flow_result_2 = rdf_flow_objects.FlowResult()
        flow_result_2.client_id = client_id
        flow_result_2.flow_id = flow_id
        flow_result_2.payload = result_2

        data_store.REL_DB.WriteFlowResults([flow_result_1, flow_result_2])

        args = api_timeline.ApiGetCollectedTimelineArgs()
        args.client_id = client_id
        args.flow_id = flow_id
        args.format = api_timeline.ApiGetCollectedTimelineArgs.Format.BODY

        result = self.handler.Handle(args)
        content = b"".join(result.GenerateContent()).decode("utf-8")

        self.assertIn("|/foo|", content)
        self.assertIn("|/bar|", content)
Esempio n. 3
0
    def testBodyMultipleEntries(self):
        entries = []

        for idx in range(1024):
            entry = rdf_timeline.TimelineEntry()
            entry.path = "/foo/bar/baz/quux/norf/thud{}".format(idx).encode(
                "utf-8")
            entry.size = random.randint(0, 1024)
            entries.append(entry)

        client_id = db_test_utils.InitializeClient(data_store.REL_DB)
        flow_id = _WriteTimeline(client_id, entries)

        args = api_timeline.ApiGetCollectedTimelineArgs()
        args.client_id = client_id
        args.flow_id = flow_id
        args.format = api_timeline.ApiGetCollectedTimelineArgs.Format.BODY

        result = self.handler.Handle(args)
        content = b"".join(result.GenerateContent()).decode("utf-8")

        rows = list(csv.reader(io.StringIO(content), delimiter="|"))
        self.assertLen(rows, len(entries))

        for idx, row in enumerate(rows):
            self.assertEqual(row[1].encode("utf-8"), entries[idx].path)
            self.assertEqual(int(row[6]), entries[idx].size)
Esempio n. 4
0
    def testRawGzchunkedMulipleEntries(self):
        entries = []

        for idx in range(1024):
            entry = rdf_timeline.TimelineEntry()
            entry.path = "/quux/thud/bar/baz/foo{}".format(idx).encode("utf-8")
            entry.size = random.randint(0, 1024)
            entries.append(entry)

        client_id = db_test_utils.InitializeClient(data_store.REL_DB)
        flow_id = _WriteTimeline(client_id, entries)

        args = api_timeline.ApiGetCollectedTimelineArgs()
        args.client_id = client_id
        args.flow_id = flow_id
        args.format = api_timeline.ApiGetCollectedTimelineArgs.Format.RAW_GZCHUNKED

        content = b"".join(self.handler.Handle(args).GenerateContent())

        buf = io.BytesIO(content)
        chunks = chunked.ReadAll(buf)
        deserialized = list(
            rdf_timeline.TimelineEntry.DeserializeStream(chunks))

        self.assertEqual(entries, deserialized)
Esempio n. 5
0
    def testBodySingleEntry(self):
        entry = rdf_timeline.TimelineEntry()
        entry.path = "/foo/bar/baz".encode("utf-8")
        entry.ino = 4815162342
        entry.size = 42
        entry.atime_ns = 123 * 10**9
        entry.mtime_ns = 456 * 10**9
        entry.ctime_ns = 789 * 10**9

        client_id = db_test_utils.InitializeClient(data_store.REL_DB)
        flow_id = _WriteTimeline(client_id, [entry])

        args = api_timeline.ApiGetCollectedTimelineArgs()
        args.client_id = client_id
        args.flow_id = flow_id
        args.format = api_timeline.ApiGetCollectedTimelineArgs.Format.BODY

        result = self.handler.Handle(args)
        content = b"".join(result.GenerateContent()).decode("utf-8")

        rows = list(csv.reader(io.StringIO(content), delimiter="|"))
        self.assertLen(rows, 1)
        self.assertEqual(rows[0][1], "/foo/bar/baz")
        self.assertEqual(rows[0][2], "4815162342")
        self.assertEqual(rows[0][6], "42")
        self.assertEqual(rows[0][7], "123")
        self.assertEqual(rows[0][8], "456")
        self.assertEqual(rows[0][9], "789")
Esempio n. 6
0
    def testGetCollectedTimelineBody(self):
        entry = rdf_timeline.TimelineEntry()
        entry.path = "/foo/bar/baz".encode("utf-8")

        client_id = db_test_utils.InitializeClient(data_store.REL_DB)
        flow_id = timeline_test_lib.WriteTimeline(client_id, [entry])

        data = io.BytesIO()

        flow = self.api.Client(client_id).Flow(flow_id)
        flow.GetCollectedTimelineBody().WriteToStream(data)  # pytype: disable=wrong-arg-types

        content = data.getvalue().decode("utf-8")
        self.assertIn("|/foo/bar/baz|", content)
Esempio n. 7
0
    def testGetCollectedTimelineBodyCarriageReturnEscape(self):
        entry = rdf_timeline.TimelineEntry()
        entry.path = "/foo\rbar/baz\r\r\rquux".encode("utf-8")

        client_id = db_test_utils.InitializeClient(data_store.REL_DB)
        flow_id = timeline_test_lib.WriteTimeline(client_id, [entry])

        flow = self.api.Client(client_id).Flow(flow_id)
        chunks = flow.GetCollectedTimelineBody(carriage_return_escape=True)

        data = io.BytesIO()
        chunks.WriteToStream(data)

        content = data.getvalue().decode("utf-8")
        self.assertIn("|/foo\\rbar/baz\\r\\r\\rquux|", content)
Esempio n. 8
0
    def testGetCollectedTimelineBodyBackslashEscape(self):
        entry = rdf_timeline.TimelineEntry()
        entry.path = "C:\\Windows\\system32\\notepad.exe".encode("utf-8")

        client_id = db_test_utils.InitializeClient(data_store.REL_DB)
        flow_id = timeline_test_lib.WriteTimeline(client_id, [entry])

        data = io.BytesIO()

        flow = self.api.Client(client_id).Flow(flow_id)
        flow.GetCollectedTimelineBody(
            backslash_escape=True).WriteToStream(data)

        content = data.getvalue().decode("utf-8")
        self.assertIn("|C:\\\\Windows\\\\system32\\\\notepad.exe|", content)
Esempio n. 9
0
    def testGetCollectedTimelineBodyNonPrintableEscape(self):
        entry = rdf_timeline.TimelineEntry()
        entry.path = b"/f\x00b\x0ar\x1baz"

        client_id = db_test_utils.InitializeClient(data_store.REL_DB)
        flow_id = timeline_test_lib.WriteTimeline(client_id, [entry])

        flow = self.api.Client(client_id).Flow(flow_id)
        chunks = flow.GetCollectedTimelineBody(non_printable_escape=True)

        data = io.BytesIO()
        chunks.WriteToStream(data)

        content = data.getvalue().decode("utf-8")
        self.assertIn(r"|/f\x00b\x0ar\x1baz|", content)
Esempio n. 10
0
    def testCarriageReturnEscape(self):
        entry = rdf_timeline.TimelineEntry()
        entry.path = "/foo/bar\r\rbaz/quux\rnorf".encode("utf-8")

        client_id = db_test_utils.InitializeClient(data_store.REL_DB)
        flow_id = timeline_test_lib.WriteTimeline(client_id, [entry])

        args = api_timeline.ApiGetCollectedTimelineArgs()
        args.client_id = client_id
        args.flow_id = flow_id
        args.format = api_timeline.ApiGetCollectedTimelineArgs.Format.BODY
        args.body_opts.carriage_return_escape = True

        result = self.handler.Handle(args)
        content = b"".join(result.GenerateContent()).decode("utf-8")

        self.assertIn("|/foo/bar\\r\\rbaz/quux\\rnorf|", content)
Esempio n. 11
0
    def testBackslashEscape(self):
        entry = rdf_timeline.TimelineEntry()
        entry.path = "C:\\Windows\\system32\\notepad.exe".encode("utf-8")

        client_id = db_test_utils.InitializeClient(data_store.REL_DB)
        flow_id = timeline_test_lib.WriteTimeline(client_id, [entry])

        args = api_timeline.ApiGetCollectedTimelineArgs()
        args.client_id = client_id
        args.flow_id = flow_id
        args.format = api_timeline.ApiGetCollectedTimelineArgs.Format.BODY
        args.body_opts.backslash_escape = True

        result = self.handler.Handle(args)
        content = b"".join(result.GenerateContent()).decode("utf-8")

        self.assertIn("|C:\\\\Windows\\\\system32\\\\notepad.exe|", content)
Esempio n. 12
0
    def testNonPrintableEscape(self):
        entry = rdf_timeline.TimelineEntry()
        entry.path = b"/f\x00b\x0ar\x1baz"

        client_id = db_test_utils.InitializeClient(data_store.REL_DB)
        flow_id = timeline_test_lib.WriteTimeline(client_id, [entry])

        args = api_timeline.ApiGetCollectedTimelineArgs()
        args.client_id = client_id
        args.flow_id = flow_id
        args.format = api_timeline.ApiGetCollectedTimelineArgs.Format.BODY
        args.body_opts.non_printable_escape = True

        result = self.handler.Handle(args)
        content = b"".join(result.GenerateContent()).decode("utf-8")

        self.assertIn(r"|/f\x00b\x0ar\x1baz|", content)
Esempio n. 13
0
  def testSingle(self):
    entry = rdf_timeline.TimelineEntry()
    entry.path = "/foo/bar/baz".encode("utf-8")
    entry.mode = 0o100644
    entry.size = 42
    entry.dev = 101
    entry.ino = 404
    entry.uid = 13
    entry.gid = 7
    entry.atime_ns = 123 * 1_000_000_000
    entry.mtime_ns = 456 * 1_000_000_000
    entry.ctime_ns = 789 * 1_000_000_000

    content = b"".join(body.Stream(iter([entry]))).decode("utf-8")
    expected = "0|/foo/bar/baz|404|-rw-r--r--|13|7|42|123|456|789|0\n"

    self.assertEqual(content, expected)
Esempio n. 14
0
  def testMultiple(self):
    entries = []

    for idx in range(100):
      entry = rdf_timeline.TimelineEntry()
      entry.path = "/foo/bar/baz{}".format(idx).encode("utf-8")
      entry.size = idx

      entries.append(entry)

    content = b"".join(body.Stream(iter(entries))).decode("utf-8")
    reader = csv.reader(io.StringIO(content), delimiter="|")

    rows = list(reader)
    self.assertLen(rows, len(entries))

    for idx, row in enumerate(rows):
      self.assertEqual(row[1].encode("utf-8"), entries[idx].path)
      self.assertEqual(int(row[6]), entries[idx].size)
Esempio n. 15
0
    def testNtfsFileReferenceFormatInference(self):
        entry = rdf_timeline.TimelineEntry()
        entry.path = "/foo/bar/baz".encode("utf-8")
        entry.ino = 1688849860339456

        client_id = db_test_utils.InitializeClient(data_store.REL_DB)
        flow_id = "F00BA542"

        flow_obj = rdf_flow_objects.Flow()
        flow_obj.client_id = client_id
        flow_obj.flow_id = flow_id
        flow_obj.flow_class_name = timeline.TimelineFlow.__name__
        flow_obj.create_time = rdfvalue.RDFDatetime.Now()
        data_store.REL_DB.WriteFlowObject(flow_obj)

        blobs = list(rdf_timeline.TimelineEntry.SerializeStream(iter([entry])))
        blob_ids = data_store.BLOBS.WriteBlobsWithUnknownHashes(blobs)

        result = rdf_timeline.TimelineResult()
        result.entry_batch_blob_ids = [
            blob_id.AsBytes() for blob_id in blob_ids
        ]
        result.filesystem_type = "NTFS"

        flow_result = rdf_flow_objects.FlowResult()
        flow_result.client_id = client_id
        flow_result.flow_id = flow_id
        flow_result.payload = result
        data_store.REL_DB.WriteFlowResults([flow_result])

        args = api_timeline.ApiGetCollectedTimelineArgs()
        args.client_id = client_id
        args.flow_id = flow_id
        args.format = api_timeline.ApiGetCollectedTimelineArgs.Format.BODY

        result = self.handler.Handle(args)
        content = b"".join(result.GenerateContent()).decode("utf-8")

        rows = list(csv.reader(io.StringIO(content), delimiter="|"))
        self.assertLen(rows, 1)
        self.assertEqual(rows[0][1], "/foo/bar/baz")
        self.assertEqual(rows[0][2], "75520-6")
Esempio n. 16
0
    def testBodySubsecondPrecision(self):
        entry = rdf_timeline.TimelineEntry()
        entry.path = "/foo/bar/baz".encode("utf-8")
        entry.atime_ns = int(3.14 * 10**9)

        client_id = db_test_utils.InitializeClient(data_store.REL_DB)
        flow_id = timeline_test_lib.WriteTimeline(client_id, [entry])

        args = api_timeline.ApiGetCollectedTimelineArgs()
        args.client_id = client_id
        args.flow_id = flow_id
        args.format = api_timeline.ApiGetCollectedTimelineArgs.Format.BODY
        args.body_opts.timestamp_subsecond_precision = True

        result = self.handler.Handle(args)
        content = b"".join(result.GenerateContent()).decode("utf-8")

        rows = list(csv.reader(io.StringIO(content), delimiter="|"))
        self.assertLen(rows, 1)
        self.assertEqual(rows[0][1], "/foo/bar/baz")
        self.assertEqual(rows[0][7], "3.14")
Esempio n. 17
0
    def testNtfsFileReferenceFormat(self):
        entry = rdf_timeline.TimelineEntry()
        entry.path = "/foo/bar/baz".encode("utf-8")
        entry.ino = 1688849860339456

        client_id = db_test_utils.InitializeClient(data_store.REL_DB)
        flow_id = timeline_test_lib.WriteTimeline(client_id, [entry])

        args = api_timeline.ApiGetCollectedTimelineArgs()
        args.client_id = client_id
        args.flow_id = flow_id
        args.format = api_timeline.ApiGetCollectedTimelineArgs.Format.BODY
        args.body_opts.inode_ntfs_file_reference_format = True

        result = self.handler.Handle(args)
        content = b"".join(result.GenerateContent()).decode("utf-8")

        rows = list(csv.reader(io.StringIO(content), delimiter="|"))
        self.assertLen(rows, 1)
        self.assertEqual(rows[0][1], "/foo/bar/baz")
        self.assertEqual(rows[0][2], "75520-6")
Esempio n. 18
0
    def testBodySubsecondPrecision(self):
        client_id = db_test_utils.InitializeClient(data_store.REL_DB)
        hunt_id = "ABCDEABCDE"

        snapshot = rdf_objects.ClientSnapshot()
        snapshot.client_id = client_id
        snapshot.knowledge_base.fqdn = "foo.bar.baz"
        data_store.REL_DB.WriteClientSnapshot(snapshot)

        hunt_obj = rdf_hunt_objects.Hunt()
        hunt_obj.hunt_id = hunt_id
        hunt_obj.args.standard.client_ids = [client_id]
        hunt_obj.args.standard.flow_name = timeline.TimelineFlow.__name__
        hunt_obj.hunt_state = rdf_hunt_objects.Hunt.HuntState.PAUSED
        data_store.REL_DB.WriteHuntObject(hunt_obj)

        entry = rdf_timeline.TimelineEntry()
        entry.path = "/foo/bar/baz".encode("utf-8")
        entry.btime_ns = int(1337.42 * 10**9)

        timeline_test_lib.WriteTimeline(client_id, [entry], hunt_id=hunt_id)

        args = api_timeline.ApiGetCollectedHuntTimelinesArgs()
        args.hunt_id = hunt_id
        args.format = api_timeline.ApiGetCollectedTimelineArgs.Format.BODY
        args.body_opts.timestamp_subsecond_precision = True

        content = b"".join(self.handler.Handle(args).GenerateContent())
        buffer = io.BytesIO(content)

        with zipfile.ZipFile(buffer, mode="r") as archive:
            with archive.open(f"{client_id}_foo.bar.baz.body",
                              mode="r") as file:
                content_file = file.read().decode("utf-8")
                rows = list(
                    csv.reader(io.StringIO(content_file), delimiter="|"))

        self.assertLen(rows, 1)
        self.assertEqual(rows[0][1], "/foo/bar/baz")
        self.assertEqual(rows[0][10], "1337.42")
Esempio n. 19
0
    def testBodyMultipleClients(self):
        client_id_1 = db_test_utils.InitializeClient(data_store.REL_DB)
        client_id_2 = db_test_utils.InitializeClient(data_store.REL_DB)

        snapshot = rdf_objects.ClientSnapshot()
        snapshot.client_id = client_id_1
        snapshot.knowledge_base.fqdn = "bar.quux.com"
        data_store.REL_DB.WriteClientSnapshot(snapshot)

        snapshot = rdf_objects.ClientSnapshot()
        snapshot.client_id = client_id_2
        snapshot.knowledge_base.fqdn = "bar.quuz.com"
        data_store.REL_DB.WriteClientSnapshot(snapshot)

        hunt_id = "B1C2E3D4F5"

        hunt_obj = rdf_hunt_objects.Hunt()
        hunt_obj.hunt_id = hunt_id
        hunt_obj.args.standard.client_ids = [client_id_1, client_id_2]
        hunt_obj.args.standard.flow_name = timeline.TimelineFlow.__name__
        hunt_obj.hunt_state = rdf_hunt_objects.Hunt.HuntState.PAUSED

        data_store.REL_DB.WriteHuntObject(hunt_obj)

        entry_1 = rdf_timeline.TimelineEntry()
        entry_1.path = "/bar/baz/quux".encode("utf-8")
        entry_1.ino = 5926273453
        entry_1.size = 13373
        entry_1.atime_ns = 111 * 10**9
        entry_1.mtime_ns = 222 * 10**9
        entry_1.ctime_ns = 333 * 10**9
        entry_1.mode = 0o664

        entry_2 = rdf_timeline.TimelineEntry()
        entry_2.path = "/bar/baz/quuz".encode("utf-8")
        entry_2.ino = 6037384564
        entry_2.size = 13374
        entry_2.atime_ns = 777 * 10**9
        entry_2.mtime_ns = 888 * 10**9
        entry_2.ctime_ns = 999 * 10**9
        entry_2.mode = 0o777

        _WriteTimeline(client_id_1, [entry_1], hunt_id=hunt_id)
        _WriteTimeline(client_id_2, [entry_2], hunt_id=hunt_id)

        args = api_timeline.ApiGetCollectedHuntTimelinesArgs()
        args.hunt_id = hunt_id
        args.format = api_timeline.ApiGetCollectedTimelineArgs.Format.BODY

        content = b"".join(self.handler.Handle(args).GenerateContent())
        buffer = io.BytesIO(content)

        with zipfile.ZipFile(buffer, mode="r") as archive:
            client_filename_1 = f"{client_id_1}_bar.quux.com.body"
            with archive.open(client_filename_1, mode="r") as file:
                content_file = file.read().decode("utf-8")

                rows = list(
                    csv.reader(io.StringIO(content_file), delimiter="|"))
                self.assertLen(rows, 1)
                self.assertEqual(rows[0][1], "/bar/baz/quux")
                self.assertEqual(rows[0][2], "5926273453")
                self.assertEqual(rows[0][3], stat.filemode(0o664))
                self.assertEqual(rows[0][6], "13373")
                self.assertEqual(rows[0][7], "111")
                self.assertEqual(rows[0][8], "222")
                self.assertEqual(rows[0][9], "333")

            client_filename_2 = f"{client_id_2}_bar.quuz.com.body"
            with archive.open(client_filename_2, mode="r") as file:
                content_file = file.read().decode("utf-8")

                rows = list(
                    csv.reader(io.StringIO(content_file), delimiter="|"))
                self.assertLen(rows, 1)
                self.assertEqual(rows[0][1], "/bar/baz/quuz")
                self.assertEqual(rows[0][2], "6037384564")
                self.assertEqual(rows[0][3], stat.filemode(0o777))
                self.assertEqual(rows[0][6], "13374")
                self.assertEqual(rows[0][7], "777")
                self.assertEqual(rows[0][8], "888")
                self.assertEqual(rows[0][9], "999")
Esempio n. 20
0
 def RandomEntry() -> rdf_timeline.TimelineEntry:
   entry = rdf_timeline.TimelineEntry()
   entry.path = os.urandom(4096)
   entry.mode = random.randint(0x0000, 0xFFFF - 1)
   entry.size = random.randint(0, 1e9)
   return entry