Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        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
                });
            });
        }
Esempio n. 3
0
        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;
                }
            });
        }
Esempio n. 4
0
 protected void OnEtwEvent(Microsoft.O365.Security.ETW.IEventRecord record)
 {
     OnEtwEvent(record, logName);
 }
Esempio n. 5
0
        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;
                    }
                });
            }
        }