Ejemplo n.º 1
0
    def testYaraProcessScan_MultipleSignatureShards(self):
        action_mock = action_mocks.ActionMock(memory_actions.YaraProcessScan)
        procs = [
            p for p in self.procs
            if p.pid in [101, 102, 103, 104, 105, 106, 107]
        ]
        scan_params = {
            "include_misses_in_results": True,
            "include_errors_in_results": "ALL_ERRORS",
            "max_results_per_process": 0,
            "ignore_grr_process": False,
        }
        with test_lib.FakeTime(
                rdfvalue.RDFDatetime.FromMicrosecondsSinceEpoch(123456789)):
            matches, errors, misses = self._RunYaraProcessScan(
                procs, action_mock=action_mock, **scan_params)

        # Verify scan results.
        self.assertLen(matches, 2)
        self.assertLen(errors, 2)
        self.assertLen(misses, 2)
        self.assertEqual(matches[0].match[0].rule_name, "test_rule")
        self.assertEqual(matches[0].match[0].string_matches[0].data, b"1234")

        flow = data_store.REL_DB.ReadAllFlowObjects(
            self.client_id, include_child_flows=False)[0]
        # We expect to have sent 4 YaraProcessScanRequests to the client.
        self.assertEqual(flow.next_outbound_id, 5)
        scan_requests = action_mock.recorded_args["YaraProcessScan"]
        signature_bytes = _TEST_YARA_SIGNATURE.encode("utf-8")
        expected_requests = [
            rdf_memory.YaraProcessScanRequest(
                signature_shard=rdf_memory.YaraSignatureShard(
                    index=0, payload=signature_bytes[0:30]),
                num_signature_shards=4,
                **scan_params),
            rdf_memory.YaraProcessScanRequest(
                signature_shard=rdf_memory.YaraSignatureShard(
                    index=1, payload=signature_bytes[30:60]),
                num_signature_shards=4,
                **scan_params),
            rdf_memory.YaraProcessScanRequest(
                signature_shard=rdf_memory.YaraSignatureShard(
                    index=2, payload=signature_bytes[60:90]),
                num_signature_shards=4,
                **scan_params),
            rdf_memory.YaraProcessScanRequest(
                signature_shard=rdf_memory.YaraSignatureShard(
                    index=3, payload=signature_bytes[90:]),
                num_signature_shards=4,
                **scan_params),
        ]
        self.assertCountEqual(scan_requests, expected_requests)
Ejemplo n.º 2
0
    def testSignatureShards(self):
        requests = [
            rdf_memory.YaraProcessScanRequest(
                signature_shard=rdf_memory.YaraSignatureShard(index=0,
                                                              payload=b"123"),
                num_signature_shards=3),
            rdf_memory.YaraProcessScanRequest(
                signature_shard=rdf_memory.YaraSignatureShard(index=1,
                                                              payload=b"456"),
                num_signature_shards=3),
            rdf_memory.YaraProcessScanRequest(
                signature_shard=rdf_memory.YaraSignatureShard(index=2,
                                                              payload=b"789"),
                num_signature_shards=3),
        ]
        flow_id = "01234567"
        signature_dir = os.path.join(self.temp_dir, "GRRTest",
                                     "Sig_%s" % flow_id)
        session_id = "C.0123456789abcdef/%s" % flow_id

        results = self.ExecuteAction(memory.YaraProcessScan,
                                     arg=requests[2],
                                     session_id=session_id)
        self.assertLen(results, 1)
        self.assertIsInstance(results[0], rdf_flows.GrrStatus)
        self.assertTrue(os.path.isdir(signature_dir))
        self.assertCountEqual(os.listdir(signature_dir), ["shard_02_of_03"])
        with open(os.path.join(signature_dir, "shard_02_of_03"), "rb") as f:
            self.assertEqual(f.read(), b"789")

        results = self.ExecuteAction(memory.YaraProcessScan,
                                     arg=requests[0],
                                     session_id=session_id)
        self.assertLen(results, 1)
        self.assertIsInstance(results[0], rdf_flows.GrrStatus)
        self.assertCountEqual(os.listdir(signature_dir),
                              ["shard_00_of_03", "shard_02_of_03"])
        with open(os.path.join(signature_dir, "shard_00_of_03"), "rb") as f:
            self.assertEqual(f.read(), b"123")

        results = self.ExecuteAction(memory.YaraProcessScan,
                                     arg=requests[1],
                                     session_id=session_id)
        # We expect at least one YaraProcessScanResponse and a final GrrStatus.
        self.assertGreater(len(results), 1)
        self.assertIsInstance(results[0], rdf_memory.YaraProcessScanResponse)
        self.assertIsInstance(results[-1], rdf_flows.GrrStatus)
        # The Yara signature provided is invalid, so we expect errors.
        self.assertNotEmpty(results[0].errors)
        # Make sure the temporary directory gets deleted when all shards have
        # been received.
        self.assertFalse(os.path.exists(signature_dir))
Ejemplo n.º 3
0
    def testYaraSignatureReferenceDeliversFullSignatureToClient(self):
        signature = "rule foo { condition: true };"

        blob = signature.encode("utf-8")
        blob_id = data_store.BLOBS.WriteBlobWithUnknownHash(blob)

        data_store.REL_DB.WriteGRRUser(username="******")
        data_store.REL_DB.WriteYaraSignatureReference(blob_id,
                                                      username="******")

        args = rdf_memory.YaraProcessScanRequest()
        args.yara_signature_blob_id = blob_id.AsBytes()

        shards = []

        class FakeYaraProcessScan(action_mocks.ActionMock):
            def YaraProcessScan(
                self,
                args: rdf_memory.YaraProcessScanRequest,
            ) -> Iterable[rdf_memory.YaraProcessScanResponse]:
                shards.append(args.signature_shard)
                return []

        self._YaraProcessScan(args, action_mock=FakeYaraProcessScan())

        payloads = [_.payload for _ in sorted(shards, key=lambda _: _.index)]
        self.assertEqual(b"".join(payloads).decode("utf-8"), signature)
Ejemplo n.º 4
0
  def testYaraSignatureReferenceIncorrect(self):
    data = "This is very confidential and should not leak to the client."
    blob_id = data_store.BLOBS.WriteBlobWithUnknownHash(data.encode("utf-8"))

    args = rdf_memory.YaraProcessScanRequest()
    args.yara_signature_blob_id = blob_id.AsBytes()

    with self.assertRaisesRegex(RuntimeError, "signature reference"):
      self._YaraProcessScan(args)
Ejemplo n.º 5
0
  def testCmdlineRegex(self):
    scan_request = rdf_memory.YaraProcessScanRequest(
        signature_shard=rdf_memory.YaraSignatureShard(index=0, payload=b"123"),
        num_signature_shards=1,
        cmdline_regex="svchost.exe -k def")

    with mock.patch.object(
        memory.YaraProcessScan,
        "_GetMatches",
        return_value=[rdf_memory.YaraMatch()]):
      results = self.ExecuteAction(memory.YaraProcessScan, arg=scan_request)
    self.assertLen(results, 2)
    self.assertLen(results[0].matches, 1)
    self.assertEqual(results[0].matches[0].process.pid, 1)
Ejemplo n.º 6
0
  def testYaraSignatureAndSignatureReference(self):
    signature = "rule foo { condition: true };"

    blob = signature.encode("utf-8")
    blob_id = data_store.BLOBS.WriteBlobWithUnknownHash(blob)

    data_store.REL_DB.WriteGRRUser(username="******")
    data_store.REL_DB.WriteYaraSignatureReference(blob_id, username="******")

    args = rdf_memory.YaraProcessScanRequest()
    args.yara_signature = signature
    args.yara_signature_blob_id = blob_id.AsBytes()

    with self.assertRaisesRegex(RuntimeError, "can't be used together"):
      self._YaraProcessScan(args)
Ejemplo n.º 7
0
  def testSignatureShards_Single(self):
    flow_id = "01234567"
    signature_dir = os.path.join(self.temp_dir, "GRRTest", "Sig_%s" % flow_id)
    session_id = "C.0123456789abcdef/%s" % flow_id
    scan_request = rdf_memory.YaraProcessScanRequest(
        signature_shard=rdf_memory.YaraSignatureShard(index=0, payload=b"123"),
        num_signature_shards=1)

    results = self.ExecuteAction(
        memory.YaraProcessScan, arg=scan_request, session_id=session_id)
    # We expect at least one YaraProcessScanResponse and a final GrrStatus.
    self.assertGreater(len(results), 1)
    self.assertIsInstance(results[0], rdf_memory.YaraProcessScanResponse)
    self.assertIsInstance(results[-1], rdf_flows.GrrStatus)
    # The temporary directory should not get created if there is only one
    # shard.
    self.assertFalse(os.path.exists(signature_dir))
Ejemplo n.º 8
0
    def testYaraSignatureReferenceNotExisting(self):
        args = rdf_memory.YaraProcessScanRequest()
        args.yara_signature_blob_id = os.urandom(32)

        with self.assertRaisesRegex(RuntimeError, "signature reference"):
            self._YaraProcessScan(args)