public static void OnEtwEvent(Microsoft.O365.Security.ETW.IEventRecord record, string name) { // WARNING: this function is called from the worker thread string line = "ETW " + name + " id: " + record.Id + "; " + " opcode: " + record.Opcode + "; "; foreach (var property in record.Properties) { line += property.Name + ": "; switch ((EVT_VARIANT_TYPE)property.Type) { case EVT_VARIANT_TYPE.EvtVarTypeString: line += record.GetUnicodeString(property.Name); break; case EVT_VARIANT_TYPE.EvtVarTypeAnsiString: line += record.GetAnsiString(property.Name); break; case EVT_VARIANT_TYPE.EvtVarTypeByte: line += record.GetUInt8(property.Name); break; case EVT_VARIANT_TYPE.EvtVarTypeUInt16: line += record.GetUInt16(property.Name); break; case EVT_VARIANT_TYPE.EvtVarTypeUInt32: line += record.GetUInt32(property.Name); break; case EVT_VARIANT_TYPE.EvtVarTypeUInt64: line += record.GetUInt64(property.Name); break; case EVT_VARIANT_TYPE.EvtVarTypeSByte: line += record.GetInt8(property.Name); break; case EVT_VARIANT_TYPE.EvtVarTypeInt16: line += record.GetInt16(property.Name); break; case EVT_VARIANT_TYPE.EvtVarTypeInt32: line += record.GetInt32(property.Name); break; case EVT_VARIANT_TYPE.EvtVarTypeInt64: line += record.GetInt64(property.Name); break; case EVT_VARIANT_TYPE.EvtVarTypeGuid: break; // ??? default: break; } line += " (Type " + property.Type + ")"; line += "; "; } line += " proc (" + record.ProcessId + ")"; Console.WriteLine(line); }
private void OnDnsQueryEvent(Microsoft.O365.Security.ETW.IEventRecord record) { // WARNING: this function is called from the worker thread if (record.Id != 1001 && record.Id != 1004) { return; } DateTime TimeStamp = record.Timestamp; UInt32 Status = record.GetUInt32("Status", 0); int ProcessId = (int)record.ProcessId; int ThreadId = (int)record.ThreadId; var HostName = record.GetUnicodeString("NodeName", null); var Results = record.GetUnicodeString("Result", null); if (ProcessId == ProcFunc.CurID) { return; // ignore these events as thay are the result of reverse dns querries.... } /* * "192.168.163.1" "192.168.163.1;" * "localhost" "[::1]:8307;127.0.0.1:8307;" <- wtf is this why is there a port?! * "DESKTOP" "fe80::189a:f1c3:3e87:be81%12;192.168.10.12;" * "telemetry.malwarebytes.com" "54.149.69.204;54.200.191.52;54.70.191.27;54.149.66.105;54.244.17.248;54.148.98.86;" * "web.whatsapp.com" "31.13.84.51;" */ AppLog.Debug("Etw dns_query {0} => {1} for {2}", HostName, Results, ProcessId); App.engine?.RunInEngineThread(() => { // Note: this happens in the engine thread List <IPAddress> RemoteAddresses = new List <IPAddress>(); foreach (string Result in Results.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries)) { IPAddress Address = null; if (!IPAddress.TryParse(Result, out Address) && !IPAddress.TryParse(TextHelpers.Split2(Result, ":", true).Item1, out Address)) { continue; } RemoteAddresses.Add(Address); Dictionary <IPAddress, Dictionary <string, HostNameEntry> > dnsCache = dnsQueryCache.GetOrCreate(ProcessId); Dictionary <string, HostNameEntry> cacheEntries = dnsCache.GetOrCreate(Address); HostNameEntry cacheEntry; if (!cacheEntries.TryGetValue(HostName, out cacheEntry)) { cacheEntry = new HostNameEntry() { HostName = HostName }; cacheEntries.Add(HostName, cacheEntry); } cacheEntry.TimeStamp = TimeStamp; } DnsQueryEvent?.Invoke(this, new DnsEvent() { ProcessId = ProcessId, HostName = HostName, RemoteAddresses = RemoteAddresses, TimeStamp = TimeStamp }); }); }
private void OnNetworkEvent(Microsoft.O365.Security.ETW.IEventRecord record) { // WARNING: this function is called from the worker thread EtwNetEventType Type = EtwNetEventType.Unknown; UInt32 ProtocolType = 0; switch (record.Opcode) { case 0x0a: // send Type = EtwNetEventType.Send; ProtocolType = (UInt32)IPHelper.AF_INET.IP4 << 8; break; case 0x0b: // receive Type = EtwNetEventType.Recv; ProtocolType = (UInt32)IPHelper.AF_INET.IP4 << 8; break; case 0x0a + 16: // send ipv6 Type = EtwNetEventType.Send; ProtocolType = (UInt32)IPHelper.AF_INET.IP6 << 8; break; case 0x0b + 16: // receive ipv6 Type = EtwNetEventType.Recv; ProtocolType = (UInt32)IPHelper.AF_INET.IP6 << 8; break; default: return; } if (record.ProviderId.Equals(TcpIpGuid)) { ProtocolType |= (UInt32)IPHelper.AF_PROT.TCP; } else if (record.ProviderId.Equals(UdpIpGuid)) { ProtocolType |= (UInt32)IPHelper.AF_PROT.UDP; } else { return; } int ProcessId = -1; UInt32 TransferSize = 0; IPAddress LocalAddress = null; UInt16 LocalPort = 0; IPAddress RemoteAddress = null; UInt16 RemotePort = 0; if ((ProtocolType & ((UInt32)IPHelper.AF_INET.IP4 << 8)) == ((UInt32)IPHelper.AF_INET.IP4 << 8)) { TcpIpOrUdpIp_IPV4_Header data = (TcpIpOrUdpIp_IPV4_Header)Marshal.PtrToStructure(record.UserData, typeof(TcpIpOrUdpIp_IPV4_Header)); ProcessId = (int)data.PID; TransferSize = data.size; LocalAddress = new IPAddress((UInt32)data.saddr); LocalPort = (UInt16)IPAddress.NetworkToHostOrder((short)data.sport); RemoteAddress = new IPAddress((UInt32)data.daddr); RemotePort = (UInt16)IPAddress.NetworkToHostOrder((short)data.dport); } else if ((ProtocolType & ((UInt32)IPHelper.AF_INET.IP6 << 8)) == ((UInt32)IPHelper.AF_INET.IP6 << 8)) { TcpIpOrUdpIp_IPV6_Header data = (TcpIpOrUdpIp_IPV6_Header)Marshal.PtrToStructure(record.UserData, typeof(TcpIpOrUdpIp_IPV6_Header)); ProcessId = (int)data.PID; TransferSize = data.size; LocalAddress = new IPAddress(data.saddr); LocalPort = (UInt16)IPAddress.NetworkToHostOrder((short)data.sport); RemoteAddress = new IPAddress(data.daddr); RemotePort = (UInt16)IPAddress.NetworkToHostOrder((short)data.dport); } else { return; } // Note: Incomming UDP packets have the endpoints swaped :/ if ((ProtocolType & (UInt32)IPHelper.AF_PROT.UDP) == (UInt32)IPHelper.AF_PROT.UDP && Type == EtwNetEventType.Recv) { IPAddress TempAddresss = LocalAddress; UInt16 TempPort = LocalPort; LocalAddress = RemoteAddress; LocalPort = RemotePort; RemoteAddress = TempAddresss; RemotePort = TempPort; } App.engine?.RunInEngineThread(() => { // Note: this happens in the engine thread NetworkSocket Socket = FindSocket(SocketList, ProcessId, ProtocolType, LocalAddress, LocalPort, RemoteAddress, RemotePort, NetworkSocket.MatchMode.Strict); if (Socket == null) { Socket = new NetworkSocket(ProcessId, ProtocolType, LocalAddress, LocalPort, RemoteAddress, RemotePort); SocketList.Add(Socket.HashID, Socket); } switch (Type) { case EtwNetEventType.Send: Socket.CountUpload(TransferSize); break; case EtwNetEventType.Recv: Socket.CountDownload(TransferSize); break; } }); }
protected void OnEtwEvent(Microsoft.O365.Security.ETW.IEventRecord record) { OnEtwEvent(record, logName); }
private void OnProcessEvent(Microsoft.O365.Security.ETW.IEventRecord record) { // WARNING: this function is called from the worker thread if (record.Id != 0) { return; } if (record.Opcode == 1) // start { //EtwAbstractLogger.OnEtwEvent(record, "proc"); /* * UniqueProcessKey: (Type 16) * ProcessId: 27204 (Type 8) * ParentId: 8540 (Type 8) * SessionId: 1 (Type 8) * ExitStatus: 259 (Type 7) * DirectoryTableBase: (Type 16) * Flags: 0 (Type 8) * UserSID: (Type 310) * ImageFileName: calc1.exe (Type 2) * CommandLine: calc1 (Type 1) * PackageFullName: (Type 1) * ApplicationId: (Type 1) */ int ProcessId = (int)record.GetUInt32("ProcessId", 0); string CommandLine = record.GetUnicodeString("CommandLine", null); // Note: the command line may contain a realtive path (!) string FileName = record.GetAnsiString("ImageFileName", null); int ParentId = (int)record.GetUInt32("ParentId", 0); string filePath = GetPathFromCmd(CommandLine, ProcessId, FileName /*, record.Timestamp*/, ParentId); if (filePath == null) { AppLog.Debug("Process Monitor could not resolve path for prosess ({0}) : {1}", ProcessId, CommandLine); return; } //AppLog.Debug("Process Started: {0}", filePath); App.engine?.RunInEngineThread(() => { // Note: this happens in the engine thread if (Processes.ContainsKey(ProcessId)) { AppLog.Debug("Possible PID conflict (pid {0} reused): {1}", ProcessId, filePath); Processes.Remove(ProcessId); } Processes.Add(ProcessId, new ProcInfo() { filePath = filePath, StartTime = record.Timestamp }); }); } else if (record.Opcode == 2) // stop { int ProcessId = (int)record.GetUInt32("ProcessId", 0); App.engine?.RunInEngineThread(() => { // Note: this happens in the engine thread ProcInfo info; if (Processes.TryGetValue(ProcessId, out info)) { info.StopTime = record.Timestamp; } }); } }