///////////////////////////////////////////////////// // // // ScanForFileSignatures() // // // ///////////////////////////////////////////////////// //Description: Scans all logical drives for the given // file signatures. //Returns: nothing; side-effect on passed-in results ///////////////////////////////////////////////////// internal void ScanForFileSignatures(CwXML.FileSignature[] FileSignatures, ref CwXML.FileSignatureMatch[] matches) { //get list of logical drives string[] drives = Environment.GetLogicalDrives(); int numMalware = 0; ArrayList matchList; ArrayList matchRecordsList = new ArrayList(); AgentScanLog.AppendLine("SCAN: Drives: " + string.Join(",", drives)); //----------------------------------------------------------- // SCAN DISKS FOR FILE SIGNATURE MATCHES //----------------------------------------------------------- //loop through all our disk drives - returns it as C:\, D:\, F:\ foreach (string drive in drives) { AgentScanLog.AppendLine("SCAN: Scanning " + drive + "..."); //loop through all signatures foreach (CwXML.FileSignature signature in FileSignatures) { //perform search based on parameters above (some may be empty) try { matchList = FileSearch(drive, signature.FileName, signature.FileHash, signature.FileHashType, signature.FileSize.ToString(), signature.FilePEHeaderSignature); } catch (Exception ex) { AgentScanLog.AppendLine("SCAN: Failed to scan drive: " + ex.Message); break; //dont continue scanning for signatures on this drive. } AgentScanLog.AppendLine("SCAN: There were " + matchList.Count.ToString() + " matches for this signature."); //if we got a match, add those results to our array of arrays if (matchList.Count > 0) { AgentScanLog.AppendLine("file search matches: " + string.Join(",", (string[])matchList.ToArray(typeof(string)))); foreach (string fullPathToMatch in matchList) { //get info about this file FileInfo f; try { f = new FileInfo(fullPathToMatch); } catch (Exception ex) { AgentScanLog.AppendLine("SCAN: Error querying file '" + fullPathToMatch + "': " + ex.Message); continue; } CwXML.FileSignatureMatch fm = new CwXML.FileSignatureMatch(); fm.FileName = f.Name; fm.FileSize = f.Length; fm.FullPath = f.FullName; //if no file hash was specified in the signature, create one now (MD5 only) if (signature.FileHash == "") { fm.FileHash = GetMD5HashOfFile(f.FullName); fm.FileHashType = "MD5"; } else { fm.FileHash = signature.FileHash; fm.FileHashType = signature.FileHashType; } //if PE header signature was given in signature, save it if (signature.FilePEHeaderSignature != "") { fm.FilePEHeaderSignature = signature.FilePEHeaderSignature; } fm.Action = signature.Action; //get various file attribs fm.FileLastAccessDate = f.LastAccessTime.ToLongDateString(); fm.FileLastModifiedDate = f.LastWriteTime.ToLongDateString(); fm.FileCreationDate = f.CreationTime.ToLongDateString(); //add it to list matchRecordsList.Add(fm); } numMalware++; } } AgentScanLog.AppendLine("SCAN: Scan of " + drive + " complete (" + numMalware.ToString() + " malicious files found)."); numMalware = 0; } //we've scanned all disks for all file signatures. //if we got matches, create a match record for them if (matchRecordsList.Count > 0) { matches = new CwXML.FileSignatureMatch[matchRecordsList.Count]; int i = 0; foreach (CwXML.FileSignatureMatch matchRecord in matchRecordsList) { matches[i] = new CwXML.FileSignatureMatch(); matches[i] = matchRecord; i++; } } else { matches = new CwXML.FileSignatureMatch[0]; } }
///////////////////////////////////////////////////// // // // GetMitigateItems() // // // ///////////////////////////////////////////////////// //Description: Crawls the GUI listview controls that // hold the registry, file and memory // signature matches. It builds an XML // structure from these values in preparation // for sending them to the agent for mitigation. // //Returns: void ///////////////////////////////////////////////////// private CwXML.CodewordAgentSignatureMatches GetCollectMitigateItems(ref string outputMessage, string mitigateOrCollectMsg) { int numRegMitigate = 0,numFileMitigate=0,numMemMitigate=0; int count = 0; bool mitigateAll = false; CwXML.CodewordAgentSignatureMatches matches = new CwXML.CodewordAgentSignatureMatches(); outputMessage = ""; //------------------------------------- // CALCULATE COUNTS //------------------------------------- foreach (ListViewItem lvi in AgentResults_RegistryListview.Items) if (lvi.Checked) numRegMitigate++; foreach (ListViewItem lvi in AgentResults_FileListview.Items) if (lvi.Checked) numFileMitigate++; foreach (ListViewItem lvi in AgentResults_MemoryListview.Items) if (lvi.Checked) numMemMitigate++; //if there were no items selected, prompt to mitigate all findings if ((numRegMitigate + numFileMitigate + numMemMitigate) == 0) { if (MessageBox.Show("No findings were selected. Would you like to "+mitigateOrCollectMsg+" all findings?", mitigateOrCollectMsg+" all findings?", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question) != DialogResult.Yes) return null; numRegMitigate = AgentResults_RegistryListview.Items.Count; numFileMitigate = AgentResults_FileListview.Items.Count; numMemMitigate = AgentResults_MemoryListview.Items.Count; mitigateAll = true; } CwXML.RegistrySignatureMatch[] regMatchesToMitigate = new CwXML.RegistrySignatureMatch[numRegMitigate]; CwXML.FileSignatureMatch[] fileMatchesToMitigate = new CwXML.FileSignatureMatch[numFileMitigate]; CwXML.MemorySignatureMatch[] memMatchesToMitigate = new CwXML.MemorySignatureMatch[numMemMitigate]; //------------------------------------- // REGISTRY //------------------------------------- if (numRegMitigate > 0) { outputMessage += "Registry findings (" + numRegMitigate + "):\n"; //build list of registry signature matches to mitigate foreach (ListViewItem lvi in AgentResults_RegistryListview.Items) { if (!lvi.Checked && !mitigateAll) continue; //add to display based on action selected for this finding outputMessage += " " + lvi.SubItems[0].Text + "\\" + lvi.SubItems[1] + " : " + lvi.SubItems[5].Text + "\n"; regMatchesToMitigate[count] = new CwXML.RegistrySignatureMatch(); regMatchesToMitigate[count].RegistryKeyName = lvi.SubItems[0].Text; regMatchesToMitigate[count].RegistryValueName = lvi.SubItems[1].Text; regMatchesToMitigate[count].RegistryValueData = lvi.SubItems[2].Text; regMatchesToMitigate[count].RegistryChangeValueData = lvi.SubItems[3].Text; try { regMatchesToMitigate[count].IsFileOnDisk = bool.Parse(lvi.SubItems[4].Text); } catch (Exception) { regMatchesToMitigate[count].IsFileOnDisk = false; } regMatchesToMitigate[count].Action = lvi.SubItems[5].Text; try { regMatchesToMitigate[count].ActionSuccessful = bool.Parse(lvi.SubItems[6].Text); } catch (Exception) { regMatchesToMitigate[count].ActionSuccessful = false; } count++; } count = 0; } //------------------------------------- // FILE //------------------------------------- if (numFileMitigate > 0) { outputMessage += "File findings (" + numFileMitigate + "):\n"; //build list of registry signature matches to mitigate foreach (ListViewItem lvi in AgentResults_FileListview.Items) { if (!lvi.Checked && !mitigateAll) continue; //add to display based on action selected for this finding if (lvi.SubItems[0].Text != "") //filename outputMessage += " " + lvi.SubItems[1].Text + " : " + lvi.SubItems[8].Text + "\n"; else if (lvi.SubItems[3].Text != "") //hash outputMessage += " [Hash=" + lvi.SubItems[3].Text + "] : " + lvi.SubItems[8].Text + "\n"; else if (lvi.SubItems[2].Text != "") //filesize outputMessage += " [FileSize=" + lvi.SubItems[2].Text + "] : " + lvi.SubItems[8].Text + "\n"; fileMatchesToMitigate[count] = new CwXML.FileSignatureMatch(); fileMatchesToMitigate[count].FileName = lvi.SubItems[0].Text; fileMatchesToMitigate[count].FullPath = lvi.SubItems[1].Text; long.TryParse(lvi.SubItems[2].Text, out fileMatchesToMitigate[count].FileSize); fileMatchesToMitigate[count].FileHash = lvi.SubItems[3].Text; fileMatchesToMitigate[count].FilePEHeaderSignature = lvi.SubItems[4].Text; fileMatchesToMitigate[count].FileCreationDate = lvi.SubItems[5].Text; fileMatchesToMitigate[count].FileLastAccessDate = lvi.SubItems[6].Text; fileMatchesToMitigate[count].FileLastModifiedDate = lvi.SubItems[7].Text; fileMatchesToMitigate[count].Action = lvi.SubItems[8].Text; try { fileMatchesToMitigate[count].ActionSuccessful = bool.Parse(lvi.SubItems[9].Text); } catch (Exception) { fileMatchesToMitigate[count].ActionSuccessful = false; } count++; } count = 0; } //------------------------------------- // MEMORY //------------------------------------- if (numMemMitigate > 0) { outputMessage += "Memory findings (" + numMemMitigate + "):\n"; //build list of registry signature matches to mitigate foreach (ListViewItem lvi in AgentResults_MemoryListview.Items) { if (!lvi.Checked && !mitigateAll) continue; outputMessage += " " + lvi.SubItems[2].Text + " (" + lvi.SubItems[0].Text + ") : " + lvi.SubItems[7].Text; //we cant populate all the fields of the memorysignaturematch structure, //because we didn't populate the GUI listview with all these fields (there are too many) //however, memory mitigation consists of killing the process by name/pid or suspending the thread. //so we dont need all that crap anyway. memMatchesToMitigate[count] = new CwXML.MemorySignatureMatch(); uint.TryParse(lvi.SubItems[0].Text, out memMatchesToMitigate[count].ProcessId); uint.TryParse(lvi.SubItems[1].Text, out memMatchesToMitigate[count].ParentProcessId); memMatchesToMitigate[count].ProcessName = lvi.SubItems[2].Text; memMatchesToMitigate[count].ChildThreadIds = lvi.SubItems[6].Text; memMatchesToMitigate[count].Action = lvi.SubItems[7].Text; try { memMatchesToMitigate[count].ActionSuccessful = bool.Parse(lvi.SubItems[8].Text); } catch (Exception) { memMatchesToMitigate[count].ActionSuccessful = false; } count++; } } matches.RegistrySignatureMatches = regMatchesToMitigate; matches.FileSignatureMatches = fileMatchesToMitigate; matches.MemorySignatureMatches = memMatchesToMitigate; return matches; }
///////////////////////////////////////////////////// // // // ScanForFileSignatures() // // // ///////////////////////////////////////////////////// //Description: Scans all logical drives for the given // file signatures. //Returns: nothing; side-effect on passed-in results ///////////////////////////////////////////////////// internal void ScanForFileSignatures(CwXML.FileSignature[] FileSignatures, ref CwXML.FileSignatureMatch[] matches) { //get list of logical drives string[] drives = Environment.GetLogicalDrives(); int numMalware=0; ArrayList matchList; ArrayList matchRecordsList=new ArrayList(); AgentScanLog.AppendLine("SCAN: Drives: " + string.Join(",", drives)); //----------------------------------------------------------- // SCAN DISKS FOR FILE SIGNATURE MATCHES //----------------------------------------------------------- //loop through all our disk drives - returns it as C:\, D:\, F:\ foreach (string drive in drives) { AgentScanLog.AppendLine("SCAN: Scanning " + drive + "..."); //loop through all signatures foreach (CwXML.FileSignature signature in FileSignatures) { //perform search based on parameters above (some may be empty) try { matchList = FileSearch(drive, signature.FileName, signature.FileHash, signature.FileHashType, signature.FileSize.ToString(), signature.FilePEHeaderSignature); } catch (Exception ex) { AgentScanLog.AppendLine("SCAN: Failed to scan drive: " + ex.Message); break; //dont continue scanning for signatures on this drive. } AgentScanLog.AppendLine("SCAN: There were "+matchList.Count.ToString()+" matches for this signature."); //if we got a match, add those results to our array of arrays if (matchList.Count > 0) { AgentScanLog.AppendLine("file search matches: " + string.Join(",", (string[])matchList.ToArray(typeof(string)))); foreach (string fullPathToMatch in matchList) { //get info about this file FileInfo f; try { f = new FileInfo(fullPathToMatch); } catch (Exception ex) { AgentScanLog.AppendLine("SCAN: Error querying file '" + fullPathToMatch + "': " + ex.Message); continue; } CwXML.FileSignatureMatch fm = new CwXML.FileSignatureMatch(); fm.FileName = f.Name; fm.FileSize = f.Length; fm.FullPath = f.FullName; //if no file hash was specified in the signature, create one now (MD5 only) if (signature.FileHash == "") { fm.FileHash = GetMD5HashOfFile(f.FullName); fm.FileHashType = "MD5"; } else { fm.FileHash = signature.FileHash; fm.FileHashType = signature.FileHashType; } //if PE header signature was given in signature, save it if (signature.FilePEHeaderSignature != "") fm.FilePEHeaderSignature = signature.FilePEHeaderSignature; fm.Action = signature.Action; //get various file attribs fm.FileLastAccessDate = f.LastAccessTime.ToLongDateString(); fm.FileLastModifiedDate = f.LastWriteTime.ToLongDateString(); fm.FileCreationDate = f.CreationTime.ToLongDateString(); //add it to list matchRecordsList.Add(fm); } numMalware++; } } AgentScanLog.AppendLine("SCAN: Scan of " + drive + " complete (" + numMalware.ToString() + " malicious files found)."); numMalware = 0; } //we've scanned all disks for all file signatures. //if we got matches, create a match record for them if (matchRecordsList.Count > 0) { matches = new CwXML.FileSignatureMatch[matchRecordsList.Count]; int i = 0; foreach (CwXML.FileSignatureMatch matchRecord in matchRecordsList) { matches[i] = new CwXML.FileSignatureMatch(); matches[i] = matchRecord; i++; } } else matches = new CwXML.FileSignatureMatch[0]; }