def testExecuteBinaryWeirdOutput(self): binary_path = signed_binary_utils.GetAFF4ExecutablesRoot().Add( "foo.exe") maintenance_utils.UploadSignedConfigBlob(b"foobarbaz", aff4_path=binary_path) client_id = self.SetupClient(0) def Run(self, args): del args # Unused. stdout = "żółć %s gęślą {} jaźń # ⛷".encode("utf-8") stderr = b"\x00\xff\x00\xff\x00" response = rdf_client_action.ExecuteBinaryResponse(stdout=stdout, stderr=stderr, exit_status=0, time_used=0) self.SendReply(response) with mock.patch.object(standard.ExecuteBinaryCommand, "Run", new=Run): # Should not fail. flow_test_lib.TestFlowHelper(administrative.LaunchBinary.__name__, action_mocks.ActionMock( standard.ExecuteBinaryCommand), binary=binary_path, client_id=client_id, command_line="--bar --baz", token=self.token)
def _GetBinaryRootUrn(binary_type): if binary_type == api_config.ApiGrrBinary.Type.PYTHON_HACK: return signed_binary_utils.GetAFF4PythonHackRoot() elif binary_type == api_config.ApiGrrBinary.Type.EXECUTABLE: return signed_binary_utils.GetAFF4ExecutablesRoot() else: raise ValueError("Invalid binary type: %s" % binary_type)
def _GetSignedBlobsRoots(): return { ApiGrrBinary.Type.PYTHON_HACK: signed_binary_utils.GetAFF4PythonHackRoot(), ApiGrrBinary.Type.EXECUTABLE: signed_binary_utils.GetAFF4ExecutablesRoot() }
def SetUpBinaries(self): with test_lib.FakeTime(42): code = "I am a binary file" upload_path = signed_binary_utils.GetAFF4ExecutablesRoot().Add( "windows/test.exe") maintenance_utils.UploadSignedConfigBlob( code.encode("utf-8"), aff4_path=upload_path) with test_lib.FakeTime(43): code = "I'm a python hack" upload_path = signed_binary_utils.GetAFF4PythonHackRoot().Add("test") maintenance_utils.UploadSignedConfigBlob( code.encode("utf-8"), aff4_path=upload_path)
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])
def testScheduleLaunchBinaryFlow(self): self._SetUpAdminUser() maintenance_utils.UploadSignedConfigBlob( b'foo', aff4_path=signed_binary_utils.GetAFF4ExecutablesRoot().Add( 'windows/a.exe')) maintenance_utils.UploadSignedConfigBlob( b'foo', aff4_path=signed_binary_utils.GetAFF4ExecutablesRoot().Add( 'windows/test.exe')) self.Open(f'/v2/clients/{self.client_id}') self.WaitUntilContains('No access', self.GetText, 'css=client-overview') self.Type('css=flow-form input[name=flowSearchBox]', 'binary', end_with_enter=True) self.Type('css=flow-args-form input[name=binary]', 'test', end_with_enter=True) self.Type('css=flow-args-form input[name=commandLine]', '--foo --bar') self.Click('css=flow-form button:contains("Schedule")') def GetFirstScheduledFlow(): scheduled_flows = _ListScheduledFlows(self.client_id, self.test_username) return scheduled_flows[0] if len(scheduled_flows) == 1 else None scheduled_flow = self.WaitUntil(GetFirstScheduledFlow) self.assertEqual(scheduled_flow.flow_name, administrative.LaunchBinary.__name__) self.assertEqual(scheduled_flow.flow_args.binary, 'aff4:/config/executables/windows/test.exe') self.assertEqual(scheduled_flow.flow_args.command_line, '--foo --bar')
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, token=self.token) 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)
def UploadSignedBinary(source_path, binary_type, platform, upload_subdirectory="", token=None): """Signs a binary and uploads it to the datastore. Args: source_path: Path to the binary to upload. binary_type: Type of the binary, e.g python-hack or executable. platform: Client platform where the binary is intended to be run. upload_subdirectory: Path of a subdirectory to upload the binary to, relative to the canonical path for binaries of the given type and platform. token: ACL token to use for uploading. Raises: BinaryTooLargeError: If the binary to upload is too large. """ if binary_type == rdf_objects.SignedBinaryID.BinaryType.PYTHON_HACK: root_urn = signed_binary_utils.GetAFF4PythonHackRoot() elif binary_type == rdf_objects.SignedBinaryID.BinaryType.EXECUTABLE: root_urn = signed_binary_utils.GetAFF4ExecutablesRoot() else: raise ValueError("Unknown binary type %s." % binary_type) file_size = os.path.getsize(source_path) if file_size > _MAX_SIGNED_BINARY_BYTES: raise BinaryTooLargeError( "File [%s] is of size %d (bytes), which exceeds the allowed maximum " "of %d bytes." % (source_path, file_size, _MAX_SIGNED_BINARY_BYTES)) binary_urn = root_urn.Add(platform.lower()).Add(upload_subdirectory).Add( os.path.basename(source_path)) context = ["Platform:%s" % platform.title(), "Client Context"] with open(source_path, "rb") as f: file_content = f.read() maintenance_utils.UploadSignedConfigBlob(file_content, aff4_path=binary_urn, client_context=context, token=token) print("Uploaded to %s" % binary_urn)
def testExecuteBinariesWithArgs(self): client_mock = action_mocks.ActionMock(standard.ExecuteBinaryCommand) code = b"I am a binary file" upload_path = signed_binary_utils.GetAFF4ExecutablesRoot().Add( config.CONFIG["Client.platform"]).Add("test.exe") maintenance_utils.UploadSignedConfigBlob(code, aff4_path=upload_path, token=self.token) # 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(administrative.LaunchBinary.__name__, 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.assertTrue(client_test_lib.Popen.running_args[0].startswith( config.CONFIG["Client.tempdir_roots"][0]))
def testUpdateClientSingleBlob(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=1000) blob_list, _ = signed_binary_utils.FetchBlobsForSignedBinaryByURN( upload_path) self.assertLen(list(blob_list), 1) acl_test_lib.CreateAdminUser(self.token.username) flow_test_lib.TestFlowHelper( compatibility.GetName(administrative.UpdateClient), client_mock, client_id=self.SetupClient(0, system=""), binary_path=os.path.join(config.CONFIG["Client.platform"], "test.deb"), token=self.token) self.assertEqual(client_mock.GetDownloadedFileContents(), fake_installer)