A Clueless Agent Generator for Python 3.2

/ Published in: Python
Save to your folder(s)

This is an implementation of a clueless agent generator which creates self-decrypting clueless agents as described in "Environmental Key Generation towards Clueless Agents" by J. Riordan and B. Schneier.

It requires Python 3.2 and PyCrypto of a recent build (tested with 2.4 and higher).

To use, pass a python file (or other file) to be encrypted, followed by a series of "observations" on the command line. These observations are hashed to yield the encryption key. A signature is generated by hashing the key, and this signature will be expected to be present in the target environment. Pipe the resulting agent to a file or see the agent code directly on stdout. Additionally, there is an is_debug flag that can be specified (see the source) or tweaked in the resulting agent, to be more verbose.

To attempt decryption/execution of a clueless agent, simply run the generated python script (agent) and pass a set of observations on the command line. If the hash of the hash of the observations match the signature, the hash of the observations will be used as the decryption key. If the signature does not match, the agent will exit with no output.

The code previously directly exec()'d the resulting code, however, it simply outputs to stdout now. The resulting code would otherwise execute directly in-line, at that location in the program, which has many undesirable consequences. Piping it to a file and executing, piping it to a memory-backed temporary file and executing it, or placing the resulting code directly in memory afterward and then executing it, are all ways to run the code contained within. This makes it fundamentally little different from encrypting a file directly, except that the key is environmentally generated, perhaps by a daemon that feeds environmental observations on the command line to the agent.

Note, you can encrypt more than Python scripts, and agents can be made to contain themselves.

$ ./agent_generator.py plaincode.py 0 > cipheragent.py

$ ./agent_generator.py cipheragent.py some more observations > double_agent.py

$ ./double_agent.py wrong observations

--nothing here--

$ ./double_agent.py some more observations > cipheragent_2.py

--cipheragent_2.py now holds the same content as cipheragent.py--

$ ./cipheragent.py 0 > plaincode_2.py

--plaincode_2.py now holds the same content as plaincode.py--

$ ./plaincode_2.py

--should yield the same as--

$ ./plaincode.py

Report this snippet


RSS Icon Subscribe to comments

You need to login to post a comment.