Beispiel #1
0
        private CimSession DoCimConnection(Planter planter)
        {
            //Block for connecting to the remote system and returning a CimSession object
            SystemToConn = planter.System;
            Domain       = planter.Domain;
            Username     = planter.User;
            Password     = planter.Password;
            WSManSessionOptions sessionOptions = new WSManSessionOptions();
            CimSession          connectedCimSession;

            if (SystemToConn == null)
            {
                SystemToConn = "localhost";
            }
            if (Username == null)
            {
                Username = Environment.UserName;
            }

            switch (SystemToConn)
            {
            case "127.0.0.1":
            case "localhost":
                Messenger.GoodMessage("[+] Connecting to local CIM instance using " + Username + "...");
                break;

            default:
                Messenger.GoodMessage("[+] Connecting to remote CIM instance using " + Username + "...");
                break;
            }

            if (!string.IsNullOrEmpty(Password?.ToString()))
            {
                // create Credentials
                CimCredential credentials = new CimCredential(PasswordAuthenticationMechanism.Default, Domain, Username, Password);
                sessionOptions.AddDestinationCredentials(credentials);
                sessionOptions.MaxEnvelopeSize = 256000; // Not sure how else to get around this
                connectedCimSession            = CimSession.Create(SystemToConn, sessionOptions);
            }

            else
            {
                DComSessionOptions options = new DComSessionOptions {
                    Impersonation = ImpersonationType.Impersonate
                };
                connectedCimSession = CimSession.Create(SystemToConn, options);
            }

            // Test connection to make sure we're connected
            if (!connectedCimSession.TestConnection())
            {
                return(null);
            }

            Messenger.GoodMessage("[+] Connected\n");
            return(connectedCimSession);
        }
Beispiel #2
0
 public Connector(bool wmi, Planter planter)
 {
     if (wmi)
     {
         this.ConnectedWmiSession = DoWmiConnection(planter);
     }
     else
     {
         this.ConnectedCimSession = DoCimConnection(planter);
     }
 }
Beispiel #3
0
        private static void RunTestCases(Options options)
        {
            Commander commander = new Commander();
            var       connector = new Connector();
            var       planter   = new Planter(commander, connector);

            planter.Connector = new Connector(options.Wmi, planter);

            try
            {
                foreach (var command in CommandArray)
                {
                    commander = command == null ? new Commander() : new Commander(command);

                    if (commander.Method == null)
                    {
                        commander.Method = commander.Command;
                    }

                    if (planter.Commander.Command != null)
                    {
                        Messenger.GoodMessage("[+] Results from " + planter.Commander.Command + ":\n");
                    }

                    object result = null;

                    // Block to set the specific Type for WMI/CIM command
                    Type       type   = options.Wmi ? typeof(ExecuteWmi) : typeof(ExecuteCim);
                    MethodInfo method = type.GetMethod((planter.Commander.Method ?? planter.Commander.Command) ?? string.Empty);

                    // Create an instance of the type
                    object instance = Activator.CreateInstance(type);

                    // Create parameter object
                    object[] stringMethodParams = { planter };

                    result = method.Invoke(instance, stringMethodParams);
                }
            }

            catch (Exception e)
            {
                ExceptionLogging.SendErrorToText(e);
            }
        }
Beispiel #4
0
        //private Tuple<ManagementScope, ManagementScope> DoWmiConnection(Planter planter)
        private ManagementScope DoWmiConnection(Planter planter)
        {
            //Block for connecting to the remote system and returning a ManagementScope object
            SystemToConn = planter.System;
            Domain       = planter.Domain;
            Username     = planter.User;
            Password     = planter.Password;

            ConnectionOptions options = new ConnectionOptions();

            if (SystemToConn == null)
            {
                SystemToConn = "localhost";
            }
            if (Username == null)
            {
                Username = Environment.UserName;
            }

            switch (SystemToConn)
            {
            case "127.0.0.1":
            case "localhost":
                Messenger.GoodMessage("[+] Connecting to local WMI instance using " + Username + "...");
                break;

            default:
                Messenger.GoodMessage("[+] Connecting to remote WMI instance using " + Username + "...");
                break;
            }

            if (!string.IsNullOrEmpty(Password?.ToString()))
            {
                options.Username         = Username;
                options.SecurePassword   = Password;
                options.Authority        = "ntlmdomain:" + Domain;
                options.Impersonation    = ImpersonationLevel.Impersonate;
                options.EnablePrivileges = true; // This may be ok for all or may not, need to verify
            }
            else
            {
                options.Impersonation    = ImpersonationLevel.Impersonate;
                options.EnablePrivileges = true;
            }

            ManagementScope scope = new ManagementScope(@"\\" + SystemToConn + @"\root\cimv2", options);

            //ManagementScope deviceguard = new ManagementScope(@"\\" + System + @"\root\Microsoft\Windows\DeviceGuard", options);
            // Need to create a second MS object since we use a separate namespace.
            //! Need to find a more elegant solution to this!

            scope.Connect();
            //deviceguard.Connect();

            // We'll need this when we get the provider going so we can check for DG
            //ManagementScope deviceScope = scope.Clone();
            //deviceScope.Path = new ManagementPath(@"\\" + System + @"\root\Microsoft\Windows\DeviceGuard");
            //if (GetDeviceGuard.CheckDgWmi(scope, planter.System))
            //    Console.WriteLine("deviceguard enabled");

            Messenger.GoodMessage("[+] Connected\n");
            //return Tuple.Create(scope, deviceguard);
            return(scope);
        }
Beispiel #5
0
        private static void Main(string[] args)
        {
            Stopwatch watch = new Stopwatch();

            watch.Start();

            const string defaultDebugFilePath = "%SystemRoot%\\MEMORY.DMP";

            // Parse arguments passed
            Parser parser = new Parser(with =>
            {
                with.CaseInsensitiveEnumValues = true;
                with.CaseSensitive             = false;
                with.HelpWriter = null;
            });

            ParserResult <Options> parserResult = parser.ParseArguments <Options>(args);

            parserResult.WithParsed <Options>(o => { Options.Instance = o; })
            .WithNotParsed(errs => DisplayHelp(parserResult, errs));
            Options options = Options.Instance;

            Console.WriteLine();

            if (!options.NoBanner)
            {
                Messenger.ImportantAsciiArt();
            }

            // Print all commands before doing anything if that's what the user wants
            if (options.ShowCommands)
            {
                Messenger.GetCommands();
            }

            if (options.ShowExamples)
            {
                Messenger.GetExamples();
            }

            if (options.Test)
            {
                Console.WriteLine("Test method not currently supported");
                //RunTestCases(options);
                //Console.WriteLine("Test cases completed");
                System.Environment.Exit(0);
            }

            //////////
            // Block to instantiate the Commander class (houses all command information and checks for required vals)
            //////////
            Commander commander = new Commander();

            if (options.Command != null && CommandArray.Any(options.Command.ToLower().Contains) || options.Reset)
            {
                try
                {
                    commander = options.Command == null ? new Commander() : new Commander(options.Command);

                    if (commander.Method == null)
                    {
                        commander.Method = commander.Command;
                    }
                }

                catch (ArgumentNullException e)
                {
                    Messenger.ErrorMessage(
                        $"[-] Error: The parameter '{e.ParamName.ToLower()}' cannot be null (--{e.ParamName.ToLower()})");
                    System.Environment.Exit(1);
                }

                catch (SubCommandException e)
                {
                    if (e.Message == "service_mod")
                    {
                        Messenger.ErrorMessage(
                            $"[-] Error: the subcommand for '{e.Message}' is incorrect. It must be list, create, start, or delete");
                    }
                    System.Environment.Exit(1);
                }

                catch (ExtraCommandException)
                {
                    Messenger.ErrorMessage(
                        "[-] Error: Please only specify one command to execute using the -c or --command flag");
                    System.Environment.Exit(1);
                }

                catch (ProcessCommandException)
                {
                    Messenger.ErrorMessage(
                        "[-] Error: Please specify a process or handle to kill (wildcards accepted for name, ex: --process note* or --process 5384)");
                }

                catch (Exception e)
                {
                    Console.WriteLine($"Exception {e.Message} Trace {e.StackTrace}");
                }
            }

            else
            {
                Messenger.ErrorMessage("\n[-] Incorrenct command used. Try one of these:\n");
                Messenger.GetCommands();
                System.Environment.Exit(1);
            }

            //////////
            // Block to instantiate the Planter class (houses all info about the target system)
            //////////
            var connector = new Connector();
            var planter   = new Planter(commander, connector);

            //////////
            // Block to create the connection to either WMI or CIM and fallback to the other
            //////////
            try
            {
                planter.Connector = new Connector(options.Wmi, planter);

                // We can use && since one will always start as null
                if (planter.Connector.ConnectedCimSession == null && planter.Connector.ConnectedWmiSession == null)
                {
                    options.Wmi = !options.Wmi;
                    Messenger.ErrorMessage("[-] Issue with using the selected protocol, falling back to the other");
                    planter.Connector = new Connector(options.Wmi, planter);

                    if (planter.Connector.ConnectedCimSession == null && planter.Connector.ConnectedWmiSession == null)
                    {
                        Messenger.ErrorMessage("[-] ERROR: Unable to connect using either CIM or WMI.");
                        System.Environment.Exit(1);
                    }
                }
            }

            catch (COMException)
            {
                Messenger.ErrorMessage("\n[-] ERROR: Cannot connect to remote system, due to firewall or it being offline!");
                System.Environment.Exit(1);
            }

            catch (UnauthorizedAccessException e)
            {
                Messenger.ErrorMessage("\n[-] ERROR: Access is denied, check the account you are using!");
                Console.WriteLine(e);
                System.Environment.Exit(1);
            }

            catch (ManagementException e)
            {
                Messenger.ErrorMessage($"\n[-] ERROR: {e.Message}");
                Console.WriteLine(e);
                System.Environment.Exit(1);
            }

            catch (Exception e)
            {
                Messenger.ErrorMessage("\n[-] ERROR: Something else went wrong, try a different protocol maybe");
                Console.WriteLine(e);
                System.Environment.Exit(1);
            }

            //////////
            // Block to reset the DebugFilePath if needed (generally only for testing)
            //////////
            if (commander.Reset)
            {
                if (!string.IsNullOrEmpty(options.Command))
                {
                    Console.WriteLine("Please don't specify -r/--reset with -c/--command, the reset is redundant");
                    System.Environment.Exit(0);
                }

                try
                {
                    if (!options.Wmi)
                    {
                        ExecuteCim.SetOsRecovery(planter.Connector.ConnectedCimSession, defaultDebugFilePath);
                    }
                    else
                    {
                        ExecuteWmi.SetOsRecovery(planter.Connector.ConnectedWmiSession, defaultDebugFilePath);
                    }
                    Console.WriteLine("\nDebugFilePath set back to the default Windows value\n");
                    System.Environment.Exit(0);
                }

                catch (RektDebugFilePath)
                {
                    // Good Sir or Madame reading this,
                    // This only happens if something goes really, really wrong when using CIM.
                    // We need to use WMI to reset the DebugFilePath if it's too large (above 512KB) unless we want to go through
                    // A ton of mods to increase the maxEnvelopeSize within an administrative console
                    // This should rarely happen but there's really no way around it
                    Messenger.WarningMessage("[*] Something bad happened when resetting the DebugFilePath property. Using 'sudo'...");
                    try
                    {
                        planter.Connector.ConnectedCimSession.Close();
                    }
                    catch
                    {
                        //pass
                    }

                    planter.Connector = new Connector(true, planter);
                    ExecuteWmi.SetOsRecovery(planter.Connector.ConnectedWmiSession, defaultDebugFilePath);
                    System.Environment.Exit(0);
                }

                catch (Exception e)
                {
                    Messenger.ErrorMessage("[-] Issue resetting DebugFilePath\n\n");
                    Console.WriteLine(e);
                }
            }

            // We'll want this for DG check
            //if (options.Wmi == true)
            //{
            //    // Unpack the Tuple
            //    wmiScope = planter.Connector.ConnectedWmiSession.Item1;
            //    dgScope = planter.Connector.ConnectedWmiSession.Item2;
            //}

            // Block to check for the existence of Device Guard. If enabled, use PowerShell until I can find a better solution
            // If not enabled, install a WMI provider and use that method. This can be forced with the --provider flag
            //bool credguard = false;
            //if (options.Provider == false)
            //{
            //    try
            //    {
            //        credguard = !options.Wmi == true ? GetDeviceGuard.CheckDgCim(planter.Connector.ConnectedCimSession) : GetDeviceGuard.CheckDgWmi(dgScope, planter.System);
            //    }
            //    catch
            //    {
            //        Messenger.ErrorMessage("[-] Error when grabbing Device Guard info");
            //    }
            //}

            if (planter.Commander.Command != null)
            {
                Messenger.GoodMessage("[+] Results from " + planter.Commander.Command + ":\n");
            }


            ////////
            // Reflection Block
            ////////

            object result = null;

            // Block to set the specific Type for WMI/CIM command
            Type       type   = options.Wmi ? typeof(ExecuteWmi) : typeof(ExecuteCim);
            MethodInfo method = type.GetMethod(planter.Commander.Method ?? planter.Commander.Command);

            // Create an instance of the type
            object instance = Activator.CreateInstance(type);

            // Create parameter object
            object[] stringMethodParams = { planter };

            try
            {
                result = method.Invoke(instance, stringMethodParams);
            }

            catch (TargetInvocationException e)
            {
                if (e.InnerException.Message == planter.Commander.Service)
                {
                    Messenger.ErrorMessage(
                        $"[-] Error: The service name {planter.Commander.Service} not valid, please ensure it's a valid service name (case sensitive)");
                    System.Environment.Exit(1);
                }
            }

            catch (TimeoutException)
            {
                Console.WriteLine("timeout hit");
            }

            catch (PropertyNotFoundException)
            {
                Messenger.ErrorMessage("[-] Registry key does not exist or another issue occurred");
            }

            catch (FormatException e)
            {
                Messenger.ErrorMessage("[-] The registry value for subkey " + planter.Commander.RegSubKey +
                                       " is not in the correct format\n");
                Console.WriteLine("Full error:\n" + e);
            }

            catch (RektDebugFilePath)
            {
                // Good Sir or Madame reading this,
                // This only happens if something goes really, really wrong when using CIM.
                // We need to use WMI to reset the DebugFilePath if it's too large (above 512KB) unless we want to go through
                // A ton of mods to increase the maxEnvelopeSize within an administrative console
                // This should rarely happen but there's really no way around it
                Messenger.WarningMessage("[*] Something bad happened when resetting the DebugFilePath property. Using 'sudo'...");
                try
                {
                    planter.Connector.ConnectedCimSession.Close();
                }
                catch
                {
                    //pass
                }

                planter.Connector = new Connector(true, planter);
                ExecuteWmi.SetOsRecovery(planter.Connector.ConnectedWmiSession, defaultDebugFilePath);
                Console.WriteLine("Successfully reset the DebugFilePath property");
                System.Environment.Exit(0);
            }

            catch (PSRemotingTransportException)
            {
                // Pass, but we already caught above
            }

            catch (CaughtByAvException e)
            {
                Messenger.ErrorMessage("[-] Error: Issues with PowerShell script, it may have been flagged by AV");
                Console.WriteLine(e);
            }

            catch (Exception e)
            {
                //Console.WriteLine("Exception {0} Trace {1}", e.Message, e.StackTrace);
                Console.WriteLine(e);
            }

            ////////
            // End Reflection Block
            ////////

            if (result == null)
            {
                Messenger.ErrorMessage("\n[-] Issue running command after connecting");
                return;
            }

            // Just in case, close the CIM session
            if (!options.Wmi)
            {
                planter.Connector.ConnectedCimSession?.Close();
            }
            else
            {
                planter.Connector.ConnectedWmiSession = null;
            }

            Messenger.GoodMessage("\n\n[+] Successfully completed " + options.Command + " command");
            watch.Stop();
            Console.WriteLine("Execution time: " + watch.ElapsedMilliseconds / 1000 + " Seconds");
        }