def _GetVersion(self, args): """Call eficheck to find out its version.""" res = client_utils_common.Execute(args.cmd_path, ["--version"]) stdout, stderr, exit_status, time_used = res # If something went wrong, forward the output directly. if exit_status: binary_response = rdf_client_action.ExecuteBinaryResponse( stdout=stdout, stderr=stderr, exit_status=exit_status, time_used=time_used) self.SendReply(self.out_rdfvalues[0](response=binary_response)) return return stdout
def _InstallDeb(self, path, args): cmd = "/usr/bin/dpkg" cmd_args = ["-i", path] time_limit = args.time_limit client_utils_common.Execute(cmd, cmd_args, time_limit=time_limit, bypass_whitelist=True, daemon=True) # The installer will run in the background and kill the main process # so we just wait. If something goes wrong, the nanny will restart the # service after a short while and the client will come back to life. time.sleep(1000)
def ProcessFile(self, path, args): res = client_utils_common.Execute( path, args.args, args.time_limit, bypass_whitelist=True) (stdout, stderr, status, time_used) = res # Limit output to 10MB so our response doesn't get too big. stdout = stdout[:10 * 1024 * 1024] stderr = stderr[:10 * 1024 * 1024] self.SendReply( rdf_client.ExecuteBinaryResponse( stdout=stdout, stderr=stderr, exit_status=status, # We have to return microseconds. time_used=int(1e6 * time_used)))
def Start(cls, command): cmd = command.cmd args = command.args time_limit = command.time_limit res = client_utils_common.Execute(cmd, args, time_limit) (stdout, stderr, status, time_used) = res # Limit output to 10MB so our response doesn't get too big. stdout = stdout[:10 * 1024 * 1024] stderr = stderr[:10 * 1024 * 1024] yield rdf_client.ExecuteResponse( request=command, stdout=stdout, stderr=stderr, exit_status=status, # We have to return microseconds. time_used=int(1e6 * time_used))
def ProcessFile(self, path, args): cmd = "/usr/sbin/installer" cmd_args = ["-pkg", path, "-target", "/"] time_limit = args.time_limit res = client_utils_common.Execute( cmd, cmd_args, time_limit=time_limit, bypass_whitelist=True) (stdout, stderr, status, time_used) = res # Limit output to 10MB so our response doesn't get too big. stdout = stdout[:10 * 1024 * 1024] stderr = stderr[:10 * 1024 * 1024] self.SendReply( rdf_client_action.ExecuteBinaryResponse( stdout=stdout, stderr=stderr, exit_status=status, # We have to return microseconds. time_used=int(1e6 * time_used)))
def Run(self, args): """Use eficheck to extract the binary image of the flash. Args: args: EficheckConfig Returns: DumpEfiImageResponse This action executes eficheck multiple times: * First to get the binary version, using --version. * Use --save -b firmware.bin to save the image. """ eficheck_version = self._GetVersion(args) if not eficheck_version: return False with tempfiles.TemporaryDirectory(cleanup=False) as tmp_dir: res = client_utils_common.Execute(args.cmd_path, ["--save", "-b", "firmware.bin"], cwd=tmp_dir.path) stdout, stderr, exit_status, time_used = res binary_response = rdf_client_action.ExecuteBinaryResponse( stdout=stdout, stderr=stderr, exit_status=exit_status, time_used=time_used) response = rdf_apple_firmware.DumpEfiImageResponse( eficheck_version=eficheck_version, response=binary_response) if exit_status: tmp_dir.cleanup = True else: response.path = rdf_paths.PathSpec( path=os.path.join(tmp_dir.path, "firmware.bin"), pathtype=rdf_paths.PathSpec.PathType.TMPFILE) self.SendReply(response)
def Run(self, args): """Use eficheck to extract hash files in plaintext. Args: args: EficheckConfig Returns: CollectEfiHashesResponse This action executes eficheck multiple times: * First to get the binary version, using --version. * Then with the --generate-hashes option. This will create one or more .ealf files. Each file contains a binary representation of the hashes extracted from a part of the flash image (e.g, EFI, SEC). * For each file generated, we use the --show-hashes option to get a plaintext representation of the hashes. This raw output is sent to the server which will perform further parsing. """ eficheck_version = self._GetVersion(args) if not eficheck_version: return False with tempfiles.TemporaryDirectory() as tmp_dir: res = client_utils_common.Execute(args.cmd_path, ["--generate-hashes"], cwd=tmp_dir.path) stdout, stderr, exit_status, time_used = res # If something went wrong, forward the output directly. if exit_status: binary_response = rdf_client_action.ExecuteBinaryResponse( stdout=stdout, stderr=stderr, exit_status=exit_status, time_used=time_used) self.SendReply( rdf_apple_firmware.CollectEfiHashesResponse( response=binary_response)) return # Otherwise, convert all the files generated and forward the output. for filename in glob.glob(os.path.join(tmp_dir.path, "*.ealf")): cmd_args = ["--show-hashes", "-h", filename] # Get the boot rom version from the filename. basename = os.path.basename(filename) if not self._FILENAME_RE.match(basename): continue boot_rom_version, _ = os.path.splitext(basename) stdout, stderr, exit_status, time_used = client_utils_common.Execute( args.cmd_path, cmd_args, bypass_allowlist=True) binary_response = rdf_client_action.ExecuteBinaryResponse( stdout=stdout, stderr=stderr, exit_status=exit_status, time_used=time_used) self.SendReply( rdf_apple_firmware.CollectEfiHashesResponse( eficheck_version=eficheck_version, boot_rom_version=boot_rom_version, response=binary_response)) tempfiles.DeleteGRRTempFile(filename)