Пример #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;
        }
Пример #2
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;
        }
Пример #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;
        }
Пример #4
0
        /////////////////////////////////////////////////////
        //                                                 //
        // PerformMitigationTasksButton_Click()            //
        //                                                 //
        /////////////////////////////////////////////////////
        //Description:  Applies mitigation actions to selected
        //              rows of listviews.
        //
        //Returns:      void
        /////////////////////////////////////////////////////
        private void PerformMitigationTasksButton_Click(object sender, EventArgs e)
        {
            //make sure we are connected first
            if (!CurrentClient.IsConnected())
            {
                MessageBox.Show("Error:  Connection to remote agent has been lost.");
                ToggleButtons(false, false);
                return;
            }

            if (LastAnomalyReport == null)
            {
                MessageBox.Show("There are no signature matches to mitigate.");
                return;
            }
            if (LastAnomalyReport.SignatureMatches == null)
            {
                MessageBox.Show("There are no signature matches to mitigate.");
                return;
            }

            //set our own socket's read timeout to something high - a scan can take some time
            CurrentClient.SetStreamTimeout("read", CwConstants.STREAM_MITIGATE_TASK_TIMEOUT);

            //prepare an anomaly report object for mitigation tasks.
            CwXML.CodewordAgentAnomalyReport report = new CwXML.CodewordAgentAnomalyReport();
            //parse GUI listview items into an XML structure for transport.
            string outputMsg = "";
            CwXML.CodewordAgentSignatureMatches matches = GetCollectMitigateItems(ref outputMsg, "mitigate");

            //if none were selected, and the user declined to mitigate all items, just bail.
            if (matches == null)
                return;

            //verify the operation
            if (MessageBox.Show("The following irreversible mitigation operations are about to be issued:\n\n" + outputMsg + "\n\nAre you SURE?", "Review mitigation tasks", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question) != DialogResult.Yes)
                return;

            report.SignatureMatches = matches;
            report.HeuristicMatches = new CwXML.CodewordAgentHeuristicMatches(); //empty

            //disable buttons until response is received.
            //this prevents duplicate or conflicting commands from being issued
            ToggleButtons(false, true);

            //do lengthy operation in background worker thread
            //here we will need to setup any args the lengthy operation will need in the separate thread
            ArrayList args = new ArrayList();
            args.Add(CurrentClient);
            args.Add(CwConstants.AGENTCMD_MITIGATE);
            args.Add(new string[]{""});
            args.Add(CwConstants.STREAM_MITIGATE_TASK_TIMEOUT);
            args.Add(true);
            args.Add(report); //a special 6th argument for mitigation commands.
            AgentTaskBackgroundWorker = new BackgroundWorker();
            AgentTaskBackgroundWorker.WorkerReportsProgress = true;
            AgentTaskBackgroundWorker.DoWork += new DoWorkEventHandler(BackgroundWorker_DoWork);
            AgentTaskBackgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(BackgroundWorker_RunWorkerCompleted);
            AgentTaskBackgroundWorker.ProgressChanged += new ProgressChangedEventHandler(BackgroundWorker_ProgressChanged);
            AgentTaskBackgroundWorker.RunWorkerAsync(args);
        }
Пример #5
0
        /////////////////////////////////////////////////////
        //                                                 //
        // BackgroundWorker_DoWork()                       //
        //                                                 //
        /////////////////////////////////////////////////////
        //Description:  This function is called as the entry point
        //              to the background worker thread which handles
        //              lengthy operations on behalf of the main
        //              GUI thread, so that the UI doesn't stall.
        //
        //              NOTE:  Since this function runs in a separate
        //              thread, it does not have access to any global
        //              variables or GUI controls from the main thread.
        //
        //Returns:      void
        /////////////////////////////////////////////////////
        private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            //get arguments
            ArrayList args = (ArrayList)e.Argument;
            SslTcpClient client = (SslTcpClient)args[0];
            int agentCommand = (int)args[1];
            string[] parameters = (string[])args[2];
            int timeout = (int)args[3];
            bool required = (bool)args[4];
            CwXML.CodewordAgentAnomalyReport CollectionOrMitigationTask = new CwXML.CodewordAgentAnomalyReport();
            //this 6th argument is ONLY used when we are sending a MITIGATION command
            if (args.Count == 6)
                CollectionOrMitigationTask = (CwXML.CodewordAgentAnomalyReport)args[5];

            //setup return object
            //return the agent command issued even if an error occurs
            ArrayList result = new ArrayList();
            result.Add(agentCommand);

            //send command
            try
            {
                //------------------------------------------------
                //          AGENT COMMAND PRE-PROCESSING
                //------------------------------------------------
                //*DO NOT* forward this command to the agent.
                //send the XML update file the agent is waiting on.
                if (agentCommand == CwConstants.AGENTCMD_SENDUPDATEFILE)
                {
                    client.SendFile(UpdateFilename);
                }
                //*DO NOT* forward this command to the agent.
                //receive the evidence files the agent is waiting to send us.
                else if (agentCommand == CwConstants.AGENTCMD_RECVEVIDENCEFILES)
                {
                    //get the file names and file sizes to download - this will be used in ReceiveFiles()
                    CwXML.FileSignatureMatch[] fileSigsToDownload = CollectionOrMitigationTask.SignatureMatches.FileSignatureMatches;
                    client.ReceiveFiles(SaveCollectionEvidenceToFolder,fileSigsToDownload);
                }
                //*DO* forward this command to the agent for direct processing.
                else
                {
                    client.SendCommand(agentCommand, parameters, timeout, required, CollectionOrMitigationTask);
                }
            }
            catch (Exception ex)
            {
                /*
                result.Add(CwConstants.ADMINCONSOLE_ERROR_CMDFAILED);
                result.Add(ex.Message);
                e.Result = result;
                return;
                 * */
            }

            AgentTaskBackgroundWorker.ReportProgress(50);

            //receive response
            CwXML.CodewordAgentResponse response = null;

            try
            {
                response = client.ReadResponse();
            }
            catch (Exception ex)
            {
                /*
                result.Add(CwConstants.ADMINCONSOLE_ERROR_RESPONSEFAILED);
                result.Add(ex.Message);
                e.Result = result;
                return;
                 * */
            }

            AgentTaskBackgroundWorker.ReportProgress(100);

            //add the response object to the return
            result.Add(response);
            e.Result = result;
            return;
        }
Пример #6
0
        /////////////////////////////////////////////////////
        //                                                 //
        // BackgroundWorker_RunWorkerCompleted()           //
        //                                                 //
        /////////////////////////////////////////////////////
        //Description:  This function is called when the background
        //              worker thread signals that it is finished.
        //              It runs in the context of the main thread,
        //              so it is safe to modify GUI or reference
        //              main thread global variables here.
        //
        //Returns:      void
        /////////////////////////////////////////////////////
        private void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            ArrayList result = (ArrayList)e.Result;
            int commandSent = (int)result[0];
            //cast the response object from the thread's result object
            CwXML.CodewordAgentResponse response = (CwXML.CodewordAgentResponse)result[1];

            //if there are 3 objects in this arraylist, we KNOW the command failed.
            //if (result.Count == 3)
            if (response == null)
            {
                /*
                int errorCode = (int)result[1];
                string errMsg = (string)result[2];

                if (errorCode == CwConstants.ADMINCONSOLE_ERROR_CMDFAILED)
                    MessageBox.Show("Failed to send command " + commandSent.ToString() + ":  " + errMsg);
                else
                    MessageBox.Show("Failed to receive response:  " + errMsg);
                */

                MessageBox.Show("No response was sent from the client.");
                if (!CurrentClient.IsConnected())
                    ToggleButtons(false, false);

                AgentTaskProgressBarLabel.Text = "Task complete.";
                AgentTaskProgressBar.Value = 0;
                AgentTaskProgressBar.Refresh();
                AgentTaskProgressBarLabel.Refresh();

                //always re-enable all buttons if the command failed
                ToggleButtons(true, false);

                return;
            }

            //-------------------------------------------------------------
            //
            //                  GET SYSTEM INFORMATION
            //
            //-------------------------------------------------------------
            #region GET SYSTEM INFORMATION
            if (commandSent == CwConstants.AGENTCMD_GETSYSTEMINFO)
            {
                //extract the agent results object
                if (response.ResponseSystemInformation != null)
                {
                    //save in our global variable
                    LatestSystemInformation = response.ResponseSystemInformation;
                    //force GUI update
                    UpdateSystemInformationListview();
                }

                CopyResponseToLogWindow(response);

                //add to recently viewed agents
                string agentIP = ConnectToAgentIP.Text;
                int agentPort = int.Parse(ConnectToAgentPort.Text);
                bool addToList = true;
                foreach (TreeNode node in RecentAgentsTreeview.Nodes)
                    if (node.Text == agentIP)
                        addToList = false;
                if (addToList)
                    RecentAgentsTreeview.Nodes.Add(agentIP);
            }
            #endregion
            //-------------------------------------------------------------
            //
            //                  START A NEW SCAN
            //
            //-------------------------------------------------------------
            #region START A NEW SCAN
            else if (commandSent == CwConstants.AGENTCMD_STARTSCAN)
            {
                //extract the agent results object
                if (response.ResponseAnomalyReport != null)
                {
                    //save in our global variable
                    LastAnomalyReport = response.ResponseAnomalyReport;
                    //force GUI update
                    UpdateResultsListviews();
                }
            }
            #endregion
            //-------------------------------------------------------------
            //
            //              SEND NEW SIGNATURE FILE
            //
            //-------------------------------------------------------------
            #region SEND NEW SIGNATURE FILE
            else if (commandSent == CwConstants.AGENTCMD_UPDATESIG)
            {
                //CASE 1:  we are arriving from the first thread completing, in which case we need
                //to send the actual update file
                if (response.ResponseCode == CwConstants.AGENTRESPONSE_OK_SENDFILE)
                {
                    //we have to do something tricky here, so that our DoWork() function
                    //doesnt send the internal command AGENTCMD_SENDUPDATEFILE to the remote agent.
                    //create a second thread to actually send the update file.
                    //we previously created a thread to send the command to notify the agent we are
                    //about to send a file.  we are at the point right now where the response from
                    //the agent has been received, and it is awaiting the actual file.  so send it.
                    ArrayList args = new ArrayList();
                    args.Add(CurrentClient);
                    args.Add(CwConstants.AGENTCMD_SENDUPDATEFILE);
                    args.Add(new string[] { "" });
                    args.Add(CwConstants.STREAM_UPDATE_SIGNATURES_TIMEOUT);
                    args.Add(true);
                    AgentTaskBackgroundWorker = new BackgroundWorker();
                    AgentTaskBackgroundWorker.WorkerReportsProgress = true;
                    AgentTaskBackgroundWorker.DoWork += new DoWorkEventHandler(BackgroundWorker_DoWork);
                    AgentTaskBackgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(BackgroundWorker_RunWorkerCompleted);
                    AgentTaskBackgroundWorker.ProgressChanged += new ProgressChangedEventHandler(BackgroundWorker_ProgressChanged);
                    AgentTaskBackgroundWorker.RunWorkerAsync(args);
                }
                //CASE 2:  we are arriving from the second thread completing, in which case
                //we are done; the update file was sent and received successfully.
                else
                {
                    //..and we dont need to do anything!
                }
            }
            #endregion
            //-------------------------------------------------------------
            //
            //                      MITIGATE ITEMS
            //
            //-------------------------------------------------------------
            #region MITIGATE ITEMS
            else if (commandSent == CwConstants.AGENTCMD_MITIGATE)
            {
                if (LastAnomalyReport == null)
                    LastAnomalyReport = new CwXML.CodewordAgentAnomalyReport();

                if (response.ResponseAnomalyReport != null)
                {
                    //update our signatures listview with the copy we got back.
                    //the copy sent back to us contains ONLY THE FINDINGS THAT WERE MITIGATED.
                    //since the user has the option of selecting only a few for mitigation, we must
                    //search through all of the results in the GUI and update the ones that were changed.
                    FindAndUpdateMatchRecords(response.ResponseAnomalyReport.SignatureMatches);

                    //now repopulate the listviews with the udpated match records.
                    UpdateResultsListviews();
                }
            }
            #endregion
            //-------------------------------------------------------------
            //
            //                 COLLECT EVIDENCE ITEMS
            //
            //-------------------------------------------------------------
            #region COLLECT EVIDENCE ITEMS
            else if (commandSent == CwConstants.AGENTCMD_COLLECT)
            {
                //CASE 1:  we are arriving from the first thread completing, in which case we need
                //to prepare to receive the evidence files - send an internal msg to ourselves
                if (response.ResponseCode == CwConstants.AGENTRESPONSE_OK_RECVFILE)
                {
                    //we have to do something tricky here, so that our DoWork() function
                    //doesnt send the internal command AGENTCMD_RECVEVIDENCEFILE to the remote agent.
                    //create a second thread to actually receive the evidence file.
                    //we previously created a thread to send the command to notify the agent we want it
                    //to find and send us a file.  we are at the point right now where the response from
                    //the agent has been received, and it is waiting to send us the file.  so grab it!
                    ArrayList args = new ArrayList();
                    args.Add(CurrentClient);
                    args.Add(CwConstants.AGENTCMD_RECVEVIDENCEFILES);
                    args.Add(new string[] { "" });
                    args.Add(CwConstants.STREAM_COLLECT_TASK_TIMEOUT);
                    args.Add(true);
                    args.Add(LastCollectionTask);
                    AgentTaskBackgroundWorker = new BackgroundWorker();
                    AgentTaskBackgroundWorker.WorkerReportsProgress = true;
                    AgentTaskBackgroundWorker.DoWork += new DoWorkEventHandler(BackgroundWorker_DoWork);
                    AgentTaskBackgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(BackgroundWorker_RunWorkerCompleted);
                    AgentTaskBackgroundWorker.ProgressChanged += new ProgressChangedEventHandler(BackgroundWorker_ProgressChanged);
                    AgentTaskBackgroundWorker.RunWorkerAsync(args);
                }
                //CASE 2:  we are arriving from the second thread completing, in which case
                //we are done downloading.
                else
                {
                    //nothing to do..
                }
            }
            #endregion
            //-------------------------------------------------------------
            //
            //                      DISCONNECT
            //
            //-------------------------------------------------------------
            #region DISCONNECT
            else if (commandSent == CwConstants.AGENTCMD_NOMORECOMMANDS)
            {
                //make sure the remote end didnt terminate first
                if (CurrentClient.IsConnected())
                    CurrentClient.CloseConnection();

                CurrentClient = null;
            }
            #endregion

            CopyResponseToLogWindow(response);

            AgentTaskProgressBarLabel.Text = "Task complete.";
            AgentTaskProgressBar.Value = 0;
            AgentTaskProgressBar.Refresh();
            AgentTaskProgressBarLabel.Refresh();

            //always re-enable toolbar buttons unless this was a disconnect or halt command
            if (commandSent == CwConstants.AGENTCMD_EXIT || commandSent == CwConstants.AGENTCMD_NOMORECOMMANDS)
                ToggleButtons(false, false);
            else
                ToggleButtons(true, false);
        }
Пример #7
0
        /////////////////////////////////////////////////////
        //                                                 //
        // StartScanTask()                                 //
        //                                                 //
        /////////////////////////////////////////////////////
        //Description:  This function only performs the setup
        //              necessary to perform a scan of registry,
        //              disk and memory, and to report those
        //              results back to the admin console.
        //
        //Returns:      a stringbuilder object containing log data.
        /////////////////////////////////////////////////////
        internal StringBuilder StartScanTask(ref CwXML.CodewordAgentAnomalyReport anomalyReport)
        {
            //clear any existing results
            anomalyReport = new CwXML.CodewordAgentAnomalyReport();
            AgentHeuristicMatches = new CwXML.CodewordAgentHeuristicMatches();
            AgentHeuristicMatches.KernelModeMatches = new CwXML.KernelModeHeuristicMatches();
            AgentHeuristicMatches.UserModeMatches = new CwXML.UserModeHeuristicMatches();
            AgentSignatureMatches = new CwXML.CodewordAgentSignatureMatches();
            AgentSignatureMatches.RegistrySignatureMatches = new CwXML.RegistrySignatureMatch[0];
            AgentSignatureMatches.MemorySignatureMatches = new CwXML.MemorySignatureMatch[0];
            AgentSignatureMatches.FileSignatureMatches = new CwXML.FileSignatureMatch[0];
            //
            //1.  Load settings from XML file extracted to local dir from MSI
            //
            AgentScanLog.AppendLine("INITIALIZE:  Loading scan settings...");

            if (!LoadAgentSettings(ref AgentSettings))
                return AgentScanLog;

            //
            //2.  Load signatures - this only needs to be done once here for the whole file
            //
            AgentScanLog.AppendLine("SCAN:  Loading signatures from XML file...");

            if (!LoadAgentSignatures())
                return AgentScanLog;

            //
            //3.  Disable .NET security
            //
            EnvironmentHelper.ToggleDotnetSecurity("Off", "INITIALIZE");

            //
            //4.  kick off scan
            //
            AgentScanLog.AppendLine("SCAN:  Scan starting on " + DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss"));
            DoSignatureScan();
            //IMPORTANT:  pin the scan results object so the garbage collector doesn't mangle it...
            //GCHandle gchAgentSignatureMatches = GCHandle.Alloc(AgentSignatureMatches, GCHandleType.Pinned);

            //only auto-mitigate if option set.
            if (AgentSettings["Option_AutoMitigate"] == "True")
                DoMitigate();
            DoUserModeHeuristics();
            DoKernelModeHeuristics();
            AgentScanLog.AppendLine("SCAN:  Scan finished on " + DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss"));
            //
            //5.  re-enable .NET security
            //
            EnvironmentHelper.ToggleDotnetSecurity("On", "FINALIZE");

            //
            //6.  return our results object byref
            //
            //sanitize the XML by escaping invalid characters first
            int count = 0;

            foreach (CwXML.RegistrySignatureMatch match in AgentSignatureMatches.RegistrySignatureMatches)
            {
                match.RegistryValueData = CwXML.ReplaceInvalidXmlChars(match.RegistryValueData);
                match.RegistryValueName = CwXML.ReplaceInvalidXmlChars(match.RegistryValueName);
                AgentSignatureMatches.RegistrySignatureMatches[count] = match;
                count++;
            }

            count = 0;

            foreach (CwXML.MemorySignatureMatch match in AgentSignatureMatches.MemorySignatureMatches)
            {
                //keywords are not required in memory search - could just be looking for presence of a process name
                if (match.Keywords != null)
                    match.Keywords = CwXML.ReplaceInvalidXmlChars(match.Keywords);
                match.MatchingBlock = CwXML.ReplaceInvalidXmlChars(match.MatchingBlock);
                AgentSignatureMatches.MemorySignatureMatches[count] = match;
                count++;
            }

            //assign the fields of the passed-in object byref
            anomalyReport.SignatureMatches = AgentSignatureMatches;
            anomalyReport.HeuristicMatches = AgentHeuristicMatches;

            //release our pinned handle to results
            //gchAgentSignatureMatches.Free();

            return AgentScanLog;
        }