/// <summary> /// Get Cobalt Strike beacons from processes with evidence of injected threads. Outputs beacon configuration to the console. /// </summary> /// <param name="opts"></param> private static void GetBeaconsFromInjectedThreads(CommandLineOptions opts) { OutputMessageToConsole(LogLevel.Info, "Scanning processes for injected threads"); List <Beacon> beacons = new List <Beacon>(); List <InjectedThread> injectedThreads = GetInjectedThreads.GetInjectedThreads.InjectedThreads(); foreach (InjectedThread injectedThread in injectedThreads) { // Output Thread details to console OutputInjectedThreadToConsole(injectedThread, opts.Verbose); // Check if option set for dumping process memory if (opts.WriteProcessMemory) { injectedThread.WriteBytesToFile(); } // Scan process memory for injected thread OutputMessageToConsole(LogLevel.Info, "Scanning injected thread for CobaltStrike beacon"); List <BeaconMatch> beaconMatches = CobaltStrikeScan.YaraScanBytes(injectedThread.ProcessBytes); if (beaconMatches.Count > 0) { foreach (BeaconMatch match in beaconMatches) { beacons.Add(GetBeaconFromYaraScan(match, injectedThread.ProcessBytes)); } if (beacons.Count > 0) { foreach (Beacon beacon in beacons) { if (beacon.isValidBeacon()) { OutputMessageToConsole(LogLevel.Success, $"Cobalt Strike Beacon Configuration\n"); beacon.OutputToConsole(); } } } else { OutputBeaconNotFoundMessage(); } } else { OutputBeaconNotFoundMessage(); } } }
static void Main(string[] args) { //Parse command line arguments CommandLineOptions opts = new CommandLineOptions(); var result = Parser.Default.ParseArguments <CommandLineOptions>(args).WithParsed(parsed => opts = parsed); var title = new HeadingInfo("CobaltStrikeScan"); // Option Processes -p if (opts.Processes) { Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine("Scanning processes for injected threads"); Console.ResetColor(); List <InjectedThread> injectedThreads = GetInjectedThreads.GetInjectedThreads.InjectedThreads(); foreach (InjectedThread injectedThread in injectedThreads) { // Output Thread details to console OutputInjectedThreadToConsole(injectedThread, opts.Verbose); // Check if option set for dumping process memory if (opts.Dump) { injectedThread.WriteBytesToFile(); } // Scan process memory for injected thread Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine("Scanning injected thread for CobaltStrike beacon"); Console.ResetColor(); Dictionary <string, ulong> beaconMatchOffsets = CobaltStrikeScan.YaraScanBytes(injectedThread.ProcessBytes); if (beaconMatchOffsets.Count > 0) { Beacon beacon = GetBeaconFromYaraScan(beaconMatchOffsets, injectedThread.ProcessBytes); if (beacon != null) { beacon.OutputToConsole(); } } else { Console.WriteLine("Couldn't find CobaltStrike beacon in injected thread"); } } } // User supplied File option -f else if (!string.IsNullOrEmpty(opts.File)) { if (File.Exists(opts.File)) { Dictionary <string, ulong> beaconMatchOffsets = CobaltStrikeScan.YaraScanFile(opts.File); if (beaconMatchOffsets.Count > 0) { byte[] fileBytes = File.ReadAllBytes(opts.File); Beacon beacon = GetBeaconFromYaraScan(beaconMatchOffsets, fileBytes); if (beacon != null) { beacon.OutputToConsole(); } } else { Console.WriteLine("Couldn't find CobaltStrike beacon in file"); } } else { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine($"File doesn't exist: {opts.File}\nExiting..."); Console.ResetColor(); System.Environment.Exit(1); } } else if (opts.InjectedThreads) { Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine("Scanning processes for injected threads\n"); Console.ResetColor(); List <InjectedThread> injectedThreads = GetInjectedThreads.GetInjectedThreads.InjectedThreads(); foreach (InjectedThread injectedThread in injectedThreads) { // Output Thread details to console OutputInjectedThreadToConsole(injectedThread, opts.Verbose); // Check if option set for dumping process memory if (opts.Dump) { injectedThread.WriteBytesToFile(); } } } else if (opts.Help) { Console.WriteLine(HelpText.AutoBuild(result, h => h, e => e)); } else { Console.WriteLine(HelpText.AutoBuild(result, h => h, e => e)); } }