Execution of signed scripts received by e-mail

-----BEGIN PGP SIGNED MESSAGE----- This is a rough description of a perl script I'm working on to allow the automated execution of PGP signed scripts received by e-mail. I call it emscrypt. Right now it is in the volatile-ware stage. Hopefully I'll have it tested enough to post here shortly, if I feel i can pull myself away from my research for a few hours. But I thought I would post a description now to see if anyone can find any problems with the way I'm going about this or has any suggestions. I apologize for the possibly inscrutable descriptions; it's been a while since I last slept. Let me know if anything needs clarification. First, a basic description of the idea: 1. Write a script (perl, sh, etc.) to be executed on a remote machine. 2. Sign the script with PGP. It can also be encrypted using the public key for the emscrypt installation on the remote machine. 3. Mail the signed/encrypted script (a.k.a. emscrypted mail) to the address where emscrypt is installed. 4. The script is received and piped to emscrypt (using procmail or something similar). 5. Emscrypt checks the PGP signature on the message, and checks for replay attacks based on the time stamp from the signature. 6. Emscrypt executes the script, gets the results, encrypts them, and sends them back to you. The install procedure: Create a directory to hold the PGP keyrings and the emscript temporary files. Generate a secret/public key pair for the emscrypt software and place in the emscrypt directory. These need to be DIFFERENT for each installation of emscrypt. Otherwise you are subject to a "same play" attack. I suppose you could create two or more installations with the same key if you will ALWAYS be sending all the same scripts to every installation. Generate a public keyring in the emscrypt directory which has only the keys with which you want to be able to validate incoming scripts. Make them "trusted" by the emscrypt key. Update the PGPPASS, PGPPATH, and emscryptPath variables in the emscrypt script. This is very important since if the PGPPATH is pointing to your normal pubring ANYONE with a key in that ring would be able to run scripts on your system. Actually only the keys which are "trusted", but there may be lots of "trusted" keys which you wouldn't trust to run arbitrary scripts on your computer. Test the script to make sure it seems to work alright on your system. After that, you can set it up to be automatically called when you receive e-mail with the magic subject line of your choosing (or in some other way I suppose). I've been using something resembling the following procmail recipe: :0: * ^Subject.*SQUEAMISH OSSIFRAGE |/MY_PATH/emscrypt How emscrypt works: * Get input Get one input line at a time, and look for Reply-To: and From: headers to get a reply address. As we are slurping up lines, watch for '-----BEGIN PGP' lines. If it is for encryption or a signed message (i.e. as long as it is not for a key block), get all the lines up to and including the appropriate '-----END PGP' line, and save them to a temp file. Note that several scripts can be batched together in a single input file. Just generate the scripts and sign them separately and the combine all the PGP messages into a single file. Also, they may be signed with different keys. * Verify signature Run PGP on the temp file to verify/decrypt it. Save the stderr results from the PGP process in another temporary file. Get the verified(?)/decrypted output from a pipe, and save in memory. (QUESTION: is it possible to have stderr redirected to a separate input pipe and avoid writing to disk? How? (This is in Perl.) I was combining the the stderr and stdout from the PGP process into a single input pipe, but that may allow for leakage of PGP stderr output into the script we are verifying/decrypting if we aren't careful.) Search through the PGP process stderr output to look for important stuff like whether the signature was good, what the time stamp was, and what the key user string is. I'm not real happy with this method. Probably doesn't work well with versions other than 2.6.2 or non english language versions. I'm waiting for the signature code and such in the PGP library from Systemics (an announcement showed up here a couple days ago, http://www.systemics.com/software/ ) which will allow this to be much cleaner. (QUESTION: Any other ideas for handling this?) * Check for replay If the signature is good then we need to check for the dreaded replay attack. This is how I have it working: there is a separate file for each PGP public key which keeps track of the time stamp for the last executed script which was signed by that key. Right now the file names are generated from the key ID string for the pgp key. Mainly because we get that for free when we check the signature. Will probably run 'pgp -kv "ID string"' so that I can get the hex key ID, since that would probably make a more reasonable file name. Besides the value saved to disk, we store a separate time stamp for this "batch" of messages in an associative array by key ID. Each separate mail message is a batch, but we may have more than a single PGP signed script in each message. So the batch time stamp is the stamp we read from a time stamp file for a key ID when we process the first message in a batch for that specific key ID. The batch time stamp is then constant for the remainder of this run of the script. Anyway, we generate a file name based on the key ID, save it in an associative array by key ID for later use, and see if the file actually exists. If the file doesn't exist, create it and save the time stamp from the current signature to the file. Put a timestamp of 100000000000 in an associative array by key ID for later use (this is the batch time stamp: the time stamp is formatted as YYYYMMDDHHmm. I use 100000000000 here since I explicitly check the time stamp format each time to make sure it is composed of exactly 12 digits. Also, if the file doesn't exist, we need to use a batch time stamp that will be lower than that of any of the messages in the current batch for this key ID. I suppose it might be better to generate a time stamp something like (CURRENT_TIME - (some reasonable amount of time)) to limit what is accepted. I also plan to allow a limit for the amount of time which can elapse between the script being signed and being received by emscrypt for cases where the file does exist. If the file did exist on disk, read the time stamp from the file and save in the batch time stamp associative array by key ID. So now we have a replay prevention time stamp to compare to the time stamp from this PGP signed script. If the script stamp is more recent, then we can execute the script. But first, check to see if the script stamp is more recent then the stamp saved in the file. If it is, then replace the file time stamp with the script stamp, and update the associative array which keeps track of these values (this is the "most recent stamp" array, not the "batch stamp" array). * Execute the script Check the variable status to make sure that both the signature and time stamp were acceptable. If not, then generate an appropriate error message explaining why the script was rejected, include a copy of the script, encrypt the message using the submitter's public key, and mail it back. Then go back to the top of the loop to deal with the rest of the input. If it everything checks out, then prepare a file to receive the stderr output, save the script to a file, set the script to executable, and open (execute) it as an input pipe. Get the results from stdout. Open the stderr file, and get the stderr results. Combine the stdout, stderr, and the script (with separators so we can tell what is what), encrypt the whole bundle with the submitter's public key and mail it off. Repeat loop for rest of input. Problems? Suggestions? Let me know. Thanks, - --Matt - -- mcarpent@mailhost.tcs.tulane.edu Finger for PGP public key. -----BEGIN PGP SIGNATURE----- Version: 2.6.2 iQEVAwUBMedc/SjtJAMyBnp9AQF83wf+J9P1Lmr8sca12R89LUYcFxRms1gJro/9 E5Ni1kqivWKYJ+JP9geP+k7VLWbq5miby8RMfKemuz77BuK9UIQG1pd6bGNjlSg9 O+XkiB5dbHX6+hZ23wPABzeuu6+3klLfNnzQEuNZ4/jxeNwFIIY3ifYglhWIPoeG a3kpd2DXY1HVjO674TQNGBYn6bnDPi5wMzYSTxJLukKHBzlgaLt4nssv/8N2jhcg XHWqEEvHc2lY0UvBk+wuqJHigzI03NzpFkh7mgF6ll5gEuG0qGgvLIKb+ir4vF1Q k46mNHq03M+Vc5/loLjFfQzcuu24GdjlFY2pHEpHz7rhYG25ONJeDg== =Lm22 -----END PGP SIGNATURE-----

Matt> Get one input line at a time, and look for Reply-To: and Matt> From: headers to get a reply address. As we are slurping up Matt> lines, watch for '-----BEGIN PGP' lines. If it is for I suggest ignoring Reply-To: etc and requiring a return address inside the signed region of the mail, otherwise someone could intercept the mail (suppressing the original) and resend it from his account and the results would get sent to the interceptor. Another idea would be to extract the return address from the PGP userid which signed the script. Regards Steffen -- work: Steffen.Zahn%robinie@emndev.siemens.co.at | home: zahn@berlin.snafu.de phone:+49-30-38624969 | phone:+49-30-4732126 Any opinions expressed herein are not necessarily those of my employer. Use of my addresses for unsolicited commercial advertising is forbidden.

On Sat, 13 Jul 1996, Steffen Zahn wrote:
I suggest ignoring Reply-To: etc and requiring a return address inside the signed region of the mail, otherwise someone could intercept the mail (suppressing the original) and resend it from his account and the results would get sent to the interceptor.
I agree. Having a return address outside the signature allows for denial-of- service attacks and it would be trivial to intercept the output of the script. Definitely not a Good Thing.
Another idea would be to extract the return address from the PGP userid which signed the script.
There are a couple of problems with this idea: - The security of this scheme depends on trusting the user to sign her key. If the user doesn't, than an attacker can intercept the user's key and alter the key ID. - Even if the user does sign her key, there is still the problem of an attacker being able to generate a key with an identical key ID and and a different user ID. If the attacker has the ability to intercept and modify messages, a MITM attack would be very effective. If the key's fingerprint was included in the signed message, an MITM attack would be necessary to subvert the system. If the key's fingerprint is included in the message, then it certainly wouldn't take much more effort to put a return address in the signed body of the message. -- Mark =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= markm@voicenet.com | finger -l for PGP key 0xe3bf2169 http://www.voicenet.com/~markm/ | d61734f2800486ae6f79bfeb70f95348 "Freedom is the freedom to say that two plus two make four. If that is granted, all else follows." --George Orwell, _1984_

-----BEGIN PGP SIGNED MESSAGE----- Mark M. <markm@voicenet.com> writes:
On Sat, 13 Jul 1996, Steffen Zahn wrote:
I suggest ignoring Reply-To: etc and requiring a return address inside the signed region of the mail, otherwise someone could intercept the mail (suppressing the original) and resend it from his account and the results would get sent to the interceptor.
I agree. Having a return address outside the signature allows for denial-o= f- service attacks and it would be trivial to intercept the output of the scri= pt. Definitely not a Good Thing.
Another idea would be to extract the return address from the PGP userid which signed the script.
There are a couple of problems with this idea:
- The security of this scheme depends on trusting the user to sign her key. If the user doesn't, than an attacker can intercept the user's key and alter the key ID.
- Even if the user does sign her key, there is still the problem of an attacker being able to generate a key with an identical key ID and and a different user ID. If the attacker has the ability to intercept and modify messages, a MITM attack would be very effective. If the key's fingerprint was included in the signed message, an MITM attack would be necessary to subvert the system.
If the key's fingerprint is included in the message, then it certainly woul= dn't take much more effort to put a return address in the signed body of the message.
Those are both very good ideas. I'll have it require both the return address and key fingerprint in the signed portion of the message.
-- Mark
Thanks for the suggestions. - --Matt - -- mcarpent@mailhost.tcs.tulane.edu -----BEGIN PGP SIGNATURE----- Version: 2.6.2 iQEVAwUBMejMPCjtJAMyBnp9AQFWhAf+PJkWptoICREg2a0Er6aHXPaNGzsERqad dovSi5D8qByIzvr1ge0sjGxDAIaLXGjH4XMEAEjr+lZQI7jVa3f5wnGQRVneqbXB sEI+Oh+3EnWut+hCAsr+PDIcRb1kLsp9v/rGhVxQkYhsLTJ55RDv5YYXVWxmB0ye zfsuERnh6+V/q3FLs7UgAn7OjdpD3NiuFizUI4li4M03o3yT9dbecmkv0pvdeOV4 2GEHnX4WhZpmqviWHcqNkjmhcFN8hq0UHHm6oqVBW1qm/LjdHCHHZLaSHbwtIVHa Bp39AxJfmTurwMosW3alxfWselCr6fUGBSQ7j9/REFAgt9aBxk4ISg== =Ruc9 -----END PGP SIGNATURE-----
participants (3)
-
Mark M.
-
Matt Carpenter
-
Steffen Zahn