def testWrongOwnerGetsFixed(self): def mystat(filename): stat_info = os.lstat.old_target(filename) stat_list = list(stat_info) # Adjust the UID. stat_list[4] += 1 return posix.stat_result(stat_list) # Place a malicious file in the temp dir. This needs to be deleted # before we can use the temp dir. fd = tempfiles.CreateGRRTempFile(filename="maliciousfile", mode="wb") fd.close() self.assertTrue(os.path.exists(fd.name)) with utils.Stubber(os, "lstat", mystat): fd2 = tempfiles.CreateGRRTempFile(filename="temptemp", mode="wb") fd2.close() # Old file is gone. self.assertFalse(os.path.exists(fd.name)) # Cleanup. tempfiles.DeleteGRRTempFile(fd2.name)
def testCreateAndDelete(self): fd = tempfiles.CreateGRRTempFile(filename="process.42.exe", mode="wb") fd.close() self.assertTrue(os.path.exists(fd.name)) self.assertEqual(os.path.basename(fd.name), "process.42.exe") tempfiles.DeleteGRRTempFile(fd.name) self.assertFalse(os.path.exists(fd.name)) with io.open(os.path.join(self.temp_dir, "notatmpfile"), "wb") as fd: fd.write(b"something") self.assertTrue(os.path.exists(fd.name)) self.assertRaises(tempfiles.ErrorNotTempFile, tempfiles.DeleteGRRTempFile, fd.name) self.assertTrue(os.path.exists(fd.name))
def Run(self, args): # Due to talking raw to hardware, this action has some inevitable risk of # crashing the machine, so we need to flush the transaction log to ensure # we know when this happens. self.SyncTransactionLog() # Temporary extra logging for Ubuntu # TODO(user): Add generic hunt flag to notify syslog before running each # client action. if args.notify_syslog: syslog = logging.getLogger("chipsec_grr") syslog.setLevel(logging.INFO) syslog.addHandler(handlers.SysLogHandler(address="/dev/log")) syslog.info("%s: Runnning DumpFlashImage", config.CONFIG["Client.name"]) self.logs = [] # TODO(hanuszczak): This appears to be something that could be made into # `StringIO` instead of `BytesIO`. self.chipsec_log = io.BytesIO() if args.log_level: logger.logger().UTIL_TRACE = True if args.log_level == 2: logger.logger().VERBOSE = True logger.logger().logfile = self.chipsec_log logger.logger().LOG_TO_FILE = True # Create a temporary file to store the flash image. dest_fd, dest_pathspec = tempfiles.CreateGRRTempFileVFS( suffix=".flash") # Wrap most of Chipsec code to gather its logs in case of failure. try: # Initialise Chipsec (die early if unknown chipset) c = chipset.cs() # Platform = None, Start Driver = False c.init(None, False) s = spi.SPI(c) # Use hal.spi from chipsec to write BIOS to that file. with dest_fd: # Based on Chipsec code, rely on the address of BIOS(=1) region to # determine the size of the flash. _, limit, _ = s.get_SPI_region(1) spi_size = limit + 1 # Read args.chunk_size bytes at a time and heartbeat. bios = [] for i in range(0, spi_size, args.chunk_size): bios.extend(s.read_spi(i, args.chunk_size)) self.Progress() dest_fd.write("".join(bios)) except (chipset.UnknownChipsetError, oshelper.OsHelperError) as err: # If the chipset is not recognised or if the helper threw an error, # report gracefully the error to the flow. if args.log_level: self.LogError(err) tempfiles.DeleteGRRTempFile(dest_pathspec.path) self.SendReply( rdf_chipsec_types.DumpFlashImageResponse(logs=["%s" % err], )) return except Exception as err: # pylint: disable=broad-except # In case an exception is raised, if the verbose mode # is enabled, return the raw logs from Chipsec. if args.log_level: self.LogError(err) tempfiles.DeleteGRRTempFile(dest_pathspec.path) raise if args.log_level: self.logs.extend(self.chipsec_log.getvalue().splitlines()) if args.notify_syslog: syslog.info("%s: DumpFlashImage has completed successfully", config.CONFIG["Client.name"]) self.SendReply( rdf_chipsec_types.DumpFlashImageResponse(path=dest_pathspec, logs=self.logs))
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)