예제 #1
0
        /////////////////////////////////////////////////////
        //                                                 //
        // CodewordServicesStartup()                       //
        //                                                 //
        /////////////////////////////////////////////////////
        //Description:  called from Main() when this program is
        //              being executed by the SCM directly as a
        //              result of a service start request.  The
        //              sole job of CodewordServicesStartup() is to fire off
        //              StartServiceCtrlDispatcher(), the main
        //              win32 api for starting a windows svc.
        //
        //Returns:      void
        //////////////////////////////////////////////////////
        private static void CodewordServicesStartup()
        {
            //variables to hold signature and agent settings data
            Dictionary <string, string> AgentSettings = new Dictionary <string, string>();
            string DriverServiceName = "CwDriverSvc";

            //=============================================
            //              LOAD SETTINGS
            //=============================================
            if (!LoadAgentSettings(ref AgentSettings))
            {
                return;
            }

            AgentService service = new AgentService();

            //define our delegate function as the entry point for the service
            Win32Helper.LPSERVICE_MAIN_FUNCTIONW sproc = new Win32Helper.LPSERVICE_MAIN_FUNCTIONW(service.ServiceMain);
            //create a new SERVICE_TABLE_ENTRY structure
            //note:  the last element in the structure must have its members set to NULL
            Win32Helper.SERVICE_TABLE_ENTRYW[] ServiceDispatchTableEntry = new Win32Helper.SERVICE_TABLE_ENTRYW[2];
            ServiceDispatchTableEntry[0] = new Win32Helper.SERVICE_TABLE_ENTRYW();
            ServiceDispatchTableEntry[0].lpServiceName = AgentSettings["AgentServiceName"];
            ServiceDispatchTableEntry[0].lpServiceProc = Marshal.GetFunctionPointerForDelegate(sproc).ToInt32();
            ServiceDispatchTableEntry[1] = new Win32Helper.SERVICE_TABLE_ENTRYW();
            ServiceDispatchTableEntry[1].lpServiceName = null;
            ServiceDispatchTableEntry[1].lpServiceProc = 0;
            //set the appropriate field of ServiceDispatchTable to point to this table
            Win32Helper.SERVICE_TABLE ServiceDispatchTable = new Win32Helper.SERVICE_TABLE();
            ServiceDispatchTable.lpServiceTable = ServiceDispatchTableEntry;
            //marshal a ptr to the SERVICE_TABLE struct
            IntPtr lpServiceDispatchTable = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Win32Helper.SERVICE_TABLE)));

            Marshal.StructureToPtr(ServiceDispatchTable, lpServiceDispatchTable, true);

            //
            //KICK IT OFF!
            //this function returns when the service stops (system shutdown, admin stopping, etc)..
            //
            //pass it a ptr to an array of SERVICE_TABLE_ENTRY structures, the last one being null
            try
            {
                Win32Helper.StartServiceCtrlDispatcher(lpServiceDispatchTable);

                if (lpServiceDispatchTable != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(lpServiceDispatchTable);
                }
            }
            catch (Exception ex)
            {
                StreamWriter sw = new StreamWriter("StartServiceCtrlDispatcherError.txt", true);
                sw.WriteLine(ex.Message);
                if (ex.InnerException != null)
                {
                    sw.WriteLine(ex.InnerException.Message);
                }
                sw.Close();
            }

            //ok...if we got here, the AGENT service was stopped for some reason.
            //so, stop the driver service in parallel.  do NOT delete the driver file or service.
            try
            {
                ServiceHelper.StopService(DriverServiceName);
            }
            catch (Exception) { }

            return;
        }
예제 #2
0
        /////////////////////////////////////////////////////
        //                                                 //
        // CodewordInstallation()                          //
        //                                                 //
        /////////////////////////////////////////////////////
        //Description:  This function is executed by Main()
        //              when the agent binary is being executed
        //              by the installer for the first time.
        //
        //Returns:      void
        //////////////////////////////////////////////////////
        private static void CodewordInstallation(string[] CmdLineInstallArgs)
        {
            //variables to hold signature and agent settings data
            Dictionary <string, string> AgentSettings = new Dictionary <string, string>();

            Console.WriteLine("Install args:  " + string.Join(",", CmdLineInstallArgs));
            Console.WriteLine("------------------");
            Console.WriteLine("Initialization");
            Console.WriteLine("------------------");

            Console.Write("Checking pre-requisites...");

            //=============================================
            //              PREREQUISITE CHECK
            //=============================================
            //bail if we dont have admin rights.
            if (!DoPreRequisiteCheck())
            {
                Console.Write("failed!");
                Console.WriteLine("");
                return;
            }

            Console.Write("OK.");
            Console.WriteLine("");

            //=============================================
            //              ESCALATE PRIVILEGES
            //=============================================
            //we must have debug privs to succeed.
            Console.Write("Escalating privileges...");
            if (!AgentScanner.EnvironmentHelper.EscalatePrivileges())
            {
                Console.Write("failed!");
                Console.WriteLine("");
                return;
            }

            Console.Write("OK.");
            Console.WriteLine("");

            //=============================================
            //              LOAD SETTINGS
            //=============================================
            Console.Write("Loading settings...");
            if (!LoadAgentSettings(ref AgentSettings))
            {
                Console.Write("failed!");
                Console.WriteLine("");
                return;
            }

            Console.Write("OK.");
            Console.WriteLine("");

            //=============================================
            //              APPLY SETTINGS
            //=============================================
            //load some initial settings
            bool   DriverSuccessfullyLoaded = false;
            bool   Stealth_LoadAndCallImage = false;
            bool   InstallAgentService      = false;
            string DriverFileName           = CwConstants.DRIVER_BINARY_NAME;
            string DriverInstallPath        = Environment.GetFolderPath(Environment.SpecialFolder.System) + "\\Drivers\\" + DriverFileName;
            string DriverImagePath          = CwConstants.DRIVER_IMAGE_PATH_BASE + DriverFileName; //for registry entry for SCM
            string DriverServiceName        = CwConstants.DRIVER_SERVICE_NAME;
            string AgentFileName            = CwConstants.AGENT_BINARY_NAME;
            string AgentServiceName         = CwConstants.AGENT_SERVICE_NAME;
            string AgentInstallPath         = Environment.SystemDirectory + "\\" + AgentFileName;
            string AgentInstallPathWithArg  = AgentInstallPath;

            string[] AgentServiceArguments = new string[] { "-skipinstall" };

            if (AgentSettings.ContainsKey("PersistenceInstallAsService"))
            {
                if (AgentSettings["PersistenceInstallAsService"] == "True")
                {
                    InstallAgentService = true;
                }
            }
            if (AgentSettings.ContainsKey("Stealth_LoadAndCallImage"))
            {
                if (AgentSettings["Stealth_LoadAndCallImage"] == "True")
                {
                    Stealth_LoadAndCallImage = true;
                }
            }
            if (AgentSettings.ContainsKey("AgentServiceName"))
            {
                if (AgentSettings["AgentServiceName"] != "")
                {
                    AgentServiceName = AgentSettings["AgentServiceName"];
                }
            }

            /*
             * if (AgentSettings.ContainsKey("AgentInstallFolder"))
             *  if (AgentSettings["AgentInstallFolder"] != "")
             *      GetAgentInstallPath(AgentSettings["AgentInstallFolder"], AgentFileName, ref AgentInstallPath);
             */

            //when passing this value to CreateService() API, it must be a fully-escaped string
            //note:  any parameters to the service are passed here!
            //  e.g.  \"C:\windows\system32\cwagent.exe -install\"
            //AgentInstallPathWithArg = "\\\"" + AgentInstallPath.Replace("\\", "\\\\") + " -skipinstall\\\"";
            //DriverInstallPathFullyQualified = "\\\"" + DriverInstallPath.Replace("\\", "\\\\") + "\\\"";
            AgentInstallPathWithArg = AgentInstallPath + " -skipinstall";

            //=============================================
            //             STEALTH [optional]
            //=============================================
            //
            //(1) Randomize agent process name [optional]
            //(2) Hide agent's process [optional]
            //(3) Load driver using LoadAndCallImage [optional]
            //
            //

            /*
             * if (Stealth_LoadAndCallImage && !Win32Helper.Is64bit())
             * {
             *  byte[] filedata = new byte[0];
             *
             *  try
             *  {
             *      bool success = false;
             *      //extract driver binary data from our own assembly
             *      AgentScanner.DriverHelper.ExtractDriver(DriverFileName, ref filedata);
             *      //save it to C:\Windows\System32\Drivers\
             *      AgentScanner.DriverHelper.SaveDriver(DriverInstallPath, filedata);
             *      //load using load and call image
             *      AgentScanner.DriverHelper.SysLoadAndCall(DriverInstallPath, ref success);
             *      DriverSuccessfullyLoaded = success;
             *  }
             *  catch (Exception)
             *  {
             *      DriverSuccessfullyLoaded = false;
             *  }
             * }
             */

            //
            //=============================================
            //          STARTUP [required]
            //=============================================
            //
            //(1) Extract & Load driver [required] - if not already done stealthily
            Console.WriteLine("-------------------");
            Console.WriteLine("Driver Installation");
            Console.WriteLine("-------------------");

            #region DRIVER STARTUP/INSTALLATION
            //
            //NOTE:  do not quit on any errors when dealing with SCM.  It is unreliable and may report
            //the service installation/start/stop/etc failed when it really succeeeded!!!
            if (!DriverSuccessfullyLoaded && !Win32Helper.Is64bit())
            {
                Console.Write("Does the driver service exist?");
                bool   InstallNecessary = true;
                byte[] filedata         = new byte[0];

                //--------------------------------
                //     STOP EXISTING SERVICE
                //--------------------------------
                //first we have to stop the service if it is already running
                try
                {
                    if (ServiceHelper.ServiceExists(DriverServiceName))
                    {
                        Console.Write("  Yes.");
                        Console.WriteLine("");
                        Console.Write("   Is it running?");

                        InstallNecessary = false; //we dont need to re-install the service
                        long serviceStatus = 0;

                        try
                        {
                            serviceStatus = ServiceHelper.GetServiceStatus(DriverServiceName);
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine("  Critical error:  could not determine the driver service's state:  " + ex.Message);
                            Console.WriteLine("");
                            return;
                        }

                        //STATUS IS RUNNING:  stop the service
                        if (serviceStatus == Win32Helper.SERVICE_RUNNING)
                        {
                            Console.Write("  Yes, stopping...");
                            try
                            {
                                if (!ServiceHelper.StopService(DriverServiceName))
                                {
                                    Console.WriteLine("  Critical error:  could not stop running driver service.");
                                    return;
                                }
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine("  Critical error:  could not stop running driver service:  " + ex.Message);
                                return;
                            }
                            Console.Write("OK.");
                            Console.WriteLine("");
                        }
                        //SOME OTHER STATUS, IGNORE.
                        else
                        {
                            if (serviceStatus == Win32Helper.SERVICE_STOPPED)
                            {
                                Console.Write("  No, it is STOPPED.");
                            }
                            else if (serviceStatus == Win32Helper.SERVICE_STOP_PENDING)
                            {
                                Console.Write("  No, it is STOP PENDING.");
                            }
                            else if (serviceStatus == Win32Helper.SERVICE_START_PENDING)
                            {
                                Console.Write("  No, it is START PENDING.");
                            }
                            else if (serviceStatus == Win32Helper.SERVICE_PAUSED)
                            {
                                Console.Write("  No, it is PAUSED.");
                            }
                            else if (serviceStatus == Win32Helper.SERVICE_PAUSE_PENDING)
                            {
                                Console.Write("  No, it is PAUSE PENDING.");
                            }
                            else if (serviceStatus == Win32Helper.SERVICE_CONTINUE_PENDING)
                            {
                                Console.Write("  No, it is CONTINUE PENDING.");
                            }
                            else
                            {
                                Console.Write("  No, it is UNKNOWN!");
                            }
                            Console.WriteLine("");
                        }
                    }
                    else
                    {
                        Console.Write("  No.");
                        Console.WriteLine("");
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Critical error:  caught exception attempting to detect/stop driver service:  " + ex.Message);
                    Console.WriteLine("");
                    return;
                }

                //
                //SKIP EXTRACT/SAVE STEP IF INSTALL ARGS REQUEST
                //
                //this is useful for debugging the driver, so we dont have to worry about
                //repackaging the .sys file with the agent installer
                //
                if (CmdLineInstallArgs[0].IndexOf("-skipExtract") == -1)
                {
                    Thread.Sleep(500); //sleep .5 second
                    Console.Write("Extracting driver...");

                    //--------------------------------
                    //     EXTRACT NEW DRIVER BINARY
                    //--------------------------------
                    //overwrite any previous version
                    bool ExtractSuccessful = false;
                    try
                    {
                        ExtractSuccessful = AgentScanner.DriverHelper.ExtractDriver(DriverFileName, ref filedata);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("Critical error:  caught exception attempting to extract driver binary:  " + ex.Message);
                        Console.WriteLine("");
                        return;
                    }

                    //FAILED.
                    if (!ExtractSuccessful)
                    {
                        Console.Write("failed:  " + Win32Helper.GetLastError32());
                        return;
                    }
                    else
                    {
                        Console.Write("OK.");
                        Console.WriteLine("");
                    }

                    Thread.Sleep(500); //sleep .5 second
                    Console.Write("Saving driver to disk...");

                    //save it to C:\Windows\System32\Drivers\
                    bool SaveSuccessful = false;
                    try
                    {
                        SaveSuccessful = AgentScanner.DriverHelper.SaveDriver(DriverInstallPath, filedata);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("Critical error:  caught exception attempting to save driver binary to disk:  " + ex.Message);
                        Console.WriteLine("");
                        return;
                    }

                    //FAILED.
                    if (!SaveSuccessful)
                    {
                        Console.Write("failed:  " + Win32Helper.GetLastError32());
                        return;
                    }
                    else
                    {
                        Console.Write("OK.");
                        Console.WriteLine("");
                        Console.WriteLine("Wrote " + filedata.Length.ToString() + " bytes to " + DriverInstallPath + ".");
                    }

                    Thread.Sleep(500); //sleep .5 second
                } //end save/extract driver binary

                Console.Write("Is driver installation necessary?  ");

                //--------------------------------
                //     CREATE NEW SERVICE
                //--------------------------------
                //install driver as a service if necessary
                if (InstallNecessary)
                {
                    Console.Write("Yes, installing from path:");
                    Console.WriteLine("");
                    Console.WriteLine("     " + DriverInstallPath);
                    Console.WriteLine("Creating new service:  ");
                    Console.WriteLine("     Service name:  " + DriverServiceName);
                    Console.WriteLine("     Display name:  " + DriverServiceName);
                    Console.WriteLine("     Service type:  " + Win32Helper.SERVICE_KERNEL_DRIVER);
                    Console.WriteLine("     Start type  :  " + Win32Helper.SERVICE_DEMAND_START);
                    Console.WriteLine("     Image path  :  " + DriverImagePath);
                    Console.Write("Installing service...");

                    bool CreateSuccessful = false;
                    try
                    {
                        CreateSuccessful = ServiceHelper.CreateService(DriverServiceName, DriverServiceName, Win32Helper.SERVICE_KERNEL_DRIVER, Win32Helper.SERVICE_DEMAND_START, DriverImagePath);
                    }
                    catch (Exception ex)
                    {
                        Console.Write("Caught exception trying to create service:  " + ex.Message);

                        //ignore ERROR_IO_PENDING
                        if (Win32Helper.GetLastError() == Win32Helper.ERROR_IO_PENDING)
                        {
                            Console.Write("...Ignoring.");
                        }
                        //bail..
                        else
                        {
                            Console.WriteLine("(" + Win32Helper.GetLastError() + ")");
                            return;
                        }
                    }

                    //FAILED.
                    if (!CreateSuccessful)
                    {
                        Console.Write("failed:  " + Win32Helper.GetLastError32());
                        return;
                    }
                    else
                    {
                        Console.Write("OK.");
                        Console.WriteLine("");
                    }
                }
                else
                {
                    Console.Write("No.");
                    Console.WriteLine("");
                }

                Thread.Sleep(500); //sleep .5 second
                Console.Write("Starting driver service...");

                //--------------------------------
                //     START  SERVICE
                //--------------------------------
                bool StartSuccessful = false;
                try
                {
                    StartSuccessful = ServiceHelper.StartService(DriverServiceName, null);
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Caught exception trying to start service:  " + ex.Message);
                    return;
                }

                //FAILED.
                if (!StartSuccessful)
                {
                    Console.Write("failed:  " + Win32Helper.GetLastError32() + " (" + Win32Helper.GetLastError() + ")");
                    return;
                }
                else
                {
                    Console.Write("OK.");
                    Console.WriteLine("");
                }
            }
            #endregion

            //(2) Any self-protection measures [optional]
            //      -run all kernel-mode heuristics to see if this system is hosed
            //      -if this option is set, the reporting mode is always set to Fire and forget
            //

            //(3) Install agent as a service [optional]
            //
            Console.WriteLine("------------------");
            Console.WriteLine("Agent Installation");
            Console.WriteLine("------------------");

            #region AGENT STARTUP/INSTALLATION

            //------------------------------------
            //          RUN ONCE
            //------------------------------------
            if (!InstallAgentService)
            {
                Console.WriteLine("Startup mode is Fire and Forget...");

                string args2 = "";
                IntPtr pArgs = Marshal.StringToHGlobalAuto(args2);

                AgentService service = new AgentService();
                service.ServiceMain(0, ref pArgs);

                if (pArgs != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pArgs);
                }

                //the scan has completed -- terminate driver service
                //no need to leave it running b/c we didnt install agent as a service
                try
                {
                    ServiceHelper.StopService(DriverServiceName);
                    ServiceHelper.RemoveService(DriverServiceName);
                    File.Delete(DriverInstallPath);
                }
                catch (Exception) { }
                return;
            }
            //------------------------------------
            //          RUN AS SERVICE
            //------------------------------------
            else
            {
                //kill any other CwAgent.exe process in case the agent is already installed as a service
                TerminateAgents();
                bool InstallNecessary = true;

                Console.Write("Does the agent service exist?");

                //--------------------------------
                //     STOP EXISTING SERVICE
                //--------------------------------
                //first we have to stop the service if it is already running
                try
                {
                    if (ServiceHelper.ServiceExists(AgentServiceName))
                    {
                        Console.Write("  Yes.");
                        Console.WriteLine("");
                        Console.Write("   Is it running?");

                        InstallNecessary = false; //we dont need to re-install the service
                        long serviceStatus = 0;

                        try
                        {
                            serviceStatus = ServiceHelper.GetServiceStatus(AgentServiceName);
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine("  Critical error:  could not determine the agent service's state:  " + ex.Message);
                            Console.WriteLine("");
                            return;
                        }

                        //STATUS IS RUNNING:  stop the service
                        if (serviceStatus == Win32Helper.SERVICE_RUNNING)
                        {
                            Console.Write("  Yes, stopping...");
                            try
                            {
                                if (!ServiceHelper.StopService(AgentServiceName))
                                {
                                    Console.WriteLine("  Critical error:  could not stop running agent service.");
                                    return;
                                }
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine("  Critical error:  could not stop running agent service:  " + ex.Message);
                                return;
                            }
                            Console.Write("OK.");
                            Console.WriteLine("");
                        }
                        //SOME OTHER STATUS, IGNORE.
                        else
                        {
                            if (serviceStatus == Win32Helper.SERVICE_STOPPED)
                            {
                                Console.Write("  No, it is STOPPED.");
                            }
                            else if (serviceStatus == Win32Helper.SERVICE_STOP_PENDING)
                            {
                                Console.Write("  No, it is STOP PENDING.");
                            }
                            else if (serviceStatus == Win32Helper.SERVICE_START_PENDING)
                            {
                                Console.Write("  No, it is START PENDING.");
                            }
                            else if (serviceStatus == Win32Helper.SERVICE_PAUSED)
                            {
                                Console.Write("  No, it is PAUSED.");
                            }
                            else if (serviceStatus == Win32Helper.SERVICE_PAUSE_PENDING)
                            {
                                Console.Write("  No, it is PAUSE PENDING.");
                            }
                            else if (serviceStatus == Win32Helper.SERVICE_CONTINUE_PENDING)
                            {
                                Console.Write("  No, it is CONTINUE PENDING.");
                            }
                            else
                            {
                                Console.Write("  No, it is UNKNOWN!");
                            }
                            Console.WriteLine("");
                        }
                    }
                    else
                    {
                        Console.Write("  No.");
                        Console.WriteLine("");
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Critical error:  caught exception attempting to detect/stop agent service:  " + ex.Message);
                    Console.WriteLine("");
                    return;
                }

                Thread.Sleep(500); //sleep .5 second
                Console.Write("Is agent service installation necessary?  ");

                //--------------------------------
                //     CREATE NEW SERVICE
                //--------------------------------
                //install driver as a service if necessary
                if (InstallNecessary)
                {
                    Console.Write("Yes, installing from path:");
                    Console.WriteLine("");
                    Console.WriteLine("     " + AgentInstallPathWithArg);
                    Console.WriteLine("Creating new service:  ");
                    Console.WriteLine("     Service name:  " + AgentServiceName);
                    Console.WriteLine("     Display name:  " + AgentServiceName);
                    Console.WriteLine("     Service type:  " + Win32Helper.SERVICE_WIN32_OWN_PROCESS);
                    Console.WriteLine("     Start type  :  " + Win32Helper.SERVICE_DEMAND_START);
                    Console.WriteLine("     Install folder:  " + AgentInstallPathWithArg);
                    Console.Write("Installing service...");

                    bool CreateSuccessful = false;
                    try
                    {
                        CreateSuccessful = ServiceHelper.CreateService(AgentServiceName, AgentServiceName, Win32Helper.SERVICE_WIN32_OWN_PROCESS, Win32Helper.SERVICE_DEMAND_START, AgentInstallPathWithArg);
                    }
                    catch (Exception ex)
                    {
                        Console.Write("Caught exception trying to create service:  " + ex.Message);

                        //ignore ERROR_IO_PENDING
                        if (Win32Helper.GetLastError() == Win32Helper.ERROR_IO_PENDING)
                        {
                            Console.Write("...Ignoring.");
                        }
                        //bail..
                        else
                        {
                            Console.WriteLine("");
                            return;
                        }
                    }

                    //FAILED.
                    if (!CreateSuccessful)
                    {
                        Console.Write("failed:  " + Win32Helper.GetLastError32());
                        return;
                    }
                    else
                    {
                        Console.Write("OK.");
                        Console.WriteLine("");
                    }
                }
                else
                {
                    Console.Write("No.");
                    Console.WriteLine("");
                }

                Thread.Sleep(500); //sleep .5 second
                Console.Write("Starting agent service...");

                //--------------------------------
                //     START  SERVICE
                //--------------------------------
                bool StartSuccessful = false;
                try
                {
                    StartSuccessful = ServiceHelper.StartService(AgentServiceName, null);
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Caught exception trying to start service:  " + ex.Message);
                    return;
                }

                //FAILED.
                if (!StartSuccessful)
                {
                    Console.Write("failed:  " + Win32Helper.GetLastError32());
                    return;
                }
                else
                {
                    Console.Write("OK.");
                    Console.WriteLine("");
                }

                //TODO:
                //try to do some cleanup in user's app folder C:\Documents and Settings\<user>\Local Settings\Temp
                //

                return;
            }

            #endregion
        }