rapid7/metasploit-framework — pull request #1223 by schierlm (2012-12-31 21:52:40+00:00)
Title: RC4 shellcode for bind/reverse stagers

As Boris Lukashev already quoted egypt in http://dev.metasploit.com/redmine/issues/7192#note-3,
it should be possible to do a stager shellcode that decrypts its stage via RC4.

This pull requests contains a shellcode block that can be used to decode an arbitrary buffer in memory with RC4, in addition to stagers that use the block for bind_tcp and reverse_tcp. As the length of the payload is needed before decoding, the payload length is encoded with a XOR key instead. The ruby payload modules split a SHA-1 hash of a user-defined password for both the XOR key and the RC4 key (32 bit XOR key + 128 bit RC4 key = 160 bit SHA-1).

The RC4 decoder block can be used for other use cases as well, for example a decoder stub for an encoder to encode long payloads before encoding the stub with e. g. shikata_ga_nai, or as a midstager (This is not contained in this pull request).

As already mentioned in the commit messages, this will not encrypt the stage communication (shell or meterpreter) at all, so for best effect it should be combined with stages that encrypt their communication as well (with a key embedded in the stage).

And since RC4 does not contain any random components, reusing the key for more than one use will result in an identical cipher stream and is therefore bad from a cryptanalysis standpoint as you can obtain the XOR difference of two different plaintexts by XORing the cipher texts (when using the same key). The XOR key for the length should not weaken the cipher as it has the same weakness as the RC4 cipher stream. (But compared to the adaptive XOR "cryptography" used elsewhere it is a lot stronger as it does not enable to obtain the key from just a few known plaintext bytes. And RC4 should be just fine for AV evasion).

Also note that while I have a bit of a cryptography background, my shellcode coding (and sizecoding) skills are lacking, so feel free to optimize the shellcode to be smaller, faster or "more null-free".