def testExecuteModifiedPython(self): """Test that rejects invalid ExecutePython action.""" utils.TEST_VAL = "original" python_code = "utils.TEST_VAL = 'modified'" signed_blob = rdf_crypto.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 = rdf_client.ExecutePythonRequest(python_code=signed_blob) # Should raise since the code has been modified. self.assertRaises(rdf_crypto.VerificationError, self.RunAction, standard.ExecutePython, request) # Lets also adjust the hash. signed_blob.digest = hashlib.sha256(signed_blob.data).digest() request = rdf_client.ExecutePythonRequest(python_code=signed_blob) self.assertRaises(rdf_crypto.VerificationError, self.RunAction, standard.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 = rdf_crypto.SignedBlob() signed_blob.Sign(python_code, self.signing_key) request = rdf_client.ExecutePythonRequest(python_code=signed_blob) result = self.RunAction(standard.ExecutePython, request)[0] self.assertTrue(result.time_used > 0) self.assertEqual(result.return_val, "Hello World!")
def testReturnVals(self): """Test return values.""" python_code = "magic_return_str = 'return string'" signed_blob = rdf_crypto.SignedBlob() signed_blob.Sign(python_code, self.signing_key) request = rdf_client.ExecutePythonRequest(python_code=signed_blob) result = self.RunAction(standard.ExecutePython, request)[0] self.assertEqual(result.return_val, "return string")
def testExecuteBrokenPython(self): """Test broken code raises back to the original flow.""" python_code = "raise ValueError" signed_blob = rdf_crypto.SignedBlob() signed_blob.Sign(python_code, self.signing_key) request = rdf_client.ExecutePythonRequest(python_code=signed_blob) self.assertRaises(ValueError, self.RunAction, standard.ExecutePython, request)
def testWrongKey(self): """Test return values.""" python_code = "print 'test'" # Generate a test valid RSA key that isn't the real one. signing_key = rdf_crypto.RSAPrivateKey.GenerateKey(2048, 65537) signed_blob = rdf_crypto.SignedBlob() signed_blob.Sign(python_code, signing_key) request = rdf_client.ExecutePythonRequest(python_code=signed_blob) self.assertRaises(rdf_crypto.VerificationError, self.RunAction, standard.ExecutePython, request)
def testExecutePython(self): """Test the basic ExecutePython action.""" utils.TEST_VAL = "original" python_code = "utils.TEST_VAL = 'modified'" signed_blob = rdf_crypto.SignedBlob() signed_blob.Sign(python_code, self.signing_key) request = rdf_client.ExecutePythonRequest(python_code=signed_blob) result = self.RunAction(standard.ExecutePython, request)[0] self.assertTrue(result.time_used > 0) self.assertEqual(result.return_val, "") self.assertEqual(utils.TEST_VAL, "modified")
def testExecuteBinary(self): """Test the basic ExecuteBinaryCommand action.""" signed_blob = rdf_crypto.SignedBlob() signed_blob.Sign(open("/bin/ls", "rb").read(), self.signing_key) request = rdf_client.ExecuteBinaryRequest(executable=signed_blob, args=[__file__], write_path="ablob") result = self.RunAction(standard.ExecuteBinaryCommand, request)[0] self.assertTrue(result.time_used > 0) self.assertTrue(__file__ in result.stdout)
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 = rdf_crypto.SignedBlob() signed_blob.Sign(python_code, self.signing_key) pdict = rdf_protodict.Dict({"test": "dict_arg", 43: "dict_arg2"}) request = rdf_client.ExecutePythonRequest(python_code=signed_blob, py_args=pdict) result = self.RunAction(standard.ExecutePython, request)[0] self.assertEqual(result.return_val, "dict_arg") self.assertEqual(utils.TEST_VAL, "dict_arg2")
def testStdoutHooking(self): python_code = """ def f(n): print("F called:", n) print("Calling f.") f(1) print("Done.") """ signed_blob = rdf_crypto.SignedBlob() signed_blob.Sign(python_code, self.signing_key) request = rdf_client.ExecutePythonRequest(python_code=signed_blob) result = self.RunAction(standard.ExecutePython, request)[0] self.assertTrue(result.time_used > 0) self.assertEqual(result.return_val, "Calling f.\nF called: 1\nDone.\n")
def testProgress(self): python_code = """ def f(): # This should also work inside a function. Progress() f() Progress() print("Done.") """ signed_blob = rdf_crypto.SignedBlob() signed_blob.Sign(python_code, self.signing_key) request = rdf_client.ExecutePythonRequest(python_code=signed_blob) result = self.RunAction(standard.ExecutePython, request)[0] self.assertTrue(result.time_used > 0) self.assertEqual(result.return_val, "Done.\n")
def NewFromContent(cls, content, urn, chunk_size=1024, token=None, private_key=None, public_key=None): """Alternate constructor for GRRSignedBlob. Creates a GRRSignedBlob from a content string by chunking it and signing each chunk. Args: content: The data to stored in the GRRSignedBlob. urn: The AFF4 URN to create. chunk_size: Data will be chunked into this size (each chunk is individually signed. token: The ACL Token. private_key: An rdf_crypto.RSAPrivateKey() instance. public_key: An rdf_crypto.RSAPublicKey() instance. Returns: the URN of the new object written. """ aff4.FACTORY.Delete(urn, token=token) with data_store.DB.GetMutationPool() as pool: with aff4.FACTORY.Create(urn, cls, mode="w", mutation_pool=pool, token=token) as fd: for start_of_chunk in xrange(0, len(content), chunk_size): chunk = content[start_of_chunk:start_of_chunk + chunk_size] blob_rdf = rdf_crypto.SignedBlob() blob_rdf.Sign(chunk, private_key, public_key) fd.Add(blob_rdf, mutation_pool=pool) return urn