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
        /////////////////////////////////////////////////////
        //                                                 //
        // 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;
        }