def testExecuteModifiedPython(self): """Test that rejects invalid ExecutePython action.""" utils.TEST_VAL = "original" python_code = "utils.TEST_VAL = 'modified'" signed_blob = rdfvalue.SignedBlob() signed_blob.Sign(python_code, self.signing_key) # Modify the data so the signature does not match. signed_blob.data = "utils.TEST_VAL = 'notmodified'" request = rdfvalue.ExecutePythonRequest(python_code=signed_blob) # Should raise since the code has been modified. self.assertRaises(rdfvalue.DecodeError, self.RunAction, "ExecutePython", request) # Lets also adjust the hash. signed_blob.digest = hashlib.sha256(signed_blob.data).digest() request = rdfvalue.ExecutePythonRequest(python_code=signed_blob) self.assertRaises(rdfvalue.DecodeError, self.RunAction, "ExecutePython", request) # Make sure the code never ran. self.assertEqual(utils.TEST_VAL, "original")
def testExecutePythonEnvironment(self): """Test the basic ExecutePython action.""" python_code = """ import StringIO import uu def decode(encoded): # Use the import (uu) inside a function. This will fail if the environment # for exec is not set up properly. i = StringIO.StringIO(s) o = StringIO.StringIO() uu.decode(i, o) return o.getvalue() s = "626567696e20363636202d0a2c3226354c3b265c4035565d523b2630410a200a656e640a" s = s.decode("hex") magic_return_str = decode(s) """ signed_blob = rdfvalue.SignedBlob() signed_blob.Sign(python_code, self.signing_key) request = rdfvalue.ExecutePythonRequest(python_code=signed_blob) result = self.RunAction("ExecutePython", request)[0] self.assertTrue(result.time_used > 0) self.assertEqual(result.return_val, "Hello World!")
def testExecuteBrokenPython(self): """Test broken code raises back to the original flow.""" python_code = "raise ValueError" signed_blob = rdfvalue.SignedBlob() signed_blob.Sign(python_code, self.signing_key) request = rdfvalue.ExecutePythonRequest(python_code=signed_blob) self.assertRaises(ValueError, self.RunAction, "ExecutePython", request)
def testReturnVals(self): """Test return values.""" python_code = "magic_return_str = 'return string'" signed_blob = rdfvalue.SignedBlob() signed_blob.Sign(python_code, self.signing_key) request = rdfvalue.ExecutePythonRequest(python_code=signed_blob) result = self.RunAction("ExecutePython", request)[0] self.assertEqual(result.return_val, "return string")
def testWrongKey(self): """Test return values.""" python_code = "print 'test'" # Generate a test valid RSA key that isn't the real one. signing_key = rdfvalue.PEMPrivateKey.GenKey(2048, 65537) signed_blob = rdfvalue.SignedBlob() signed_blob.Sign(python_code, signing_key) request = rdfvalue.ExecutePythonRequest(python_code=signed_blob) self.assertRaises(rdfvalue.DecodeError, self.RunAction, "ExecutePython", request)
def testExecutePython(self): """Test the basic ExecutePython action.""" utils.TEST_VAL = "original" python_code = "utils.TEST_VAL = 'modified'" signed_blob = rdfvalue.SignedBlob() signed_blob.Sign(python_code, self.signing_key) request = rdfvalue.ExecutePythonRequest(python_code=signed_blob) result = self.RunAction("ExecutePython", request)[0] self.assertTrue(result.time_used > 0) self.assertEqual(result.return_val, "") self.assertEqual(utils.TEST_VAL, "modified")
def testArgs(self): """Test passing arguments.""" utils.TEST_VAL = "original" python_code = """ magic_return_str = py_args['test'] utils.TEST_VAL = py_args[43] """ signed_blob = rdfvalue.SignedBlob() signed_blob.Sign(python_code, self.signing_key) pdict = rdfvalue.Dict({"test": "dict_arg", 43: "dict_arg2"}) request = rdfvalue.ExecutePythonRequest(python_code=signed_blob, py_args=pdict) result = self.RunAction("ExecutePython", request)[0] self.assertEqual(result.return_val, "dict_arg") self.assertEqual(utils.TEST_VAL, "dict_arg2")
def testExecuteBinary(self): """Test the basic ExecuteBinaryCommand action.""" signed_blob = rdfvalue.SignedBlob() signed_blob.Sign(open("/bin/ls").read(), self.signing_key) writefile = utils.Join(self.temp_dir, "binexecute", "ablob") os.makedirs(os.path.dirname(writefile)) request = rdfvalue.ExecuteBinaryRequest(executable=signed_blob, args=[__file__], write_path=writefile) result = self.RunAction("ExecuteBinaryCommand", request)[0] self.assertTrue(result.time_used > 0) self.assertTrue(__file__ in result.stdout)
def testStdoutHooking(self): python_code = """ def f(n): print "F called:", n print "Calling f." f(1) print "Done." """ signed_blob = rdfvalue.SignedBlob() signed_blob.Sign(python_code, self.signing_key) request = rdfvalue.ExecutePythonRequest(python_code=signed_blob) result = self.RunAction("ExecutePython", request)[0] self.assertTrue(result.time_used > 0) self.assertEqual(result.return_val, "Calling f.\nF called: 1\nDone.\n")
def UploadSignedConfigBlob(content, aff4_path, client_context=None, limit=None, token=None): """Upload a signed blob into the datastore. Args: content: File content to upload. aff4_path: aff4 path to upload to. client_context: The configuration contexts to use. limit: The maximum size of the chunk to use. token: A security token. Raises: IOError: On failure to write. """ if limit is None: limit = config_lib.CONFIG["Datastore.maximum_blob_size"] # Get the values of these parameters which apply to the client running on the # target platform. if client_context is None: # Default to the windows client. client_context = ["Platform:Windows", "Client"] config_lib.CONFIG.Validate( parameters="PrivateKeys.executable_signing_private_key") sig_key = config_lib.CONFIG.Get( "PrivateKeys.executable_signing_private_key", context=client_context) ver_key = config_lib.CONFIG.Get("Client.executable_signing_public_key", context=client_context) with aff4.FACTORY.Create(aff4_path, "GRRSignedBlob", mode="w", token=token) as fd: for start_of_chunk in xrange(0, len(content), limit): chunk = content[start_of_chunk:start_of_chunk + limit] blob_rdf = rdfvalue.SignedBlob() blob_rdf.Sign(chunk, sig_key, ver_key, prompt=True) fd.Add(blob_rdf) logging.info("Uploaded to %s", fd.urn)
def testProgress(self): python_code = """ def f(): # This should also work inside a function. Progress() f() Progress() print "Done." """ signed_blob = rdfvalue.SignedBlob() signed_blob.Sign(python_code, self.signing_key) request = rdfvalue.ExecutePythonRequest(python_code=signed_blob) result = self.RunAction("ExecutePython", request)[0] self.assertTrue(result.time_used > 0) self.assertEqual(result.return_val, "Done.\n")
def UploadSignedConfigBlob(content, aff4_path, client_context=None, token=None): """Upload a signed blob into the datastore. Args: content: File content to upload. aff4_path: aff4 path to upload to. client_context: The configuration contexts to use. token: A security token. Raises: IOError: On failure to write. """ # Get the values of these parameters which apply to the client running on the # trarget platform. if client_context is None: # Default to the windows client. client_context = ["Platform:Windows", "Client"] config_lib.CONFIG.Validate( parameters="PrivateKeys.executable_signing_private_key") sig_key = config_lib.CONFIG.Get( "PrivateKeys.executable_signing_private_key", context=client_context) ver_key = config_lib.CONFIG.Get("Client.executable_signing_public_key", context=client_context) blob_rdf = rdfvalue.SignedBlob() blob_rdf.Sign(content, sig_key, ver_key, prompt=True) fd = aff4.FACTORY.Create(aff4_path, "GRRSignedBlob", mode="w", token=token) fd.Set(fd.Schema.BINARY(blob_rdf)) fd.Close() logging.info("Uploaded to %s", fd.urn)
def UploadSignedDriverBlob(content, aff4_path=None, client_context=None, install_request=None, token=None): """Upload a signed blob into the datastore. Args: content: Content of the driver file to upload. aff4_path: aff4 path to upload to. If not specified, we use the config to figure out where it goes. client_context: The configuration contexts to use. install_request: A DriverInstallRequest rdfvalue describing the installation parameters for this driver. If None these are read from the config. token: A security token. Returns: String containing path the file was written to. Raises: IOError: On failure to write. """ sig_key = config_lib.CONFIG.Get("PrivateKeys.driver_signing_private_key", context=client_context) ver_key = config_lib.CONFIG.Get("Client.driver_signing_public_key", context=client_context) if aff4_path is None: aff4_paths = config_lib.CONFIG.Get("MemoryDriver.aff4_paths", context=client_context) if not aff4_paths: raise IOError("Could not determine driver location.") if len(aff4_paths) > 1: logging.info("Possible driver locations: %s", aff4_paths) raise IOError("Ambiguous driver location, please specify.") aff4_path = aff4_paths[0] blob_rdf = rdfvalue.SignedBlob() blob_rdf.Sign(content, sig_key, ver_key, prompt=True) with aff4.FACTORY.Create( aff4_path, "GRRMemoryDriver", mode="w", token=token) as fd: fd.Add(blob_rdf) if install_request is None: # Create install_request from the configuration. install_request = rdfvalue.DriverInstallTemplate( device_path=config_lib.CONFIG.Get( "MemoryDriver.device_path", context=client_context), driver_display_name=config_lib.CONFIG.Get( "MemoryDriver.driver_display_name", context=client_context), driver_name=config_lib.CONFIG.Get( "MemoryDriver.driver_service_name", context=client_context)) fd.Set(fd.Schema.INSTALLATION(install_request)) logging.info("Uploaded to %s", fd.urn) return fd.urn