/// <summary> /// Monitor for module loads using the WMI Event Win32_ModuleLoadTrace. Optionally filter by module names. /// </summary> /// <param name="filters">A list of module names to filter for.</param> public static void MonitorModuleLoads(List <string> filters) { Console.WriteLine("Monitoring Win32_ModuleLoadTrace...\n"); while (true) { Win32_ModuleLoadTrace trace = new Win32_ModuleLoadTrace(); Win32_ModuleLoadTrace tracecomp = new Win32_ModuleLoadTrace(); //Get the details of the next module load trace = GetNextModuleLoad(filters); //If the trace is not empty if (!trace.Equals(tracecomp)) { Console.WriteLine(); //Display information from the event Console.WriteLine("[>] Process {0} has loaded a module:", trace.ProcessID); Console.WriteLine("{0,15} Win32_ModuleLoadTrace:", "[!]"); DateTime time = new DateTime(); DateTime.TryParse(trace.TIME_CREATED.ToString(), out time); time.ToLocalTime(); //TODO: Time is printing strangley Console.WriteLine("{0,15} (Event) TIME_CREATED: {1}", "[+]", time.ToString()); //TODO: Convert to hex Console.WriteLine("{0,15} (Process) ImageBase: {1}", "[+]", trace.ImageBase); Console.WriteLine("{0,15} (Process) DefaultBase: {1}", "[+]", trace.DefaultBase); Console.WriteLine("{0,15} (Module) FileName: {1}", "[+]", trace.FileName); Console.WriteLine("{0,15} (Module) TimeStamp: {1}", "[+]", trace.TimeDateSTamp); Console.WriteLine("{0,15} (Module) ImageSize: {1}", "[+]", trace.ImageSize); Console.WriteLine("{0,15} (Module) ImageChecksum: {1}", "[+]", trace.ImageChecksum); Console.WriteLine("{0,15} Additional Information:", "[>]"); Process process = SafeGetProcessByID(int.Parse(trace.ProcessID.ToString())); if (process != null) { Console.WriteLine("{0,30} Process Name: {1}", "[+]", process.ProcessName); Console.WriteLine("{0,30} Process User: {1}", "[+]", GetProcessUser(process)); } } } }
/// <summary> /// Get the details of the next module load /// </summary> /// <param name="filters">Filenames to filter for.</param> /// <returns></returns> public static Win32_ModuleLoadTrace GetNextModuleLoad(List <string> filters) { Win32_ModuleLoadTrace trace = new Win32_ModuleLoadTrace(); //Ideally, we would filter here to reduce the amount of events that we have to consume. //However, we cannot use the WHERE clause because the var startWatch = new ManagementEventWatcher(new WqlEventQuery("SELECT * FROM Win32_ModuleLoadTrace")); ManagementBaseObject e = startWatch.WaitForNextEvent(); //Instead, we filter here, because it's easy and we're a bit lazy if (filters.Count == 0 ^ filters.Contains(((ManagementBaseObject)e)["FileName"].ToString())) { if (((ManagementBaseObject)e)["SECURITY_DESCRIPTOR"] != null) { trace.SECURITY_DESCRIPTOR = (sbyte[])((ManagementBaseObject)e)["SECURITY_DESCRIPTOR"]; } if (((ManagementBaseObject)e)["TIME_CREATED"] != null) { trace.TIME_CREATED = (UInt64)((ManagementBaseObject)e)["TIME_CREATED"]; } if (((ManagementBaseObject)e)["FileName"] != null) { trace.FileName = (string)((ManagementBaseObject)e)["FileName"]; } if (((ManagementBaseObject)e)["DefaultBase"] != null) { trace.DefaultBase = (UInt64)((ManagementBaseObject)e)["DefaultBase"]; } if (((ManagementBaseObject)e)["ImageBase"] != null) { trace.ImageBase = (UInt64)((ManagementBaseObject)e)["ImageBase"]; } if (((ManagementBaseObject)e)["ImageChecksum"] != null) { trace.ImageChecksum = (UInt32)((ManagementBaseObject)e)["ImageChecksum"]; } if (((ManagementBaseObject)e)["ImageSize"] != null) { trace.ImageSize = (UInt64)((ManagementBaseObject)e)["ImageSize"]; } if (((ManagementBaseObject)e)["ProcessID"] != null) { trace.ProcessID = (UInt32)((ManagementBaseObject)e)["ProcessID"]; } if (((ManagementBaseObject)e)["TimeDateSTamp"] != null) { trace.TimeDateSTamp = (UInt32)((ManagementBaseObject)e)["TimeDateSTamp"]; } return(trace); } else { return(trace); } }
public static void CLRSentry() { //Sentries never sleep. //UCMJ Article 113 /* Any sentinel or look-out who is found drunk or sleeping upon his post, * or leaves it before he is regularly relieved, shall be punished, * if the offense is committed in time of war, by death or such other punishment as a court-martial may direct, * by if the offense is committed at any other time, * by such punishment other than death as court-martial may direct. */ while (true) { //Get the module load. Win32_ModuleLoadTrace trace = GetNextModuleLoad(); //Split the string[] parts = trace.FileName.Split('\\'); //Check whether it is a .NET Runtime DLL if (parts[parts.Length - 1].Contains("msco")) { Process proc = Process.GetProcessById((int)trace.ProcessID); //Check if the file is a .NET Assembly if (!IsValidAssembly(proc.StartInfo.FileName)) { //If it is not, then the CLR has been injected. Console.WriteLine(); Console.WriteLine("[!] CLR Injection has been detected!"); //Display information from the event Console.WriteLine("[>] Process {0} has loaded the CLR but is not a .NET Assembly:", trace.ProcessID); Console.WriteLine("{0,15} Win32_ModuleLoadTrace:", "[!]"); DateTime time = new DateTime(); DateTime.TryParse(trace.TIME_CREATED.ToString(), out time); time.ToLocalTime(); //TODO: Time is printing strangley Console.WriteLine("{0,15} (Event) TIME_CREATED: {1}", "[+]", time.ToString()); //TODO: Convert to hex Console.WriteLine("{0,15} (Process) ImageBase: {1}", "[+]", trace.ImageBase); Console.WriteLine("{0,15} (Process) DefaultBase: {1}", "[+]", trace.DefaultBase); Console.WriteLine("{0,15} (Module) FileName: {1}", "[+]", trace.FileName); Console.WriteLine("{0,15} (Module) TimeStamp: {1}", "[+]", trace.TimeDateSTamp); Console.WriteLine("{0,15} (Module) ImageSize: {1}", "[+]", trace.ImageSize); Console.WriteLine("{0,15} (Module) ImageChecksum: {1}", "[+]", trace.ImageChecksum); Console.WriteLine("{0,15} Additional Information:", "[>]"); Process process = SafeGetProcessByID(int.Parse(trace.ProcessID.ToString())); if (process != null) { Console.WriteLine("{0,30} Process Name: {1}", "[+]", process.ProcessName); Console.WriteLine("{0,30} Process User: {1}", "[+]", GetProcessUser(process)); } } } } }