def StoreSystemRoot(self, responses): if not responses.success or not responses.First(): if self.state.drive_letters: # We have at least one path that already has a drive letter so we'll log # rather than raise. self.Log("Error collecting SystemRoot artifact: %s", responses.status) else: raise flow.FlowError( "Error collecting SystemRoot artifact: %s" % responses.status) drive = str(responses.First())[0:2] if drive: self.state.drive_letters.add(drive) else: self.Log("Bad result for systemdrive: %s", responses.First()) self.CallStateInline(next_state="CollectVolumeInfo")
def ProcessKnowledgeBase(self, responses): """Collect and store any extra non-kb artifacts.""" if not responses.success: raise flow.FlowError( "Error while collecting the knowledge base: %s" % responses.status) kb = responses.First() # AFF4 client. client = self._OpenClient(mode="rw") client.Set(client.Schema.KNOWLEDGE_BASE, kb) # Copy usernames. usernames = [user.username for user in kb.users if user.username] client.AddAttribute(client.Schema.USERNAMES(" ".join(usernames))) self.CopyOSReleaseFromKnowledgeBase(kb, client) client.Flush() # rdf_objects.ClientSnapshot. # Information already present in the knowledge base takes precedence. if not kb.os: kb.os = self.state.system if not kb.fqdn: kb.fqdn = self.state.fqdn self.state.client.knowledge_base = kb self.CallFlow(collectors.ArtifactCollectorFlow.__name__, artifact_list=config. CONFIG["Artifacts.non_kb_interrogate_artifacts"], next_state="ProcessArtifactResponses") # Update the client index for the AFF4 client. client_index.CreateClientIndex(token=self.token).AddClient(client) if data_store.RelationalDBWriteEnabled(): try: # Update the client index for the rdf_objects.ClientSnapshot. client_index.ClientIndex().AddClient(self.state.client) except db.UnknownClientError: pass
def List(self, responses): """Collect the directory listing and store in the datastore.""" if not responses.success: raise flow.FlowError(str(responses.status)) self.Status("Listed %s", self.state.urn) with data_store.DB.GetMutationPool() as pool: with aff4.FACTORY.Create(self.state.urn, standard.VFSDirectory, mode="w", mutation_pool=pool, token=self.token) as fd: fd.Set(fd.Schema.PATHSPEC(self.state.stat.pathspec)) fd.Set(fd.Schema.STAT(self.state.stat)) for st in responses: st = rdf_client.StatEntry(st) CreateAFF4Object(st, self.client_id, pool, token=self.token) self.SendReply(st) # Send Stats to parent flows.
def CollectImage(self, responses): """Collect the image and store it into the database.""" # If we have any log, forward them. for response in responses: if hasattr(response, "logs"): for log in response.logs: self.Log(log) if not responses.success: raise flow.FlowError("Failed to dump the flash image: {0}".format( responses.status)) elif not responses.First().path: self.Log("No path returned. Skipping host.") self.CallState(next_state="End") else: image_path = responses.First().path self.CallFlow(transfer.MultiGetFile.__name__, pathspecs=[image_path], request_data={"image_path": image_path}, next_state="DeleteTemporaryImage")
def DeleteTemporaryImage(self, responses): """Remove the temporary image from the client.""" if not responses.success: raise flow.FlowError( "Unable to collect the flash image: {0}".format( responses.status)) response = responses.First() self.SendReply(response) # Update the symbolic link to the new instance. with aff4.FACTORY.Create(self.client_id.Add("spiflash"), aff4.AFF4Symlink, token=self.token) as symlink: symlink.Set(symlink.Schema.SYMLINK_TARGET, response.AFF4Path(self.client_id)) # Clean up the temporary image from the client. self.CallClient(server_stubs.DeleteGRRTempFiles, responses.request_data["image_path"], next_state="TemporaryImageRemoved")
def Start(self): """Determine the Firefox history directory.""" self.state.hist_count = 0 self.state.history_paths = [] if self.args.history_path: self.state.history_paths.append(self.args.history_path) else: self.state.history_paths = self.GuessHistoryPaths( self.args.username) if not self.state.history_paths: raise flow.FlowError("Could not find valid History paths.") filename = "places.sqlite" for path in self.state.history_paths: self.CallFlow(file_finder.FileFinder.__name__, paths=[os.path.join(path, "**2", filename)], pathtype=self.args.pathtype, action=rdf_file_finder.FileFinderAction.Download(), next_state="ParseFiles")
def StoreResults(self, responses): if not responses.success: raise flow.FlowError(responses.status) self.state.files_found = len(responses) with data_store.DB.GetMutationPool() as pool: for response in responses: if response.HasField("transferred_file"): self._CreateAff4BlobImage(response, mutation_pool=pool) elif response.HasField("stat_entry"): self._CreateAff4Stat(response, mutation_pool=pool) self.SendReply(response) if stat.S_ISREG(response.stat_entry.st_mode): # Publish the new file event to cause the file to be added to the # filestore. This is not time critical so do it when we have spare # capacity. self.Publish( "FileStore.AddFileToStore", response.stat_entry.pathspec.AFF4Path(self.client_id), priority=rdf_flows.GrrMessage.Priority.LOW_PRIORITY)
def StoreResults(self, responses): if not responses.success: raise flow.FlowError(responses.status) self.state.files_found = len(responses) files_to_publish = [] with data_store.DB.GetMutationPool() as pool: for response in responses: if response.HasField("transferred_file"): self._CreateAff4BlobImage(response, mutation_pool=pool) elif response.HasField("stat_entry"): self._CreateAff4Stat(response, mutation_pool=pool) self.SendReply(response) if stat.S_ISREG(response.stat_entry.st_mode): files_to_publish.append( response.stat_entry.pathspec.AFF4Path(self.client_id)) if files_to_publish: events.Events.PublishMultipleEvents( {"FileStore.AddFileToStore": files_to_publish})
def SendMail(self, responses): """Sends a mail when the client has responded.""" if responses.success: client = aff4.FACTORY.Open(self.client_id, token=self.token) hostname = client.Get(client.Schema.HOSTNAME) subject = self.__class__.subject_template.render(hostname=hostname) body = self.__class__.template.render( client_id=self.client_id, admin_ui=config.CONFIG["AdminUI.url"], hostname=hostname, url="/clients/%s" % self.client_id.Basename(), creator=self.token.username, signature=utils.SmartUnicode(config.CONFIG["Email.signature"])) email_alerts.EMAIL_ALERTER.SendEmail(self.args.email, "grr-noreply", utils.SmartStr(subject), utils.SmartStr(body), is_html=True) else: flow.FlowError("Error while pinging client.")
def SendMessage(self, responses): if not responses.success: self.Log(responses.status.error_message) raise flow.FlowError(responses.status.error_message) self.CallClient(server_stubs.Echo, data="Wake up!", next_state="Sleep")
def CheckUpdateAgent(self, responses): if not responses.success: raise flow.FlowError("Error while calling UpdateAgent: %s" % responses.status)
def Confirmation(self, responses): """Confirmation.""" if not responses.success: raise flow.FlowError("Failed to write config. Err: {0}".format( responses.status))
def Done(self, responses): if not responses.success: self.Log(responses.status.error_message) raise flow.FlowError(responses.status.error_message)
def Done(self, responses): if not responses.success: raise flow.FlowError(str(responses.status)) for response in responses: self.Log(response.data)
def End(self): if self.state.plugin_errors: all_errors = u"\n".join( [unicode(e) for e in self.state.plugin_errors]) raise flow.FlowError("Error running plugins: %s" % all_errors)
def LogDeleteFiles(self, responses): # Check that the DeleteFiles flow worked. if not responses.success: raise flow.FlowError("Could not delete file: %s" % responses.status)
def CheckDumpProcessMemoryResults(self, responses): if not responses.success: raise flow.FlowError(responses.status) for response in responses: self.SendReply(response)
def TemporaryImageRemoved(self, responses): """Verify that the temporary image has been removed successfully.""" if not responses.success: raise flow.FlowError("Unable to delete the temporary flash image: " "{0}".format(responses.status))
def Done(self, responses): if not responses.success: raise flow.FlowError("Registry search failed %s" % responses.status) for response in responses: self.SendReply(response)