Skip to content

Instantly share code, notes, and snippets.

@FrankSpierings
Last active September 22, 2018 09:47
Show Gist options
  • Save FrankSpierings/16843fa18b2008efafab9415ef5da38c to your computer and use it in GitHub Desktop.
Save FrankSpierings/16843fa18b2008efafab9415ef5da38c to your computer and use it in GitHub Desktop.
Out-EncryptedScript Python Edition. Encrypts content (like a script) and wraps a Powershell decryption routine around it.
#!/usr/bin/env python2
from Crypto.Cipher import AES
from base64 import b64encode
from Crypto.Protocol import KDF
from Crypto.Random import get_random_bytes
import sys
import argparse
import string
import random
pstemplate = '''
function {var_decrypt}([String] ${var_p}, [String] ${var_s})
{{
Set-Alias {var_new_object} New-Object;
${var_iv} = "{iv}";
${var_iv} = [Convert]::FromBase64String(${var_iv});
${var_ct} = "{ct}";
${var_ct} = [Convert]::FromBase64String(${var_ct});
${var_enc} = {var_new_object} System.Text.ASCIIEncoding;
${var_key} = {var_new_object} System.Security.Cryptography.PasswordDeriveBytes(${var_p}, ${var_enc}.GetBytes(${var_s}), "SHA1", {iternr});
${var_key} = ${var_key}.GetBytes(16);
${var_aes} = {var_new_object} System.Security.Cryptography.AesManaged;
${var_aes}.Mode = [System.Security.Cryptography.CipherMode]::CBC;
${var_dc} = ${var_aes}.CreateDecryptor(${var_key}, ${var_iv});
[Byte[]] ${var_pt} = {var_new_object} Byte[](${var_ct}.Length);
${var_ms} = {var_new_object} System.IO.MemoryStream(${var_ct}, $True);
${var_cs} = {var_new_object} System.Security.Cryptography.CryptoStream(${var_ms}, ${var_dc}, [System.Security.Cryptography.CryptoStreamMode]::Read);
${var_nr} = ${var_cs}.Read(${var_pt}, 0, ${var_pt}.Length);
${var_pt} = ${var_pt}[0..(${var_nr}-1)];
${var_ms}.Close();
${var_cs}.Close();
${var_aes}.Clear();
return ${var_enc}.GetString(${var_pt});
}}
'''
def randomstring(l, pattern=string.ascii_lowercase):
return ''.join(random.choice(pattern) for _ in range(l))
def obfuscate_vars(debug=False):
conf = {}
while (len(conf.keys()) != len(set(conf.values())) or len(conf.values()) == 0):
conf = {
'var_decrypt': '',
'var_p': '',
'var_s': '',
'var_iv': '',
'var_ct': '',
'var_enc': '',
'var_key': '',
'var_aes': '',
'var_dc': '',
'var_pt': '',
'var_nr': '',
'var_ms': '',
'var_cs': '',
'var_new_object': '',
}
if debug:
for k in conf.keys():
conf[k] = k.replace('var_', '')
else:
for k in conf.keys():
conf[k] = '{0}'.format(randomstring(random.randint(3, 6)))
return conf
def pkcs7pad(pt, bs):
nrpad = bs - (len(pt) % bs)
if nrpad == 0:
nrpad == bs
pt = pt + (chr(nrpad) * nrpad)
return pt
def generate(password, salt, pt, iternr=2, auto=False, debug=False):
bs = 16
key = KDF.PBKDF1(password, salt, bs, iternr)
iv = get_random_bytes(bs)
mode = AES.MODE_CBC
encryptor = AES.new(key, mode, IV=iv)
ppt = pkcs7pad(pt, bs)
ct = encryptor.encrypt(ppt)
iv = b64encode(iv)
ct = b64encode(ct)
var_conf = obfuscate_vars(debug=debug)
ps = pstemplate.format(iv=iv, ct=ct, iternr=iternr, **var_conf)
if not debug:
ps = ps.replace('\n', '')
ps = ps.replace(' = ', '=')
ps = ps.replace(', ', ',')
extractline = 'iex ({0} {1} {2})'.format(
var_conf['var_decrypt'], password, salt)
if auto:
ps += extractline
return ps, extractline
def main():
parser = argparse.ArgumentParser(
description='Outputs an encrypted PowerShell script.')
parser.add_argument(
'-a',
'--auto',
help='Automatic decryption of the PowerShell script. This will leave more traces on disk!',
action='store_true')
parser.add_argument(
'-d',
'--debug',
help="Don't obfuscate the PowerShell script.",
action='store_true')
parser.add_argument(
'-p',
'--password',
help='Password to use for the key derivation function.',
default=randomstring(14, pattern=string.ascii_letters + string.digits))
parser.add_argument(
'-s',
'--salt', help='Salt to use, make sure it is 8 bytes long.',
default=randomstring(8, pattern=string.ascii_letters + string.digits))
parser.add_argument('file',
help='File to convert, you may also use stdin.',
nargs='?',
type=argparse.FileType('r'), default=sys.stdin)
args = parser.parse_args()
out = generate(args.password,
args.salt,
args.file.read(),
auto=args.auto,
debug=args.debug)
print(out[0])
if not args.auto:
sys.stderr.write("Command: PowerShell -command '. <PATH_TO_SCRIPT>; {0}'".format(out[1]))
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment