def process(self): """Collect the files. Returns: list of tuples containing: str: human-readable description of the source of the collection. For example, the name of the source host. str: path to the collected data. Raises: RuntimeError: if no files specified. """ # TODO(tomchop): Thread this for client in self._clients: file_list = self.files if not file_list: raise RuntimeError( 'File paths must be specified for FileFinder') print('Filefinder to collect {0:d} items'.format(len(file_list))) flow_action = flows_pb2.FileFinderAction( action_type=flows_pb2.FileFinderAction.DOWNLOAD) flow_args = flows_pb2.FileFinderArgs( paths=file_list, action=flow_action, ) flow_id = self._launch_flow(client, 'FileFinder', flow_args) self._await_flow(client, flow_id) self.state.output = [self.output_path]
def fgrep(self, path: Text, literal: bytes) -> Sequence[jobs_pb2.BufferReference]: """Greps for given content on the specified path. Args: path: A path to a file to be searched. literal: A literal expression on search for. Returns: A list of buffer references to the matched content. """ args = flows_pb2.FileFinderArgs() args.paths.append(path) args.pathtype = self._path_type cond = args.conditions.add() cond.condition_type = \ flows_pb2.FileFinderCondition.Type.CONTENTS_LITERAL_MATCH cond.contents_literal_match.mode = \ flows_pb2.FileFinderContentsLiteralMatchCondition.Mode.ALL_HITS cond.contents_literal_match.literal = literal args.action.action_type = flows_pb2.FileFinderAction.Action.STAT try: ff = self._client.CreateFlow(name='FileFinder', args=args) except api_errors.AccessForbiddenError as e: raise errors.ApprovalMissingError(self.id, e) _timeout.await_flow(ff) results = [_first_match(result.payload) for result in ff.ListResults()] return representer.BufferReferenceList(results)
def grep(self, path, pattern): """Greps for given content on the specified path. Args: path: A path to a file to be searched. pattern: A regular expression on search for. Returns: A list of buffer references to the matched content. """ args = flows_pb2.FileFinderArgs() args.paths.append(path) args.pathtype = self._path_type cond = args.conditions.add() cond.condition_type = \ flows_pb2.FileFinderCondition.Type.CONTENTS_REGEX_MATCH cond.contents_regex_match.mode = \ flows_pb2.FileFinderContentsRegexMatchCondition.ALL_HITS cond.contents_regex_match.regex = pattern args.action.action_type = flows_pb2.FileFinderAction.Action.STAT try: ff = self._client.CreateFlow(name='FileFinder', args=args) except api_errors.AccessForbiddenError as e: raise errors.ApprovalMissingError(self.id, e) _timeout.await_flow(ff) return representer.BufferReferenceList( [list(_.payload.matches)[0] for _ in ff.ListResults()])
def _ProcessThread(self, client): """Processes a single client. This function is used as a callback for the processing thread. Args: client (object): GRR client object to act on. """ file_list = self.files if not file_list: return self.logger.info('Filefinder to collect {0:d} items'.format( len(file_list))) flow_action = flows_pb2.FileFinderAction(action_type=self.action) flow_args = flows_pb2.FileFinderArgs( paths=file_list, action=flow_action, ) flow_id = self._LaunchFlow(client, 'FileFinder', flow_args) self._AwaitFlow(client, flow_id) collected_flow_data = self._DownloadFiles(client, flow_id) if collected_flow_data: self.logger.info('{0!s}: Downloaded: {1:s}'.format( flow_id, collected_flow_data)) container = containers.File(name=client.data.os_info.fqdn.lower(), path=collected_flow_data) self.state.StoreContainer(container)
def _ProcessThread(self, client): """Processes a single client. This function is used as a callback for the processing thread. Args: client (object): GRR client object to act on. """ file_list = self.files if not file_list: return print('Filefinder to collect {0:d} items'.format(len(file_list))) flow_action = flows_pb2.FileFinderAction( action_type=flows_pb2.FileFinderAction.DOWNLOAD) flow_args = flows_pb2.FileFinderArgs( paths=file_list, action=flow_action, ) flow_id = self._LaunchFlow(client, 'FileFinder', flow_args) self._AwaitFlow(client, flow_id) collected_flow_data = self._DownloadFiles(client, flow_id) if collected_flow_data: print('{0!s}: Downloaded: {1:s}'.format(flow_id, collected_flow_data)) fqdn = client.data.os_info.fqdn.lower() self.state.output.append((fqdn, collected_flow_data))
def Process(self): """Starts a new File Finder GRR hunt. Raises: RuntimeError: if no items specified for collection. """ print('Hunt to collect {0:d} items'.format(len(self.file_path_list))) print('Files to be collected: {0!s}'.format(self.file_path_list)) hunt_action = grr_flows.FileFinderAction( action_type=grr_flows.FileFinderAction.DOWNLOAD) hunt_args = grr_flows.FileFinderArgs( paths=self.file_path_list, action=hunt_action) self._create_hunt('FileFinder', hunt_args)
def testProcess(self, mock_launch_flow, mock_SearchClients, mock_download_files, _): """Tests that processing launches appropriate flows.""" mock_SearchClients.return_value = mock_grr_hosts.MOCK_CLIENT_LIST mock_download_files.return_value = '/tmp/something' self.grr_file_collector.process() mock_launch_flow.assert_called_with( mock_grr_hosts.MOCK_CLIENT_RECENT, 'FileFinder', flows_pb2.FileFinderArgs( paths=['/etc/passwd'], action=flows_pb2.FileFinderAction( action_type=flows_pb2.FileFinderAction.DOWNLOAD))) self.assertEqual(self.test_state.output[0], ('tomchop', '/tmp/something'))
def process(self): """Construct and start a new File hunt. Returns: The newly created GRR hunt object. Raises: RuntimeError: if no items specified for collection. """ print('Hunt to collect {0:d} items'.format(len(self.file_path_list))) print('Files to be collected: {0:s}'.format(self.file_path_list)) hunt_action = flows_pb2.FileFinderAction( action_type=flows_pb2.FileFinderAction.DOWNLOAD) hunt_args = flows_pb2.FileFinderArgs(paths=self.file_path_list, action=hunt_action) return self._create_hunt('FileFinder', hunt_args)
def testProcess(self, mock_LaunchFlow, mock_DownloadFiles, _): """Tests that processing launches appropriate flows.""" self.mock_grr_api.SearchClients.return_value = \ mock_grr_hosts.MOCK_CLIENT_LIST mock_DownloadFiles.return_value = '/tmp/something' self.grr_file_collector.Process() mock_LaunchFlow.assert_called_with( mock_grr_hosts.MOCK_CLIENT_RECENT, 'FileFinder', flows_pb2.FileFinderArgs( paths=['/etc/passwd'], action=flows_pb2.FileFinderAction( action_type=flows_pb2.FileFinderAction.STAT))) results = self.test_state.GetContainers(containers.File) self.assertEqual(len(results), 1) result = results[0] self.assertEqual(result.name, 'tomchop') self.assertEqual(result.path, '/tmp/something')
def _process_thread(self, client): """Process a single client. Args: client: GRR client object to act on. """ file_list = self.files if not file_list: return print('Filefinder to collect {0:d} items'.format(len(file_list))) flow_action = flows_pb2.FileFinderAction( action_type=flows_pb2.FileFinderAction.DOWNLOAD) flow_args = flows_pb2.FileFinderArgs( paths=file_list, action=flow_action,) flow_id = self._launch_flow(client, 'FileFinder', flow_args) self._await_flow(client, flow_id) collected_flow_data = self._download_files(client, flow_id) if collected_flow_data: print('{0!s}: Downloaded: {1:s}'.format(flow_id, collected_flow_data)) fqdn = client.data.os_info.fqdn.lower() self.state.output.append((fqdn, collected_flow_data))