Exemple #1
0
        public EventRecord(BinaryReader recordData, int recordPosition, ChunkInfo chunk)
        {
            var l = LogManager.GetLogger("EventRecord");

            RecordPosition = recordPosition;

            ChunkNumber = chunk.ChunkNumber;

            recordData.ReadInt32(); //signature

            Size         = recordData.ReadUInt32();
            RecordNumber = recordData.ReadInt64();
            Timestamp    = DateTimeOffset.FromFileTime(recordData.ReadInt64()).ToUniversalTime();

            if (recordData.PeekChar() != 0xf)
            {
                throw new Exception("Payload does not start with 0x1f!");
            }

            l.Trace(
                $"Record position: 0x{RecordPosition:X4} Record #: {RecordNumber.ToString().PadRight(3)} Timestamp: {Timestamp:yyyy-MM-dd HH:mm:ss.fffffff}");

            Nodes = new List <IBinXml>();

            var eof = false;

            while (eof == false)
            {
                var nextTag = TagBuilder.BuildTag(recordPosition, recordData, chunk);
                Nodes.Add(nextTag);

                if (nextTag is EndOfBXmlStream)
                //nothing left to do, so exit
                {
                    eof = true;
                }
            }

            BuildProperties();
        }
Exemple #2
0
        public EventRecord(BinaryReader recordData, int recordPosition, ChunkInfo chunk)
        {
            var l = LogManager.GetLogger("EventRecord");

            RecordPosition = recordPosition;

            ChunkNumber = chunk.ChunkNumber;

            recordData.ReadInt32(); //signature

            Size         = recordData.ReadUInt32();
            RecordNumber = recordData.ReadInt64();
            Timestamp    = DateTimeOffset.FromFileTime(recordData.ReadInt64()).ToUniversalTime();

            if (recordData.PeekChar() != 0xf)
            {
                throw new Exception("Payload does not start with 0x1f!");
            }

            l.Trace(
                $"\r\nRecord position: 0x{RecordPosition:X4} Record #: {RecordNumber.ToString().PadRight(3)} Timestamp: {Timestamp:yyyy-MM-dd HH:mm:ss.fffffff}");

            Nodes = new List <IBinXml>();

            var eof = false;

            while (eof == false)
            {
                var nextTag = TagBuilder.BuildTag(recordPosition, recordData, chunk);
                Nodes.Add(nextTag);

                if (nextTag is EndOfBXmlStream)

                {
                    //nothing left to do, so exit
                    eof = true;

                    //check here if there is a 0x2a0x2a and if so, another record!

                    var found2a  = true; //danderspritz test
                    var maxCount = 0;
                    while (recordData.ReadByte() != 0x2a && maxCount < 15)
                    {
                        if (recordData.BaseStream.Position == recordData.BaseStream.Length)
                        {
                            found2a = false;
                            break; //out of data
                        }

                        maxCount += 1;
                    }

                    if (found2a)
                    {
                        //a secondary check to eliminate false positives
                        if (recordData.ReadByte() == 0x2a)
                        {
                            //back up two
                            recordData.BaseStream.Seek(-2, SeekOrigin.Current);

                            ExtraDataOffset = recordData.BaseStream.Position;
                        }
                    }
                }
            }

            BuildProperties();
        }
Exemple #3
0
        public EventLog(Stream fileStream)
        {
            const long eventSignature = 0x00656c6946666c45;
            const long chunkSignature = 0x6B6E6843666C45;

            var headerBytes = new byte[4096];

            fileStream.Read(headerBytes, 0, 4096);

            if (BitConverter.ToInt64(headerBytes, 0) != eventSignature)
            {
                throw new Exception("Invalid signature! Expected 'ElfFile'");
            }

            FirstChunkNumber = BitConverter.ToInt64(headerBytes, 0x8);
            LastChunkNumber  = BitConverter.ToInt64(headerBytes, 0x10);

            NextRecordId = BitConverter.ToInt64(headerBytes, 0x18);
            var unusedSize = BitConverter.ToInt32(headerBytes, 0x20);

            MinorVersion = BitConverter.ToInt16(headerBytes, 0x24);
            MajorVersion = BitConverter.ToInt16(headerBytes, 0x26);

            var unusedHeaderSize = BitConverter.ToInt16(headerBytes, 0x28);

            ChunkCount = BitConverter.ToInt16(headerBytes, 0x2A);

            Flags = (EventLogFlag)BitConverter.ToInt32(headerBytes, 0x78);

            Crc = BitConverter.ToInt32(headerBytes, 0x7C);

            var inputArray = new byte[120 + 4];

            Buffer.BlockCopy(headerBytes, 0, inputArray, 0, 120);

            Crc32Algorithm.ComputeAndWriteToEnd(inputArray); // last 4 bytes contains CRC
            CalculatedCrc = BitConverter.ToInt32(inputArray, inputArray.Length - 4);

            //we are at offset 0x1000 and ready to start

            //chunk size == 65536, or 0x10000

            var chunkBuffer = new byte[0x10000];

            Chunks = new List <ChunkInfo>();

            var chunkOffset = fileStream.Position;
            var bytesRead   = fileStream.Read(chunkBuffer, 0, 0x10000);

            EventIdMetrics = new Dictionary <long, int>();

            Logger.Trace($"Event Log data before processing chunks:\r\n{this}");

            var chunkNumber = 0;

            while (bytesRead > 0)
            {
                var chunkSig = BitConverter.ToInt64(chunkBuffer, 0);

                Logger.Trace(
                    $"chunk offset: 0x{chunkOffset:X}, sig: {Encoding.ASCII.GetString(chunkBuffer, 0, 8)} signature val: 0x{chunkSig:X}");

                if (chunkSig == chunkSignature)
                {
                    var ci = new ChunkInfo(chunkBuffer, chunkOffset, chunkNumber);
                    Chunks.Add(ci);
                    TotalEventLogs += ci.EventRecords.Count;
                }
                else
                {
                    Logger.Trace($"Skipping chunk at 0x{chunkOffset:X} as it does not have correct signature");
                }

                chunkOffset = fileStream.Position;
                bytesRead   = fileStream.Read(chunkBuffer, 0, 0x10000);

                chunkNumber += 1;
            }

            ErrorRecords = new Dictionary <long, string>();

            foreach (var chunkInfo in Chunks)
            {
                foreach (var eventIdMetric in chunkInfo.EventIdMetrics)
                {
                    if (EventIdMetrics.ContainsKey(eventIdMetric.Key) == false)
                    {
                        EventIdMetrics.Add(eventIdMetric.Key, 0);
                    }

                    EventIdMetrics[eventIdMetric.Key] += eventIdMetric.Value;
                }

                foreach (var chunkInfoErrorRecord in chunkInfo.ErrorRecords)
                {
                    ErrorRecords.Add(chunkInfoErrorRecord.Key, chunkInfoErrorRecord.Value);
                }
            }
        }
Exemple #4
0
        public IEnumerable <EventRecord> GetEventRecords()
        {
            //we are at offset 0x1000 and ready to start

            //chunk size == 65536, or 0x10000
            var chunkBuffer = new byte[0x10000];

            var chunkOffset = _stream.Position;
            var bytesRead   = _stream.Read(chunkBuffer, 0, 0x10000);

            EventIdMetrics = new Dictionary <long, int>();

            var chunkNumber = 0;

            while (bytesRead > 0)
            {
                var chunkSig = BitConverter.ToInt64(chunkBuffer, 0);

                Logger.Debug($"Processing chunk at offset 0x{chunkOffset:X}. Events found so far: {TotalEventLogs:N0}");

                if (chunkSig == ChunkSignature)
                {
                    var ci = new ChunkInfo(chunkBuffer, chunkOffset, chunkNumber);

                    foreach (var er in ci.EventRecords)
                    {
                        if (EarliestTimestamp == null)
                        {
                            EarliestTimestamp = er.Timestamp;
                        }
                        else
                        {
                            if (er.Timestamp.Ticks < EarliestTimestamp.Value.Ticks)
                            {
                                EarliestTimestamp = er.Timestamp;
                            }
                        }

                        if (LatestTimestamp == null)
                        {
                            LatestTimestamp = er.Timestamp;
                        }
                        else
                        {
                            if (er.Timestamp.Ticks > LatestTimestamp.Value.Ticks)
                            {
                                LatestTimestamp = er.Timestamp;
                            }
                        }

                        if (EventIdMetrics.ContainsKey(er.EventId) == false)
                        {
                            EventIdMetrics.Add(er.EventId, 0);
                        }

                        EventIdMetrics[er.EventId] += 1;

                        yield return(er);
                    }

                    foreach (var chunkInfoErrorRecord in ci.ErrorRecords)
                    {
                        ErrorRecords.Add(chunkInfoErrorRecord.Key, chunkInfoErrorRecord.Value);
                    }

                    TotalEventLogs += ci.EventRecords.Count;
                }
                else
                {
                    Logger.Trace($"Skipping chunk at 0x{chunkOffset:X} as it does not have correct signature");
                }

                chunkOffset = _stream.Position;
                bytesRead   = _stream.Read(chunkBuffer, 0, 0x10000);

                chunkNumber += 1;
            }
        }
Exemple #5
0
        public EventRecord(BinaryReader recordData, int recordPosition, ChunkInfo chunk)
        {
            var l = LogManager.GetLogger("EventRecord");

            RecordPosition = recordPosition;

            recordData.ReadInt32(); //signature

            Size         = recordData.ReadUInt32();
            RecordNumber = recordData.ReadInt64();
            Timestamp    = DateTimeOffset.FromFileTime(recordData.ReadInt64()).ToUniversalTime();

            if (recordData.PeekChar() != 0xf)
            {
                throw new Exception("Payload does not start with 0x1f!");
            }

            l.Trace(
                $"Record position: 0x{RecordPosition:X4} Record #: {RecordNumber.ToString().PadRight(3)} Timestamp: {Timestamp:yyyy-MM-dd HH:mm:ss.fffffff}");

            Nodes = new List <IBinXml>();

            var eof = false;

            while (eof == false)
            {
                var nextTag = TagBuilder.BuildTag(recordPosition, recordData, chunk);
                Nodes.Add(nextTag);

                if (nextTag is EndOfBXmlStream)
                //nothing left to do, so exit
                {
                    eof = true;
                }
            }

            var xml = ConvertPayloadToXml();


            using (var sr = new StringReader(xml))
            {
                var docNav = new XPathDocument(sr);
                var nav    = docNav.CreateNavigator();

                var computer      = nav.SelectSingleNode(@"/Event/System/Computer");
                var channel       = nav.SelectSingleNode(@"/Event/System/Channel");
                var eventRecordId = nav.SelectSingleNode(@"/Event/System/EventRecordID");
                var eventId       = nav.SelectSingleNode(@"/Event/System/EventID");
                var level         = nav.SelectSingleNode(@"/Event/System/Level");
                var timeCreated   = nav.SelectSingleNode(@"/Event/System/TimeCreated")?.GetAttribute("SystemTime", "");
                var provider      = nav.SelectSingleNode(@"/Event/System/Provider")?.GetAttribute("Name", "");
                var processId     = nav.SelectSingleNode(@"/Event/System/Execution")?.GetAttribute("ProcessID", "");
                var threadId      = nav.SelectSingleNode(@"/Event/System/Execution")?.GetAttribute("ThreadID", "");
                var userId        = nav.SelectSingleNode(@"/Event/System/Security")?.GetAttribute("UserID", "");

                TimeCreated = DateTimeOffset.Parse(timeCreated, null, DateTimeStyles.AssumeUniversal).ToUniversalTime();
                if (eventId != null)
                {
                    EventId = eventId.ValueAsInt;
                }

                //if (level != null)
                //{
                //    Level = level.ValueAsInt;
                //}

                //if (eventRecordId != null)
                //{
                //    EventRecordId = eventRecordId.Value;
                //}

                //if (processId != null)
                //{
                //    ProcessId = int.Parse(processId);
                //}

                //if (threadId != null)
                //{
                //    ThreadId = int.Parse(threadId);
                //}

                var payloadNode = nav.SelectSingleNode(@"/Event/EventData");
                if (payloadNode == null)
                {
                    payloadNode = nav.SelectSingleNode(@"/Event/UserData");
                }

                var payloadXml = payloadNode?.OuterXml;


                //if (EventLog.EventLogMaps.ContainsKey($"{EventId}-{channel.ToString().ToUpperInvariant()}"))
                //{
                //    l.Trace($"Found map for event id {EventId} with Channel '{channel}'!");
                //    var map = EventLog.EventLogMaps[$"{EventId}-{channel.ToString().ToUpperInvariant()}"];

                //    MapDescription = map.Description;

                //    foreach (var mapEntry in map.Maps)
                //    {
                //        var valProps = new Dictionary<string, string>();

                //        foreach (var me in mapEntry.Values)
                //        {
                //            //xpath out variables
                //            var propVal = nav.SelectSingleNode(me.Value);
                //            if (propVal != null)
                //            {
                //                var propValue = propVal.Value;

                //                if (me.Refine.IsNullOrEmpty() == false)
                //                {
                //                    var hits = new List<string>();

                //                    //regex time
                //                    MatchCollection allMatchResults = null;
                //                    try {
                //                        Regex regexObj = new Regex(me.Refine, RegexOptions.IgnoreCase);
                //                        allMatchResults = regexObj.Matches(propValue);
                //                        if (allMatchResults.Count > 0) {
                //                            // Access individual matches using allMatchResults.Item[]

                //                            foreach (Match allMatchResult in allMatchResults)
                //                            {
                //                                hits.Add(allMatchResult.Value);
                //                            }

                //                            propValue = string.Join(" | ", hits);

                //                        }

                //                    } catch (ArgumentException ) {
                //                        // Syntax error in the regular expression
                //                    }

                //                }

                //                valProps.Add(me.Name, propValue);
                //            }
                //            else
                //            {
                //                valProps.Add(me.Name, string.Empty);
                //                l.Warn(
                //                    $"Record # {RecordNumber} (Event Record Id: {EventRecordId}): In map for event '{map.EventId}', Property '{me.Value}' not found! Replacing with empty string");
                //            }
                //        }

                //        //we have the values, now substitute
                //        var propertyValue = mapEntry.PropertyValue;
                //        foreach (var valProp in valProps)
                //        {
                //            propertyValue = propertyValue.Replace($"%{valProp.Key}%", valProp.Value);
                //        }

                //        var propertyToUpdate = mapEntry.Property.ToUpperInvariant();

                //        if (valProps.Count == 0)
                //        {
                //            propertyToUpdate = "NOMATCH"; //prevents variables from showing up in the CSV
                //        }

                //        //we should now have our new value, so stick it in its place
                //        switch (propertyToUpdate)
                //        {
                //            case "USERNAME":
                //                UserName = propertyValue;
                //                break;
                //            case "REMOTEHOST":
                //                RemoteHost = propertyValue;
                //                break;
                //            case "EXECUTABLEINFO":
                //                ExecutableInfo = propertyValue;
                //                break;
                //            case "PAYLOADDATA1":
                //                PayloadData1 = propertyValue;
                //                break;
                //            case "PAYLOADDATA2":
                //                PayloadData2 = propertyValue;
                //                break;
                //            case "PAYLOADDATA3":
                //                PayloadData3 = propertyValue;
                //                break;
                //            case "PAYLOADDATA4":
                //                PayloadData4 = propertyValue;
                //                break;
                //            case "PAYLOADDATA5":
                //                PayloadData5 = propertyValue;
                //                break;
                //            case "PAYLOADDATA6":
                //                PayloadData6 = propertyValue;
                //                break;
                //            case "NOMATCH":
                //                //when a property was not found.
                //                break;
                //            default:
                //                l.Warn(
                //                    $"Unknown property name '{propertyToUpdate}'! Dropping mapping value of '{propertyValue}'");
                //                break;
                //}

                //sanity checks
                //UserId = userId ?? string.Empty;
                Provider = provider ?? string.Empty;
                Channel  = channel?.Value ?? string.Empty;
                Computer = computer?.Value ?? string.Empty;
                Payload  = payloadXml ?? string.Empty;
            }
        }
Exemple #6
0
        public EventRecord(BinaryReader recordData, int recordPosition, ChunkInfo chunk)
        {
            var l = LogManager.GetLogger("EventRecord");

            RecordPosition = recordPosition;

            recordData.ReadInt32(); //signature

            Size         = recordData.ReadUInt32();
            RecordNumber = recordData.ReadInt64();
            Timestamp    = DateTimeOffset.FromFileTime(recordData.ReadInt64()).ToUniversalTime();

            if (recordData.PeekChar() != 0xf)
            {
                throw new Exception("Payload does not start with 0x1f!");
            }

            l.Trace(
                $"Record position: 0x{RecordPosition:X4} Record #: {RecordNumber.ToString().PadRight(3)} Timestamp: {Timestamp:yyyy-MM-dd HH:mm:ss.fffffff}");

            Nodes = new List <IBinXml>();

            var eof = false;

            while (eof == false)
            {
                var nextTag = TagBuilder.BuildTag(recordPosition, recordData, chunk);
                Nodes.Add(nextTag);

                if (nextTag is EndOfBXmlStream)
                //nothing left to do, so exit
                {
                    eof = true;
                }
            }

            var xml = ConvertPayloadToXml();

            xml = xml.Replace(" xmlns=\"http://schemas.microsoft.com/win/2004/08/events/event\"", "");

            using (var sr = new StringReader(xml))
            {
                var docNav = new XPathDocument(sr);
                var nav    = docNav.CreateNavigator();

                var computer    = nav.SelectSingleNode(@"/Event/System/Computer");
                var channel     = nav.SelectSingleNode(@"/Event/System/Channel");
                var eventId     = nav.SelectSingleNode(@"/Event/System/EventID");
                var level       = nav.SelectSingleNode(@"/Event/System/Level");
                var timeCreated = nav.SelectSingleNode(@"/Event/System/TimeCreated")?.GetAttribute("SystemTime", "");
                var provider    = nav.SelectSingleNode(@"/Event/System/Provider")?.GetAttribute("Name", "");
                var processId   = nav.SelectSingleNode(@"/Event/System/Execution")?.GetAttribute("ProcessID", "");
                var threadId    = nav.SelectSingleNode(@"/Event/System/Execution")?.GetAttribute("ThreadID", "");
                var userId      = nav.SelectSingleNode(@"/Event/System/Security")?.GetAttribute("UserID", "");

                TimeCreated = DateTimeOffset.Parse(timeCreated, null, DateTimeStyles.AssumeUniversal).ToUniversalTime();
                if (eventId != null)
                {
                    EventId = eventId.ValueAsInt;
                }

                if (level != null)
                {
                    Level = level.ValueAsInt;
                }

                if (processId != null)
                {
                    ProcessId = int.Parse(processId);
                }

                if (threadId != null)
                {
                    ThreadId = int.Parse(threadId);
                }

                var payloadNode = nav.SelectSingleNode(@"/Event/EventData");
                if (payloadNode == null)
                {
                    payloadNode = nav.SelectSingleNode(@"/Event/UserData");
                }

                var payloadXml = payloadNode?.OuterXml;


                if (EventLog.EventLogMaps.ContainsKey(EventId))
                {
                    l.Trace($"Found map for event id {EventId}!");
                    var map = EventLog.EventLogMaps[EventId];

                    foreach (var mapEntry in map.Maps)
                    {
                        var valProps = new Dictionary <string, string>();

                        foreach (var me in mapEntry.Values)
                        {
                            //xpath out variables
                            var propVal = nav.SelectSingleNode(me.Value);
                            valProps.Add(me.Name, propVal.Value);
                        }

                        //we have the values, now substitute
                        var propertyValue = mapEntry.PropertyValue;
                        foreach (var valProp in valProps)
                        {
                            propertyValue = propertyValue.Replace($"%{valProp.Key}%", valProp.Value);
                        }

                        //we should now have our new value, so stick it in its place
                        switch (mapEntry.Property.ToUpperInvariant())
                        {
                        case "USERNAME":
                            UserName = propertyValue;
                            break;

                        case "REMOTEHOST":
                            RemoteHost = propertyValue;
                            break;

                        case "EXECUTABLEINFO":
                            ExecutableInfo = propertyValue;
                            break;

                        case "PAYLOADDATA1":
                            PayloadData1 = propertyValue;
                            break;

                        case "PAYLOADDATA2":
                            PayloadData2 = propertyValue;
                            break;

                        case "PAYLOADDATA3":
                            PayloadData3 = propertyValue;
                            break;

                        case "PAYLOADDATA4":
                            PayloadData4 = propertyValue;
                            break;

                        case "PAYLOADDATA5":
                            PayloadData5 = propertyValue;
                            break;

                        case "PAYLOADDATA6":
                            PayloadData6 = propertyValue;
                            break;

                        default:
                            l.Warn($"Unknown property name '{mapEntry.Property}'! Dropping mapping value of '{propertyValue}'");
                            break;
                        }
                    }
                }

                //sanity checks
                UserId     = userId ?? string.Empty;
                Provider   = provider ?? string.Empty;
                Channel    = channel?.Value ?? string.Empty;
                Computer   = computer?.Value ?? string.Empty;
                PayloadXml = payloadXml ?? string.Empty;
            }
        }