예제 #1
0
    def Start(self):
        """The start method."""
        binary_urn = rdfvalue.RDFURN(self.args.binary)
        try:
            blob_iterator, _ = signed_binary_utils.FetchBlobsForSignedBinary(
                binary_urn, token=self.token)
        except signed_binary_utils.SignedBinaryNotFoundError:
            raise flow.FlowError("Executable binary %s not found." %
                                 self.args.binary)

        try:
            current_blob = next(blob_iterator)
        except StopIteration:
            current_blob = None

        offset = 0
        write_path = "%d" % time.time()
        while current_blob is not None:
            try:
                next_blob = next(blob_iterator)
            except StopIteration:
                next_blob = None
            self.CallClient(server_stubs.ExecuteBinaryCommand,
                            executable=current_blob,
                            more_data=next_blob is not None,
                            args=shlex.split(self.args.command_line),
                            offset=offset,
                            write_path=write_path,
                            next_state="End")

            offset += len(current_blob.data)
            current_blob = next_blob
예제 #2
0
파일: config.py 프로젝트: x35029/grr
def _GetSignedBinaryMetadata(binary_type, relative_path):
    """Fetches metadata for the given binary from the datastore.

  Args:
    binary_type: ApiGrrBinary.Type of the binary.
    relative_path: Relative path of the binary, relative to the canonical URN
      roots for signed binaries (see _GetSignedBlobsRoots()).

  Returns:
    An ApiGrrBinary RDFProtoStruct containing metadata for the binary.
  """
    root_urn = _GetSignedBlobsRoots()[binary_type]
    binary_urn = root_urn.Add(relative_path)
    blob_iterator, timestamp = signed_binary_utils.FetchBlobsForSignedBinary(
        binary_urn)
    binary_size = 0
    has_valid_signature = True
    for blob in blob_iterator:
        binary_size += len(blob.data)
        if not has_valid_signature:
            # No need to check the signature if a previous blob had an invalid
            # signature.
            continue
        try:
            blob.Verify(config.CONFIG["Client.executable_signing_public_key"])
        except rdf_crypto.Error:
            has_valid_signature = False

    return ApiGrrBinary(path=relative_path,
                        type=binary_type,
                        size=binary_size,
                        timestamp=timestamp,
                        has_valid_signature=has_valid_signature)
예제 #3
0
 def _BlobIterator(self, binary_urn):
     try:
         blob_iterator, _ = signed_binary_utils.FetchBlobsForSignedBinary(
             binary_urn)
     except signed_binary_utils.SignedBinaryNotFoundError:
         raise flow_base.FlowError("%s is not a valid signed binary." %
                                   self.args.blob_path)
     return blob_iterator
예제 #4
0
  def _BlobIterator(self, binary_urn):
    try:
      blob_iterator, _ = signed_binary_utils.FetchBlobsForSignedBinary(
          binary_urn, token=self.token)
    except signed_binary_utils.SignedBinaryNotFoundError:
      raise flow.FlowError("Executable binary %s not found." % self.args.binary)

    return blob_iterator
예제 #5
0
 def testMissingSignedBinary(self):
     missing_urn = rdfvalue.RDFURN("aff4:/config/executables/not/exist")
     with self.assertRaises(signed_binary_utils.SignedBinaryNotFoundError):
         signed_binary_utils.DeleteSignedBinary(missing_urn)
     with self.assertRaises(signed_binary_utils.SignedBinaryNotFoundError):
         signed_binary_utils.FetchBlobsForSignedBinary(missing_urn)
     with self.assertRaises(signed_binary_utils.SignedBinaryNotFoundError):
         signed_binary_utils.FetchSizeOfSignedBinary(missing_urn)
예제 #6
0
 def _WriteTestBinaryAndGetBlobIterator(self, binary_data, chunk_size):
     binary_urn = rdfvalue.RDFURN("aff4:/config/executables/foo")
     signed_binary_utils.WriteSignedBinary(binary_urn,
                                           binary_data,
                                           private_key=self._private_key,
                                           public_key=self._public_key,
                                           chunk_size=chunk_size)
     blob_iterator, _ = signed_binary_utils.FetchBlobsForSignedBinary(
         binary_urn)
     return blob_iterator
예제 #7
0
파일: config.py 프로젝트: wxh0000mm/grr
 def Handle(self, args, token=None):
   root_urn = _GetSignedBlobsRoots()[args.type]
   binary_urn = root_urn.Add(args.path)
   binary_size = signed_binary_utils.FetchSizeOfSignedBinary(binary_urn)
   blob_iterator, _ = signed_binary_utils.FetchBlobsForSignedBinary(binary_urn)
   chunk_iterator = signed_binary_utils.StreamSignedBinaryContents(
       blob_iterator, chunk_size=self.CHUNK_SIZE)
   return api_call_handler_base.ApiBinaryStream(
       filename=binary_urn.Basename(),
       content_generator=chunk_iterator,
       content_length=binary_size)
예제 #8
0
 def testWriteSignedBinaryBlobs(self):
     test_urn = rdfvalue.RDFURN("aff4:/config/executables/foo")
     test_blobs = [
         rdf_crypto.SignedBlob().Sign(b"\x00\x11\x22", self._private_key),
         rdf_crypto.SignedBlob().Sign(b"\x33\x44\x55", self._private_key),
         rdf_crypto.SignedBlob().Sign(b"\x66\x77\x88", self._private_key),
         rdf_crypto.SignedBlob().Sign(b"\x99", self._private_key)
     ]
     signed_binary_utils.WriteSignedBinaryBlobs(test_urn, test_blobs)
     blobs_iterator, timestamp = signed_binary_utils.FetchBlobsForSignedBinary(
         test_urn)
     self.assertGreater(timestamp.AsMicrosecondsSinceEpoch(), 0)
     self.assertCountEqual(list(blobs_iterator), test_blobs)
예제 #9
0
    def testExecuteLargeBinaries(self):
        client_mock = action_mocks.ActionMock(standard.ExecuteBinaryCommand)

        code = b"I am a large binary file" * 100
        upload_path = signed_binary_utils.GetAFF4ExecutablesRoot().Add(
            config.CONFIG["Client.platform"]).Add("test.exe")

        maintenance_utils.UploadSignedConfigBlob(code,
                                                 aff4_path=upload_path,
                                                 limit=100,
                                                 token=self.token)

        binary_urn = rdfvalue.RDFURN(upload_path)
        binary_size = signed_binary_utils.FetchSizeOfSignedBinary(
            binary_urn, token=self.token)
        blob_iterator, _ = signed_binary_utils.FetchBlobsForSignedBinary(
            binary_urn, token=self.token)

        # Total size is 2400.
        self.assertEqual(binary_size, 2400)

        # There should be 24 parts to this binary.
        self.assertLen(list(blob_iterator), 24)

        # This flow has an acl, the user needs to be admin.
        acl_test_lib.CreateAdminUser(self.token.username)

        with utils.Stubber(subprocess, "Popen", client_test_lib.Popen):
            flow_test_lib.TestFlowHelper(compatibility.GetName(
                administrative.LaunchBinary),
                                         client_mock,
                                         client_id=self.SetupClient(0),
                                         binary=upload_path,
                                         command_line="--value 356",
                                         token=self.token)

            # Check that the executable file contains the code string.
            self.assertEqual(client_test_lib.Popen.binary, code)

            # At this point, the actual binary should have been cleaned up by the
            # client action so it should not exist.
            self.assertRaises(IOError, open,
                              client_test_lib.Popen.running_args[0])

            # Check the binary was run with the correct command line.
            self.assertEqual(client_test_lib.Popen.running_args[1], "--value")
            self.assertEqual(client_test_lib.Popen.running_args[2], "356")

            # Check the command was in the tmp file.
            self.assertStartsWith(client_test_lib.Popen.running_args[0],
                                  config.CONFIG["Client.tempdir_roots"][0])
예제 #10
0
    def Start(self):
        """The start method."""
        python_hack_urn = signed_binary_utils.GetAFF4PythonHackRoot().Add(
            self.args.hack_name)

        try:
            blob_iterator, _ = signed_binary_utils.FetchBlobsForSignedBinary(
                python_hack_urn)
        except signed_binary_utils.SignedBinaryNotFoundError:
            raise flow_base.FlowError("Python hack %s not found." %
                                      self.args.hack_name)

        # TODO(amoser): This will break if someone wants to execute lots of Python.
        for python_blob in blob_iterator:
            self.CallClient(server_stubs.ExecutePython,
                            python_code=python_blob,
                            py_args=self.args.py_args,
                            next_state="Done")
예제 #11
0
 def testUploadPythonHack(self):
     with utils.TempDirectory() as dir_path:
         python_hack_path = os.path.join(dir_path, "hello_world.py")
         with open(python_hack_path, "wb") as f:
             f.write(b"print('Hello, world!')")
         config_updater_util.UploadSignedBinary(
             python_hack_path,
             rdf_objects.SignedBinaryID.BinaryType.PYTHON_HACK,
             "linux",
             upload_subdirectory="test")
         python_hack_urn = rdfvalue.RDFURN(
             "aff4:/config/python_hacks/linux/test/hello_world.py")
         blob_iterator, _ = signed_binary_utils.FetchBlobsForSignedBinary(
             python_hack_urn)
         uploaded_blobs = list(
             signed_binary_utils.StreamSignedBinaryContents(blob_iterator))
         uploaded_content = b"".join(uploaded_blobs)
         self.assertEqual(uploaded_content, b"print('Hello, world!')")
예제 #12
0
 def testUploadExecutable(self):
     with utils.TempDirectory() as dir_path:
         executable_path = os.path.join(dir_path, "foo.exe")
         with open(executable_path, "wb") as f:
             f.write(b"\xaa\xbb\xcc\xdd")
         config_updater_util.UploadSignedBinary(
             executable_path,
             rdf_objects.SignedBinaryID.BinaryType.EXECUTABLE,
             "windows",
             upload_subdirectory="anti-malware/registry-tools")
         executable_urn = rdfvalue.RDFURN(
             "aff4:/config/executables/windows/anti-malware/registry-tools/"
             "foo.exe")
         blob_iterator, _ = signed_binary_utils.FetchBlobsForSignedBinary(
             executable_urn)
         uploaded_blobs = list(
             signed_binary_utils.StreamSignedBinaryContents(blob_iterator))
         uploaded_content = b"".join(uploaded_blobs)
         self.assertEqual(uploaded_content, b"\xaa\xbb\xcc\xdd")
예제 #13
0
 def testWriteSignedBinary(self):
     binary_data = b"\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99"  # 10 bytes.
     test_urn = rdfvalue.RDFURN("aff4:/config/executables/foo")
     signed_binary_utils.WriteSignedBinary(test_urn,
                                           binary_data,
                                           private_key=self._private_key,
                                           public_key=self._public_key,
                                           chunk_size=3)
     blobs_iterator, timestamp = signed_binary_utils.FetchBlobsForSignedBinary(
         test_urn)
     self.assertGreater(timestamp.AsMicrosecondsSinceEpoch(), 0)
     self.assertIsInstance(blobs_iterator, collections.Iterator)
     # We expect blobs to have at most 3 contiguous bytes of data.
     expected_blobs = [
         rdf_crypto.SignedBlob().Sign(b"\x00\x11\x22", self._private_key),
         rdf_crypto.SignedBlob().Sign(b"\x33\x44\x55", self._private_key),
         rdf_crypto.SignedBlob().Sign(b"\x66\x77\x88", self._private_key),
         rdf_crypto.SignedBlob().Sign(b"\x99", self._private_key)
     ]
     self.assertCountEqual(list(blobs_iterator), expected_blobs)
예제 #14
0
    def testUpdateClient(self):
        client_mock = action_mocks.UpdateAgentClientMock()
        fake_installer = b"FakeGRRDebInstaller" * 20
        upload_path = signed_binary_utils.GetAFF4ExecutablesRoot().Add(
            config.CONFIG["Client.platform"]).Add("test.deb")
        maintenance_utils.UploadSignedConfigBlob(fake_installer,
                                                 aff4_path=upload_path,
                                                 limit=100)

        blob_list, _ = signed_binary_utils.FetchBlobsForSignedBinary(
            upload_path)
        self.assertLen(list(blob_list), 4)

        acl_test_lib.CreateAdminUser(self.token.username)

        flow_test_lib.TestFlowHelper(administrative.UpdateClient.__name__,
                                     client_mock,
                                     client_id=self.SetupClient(0, system=""),
                                     blob_path=upload_path,
                                     token=self.token)
        self.assertEqual(client_mock.GetDownloadedFileContents(),
                         fake_installer)
예제 #15
0
    def Start(self):
        """Start."""
        binary_path = self.args.blob_path
        if not binary_path:
            raise flow.FlowError("Please specify an installer binary.")

        binary_urn = rdfvalue.RDFURN(binary_path)
        try:
            blob_iterator, _ = signed_binary_utils.FetchBlobsForSignedBinary(
                binary_urn, token=self.token)
        except signed_binary_utils.SignedBinaryNotFoundError:
            raise flow.FlowError("%s is not a valid signed binary." %
                                 binary_path)

        offset = 0
        write_path = "%d_%s" % (time.time(), binary_urn.Basename())

        try:
            current_blob = next(blob_iterator)
        except StopIteration:
            current_blob = None

        while current_blob is not None:
            try:
                next_blob = next(blob_iterator)
            except StopIteration:
                next_blob = None
            more_data = next_blob is not None
            self.CallClient(server_stubs.UpdateAgent,
                            executable=current_blob,
                            more_data=more_data,
                            offset=offset,
                            write_path=write_path,
                            next_state=("CheckUpdateAgent"
                                        if more_data else "Interrogate"),
                            use_client_env=False)
            offset += len(current_blob.data)
            current_blob = next_blob