Ejemplo n.º 1
0
        /////////////////////////////////////////////////////
        //                                                 //
        // InitiateScanThread()                            //
        //                                                 //
        /////////////////////////////////////////////////////
        //Description:  Kicks of a scan of the host in a separate
        //              thread.  ServiceMain() will wait for
        //              this thread to complete.  This function
        //              is only called in Enterprise mode.
        //
        //Returns:      void
        //////////////////////////////////////////////////////
        internal void InitiateScanThread()
        {
            AgentScanner scanner = new AgentScanner();
            CwXML.CodewordAgentAnomalyReport anomalyReport = new CwXML.CodewordAgentAnomalyReport();
            //this wont modify our global variable "ScanResultsLog", so we have to write it to a file
            //in this child thread and then once back in the main thread, slurp it back up
            try
            {
                ScanResultsLog = scanner.StartScanTask(ref anomalyReport);
                StreamWriter sw = new StreamWriter("xxzz1tmp1");
                sw.Write(ScanResultsLog.ToString());
                sw.Close();
            }
            catch (Exception ex)
            {
                StreamWriter sw = new StreamWriter("errcw.txt");
                sw.WriteLine(ex.Message);
                if (ex.InnerException != null)
                    sw.WriteLine(ex.InnerException.Message);
                sw.Close();
            }

            return;
        }
Ejemplo n.º 2
0
        /////////////////////////////////////////////////////
        //                                                 //
        // ServiceMain()                                   //
        //                                                 //
        /////////////////////////////////////////////////////
        //Description:  Entry point for the agent service process.
        //              This function is called automatically
        //              by the Windows SCM if we are running
        //              as a service, or it's called manually
        //              in AgentMain if not a service.
        //
        //              This function's prototype is dictated
        //              by the Win32Helper.LPSERVICE_MAIN_FUNCTIONW
        //              delegate definition.
        //
        //Returns:      true if successful
        /////////////////////////////////////////////////////
        internal unsafe void ServiceMain(uint dwNumServicesArgs, ref IntPtr lpServiceArgVectors)
        {
            AgentSettings = new Dictionary<string, string>();
            AgentServiceLog = new StringBuilder();
            ScanResultsLog = new StringBuilder();

            //=============================================
            //              INITIALIZATION
            //=============================================
            //
            //1.  Load settings from XML file extracted to local dir from MSI
            //
            if (!LoadAgentSettings(ref AgentSettings))
                return;

            //=============================================
            //      SET SERVICE CONTROL HANDLER FUNCTION
            //=============================================
            //the function ServiceMain() is called either by:
            //      (1) the agent binary itself inside CwAgent.exe in "Fire and Forget" mode
            //      (2) the CwAgent service has been started by the SCM
            //
            //in #1, we dont need to do anything special, but in #2, we have to do a few items
            //to make sure the SCM is "in the know":
            //      http://msdn.microsoft.com/en-us/library/ms685984(VS.85).aspx
            //
            //we will distinguish between case #1 and case #2 by the number of args
            if (dwNumServicesArgs > 0)
            {
                //get a pointer to our callback delegate.
                Win32Helper.LPHANDLER_FUNCTION lpHandlerProc = new Win32Helper.LPHANDLER_FUNCTION(ServiceHandler);

                //call RegisterServiceCtrlHandler() with this ptr.  all SCM notifications will be handled by it.
                IntPtr svcStatusHandle = Win32Helper.RegisterServiceCtrlHandler(AgentSettings["AgentServiceName"], lpHandlerProc);

                if (svcStatusHandle == IntPtr.Zero)
                    return;

                //!!!!!!!!!!!!!!!!!!!!!!!!!!!
                //!!     MUI IMPORTANTE    !!
                //!!!!!!!!!!!!!!!!!!!!!!!!!!!
                //we must save this handle for later updates to SCM
                globalHSvcHandle = svcStatusHandle;
                bool success = false;

                //set service to the START_PENDING state
                try
                {
                    ServiceHelper.SetServiceStatus(globalHSvcHandle, Win32Helper.SERVICE_START_PENDING, ref success);
                }
                catch (Exception) { }
            }

            //=============================================
            //              ESCALATE PRIVILEGES
            //=============================================
            //we must have debug privs to succeed.
            if (!AgentScanner.EnvironmentHelper.EscalatePrivileges())
            {
                //set our service to the STOPPED state
                try
                {
                    bool success = false;
                    ServiceHelper.StopService(AgentSettings["AgentServiceName"]);
                    ServiceHelper.SetServiceStatus(globalHSvcHandle, Win32Helper.SERVICE_STOPPED, ref success);
                }
                catch (Exception) { }

                return;
            }

            AgentServiceLog.AppendLine("*********************************************");
            AgentServiceLog.AppendLine("Codeword Agent v" + Assembly.GetExecutingAssembly().GetName().Version);
            AgentServiceLog.AppendLine("*********************************************");
            AgentServiceLog.AppendLine("Copyright © 2009, Sippy Development International");
            AgentServiceLog.AppendLine("Author:  sippy");
            AgentServiceLog.AppendLine("Please contact [email protected] with questions.");
            AgentServiceLog.AppendLine("*********************************************");
            AgentServiceLog.AppendLine("");
            AgentServiceLog.AppendLine("*********************************************");
            AgentServiceLog.AppendLine("                 INITIALIZE                  ");
            AgentServiceLog.AppendLine("*********************************************");
            AgentServiceLog.AppendLine("");
            AgentServiceLog.AppendLine("INITIALIZE:  Codeword starting on " + DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss"));
            AgentServiceLog.AppendLine("INITIALIZE:  Loading settings...");

            //=============================================
            //                  STARTUP
            //=============================================
            //
            //1.  determine our startup mode.
            //
            string[] possibleStartupModes = new string[] { "StartupFireAndForgetMode", "StartupRemoteControlMode", "StartupEnterpriseMode" };
            string AgentStartupMode = "";
            foreach (string s in possibleStartupModes)
                if (AgentSettings.ContainsKey(s))
                    if (AgentSettings[s] == "True")
                        AgentStartupMode = s;

            AgentServiceLog.AppendLine("INITIALIZE:  Agent startup mode set to " + AgentStartupMode);

            //
            //2.  start TCP server and listen for commands
            //
            if (AgentStartupMode == "StartupRemoteControlMode" || AgentStartupMode == "StartupEnterpriseMode")
            {
                SslTcpServer server = new SslTcpServer();
                string certfile = "", encPwd = "", issuer = "";
                bool authClientToServer = false;
                bool authServerToClient = false;
                bool strongAuth = false;
                int port = 1111;

                AgentServiceLog.AppendLine("STARTUP:  Initializing TCP/SSL server...");
                AgentServiceLog.AppendLine("STARTUP:  Using settings:");

                //------------------------------------
                //      LOAD TCP SERVER SETTINGS
                //------------------------------------
                //extract certificate from internal PKCS-12 file if provided
                if (AgentSettings.ContainsKey("AgentPFXFile"))
                    if (AgentSettings["AgentPFXFile"] != "")
                        certfile = Path.GetFileName(AgentSettings["AgentPFXFile"]);
                //get encrypted password for PFX keystore
                if (AgentSettings.ContainsKey("AgentPFXPassword"))
                    if (AgentSettings["AgentPFXPassword"] != "")
                        encPwd = AgentSettings["AgentPFXPassword"];
                //server port to listen on locally
                if (AgentSettings.ContainsKey("AgentListeningPort"))
                    if (AgentSettings["AgentListeningPort"] != "")
                        port = int.Parse(AgentSettings["AgentListeningPort"]);
                //authenticate client to server?
                if (AgentSettings.ContainsKey("AgentAuthenticateClientToServer"))
                    if (AgentSettings["AgentAuthenticateClientToServer"] == "True")
                        authClientToServer = true;
                //authenticate server to client?
                if (AgentSettings.ContainsKey("AgentAuthenticateServerToClient"))
                    if (AgentSettings["AgentAuthenticateServerToClient"] == "True")
                        authServerToClient = true;
                //required issuer of client certs
                if (AgentSettings.ContainsKey("AgentEnforceCertificateIssuer"))
                    if (AgentSettings["AgentEnforceCertificateIssuer"] != "")
                        issuer = AgentSettings["AgentEnforceCertificateIssuer"];
                //force strong authentication
                if (AgentSettings.ContainsKey("AgentEnforceStrongAuthentication"))
                    if (AgentSettings["AgentEnforceStrongAuthentication"] == "True")
                        strongAuth = true;

                AgentServiceLog.AppendLine("    PFX file name:  " + certfile);
                AgentServiceLog.AppendLine("    Listening on port:  " + port.ToString());
                AgentServiceLog.AppendLine("    Authenticate client to server:  " + authClientToServer.ToString());
                AgentServiceLog.AppendLine("    Authenticate server to client:  " + authServerToClient.ToString());
                AgentServiceLog.AppendLine("    Required issuer:  " + issuer);
                AgentServiceLog.AppendLine("    Strong authentication required:  " + strongAuth.ToString());

                //set server fields
                server.PFXFileName = certfile;
                server.EncryptedPassword = encPwd;
                server.ServerPort = port;
                server.AuthenticateClientToServer = authClientToServer;
                server.AuthenticateServerToClient = authServerToClient;
                server.RequiredIssuer = issuer;
                server.RequireStrongAuthentication = strongAuth;

                //insure the certificate file exists
                if (!File.Exists(certfile))
                {
                    AgentServiceLog.AppendLine("Error:  PFX certificate file '" + certfile + "' does not exist!");
                    return;
                }

                //------------------------------------
                //      RUN THE SCAN IF MODE IS
                //      StartupEnterpriseMode
                //------------------------------------
                if (AgentStartupMode == "StartupEnterpriseMode")
                {
                    //kick it off in a new thread so it doesnt stall the service
                    //and cause the SCM to barf.
                    Thread thr = new Thread(new ThreadStart(InitiateScanThread));
                    thr.Start();

                    while (!thr.IsAlive) { }
                    Thread.Sleep(1);

                    //we will wait for it to complete, b/c we've already set the status of
                    //our service to RUNNING, so SCM is satisfied.
                    //Ideally, we would also kick the RunServer() below in a new thread
                    //as well, and synchronize the three threads.
                    thr.Join();
                }

                //read the data back in from the file the child thread just wrote
                //ScanResultsLog = new StringBuilder(File.ReadAllText("xxzz1tmp1"));
                //promptly delete the file
                //File.Delete("xxzz1tmp1");

                //set our service to the RUNNING state
                try
                {
                    bool success = false;
                    ServiceHelper.SetServiceStatus(globalHSvcHandle, Win32Helper.SERVICE_RUNNING, ref success);
                }
                catch (Exception) { }

                //------------------------------------
                //      START THE TCP SERVER
                //------------------------------------
                //pass the results of an enterprise mode scan, if there is one
                //note:  ScanResultsLog is populated from the child thread above.
                try
                {
                    server.RunServer(ScanResultsLog);
                }
                catch (Exception ex)
                {
                    StreamWriter sw = new StreamWriter("SslServerError.txt", true);
                    sw.WriteLine(ex.Message);
                    sw.Close();
                }

                //set our service to the STOPPED state
                try
                {
                    bool success = false;
                    ServiceHelper.StopService(AgentSettings["AgentServiceName"]);
                    ServiceHelper.SetServiceStatus(globalHSvcHandle, Win32Helper.SERVICE_STOPPED, ref success);
                }
                catch (Exception) { }
            }
            //StartupFireAndForgetMode - do not start any server; just run the scan and report
            //note:  if we get here, we are not being called by SCM.
            else if (AgentStartupMode == "StartupFireAndForgetMode")
            {
                AgentScanner scanner = new AgentScanner();
                scanner.FireAndForget();
            }

            return;
        }
Ejemplo n.º 3
0
        /////////////////////////////////////////////////////
        //                                                 //
        // ExecuteCommand()                                //
        //                                                 //
        /////////////////////////////////////////////////////
        //Description:  Executes the given command and returns
        //              a response object.
        //
        //Returns:      A response code, one of the following:
        //                  RESPONSE_EXITING - connection closing
        //                  RESPONSE_OK - command completed successfully
        //                  RESPONSE_FAIL = command failed
        /////////////////////////////////////////////////////
        internal CwXML.CodewordAgentResponse ExecuteCommand(CwXML.CodewordAgentCommand command)
        {
            CwXML.CodewordAgentResponse response = new CwXML.CodewordAgentResponse();
            response.CommandReceiveDate = DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss");
            response.CommandProcessingStartDate = DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss");
            response.ResponseCode = CwConstants.AGENTRESPONSE_OK;
            response.CommandCodeReceived = command.CommandCode;

            //-------------------------------------------------------------
            //
            //                  GET SYSTEM INFORMATION
            //
            //-------------------------------------------------------------
            #region GET SYSTEM INFORMATION
            if (command.CommandCode == CwConstants.AGENTCMD_GETSYSTEMINFO)
            {
                response.ResponseInfo = "System information retrieved.";
                CwXML.CodewordSystemInformation sysinfo = new CwXML.CodewordSystemInformation();
                sysinfo.HostInformation = new CwXML.HostInformation();
                sysinfo.AgentInformation = new CwXML.AgentInformation();
                //host info
                sysinfo.HostInformation.AgentCurrentDirectory = Environment.CurrentDirectory;
                sysinfo.HostInformation.MachineName = Environment.MachineName;
                sysinfo.HostInformation.NumProcessors = Environment.ProcessorCount.ToString();
                sysinfo.HostInformation.OSVersionShort = Environment.OSVersion.VersionString;
                sysinfo.HostInformation.LogicalDrives = string.Join(",", Environment.GetLogicalDrives());
                sysinfo.HostInformation.IPAddresses = string.Join(",", AgentScanner.EnvironmentHelper.GetIPAddresses());
                sysinfo.HostInformation.OSVersionLong = AgentScanner.EnvironmentHelper.GetOSName();
                sysinfo.HostInformation.UserDomainName = Environment.UserDomainName;
                sysinfo.HostInformation.UserName = Environment.UserName;
                sysinfo.HostInformation.WorkingSetSize = (Environment.WorkingSet / 1000000).ToString() + "MB";
                //agent info
                sysinfo.AgentInformation.Version = Assembly.GetExecutingAssembly().GetName().ToString();
                //use XML settings file in current directory - "CwAgentConfiguration.xml"
                //this will allow us to deserialize the XML data into class structures
                CwXML xml = new CwXML();
                CwXML.CodewordSettingsTemplate cst = new CwXML.CodewordSettingsTemplate();
                try
                {
                    cst = xml.LoadSettingsXML("CwAgentConfiguration.xml");
                }
                catch (Exception e)
                {
                    response.ResponseInfo = "There was an error retrieving the agent settings:  " + e.Message;
                }
                sysinfo.AgentInformation.AgentSettings = cst;
                //use XML signatures file in current directory - "CwAgentSignatures.xml"
                //this will allow us to deserialize the XML data into class structures
                xml = new CwXML();
                CwXML.CodewordSignatureTemplate sigs = new CwXML.CodewordSignatureTemplate();
                try
                {
                    sigs = xml.ImportSignatureTemplate("CwAgentSignatures.xml");
                }
                catch (Exception e)
                {
                    response.ResponseInfo = "There was an error retrieving the agent signatures:  " + e.Message;
                }
                sysinfo.AgentInformation.AgentSignatures = sigs;

                //assign sysinfo object to return response
                response.ResponseSystemInformation = sysinfo;
            }
            #endregion
            //-------------------------------------------------------------
            //
            //                  DOWNLOAD EVIDENCE FILES (COLLECT)
            //
            //-------------------------------------------------------------
            #region DOWNLOAD EVIDENCE FILES (COLLECT)
            else if (command.CommandCode == CwConstants.AGENTCMD_COLLECT)
            {
                //===================================================================
                //  SEND INTERMEDIATE RESPONSE TO TELL HOST TO START RECEIVING FILES
                //===================================================================
                //send a response then prepare to send
                WriteConnectionLog("CONNECT:  Got command to send evidence files...");

                CwXML.CodewordAgentResponse response2 = new CwXML.CodewordAgentResponse();
                response2.CommandReceiveDate = DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss");
                response2.CommandProcessingStartDate = DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss");
                response2.ResponseCode = CwConstants.AGENTRESPONSE_OK_RECVFILE;
                response2.CommandCodeReceived = command.CommandCode;

                WriteConnectionLog("CONNECT:  Sending response...");

                //send response
                try
                {
                    SendResponse(response2);
                }
                catch (Exception ex)
                {
                    WriteConnectionLog("Failed to send response in preparation for evidence collection:  " + ex.Message);
                    response.ResponseCode = CwConstants.AGENTRESPONSE_FAIL;
                    response.ResponseInfo = "Failed to send response in preparation for evidence collection:  " + ex.Message;
                    return response;
                }

                WriteConnectionLog("CONNECT:  Sending files..");

                //===================================================================
                //                      SEND EVIDENCE FILES
                //===================================================================
                //get list of files tos end
                CwXML.FileSignatureMatch[] fileSigsToSend = command.CommandCollectOrMitigationTask.SignatureMatches.FileSignatureMatches;
                int count = 0;

                //send the files
                foreach (CwXML.FileSignatureMatch match in fileSigsToSend)
                {
                    try
                    {
                        SendBinaryFile(match.FullPath);
                    }
                    catch (Exception ex)
                    {
                        response.ResponseCode = CwConstants.AGENTRESPONSE_FAIL;
                        response.ResponseInfo = "Failed to send binary file '" + match.FullPath + "':  " + ex.Message;
                        break;
                    }
                    count++;
                }

                if (response.ResponseCode == CwConstants.AGENTRESPONSE_OK)
                    response.ResponseInfo = "Successfully sent " + count + " evidence files.";
            }
            #endregion
            //-------------------------------------------------------------
            //
            //                  PERFORM MITIGATION TASK
            //
            //-------------------------------------------------------------
            #region PERFORM MITIGATION TASK
            else if (command.CommandCode == CwConstants.AGENTCMD_MITIGATE)
            {
                //the mitigation task is stored in the command object as an anomaly report
                CwXML.CodewordAgentAnomalyReport MitigationTask = command.CommandCollectOrMitigationTask;

                if (MitigationTask != null)
                {
                    CwXML.CodewordAgentSignatureMatches matches = MitigationTask.SignatureMatches;
                    //mitigate registry items
                    if (matches.RegistrySignatureMatches != null)
                    {
                        if (matches.RegistrySignatureMatches.Length > 0)
                        {
                            CwXML.RegistrySignatureMatch[] regMatches = matches.RegistrySignatureMatches;
                            AgentScanner.RegistryHelper RegistryScanner = new AgentScanner.RegistryHelper();
                            RegistryScanner.LoadNtUserDatFiles(false);
                            RegistryScanner.CleanRegistryFindings(ref regMatches, false);
                            RegistryScanner.LoadNtUserDatFiles(true);
                            response.ResponseLog = RegistryScanner.RegistryHelperLog.ToString();
                            //assign the matches back to our main object, so the ActionSuccessful variable gets sent back
                            matches.RegistrySignatureMatches = regMatches;
                        }
                    }
                    //mitigate file items
                    if (matches.FileSignatureMatches != null)
                    {
                        if (matches.FileSignatureMatches.Length > 0)
                        {
                            CwXML.FileSignatureMatch[] fileMatches = matches.FileSignatureMatches;
                            AgentScanner.FileHelper FileScanner = new AgentScanner.FileHelper();
                            FileScanner.CleanFileFindings(ref fileMatches);
                            response.ResponseLog = FileScanner.FileHelperLog.ToString();
                            //assign the matches back to our main object, so the ActionSuccessful variable gets sent back
                            matches.FileSignatureMatches = fileMatches;
                        }
                    }
                    //mitigate memory items
                    if (matches.MemorySignatureMatches != null)
                    {
                        if (matches.MemorySignatureMatches.Length > 0)
                        {
                            CwXML.MemorySignatureMatch[] memMatches = matches.MemorySignatureMatches;
                            AgentScanner.MemoryHelper MemoryScanner = new AgentScanner.MemoryHelper();
                            MemoryScanner.CleanMemoryFindings(ref memMatches);
                            response.ResponseLog = MemoryScanner.MemoryHelperLog.ToString();
                            //assign the matches back to our main object, so the ActionSuccessful variable gets sent back
                            matches.MemorySignatureMatches = memMatches;
                        }
                    }
                    //assign the main object to the response's anomaly report
                    response.ResponseAnomalyReport = new CwXML.CodewordAgentAnomalyReport();
                    response.ResponseAnomalyReport.SignatureMatches = matches;
                }
                else
                {
                    response.ResponseInfo = "Error completing mitigation task:  the mitigation object was null!";
                    response.ResponseCode = CwConstants.AGENTRESPONSE_FAIL;
                }
            }
            #endregion
            //-------------------------------------------------------------
            //
            //                  START A NEW SCAN
            //
            //-------------------------------------------------------------
            #region START A NEW SCAN
            else if (command.CommandCode == CwConstants.AGENTCMD_STARTSCAN)
            {
                //ENTERPRISE MODE CHECK:
                //make sure there isnt an already-completed scan from
                //starting up in enterprise mode.
                if (EnterpriseModeScanLog != null)
                {
                    response.ResponseLog = EnterpriseModeScanLog.ToString();
                    response.ResponseInfo = "These results are from a previous scan issued during agent startup.  To run a new scan, please re-issue the scan command.";
                    //clear the enterprise scan results
                    EnterpriseModeScanLog = null;
                }
                //otherwise, issue a completely new scan task
                //warning:  this can be a lengthy operation (> 10 min)
                else
                {
                    CwXML.CodewordAgentAnomalyReport anomalyReport = new CwXML.CodewordAgentAnomalyReport();
                    AgentScanner scanner = new AgentScanner();
                    StringBuilder scannerLog = new StringBuilder();

                    try
                    {
                        scannerLog = scanner.StartScanTask(ref anomalyReport);
                    }
                    catch (Exception ex)
                    {
                        StreamWriter sw = new StreamWriter("AgentScanLog.txt", false);
                        sw.WriteLine(ex.Message);
                        sw.WriteLine("");
                        if (AgentScanner.AgentScanLog != null)
                            sw.WriteLine(AgentScanner.AgentScanLog.ToString());
                        sw.Close();
                    }

                    if (scannerLog != null && anomalyReport != null)
                    {
                        response.ResponseAnomalyReport = anomalyReport; //invalid xml chars replaced in AgentScanner.StartScanTask()
                        response.ResponseInfo = "Scan complete.";
                        response.ResponseLog = CwXML.ReplaceInvalidXmlChars(scannerLog.ToString());
                    }
                    else
                    {
                        response.ResponseCode = CwConstants.AGENTRESPONSE_FAIL;
                        response.ResponseInfo = "An unrecoverable error occured during the scan.";
                    }
                }
            }
            #endregion
            //-------------------------------------------------------------
            //
            //                  EXIT, NO MORE COMMANDS
            //
            //-------------------------------------------------------------
            #region EXIT
            else if (command.CommandCode == CwConstants.AGENTCMD_EXIT || command.CommandCode == CwConstants.AGENTCMD_NOMORECOMMANDS)
            {
                //
                //NO ACTION REQUIRED
                //
            }
            #endregion
            //-------------------------------------------------------------
            //
            //                  INVALID COMMAND
            //
            //-------------------------------------------------------------
            #region INVALID COMMAND
            else if (command.CommandCode == CwConstants.AGENTCMD_UNKNOWN)
            {
                response.ResponseCode = CwConstants.AGENTRESPONSE_FAIL;
                //the error is stored in this member of the fake command we created earlier
                response.ResponseInfo = string.Join(",", command.CommandParameters);
            }
            #endregion
            //-------------------------------------------------------------
            //
            //              RECEIVE NEW SIGNATURE UPDATE FILE
            //
            //-------------------------------------------------------------
            #region RECEIVE NEW SIGNATURE UPDATE FILE
            else if (command.CommandCode == CwConstants.AGENTCMD_UPDATESIG)
            {
                //send a response then prepare to receive
                WriteConnectionLog("CONNECT:  Got command to download new signature file...");

                CwXML.CodewordAgentResponse response2 = new CwXML.CodewordAgentResponse();
                response2.CommandReceiveDate = DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss");
                response2.CommandProcessingStartDate = DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss");
                response2.ResponseCode = CwConstants.AGENTRESPONSE_OK_SENDFILE;
                response2.CommandCodeReceived = command.CommandCode;

                WriteConnectionLog("CONNECT:  Sending response...");

                //send response
                try
                {
                    SendResponse(response2);
                }
                catch (Exception ex)
                {
                    WriteConnectionLog("Failed to send response in preparation for file retrieval:  " + ex.Message);
                    response.ResponseCode = CwConstants.AGENTRESPONSE_FAIL;
                    response.ResponseInfo = "Failed to send response in preparation for file retrieval:  " + ex.Message;
                    return response;
                }

                byte[] filedata;

                WriteConnectionLog("CONNECT:  Waiting for file...");

                //receive the file
                try
                {
                    filedata = ReceiveFile();
                }
                catch (Exception ex)
                {
                    WriteConnectionLog("Failed to receive file contents:  " + ex.Message);
                    response.ResponseCode = CwConstants.AGENTRESPONSE_FAIL;
                    response.ResponseInfo = "Failed to receive file contents:  " + ex.Message;
                    return response;
                }

                WriteConnectionLog("CONNECT:  File retrieved, saving locally...");

                //overwrite our current XML signature file
                try
                {
                    if (File.Exists("CwAgentSignatures.xml"))
                        File.Delete("CwAgentSignatures.xml");

                    AgentScanner.EnvironmentHelper.BinaryWrite("CwAgentSignatures.XML", filedata);
                }
                catch (Exception ex)
                {
                    WriteConnectionLog("Failed to write new signature file:  " + ex.Message);
                    response.ResponseCode = CwConstants.AGENTRESPONSE_FAIL;
                    response.ResponseInfo = "Failed to write new signature file:  " + ex.Message;
                    return response;
                }

                //success!
                response.ResponseInfo = "Successfully updated signatures file.";
            }
            #endregion

            response.CommandProcessingEndDate = DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss");

            return response;
        }