public void addReadEvent(FileIOReadWriteTraceData readEvent) { //first check for correlation string currFileName = Path.GetFileNameWithoutExtension(readEvent.FileName); ReadEventTracker existingReadEvent = null; foreach (ReadEventTracker ret in readEvents) { if (Path.GetFileNameWithoutExtension(ret.fileName).ToLower() == currFileName.ToLower()) { existingReadEvent = ret; break; } } //new read event if (existingReadEvent == null) { ReadEventTracker ret = new ReadEventTracker(readEvent); readEvents.Add(ret); } else { readEvents.Remove(existingReadEvent); existingReadEvent.updateEvent(readEvent); readEvents.Add(existingReadEvent); } }
public void addWriteEvent(FileIOReadWriteTraceData writeEvent) { //first check for correlation string currFileName = Path.GetFileNameWithoutExtension(writeEvent.FileName); ReadEventTracker correspondingReadEvent = null; int corrReadEvent = -1; int i = 0; foreach (ReadEventTracker ret in readEvents) { if (Path.GetFileNameWithoutExtension(ret.fileName).ToLower() == currFileName.ToLower()) { corrReadEvent = i; correspondingReadEvent = ret; break; } i++; } // There are times when we receive writes before reads are detected. The obvious case is // when the file written to has changed it's name drastically and we fail to recognize it. // For now these events are dropped. if (corrReadEvent == -1) { return; } // check timestamp // doesn't matter if the writeEvent is new or old it still needs to be under the threshold if (writeEvent.TimeStampRelativeMSec - correspondingReadEvent.eventTime > IO_DELTA_THRESHOLD) { Out.WriteLine("Timestamp for incoming writeEvent is outside of threshold [" + (writeEvent.TimeStampRelativeMSec - correspondingReadEvent.eventTime).ToString() + "]. Disregarding: " + writeEvent.FileName); return; } ////////////////////////////////////// // at this point we know there has been a Read and a write to the same file, from the same process // and it was within the timing threshold. All that's left is to check the size of the read first // the file write. ////////////////////////////////////// // Check if previous event exist WriteEventTracker tempWE = null; foreach (WriteEventTracker wet in writeEvents) { if (writeEvent.FileName == wet.fileName) { tempWE = wet; break; } } //if it's new if (tempWE == null) { //update time stamps firstWriteTime = writeEvent.TimeStampRelativeMSec; lastWriteTime = writeEvent.TimeStampRelativeMSec; bool suspicious = false; if (writeEvent.IoSize - correspondingReadEvent.fileSize >= 0 && writeEvent.IoSize - correspondingReadEvent.fileSize <= READ_WRITE_SIZE_DIFF_THRESHOLD) { suspicious = true; Out.WriteLine("[!] Suspicious write event detected! " + writeEvent.FileName); Out.WriteLine("\tSize of file write(s): " + writeEvent.IoSize.ToString() + " Size of file read(s): " + correspondingReadEvent.fileSize.ToString() + ". PID: " + writeEvent.ProcessID.ToString() + ". Process name: " + writeEvent.ProcessName); //if we encounter a certain number of suspicious events we call it ransomware! if (suspiciousWriteEvents.Count >= SUSPICOUS_EVENTS_THRESHOLD) { Out.WriteLine("[!!] Ransomware detected! - PID[" + writeEvent.ProcessID.ToString() + "] Process Name: " + writeEvent.ProcessName); } //don't add duplicates bool dup = false; foreach (WriteEventTracker swe in suspiciousWriteEvents) { if (swe.fileName == writeEvent.FileName) { dup = true; Out.WriteLine("\t Already detected entry, not added"); } } if (!dup) { suspiciousWriteEvents.Add(new WriteEventTracker(writeEvent, false)); } } WriteEventTracker wet = new WriteEventTracker(writeEvent, suspicious); writeEvents.Add(wet); } //update existing write event else { //remove old before we add in our updated version writeEvents.Remove(tempWE); //update time stamps firstWriteTime = writeEvent.TimeStampRelativeMSec; lastWriteTime = writeEvent.TimeStampRelativeMSec; //update time, file size with current time then check tempWE.updateEvent(writeEvent); if (tempWE.fileSize - correspondingReadEvent.fileSize >= 0 && tempWE.fileSize - correspondingReadEvent.fileSize <= READ_WRITE_SIZE_DIFF_THRESHOLD) { Out.WriteLine("[!] Suspicious write event on existing file: " + writeEvent.FileName); Out.WriteLine("\tSize of file write(s): " + tempWE.fileSize.ToString() + " Size of file read(s): " + correspondingReadEvent.fileSize.ToString() + ". PID: " + correspondingReadEvent.pid.ToString() + ". Process name: " + writeEvent.ProcessName); //if we encounter a certain number of suspicious events we call it cryptolocker if (suspiciousWriteEvents.Count >= SUSPICOUS_EVENTS_THRESHOLD) { Out.WriteLine("[!!] Ransomware detected! - PID[" + writeEvent.ProcessID.ToString() + "] Process Name: " + writeEvent.ProcessName); } //don't add duplicates bool dup = false; foreach (WriteEventTracker swe in suspiciousWriteEvents) { if (swe.fileName == tempWE.fileName) { dup = true; Out.WriteLine("\tAlready detected entry, not added"); } } if (!dup) { suspiciousWriteEvents.Add(tempWE); } } writeEvents.Add(tempWE); } }