Empire/lib/common/encryption.py

349 lines
16 KiB
Python
Raw Normal View History

2015-08-05 18:36:39 +00:00
"""
2016-09-23 18:04:35 +00:00
Empire encryption functions.
Includes:
pad() - performs PKCS#7 padding
depad() - Performs PKCS#7 depadding
rsa_xml_to_key() - parses a PowerShell RSA xml import and builds a M2Crypto object
rsa_encrypt() - encrypts data using the M2Crypto crypto object
aes_encrypt() - encrypts data using a pyCrypto AES object
aes_encrypt_then_hmac() - encrypts and SHA256 HMACs data using a pyCrypto AES object
aes_decrypt() - decrypts data using a pyCrypto AES object
verify_hmac() - verifies a SHA256 HMAC for a data blob
aes_decrypt_and_verify() - AES decrypts data if the HMAC is validated
generate_aes_key() - generates a ranodm AES key using pyCrypto's Random functionality
rc4() - encrypt/decrypt a data blob using an RC4 key
DiffieHellman() - Mark Loiseau's DiffieHellman implementation, see ./data/licenses/ for license info
2015-08-05 18:36:39 +00:00
"""
2016-09-23 18:04:35 +00:00
import base64
import hashlib
import hmac
import string
import M2Crypto
2015-08-05 18:36:39 +00:00
from xml.dom.minidom import parseString
from Crypto.Cipher import AES
from Crypto import Random
from Crypto.Random import random
2016-09-23 18:04:35 +00:00
from binascii import hexlify
def to_bufferable(binary):
return binary
def _get_byte(c):
return ord(c)
2015-08-05 18:36:39 +00:00
2016-09-23 18:04:35 +00:00
# Python 3 compatibility stuffz
try:
xrange
except Exception:
xrange = range
2015-08-05 18:36:39 +00:00
2016-09-23 18:04:35 +00:00
def to_bufferable(binary):
if isinstance(binary, bytes):
return binary
return bytes(ord(b) for b in binary)
2015-08-05 18:36:39 +00:00
2016-09-23 18:04:35 +00:00
def _get_byte(c):
return c
2015-08-05 18:36:39 +00:00
2016-09-23 18:04:35 +00:00
# If a secure random number generator is unavailable, exit with an error.
try:
import ssl
random_function = ssl.RAND_bytes
random_provider = "Python SSL"
except (AttributeError, ImportError):
import OpenSSL
random_function = OpenSSL.rand.bytes
random_provider = "OpenSSL"
def pad(data):
2015-08-05 18:36:39 +00:00
"""
Performs PKCS#7 padding for 128 bit block size.
"""
pad = 16 - (len(data) % 16)
return data + to_bufferable(chr(pad) * pad)
2016-09-23 18:04:35 +00:00
# return str(s) + chr(16 - len(str(s)) % 16) * (16 - len(str(s)) % 16)
2015-08-05 18:36:39 +00:00
2016-09-23 18:04:35 +00:00
def depad(data):
2015-08-05 18:36:39 +00:00
"""
Performs PKCS#7 depadding for 128 bit block size.
"""
2016-09-23 18:04:35 +00:00
if len(data) % 16 != 0:
raise ValueError("invalid length")
pad = _get_byte(data[-1])
return data[:-pad]
2016-09-23 18:04:35 +00:00
# return s[:-(ord(s[-1]))]
2015-08-05 18:36:39 +00:00
def rsa_xml_to_key(xml):
"""
Parse powershell RSA.ToXmlString() public key string and
return a M2Crypto key object.
2016-09-23 18:04:35 +00:00
Used during PowerShell RSA-EKE key exchange in agents.py.
2015-08-05 18:36:39 +00:00
Reference- http://stackoverflow.com/questions/10367072/m2crypto-import-keys-from-non-standard-file
"""
try:
# parse the xml DOM and extract the exponent/modulus
dom = parseString(xml)
e = base64.b64decode(dom.getElementsByTagName('Exponent')[0].childNodes[0].data)
n = base64.b64decode(dom.getElementsByTagName('Modulus')[0].childNodes[0].data)
# build the new key
key = M2Crypto.RSA.new_pub_key((
M2Crypto.m2.bn_to_mpi(M2Crypto.m2.hex_to_bn(hexlify(e))),
M2Crypto.m2.bn_to_mpi(M2Crypto.m2.hex_to_bn(hexlify(n))),
))
return key
# if there's an XML parsing error, return None
except:
return None
def rsa_encrypt(key, data):
"""
Take a M2Crypto key object and use it to encrypt the passed data.
"""
return key.public_encrypt(data, M2Crypto.RSA.pkcs1_padding)
def aes_encrypt(key, data):
"""
Generate a random IV and new AES cipher object with the given
key, and return IV + encryptedData.
"""
IV = Random.new().read(16)
cipher = AES.new(key, AES.MODE_CBC, IV)
return IV + cipher.encrypt(pad(data))
2016-09-23 18:04:35 +00:00
def aes_encrypt_then_hmac(key, data):
"""
Encrypt the data then calculate HMAC over the ciphertext.
"""
data = aes_encrypt(key, data)
2016-09-23 18:04:35 +00:00
mac = hmac.new(str(key), data, hashlib.sha256).digest()
return data + mac[0:10]
2015-08-05 18:36:39 +00:00
def aes_decrypt(key, data):
"""
Generate an AES cipher object, pull out the IV from the data
and return the unencrypted data.
"""
if len(data) > 16:
IV = data[0:16]
cipher = AES.new(key, AES.MODE_CBC, IV)
return depad(cipher.decrypt(data[16:]))
def verify_hmac(key, data):
"""
Verify the HMAC supplied in the data with the given key.
"""
if len(data) > 20:
2016-09-23 18:04:35 +00:00
mac = data[-10:]
data = data[:-10]
expected = hmac.new(key, data, hashlib.sha256).digest()[0:10]
# Double HMAC to prevent timing attacks. hmac.compare_digest() is
# preferable, but only available since Python 2.7.7.
return hmac.new(str(key), expected).digest() == hmac.new(str(key), mac).digest()
2016-09-23 18:04:35 +00:00
else:
return False
def aes_decrypt_and_verify(key, data):
"""
Decrypt the data, but only if it has a valid MAC.
"""
if len(data) > 32 and verify_hmac(key, data):
2016-09-23 18:04:35 +00:00
return aes_decrypt(key, data[:-10])
raise Exception("Invalid ciphertext received.")
2015-08-05 18:36:39 +00:00
def generate_aes_key():
"""
Generate a random new 128-bit AES key using Pycrypto's secure Random functions.
"""
punctuation = '!#$%&()*+,-./:;<=>?@[\]^_`{|}~'
return ''.join(random.sample(string.ascii_letters + string.digits + '!#$%&()*+,-./:;<=>?@[\]^_`{|}~', 32))
2016-09-23 18:04:35 +00:00
def rc4(key, data):
2015-08-05 18:36:39 +00:00
"""
2016-09-23 18:04:35 +00:00
RC4 encrypt/decrypt the given data input with the specified key.
From: http://stackoverflow.com/questions/29607753/how-to-decrypt-a-file-that-encrypted-with-rc4-using-python
2015-08-05 18:36:39 +00:00
"""
2016-09-23 18:04:35 +00:00
S, j, out = range(256), 0, []
# KSA Phase
for i in range(256):
j = (j + S[i] + ord(key[i % len(key)])) % 256
S[i], S[j] = S[j], S[i]
# PRGA Phase
i = j = 0
for char in data:
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i], S[j] = S[j], S[i]
out.append(chr(ord(char) ^ S[(S[i] + S[j]) % 256]))
return ''.join(out)
class DiffieHellman(object):
"""
A reference implementation of the Diffie-Hellman protocol.
By default, this class uses the 6144-bit MODP Group (Group 17) from RFC 3526.
This prime is sufficient to generate an AES 256 key when used with
a 540+ bit exponent.
Authored by Mark Loiseau's implementation at https://github.com/lowazo/pyDHE
version 3.0 of the GNU General Public License
see ./data/licenses/pyDHE_license.txt for license info
Also used in ./data/agent/stager.py for the Python key-negotiation stager
"""
def __init__(self, generator=2, group=17, keyLength=540):
"""
Generate the public and private keys.
"""
min_keyLength = 180
default_generator = 2
valid_generators = [2, 3, 5, 7]
# Sanity check fors generator and keyLength
if(generator not in valid_generators):
print("Error: Invalid generator. Using default.")
self.generator = default_generator
else:
self.generator = generator
if(keyLength < min_keyLength):
print("Error: keyLength is too small. Setting to minimum.")
self.keyLength = min_keyLength
else:
self.keyLength = keyLength
self.prime = self.getPrime(group)
self.privateKey = self.genPrivateKey(keyLength)
self.publicKey = self.genPublicKey()
def getPrime(self, group=17):
"""
Given a group number, return a prime.
"""
default_group = 17
primes = {
5: 0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF,
14: 0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF,
15: 0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF,
16: 0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199FFFFFFFFFFFFFFFF,
17:
0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C93402849236C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AACC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E6DCC4024FFFFFFFFFFFFFFFF,
18:
0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C93402849236C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AACC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E438777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300741FA7BF8AFC47ED2576F6936BA424663AAB639C5AE4F5683423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD922222E04A4037C0713EB57A81A23F0C73473FC646CEA306B4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A062B3CF5B3A278A66D2A13F83F44F82DDF310EE074AB6A364597E899A0255DC164F31CC50846851DF9AB48195DED7EA1B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F924009438B481C6CD7889A002ED5EE382BC9190DA6FC026E479558E4475677E9AA9E3050E2765694DFC81F56E880B96E7160C980DD98EDD3DFFFFFFFFFFFFFFFFF
}
if group in primes.keys():
return primes[group]
else:
print("Error: No prime with group %i. Using default." % group)
return primes[default_group]
def genRandom(self, bits):
"""
Generate a random number with the specified number of bits
"""
_rand = 0
_bytes = bits // 8 + 8
while(len(bin(_rand))-2 < bits):
try:
# Python 3
_rand = int.from_bytes(random_function(_bytes), byteorder='big')
except:
# Python 2
_rand = int(OpenSSL.rand.bytes(_bytes).encode('hex'), 16)
return _rand
def genPrivateKey(self, bits):
"""
Generate a private key using a secure random number generator.
"""
return self.genRandom(bits)
def genPublicKey(self):
"""
Generate a public key X with g**x % p.
"""
return pow(self.generator, self.privateKey, self.prime)
def checkPublicKey(self, otherKey):
"""
Check the other party's public key to make sure it's valid.
Since a safe prime is used, verify that the Legendre symbol == 1
"""
if(otherKey > 2 and otherKey < self.prime - 1):
if(pow(otherKey, (self.prime - 1)//2, self.prime) == 1):
return True
return False
def genSecret(self, privateKey, otherKey):
"""
Check to make sure the public key is valid, then combine it with the
private key to generate a shared secret.
"""
if(self.checkPublicKey(otherKey) is True):
sharedSecret = pow(otherKey, privateKey, self.prime)
return sharedSecret
else:
raise Exception("Invalid public key.")
def genKey(self, otherKey):
"""
Derive the shared secret, then hash it to obtain the shared key.
"""
self.sharedSecret = self.genSecret(self.privateKey, otherKey)
# Convert the shared secret (int) to an array of bytes in network order
# Otherwise hashlib can't hash it.
try:
_sharedSecretBytes = self.sharedSecret.to_bytes(
len(bin(self.sharedSecret))-2 // 8 + 1, byteorder="big")
except AttributeError:
_sharedSecretBytes = str(self.sharedSecret)
s = hashlib.sha256()
s.update(bytes(_sharedSecretBytes))
self.key = s.digest()
def getKey(self):
"""
Return the shared secret key
"""
return self.key