Esempio n. 1
0
        public static void StartProcess_old(string binary, string cmdline, Lib.Logger logger, bool cleanup = false)
        {
            if (!cleanup)
            {
                logger.TimestampInfo("Executing Command: " + cmdline);
            }
            else
            {
                logger.TimestampInfo("Executing Cleanup Command: " + cmdline);
            }

            const uint NORMAL_PRIORITY_CLASS = 0x0020;
            bool       retValue;

            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);

            retValue = WinAPI.CreateProcess(null, cmdline, ref pSec, ref tSec, false, NORMAL_PRIORITY_CLASS, IntPtr.Zero, null, ref sInfo, out pInfo);

            if (retValue && cleanup == false)
            {
                logger.TimestampInfo(String.Format("Process successfully created. (PID): " + pInfo.dwProcessId));
            }
            else if (retValue != false && cleanup == false)
            {
                logger.TimestampInfo("Could not start process!");
            }
        }
Esempio n. 2
0
    public static void StartProcess(string binary, string cmdline)
    {
        const uint NORMAL_PRIORITY_CLASS = 0x0020;
        bool       retValue;
        string     Application;

        if (binary == "powershell")
        {
            Application = Environment.GetEnvironmentVariable("windir") + @"\System32\WindowsPowerShell\v1.0\" + binary + ".exe " + cmdline;
            Console.WriteLine(Environment.GetEnvironmentVariable("windir") + @"\System32\WindowsPowerShell\v1.0\" + binary + ".exe " + cmdline);
        }
        else
        {
            Application = Environment.GetEnvironmentVariable("windir") + @"\" + binary + ".exe " + @cmdline;
        }


        string CommandLine = @cmdline;

        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);

        retValue = WinAPI.CreateProcess(null, cmdline, ref pSec, ref tSec, false, NORMAL_PRIORITY_CLASS, IntPtr.Zero, null, ref sInfo, out pInfo);

        Console.WriteLine("Process ID (PID): " + pInfo.dwProcessId);
        Console.WriteLine("Process Handle : " + pInfo.hProcess);
    }
Esempio n. 3
0
        public static void StartProcessApi(string binary, string cmdline, Lib.Logger logger)
        {
            const uint NORMAL_PRIORITY_CLASS = 0x0020;
            bool       retValue;

            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);
            logger.TimestampInfo(String.Format("Using the Win32 API call CreateProcess to execute: '{0}'", cmdline));
            retValue = WinAPI.CreateProcess(null, cmdline, ref pSec, ref tSec, false, NORMAL_PRIORITY_CLASS, IntPtr.Zero, null, ref sInfo, out pInfo);

            if (retValue)
            {
                logger.TimestampInfo(String.Format("Process successfully created. (PID): " + pInfo.dwProcessId));
            }
            else
            {
                logger.TimestampInfo("Could not start process!");
            }
        }
Esempio n. 4
0
 public extern static bool CreateProcessAsUser(IntPtr hToken, String lpApplicationName, String lpCommandLine, ref Structs.SECURITY_ATTRIBUTES lpProcessAttributes,
                                               ref Structs.SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandle, int dwCreationFlags, IntPtr lpEnvironment,
                                               String lpCurrentDirectory, ref Structs.STARTUPINFO2 lpStartupInfo, out Structs.PROCESS_INFORMATION lpProcessInformation);
Esempio n. 5
0
 public extern static bool DuplicateTokenEx(IntPtr ExistingTokenHandle, uint dwDesiredAccess, ref Structs.SECURITY_ATTRIBUTES lpThreadAttributes, int TokenType, int ImpersonationLevel, ref IntPtr DuplicateTokenHandle);
Esempio n. 6
0
    public static bool SpoofParent(int parentProcessId, string binaryPath, string cmdLine)
    {
        // STARTUPINFOEX members
        const int PROC_THREAD_ATTRIBUTE_PARENT_PROCESS = 0x00020000;

        // STARTUPINFO members (dwFlags and wShowWindow)
        const int   STARTF_USESTDHANDLES = 0x00000100;
        const int   STARTF_USESHOWWINDOW = 0x00000001;
        const short SW_HIDE = 0x0000;

        // dwCreationFlags
        const uint EXTENDED_STARTUPINFO_PRESENT = 0x00080000;
        const uint CREATE_NO_WINDOW             = 0x08000000;

        //var error = Marshal.GetLastWin32Error();

        var pInfo = new Structs.PROCESS_INFORMATION();
        var siEx  = new Structs.STARTUPINFOEX();

        // Be sure to set the cb member of the STARTUPINFO structure to sizeof(STARTUPINFOEX).
        siEx.StartupInfo.cb = Marshal.SizeOf(siEx);
        IntPtr lpValueProc          = IntPtr.Zero;
        IntPtr hSourceProcessHandle = IntPtr.Zero;

        if (parentProcessId > 0)
        {
            var lpSize  = IntPtr.Zero;
            var success = WinAPI.InitializeProcThreadAttributeList(IntPtr.Zero, 1, 0, ref lpSize);
            if (success || lpSize == IntPtr.Zero)
            {
                return(false);
            }
            Console.WriteLine("successfully used InitializeProcThreadAttributeList ");

            siEx.lpAttributeList = Marshal.AllocHGlobal(lpSize);
            success = WinAPI.InitializeProcThreadAttributeList(siEx.lpAttributeList, 1, 0, ref lpSize);
            if (!success)
            {
                return(false);
            }
            Console.WriteLine("successfully used InitializeProcThreadAttributeList");

            IntPtr parentHandle = WinAPI.OpenProcess(Structs.ProcessAccessFlags.CreateProcess | Structs.ProcessAccessFlags.DuplicateHandle, false, parentProcessId);
            if (parentHandle == null)
            {
                return(false);
            }

            Console.WriteLine("obtained a handle to parent process");

            // This value should persist until the attribute list is destroyed using the DeleteProcThreadAttributeList function
            lpValueProc = Marshal.AllocHGlobal(IntPtr.Size);
            Marshal.WriteIntPtr(lpValueProc, parentHandle);

            success = WinAPI.UpdateProcThreadAttribute(siEx.lpAttributeList, 0, (IntPtr)PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, lpValueProc, (IntPtr)IntPtr.Size, IntPtr.Zero, IntPtr.Zero);
            if (!success)
            {
                return(false);
            }
            Console.WriteLine("successfully used UpdateProcThreadAttribute");


            IntPtr hCurrent   = System.Diagnostics.Process.GetCurrentProcess().Handle;
            IntPtr hNewParent = WinAPI.OpenProcess(Structs.ProcessAccessFlags.DuplicateHandle, true, parentProcessId);
            if (hNewParent == null)
            {
                return(false);
            }

            Console.WriteLine("successfully used OpenProcess");
        }

        siEx.StartupInfo.dwFlags     = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
        siEx.StartupInfo.wShowWindow = SW_HIDE;

        var ps = new Structs.SECURITY_ATTRIBUTES();
        var ts = new Structs.SECURITY_ATTRIBUTES();

        ps.nLength = Marshal.SizeOf(ps);
        ts.nLength = Marshal.SizeOf(ts);
        //bool ret = CreateProcess(null, command, ref ps, ref ts, true, EXTENDED_STARTUPINFO_PRESENT | CREATE_NO_WINDOW, IntPtr.Zero, null, ref siEx, out pInfo);
        Console.WriteLine("About to call create processd");
        bool ret = WinAPI.CreateProcess(binaryPath, cmdLine, ref ps, ref ts, true, EXTENDED_STARTUPINFO_PRESENT | CREATE_NO_WINDOW, IntPtr.Zero, null, ref siEx, out pInfo);

        Console.WriteLine(Marshal.GetLastWin32Error());
        if (!ret)
        {
            Console.WriteLine("[!] Proccess failed to execute!");
            return(false);
        }

        Console.WriteLine("successfully used CreateProcess");
        return(true);
    }
Esempio n. 7
0
    // From https://www.codeproject.com/Articles/35773/Subverting-Vista-UAC-in-Both-32-and-64-bit-Archite
    public static bool StartProcessAsLoggedUser(String applicationName, string startingDir, out Structs.PROCESS_INFORMATION procInfo)
    {
        int    winlogonPid = 0;
        IntPtr hUserTokenDup = IntPtr.Zero, hPToken = IntPtr.Zero, hProcess = IntPtr.Zero;

        procInfo = new Structs.PROCESS_INFORMATION();

        // obtain the currently active session id; every logged on user in the system has a unique session id
        uint dwSessionId = WinAPI.WTSGetActiveConsoleSessionId();

        // obtain the process id of the winlogon process that is running within the currently active session
        // -- chaged by ty
        // Process[] processes = Process.GetProcessesByName("winlogon");
        Process[] processes = Process.GetProcessesByName("explorer");
        foreach (Process p in processes)
        {
            if ((uint)p.SessionId == dwSessionId)
            {
                winlogonPid = p.Id;
            }
        }

        // obtain a handle to the winlogon process
        //hProcess = OpenProcess(MAXIMUM_ALLOWED, false, winlogonPid);
        hProcess = WinAPI.OpenProcess(Structs.ProcessAccessFlags.CreateProcess | Structs.ProcessAccessFlags.DuplicateHandle | Structs.ProcessAccessFlags.QueryInformation, false, winlogonPid);

        // obtain a handle to the access token of the winlogon process
        if (!WinAPI.OpenProcessToken(hProcess, TOKEN_DUPLICATE, ref hPToken))
        {
            WinAPI.CloseHandle(hProcess);
            return(false);
        }

        // Security attibute structure used in DuplicateTokenEx and CreateProcessAsUser
        // I would prefer to not have to use a security attribute variable and to just
        // simply pass null and inherit (by default) the security attributes
        // of the existing token. However, in C# structures are value types and therefore
        // cannot be assigned the null value.
        Structs.SECURITY_ATTRIBUTES sa = new Structs.SECURITY_ATTRIBUTES();
        sa.nLength = Marshal.SizeOf(sa);

        // copy the access token of the winlogon process; the newly created token will be a primary token
        if (!WinAPI.DuplicateTokenEx(hPToken, MAXIMUM_ALLOWED, ref sa, (int)Structs.SECURITY_IMPERSONATION_LEVEL.SecurityIdentification, (int)Structs.TOKEN_TYPE.TokenPrimary, ref hUserTokenDup))
        {
            WinAPI.CloseHandle(hProcess);
            WinAPI.CloseHandle(hPToken);
            return(false);
        }

        // By default CreateProcessAsUser creates a process on a non-interactive window station, meaning
        // the window station has a desktop that is invisible and the process is incapable of receiving
        // user input. To remedy this we set the lpDesktop parameter to indicate we want to enable user
        // interaction with the new process.
        Structs.STARTUPINFO2 si = new Structs.STARTUPINFO2();
        si.cb        = (int)Marshal.SizeOf(si);
        si.lpDesktop = @"winsta0\default"; // interactive window station parameter; basically this indicates that the process created can display a GUI on the desktop

        // flags that specify the priority and creation method of the process
        int dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE;

        // create a new process in the current user's logon session
        bool result = WinAPI.CreateProcessAsUser(hUserTokenDup,   // client's access token
                                                 null,            // file to execute
                                                 applicationName, // command line
                                                 ref sa,          // pointer to process SECURITY_ATTRIBUTES
                                                 ref sa,          // pointer to thread SECURITY_ATTRIBUTES
                                                 false,           // handles are not inheritable
                                                 dwCreationFlags, // creation flags
                                                 IntPtr.Zero,     // pointer to new environment block
                                                 startingDir,     // name of current directory
                                                 ref si,          // pointer to STARTUPINFO structure
                                                 out procInfo     // receives information about new process
                                                 );

        // invalidate the handles
        WinAPI.CloseHandle(hProcess);
        WinAPI.CloseHandle(hPToken);
        WinAPI.CloseHandle(hUserTokenDup);

        return(result); // return the result
    }
Esempio n. 8
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);
            }
        }