protected bool ReadLocal(string fileName) { L.Log(LogType.FILE, LogLevel.INFORM, "EventLogFileAuditRecorder In ReadLocal -- Started."); if (!callable.WaitOne(0)) { L.Log(LogType.FILE, LogLevel.INFORM, "EventLogFileAuditRecorder In ReadLocal -- CALLED MULTIPLE TIMES STILL IN USE"); callable.WaitOne(); try { throw new Exception("Parse already been processed by another thread while this call has made"); } finally { callable.ReleaseMutex(); } } try { L.Log(LogType.FILE, LogLevel.INFORM, "EventLogFileAuditRecorder In ReadLocal -- Started with lastfile: " + lastFile); var eventLogLocation = fileName; var query = last_recordnum > 0 ? "*[System/EventRecordID > " + last_recordnum + "]" : null; var handle = IntPtr.Zero; var events = new IntPtr[] { IntPtr.Zero }; var hRenderContext = IntPtr.Zero; var pRenderedValues = IntPtr.Zero; var hRenderContextEvtData = IntPtr.Zero; var metaDict = new Dictionary<string, IntPtr>(); var dwBufferUsed = 0; var dwPropertyCount = 0; var dwBufferSize = 0; var status = UnsafeNativeMethods.ERROR_SUCCESS; var session = IntPtr.Zero; try { var info = user == null ? null : user.Split('\\'); if (info != null && info.Length >= 2) { domain = string.IsNullOrEmpty(info[0]) ? null : info[0]; ip = info.Length == 2 ? remoteHost : (string.IsNullOrEmpty(info[1]) ? null : info[1]); domainUser = string.IsNullOrEmpty(info[info.Length - 1]) ? null : info[info.Length - 1]; if (!string.IsNullOrEmpty(domain) && !string.IsNullOrEmpty(domainUser)) { L.Log(LogType.FILE, LogLevel.DEBUG, "EventLogFileAuditRecorder In ReadLocal -- Remote Logger: " + user); var login = new UnsafeNativeMethods.EvtRpcLogin() { Domain = domain, User = domainUser, Password = CoTaskMemUnicodeSafeHandle.Zero, Server = ip }; var secureString = new SecureString(); if (!string.IsNullOrEmpty(password)) { foreach (var ch in password) { secureString.AppendChar(ch); } } login.Password.SetMemory(Marshal.SecureStringToCoTaskMemUnicode(secureString)); session = UnsafeNativeMethods.EvtOpenSession(UnsafeNativeMethods.EvtLoginClass.EvtRpcLogin, ref login, 0, 0); L.Log(LogType.FILE, LogLevel.DEBUG, "EventLogFileAuditRecorder In ReadLocal -- UnsafeNativeMethods.EvtQueryFlags.EvtQueryChannelPath: " + UnsafeNativeMethods.EvtQueryFlags.EvtQueryChannelPath); } } /* flags = (int)UnsafeNativeMethods.EvtQueryFlags.EvtQueryFilePath; L.Log(LogType.FILE, LogLevel.DEBUG, "EventLogFileAuditRecorder In ReadLocal -- UnsafeNativeMethods.EvtQueryFlags.EvtQueryFilePath: " + UnsafeNativeMethods.EvtQueryFlags.EvtQueryFilePath); } else { */ int flags; if (location.Contains("\\")) { flags = (int)UnsafeNativeMethods.EvtQueryFlags.EvtQueryFilePath; L.Log(LogType.FILE, LogLevel.DEBUG, "EventLogFileAuditRecorder In ReadLocal --EvtQueryFilePath"); } else { flags = (int)UnsafeNativeMethods.EvtQueryFlags.EvtQueryChannelPath; L.Log(LogType.FILE, LogLevel.DEBUG, "EventLogFileAuditRecorder In ReadLocal --EvtQueryChannelPath"); } L.Log(LogType.FILE, LogLevel.DEBUG, "EventLogFileAuditRecorder In ReadLocal -- " + session + " - " + eventLogLocation + " - " + query + " - " + flags); handle = UnsafeNativeMethods.EvtQuery(session, eventLogLocation, query, flags); if (handle == IntPtr.Zero) { L.Log(LogType.FILE, LogLevel.ERROR, "EventLogFileAuditRecorder In ReadLocal -- Error Opening Event File: " + Marshal.GetLastWin32Error()); return false; } hRenderContext = UnsafeNativeMethods.EvtCreateRenderContext(0, null, UnsafeNativeMethods .EvtRenderContextFlags .EvtRenderContextSystem); if (hRenderContext == IntPtr.Zero) { L.Log(LogType.FILE, LogLevel.ERROR, "EventLogFileAuditRecorder In ReadLocal -- Error Creating Render Context Failed: " + Marshal.GetLastWin32Error() + ")"); return false; } var buffer = new StringBuilder(); var lineBuffer = new StringBuilder(); var tmpBuffer = new StringBuilder(); var domainBuffer = new StringBuilder(); var usernameBuffer = new StringBuilder(); var returned = 0; var rec = new CustomBase.Rec(); var audit = new AuditInfo(); isFileFinished = false; try { while (UnsafeNativeMethods.EvtNext(handle, 1, events, int.MaxValue, 0, ref returned)) { PrintT(++total); try { using (Benchmark("GetRender")) { if (!GetRenderValues(hRenderContext, events[0], UnsafeNativeMethods.EvtRenderFlags.EvtRenderEventValues, ref dwBufferSize, ref pRenderedValues, ref dwBufferUsed, ref dwPropertyCount, ref status)) { L.Log(LogType.FILE, LogLevel.ERROR, "EventLogFileAuditRecorder In ReadLocal -- Error Getting Render Event Values Failed: " + status + ")"); continue; } } string description; using (Benchmark("GetFields")) { string meta; using (Benchmark("GetFields P1")) { meta = Marshal.PtrToStringAuto( ((UnsafeNativeMethods.EvtVariant) (Marshal.PtrToStructure(pRenderedValues, typeof(UnsafeNativeMethods.EvtVariant)))) .StringVal); if (meta == null) { L.Log(LogType.FILE, LogLevel.INFORM, "EventLogFileAuditRecorder In ReadLocal -- Event has no meta data. Skipping"); continue; } } using (Benchmark("GetFields P2")) { rec.EventId = ((UnsafeNativeMethods.EvtVariant) Marshal.PtrToStructure( new IntPtr((Int32)pRenderedValues + ((int) UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemEventID) * Marshal.SizeOf(typeof(UnsafeNativeMethods.EvtVariant))), typeof(UnsafeNativeMethods.EvtVariant))).UShort; L.Log(LogType.FILE, LogLevel.DEBUG, "EventId: " + rec.EventId); } IntPtr metaPtr; using (Benchmark("GetFields P3")) { if (!metaDict.TryGetValue(meta, out metaPtr)) { metaPtr = UnsafeNativeMethods.EvtOpenPublisherMetadata(session, meta, null, LangId, 0); if (metaPtr != IntPtr.Zero) metaDict[meta] = metaPtr; } } using (Benchmark("GetFields P4")) { if (!GetMessageString(metaPtr, events[0], UnsafeNativeMethods.EvtFormatMessageFlags .EvtFormatMessageEvent, ref buffer, out dwBufferUsed, ref status)) { L.Log(LogType.FILE, LogLevel.ERROR, "Get Description failed:" + status); continue; } } using (Benchmark("GetFields P5")) { description = buffer.ToString(); buffer.Remove(0, buffer.Length); //WriteLine(description); //continue; rec.Recordnum = (int) ((UnsafeNativeMethods.EvtVariant) Marshal.PtrToStructure( new IntPtr((Int32)pRenderedValues + ((int) UnsafeNativeMethods.EvtSystemPropertyId .EvtSystemEventRecordId) * Marshal.SizeOf( typeof(UnsafeNativeMethods.EvtVariant))), typeof(UnsafeNativeMethods.EvtVariant))).ULong; last_recordnum = (long)rec.Recordnum; rec.ComputerName = Marshal.PtrToStringAuto( ((UnsafeNativeMethods.EvtVariant) (Marshal.PtrToStructure( new IntPtr((Int32)pRenderedValues + ((int) UnsafeNativeMethods.EvtSystemPropertyId .EvtSystemComputer) * Marshal.SizeOf(typeof(UnsafeNativeMethods.EvtVariant))), typeof(UnsafeNativeMethods.EvtVariant)))) .StringVal); } using (Benchmark("GetFields P6")) { if (!GetMessageString(metaPtr, events[0], UnsafeNativeMethods.EvtFormatMessageFlags .EvtFormatMessageTask, ref buffer, out dwBufferUsed, ref status)) { buffer.Remove(0, buffer.Length); } rec.EventType = buffer.ToString(); if (!GetMessageString(metaPtr, events[0], UnsafeNativeMethods.EvtFormatMessageFlags .EvtFormatMessageLevel, ref buffer, out dwBufferUsed, ref status)) { buffer.Remove(0, buffer.Length); } rec.EventCategory = buffer.ToString(); ulong timeCreated = ((UnsafeNativeMethods.EvtVariant) Marshal.PtrToStructure( new IntPtr((Int32)pRenderedValues + ((int) UnsafeNativeMethods.EvtSystemPropertyId .EvtSystemTimeCreated) * Marshal.SizeOf(typeof(UnsafeNativeMethods.EvtVariant))), typeof(UnsafeNativeMethods.EvtVariant))).FileTime; rec.Datetime = DateTime.FromFileTime((long)timeCreated) .ToString("yyyy/MM/dd HH:mm:ss", CultureInfo.InvariantCulture); rec.LogName = Marshal.PtrToStringAuto( ((UnsafeNativeMethods.EvtVariant) (Marshal.PtrToStructure( new IntPtr((Int32)pRenderedValues + ((int) UnsafeNativeMethods.EvtSystemPropertyId .EvtSystemChannel) * Marshal.SizeOf(typeof(UnsafeNativeMethods.EvtVariant))), typeof(UnsafeNativeMethods.EvtVariant)))) .StringVal); rec.Description = description; } } var sentItems = 0; using (Benchmark("ParseDescriptionForAudit")) { if ( !ParseDescriptionForAudit(audit, description, buffer, domainBuffer, usernameBuffer)) continue; } using (Benchmark("ParseAuditOperations2")) { ParseAuditOperations2(ref rec, audit, buffer, domainBuffer, usernameBuffer, ref sentItems); if (sentItems > 0) continue; if (audit.Reasons.Count == 0 && audit.OriginalRights.Count == 0 && audit.NewRights.Count == 0) continue; } rec.Description = description; rec.CustomStr2 = audit.ObjectType; rec.CustomStr3 = audit.ObjectName; rec.CustomStr4 = audit.Sid; rec.CustomStr5 = audit.Username; rec.CustomStr6 = audit.Process; rec.CustomInt6 = audit.ProcessId; rec.CustomStr7 = audit.AccessMask; using (Benchmark("ParseAuditOperations2")) { if (audit.OriginalRights.Count > 0 && audit.NewRights.Count > 0) SendAccessRightChange(ref rec, audit); //else // SendAudit(ref rec, audit); } } finally { UnsafeNativeMethods.EvtClose(events[0]); events[0] = IntPtr.Zero; } } } finally { foreach (var item in benchmark) { item.Value.Stop(); } //BenchStat(Console.Out); try { var customServiceBase = GetInstanceService("Security Manager Remote Recorder"); L.Log(LogType.FILE, LogLevel.DEBUG, " EventLogFileAuditRecorder In ReadLocal -->> Setting Registry."); customServiceBase.SetReg(Id, last_recordnum.ToString(CultureInfo.InvariantCulture), "-", lastFile, "", LastRecordDate); L.Log(LogType.FILE, LogLevel.DEBUG, " EventLogFileAuditRecorder In ReadLocal -->> Registry Set."); } catch (Exception exception) { L.Log(LogType.FILE, LogLevel.ERROR, " EventLogFileAuditRecorder In ReadLocal -->> Setting Registry Error." + exception.Message); } } isFileFinished = true; return true; } finally { CleanupEvtHandle(handle); CleanupEvtHandle(events[0]); CleanupEvtHandle(hRenderContext); CleanupEvtHandle(hRenderContextEvtData); CleanupEvtHandle(metaDict); } } catch (EventLogNotFoundException e) { L.Log(LogType.FILE, LogLevel.ERROR, "EVTX Parser in ReadLocal ERROR." + e.Message); } finally { callable.ReleaseMutex(); } return false; }
private void SendAccessRightChange(ref CustomBase.Rec rec, AuditInfo audit) { foreach (var o in audit.OriginalRights.Keys) { if (audit.NewRights.Remove(o)) { audit.OriginalRights[o].Valid = false; } } rec.CustomStr1 = "RIGHT DELETED"; foreach (var r in audit.OriginalRights.Values) { if (r.Valid) { rec.CustomStr8 = r.Trustee; rec.CustomStr9 = r.AceType; rec.CustomStr10 = r.Right; SendData(ref rec); } } rec.CustomStr1 = "RIGHT ADDED"; foreach (var r in audit.NewRights.Values) { rec.CustomStr8 = r.Trustee; rec.CustomStr9 = r.AceType; rec.CustomStr10 = r.Right; SendData(ref rec); } }
private void SendAudit(ref Rec rec, AuditInfo audit) { foreach (var a in audit.Reasons) { rec.CustomStr1 = a.AccessRight; rec.CustomStr8 = a.GrantedByUser; rec.CustomStr9 = a.GrantedBy; SendData(ref rec); } }
private void Process(string file) { using (var fs = new StreamReader(file)) { string description; var audit = new AuditInfo(); var domainBuffer = new StringBuilder(); var usernameBuffer = new StringBuilder(); var buffer = new StringBuilder(); var sb = new StringBuilder(); var ln = string.Empty; int state = 1; while ((ln = fs.ReadLine()) != null) { switch (state) { case 1: if (ln == "=========== BEGIN =============") state = 2; break; case 2: if (ln == "=========== END =============") { description = sb.ToString(); sb.Remove(0, sb.Length); state = 1; var rec = new Rec(); rec.Description = description; if (!ParseDescriptionForAudit(audit, description, buffer, domainBuffer, usernameBuffer)) continue; Console.WriteLine("{0}: {1}", description.Substring(0, description.IndexOf('\r')), audit.ObjectName); var sentItems = 0; ParseAuditOperations(ref rec, audit, buffer, domainBuffer, usernameBuffer, ref sentItems); } else { sb.AppendLine(ln); } break; } } } }
private bool ParseDescriptionForAudit(AuditInfo audit, string desc, StringBuilder buffer, StringBuilder domainBuffer, StringBuilder userBuffer) { try { audit.Reset(); using (var reader = new StringReader(desc)) { var line = string.Empty; bool consumeAgain = false; while (consumeAgain || (line = reader.ReadLine()) != null) { consumeAgain = false; var m = RegField.Match(line); if (m.Success) { using (Benchmark("ParseDescriptionForAudit " + m.Groups[1].Value)) { var value = m.Groups[2].Value.Trim(); switch (m.Groups[1].Value) { case "Security ID": audit.Sid = value; break; case "Account Name": if (string.IsNullOrEmpty(audit.Username)) audit.Username = value; else audit.Username += "\\" + value; break; case "Account Domain": if (string.IsNullOrEmpty(audit.Username)) audit.Username = value; else audit.Username = value + "\\" + audit.Username; break; case "Object Type": audit.ObjectType = value; break; case "Object Name": var kernel = RegKernelPath.Match(value); audit.ObjectName = kernel.Success ? QueryDosPath(kernel.Groups[1].Value, kernel.Groups[2].Value) : value; break; case "Process ID": audit.ProcessId = GetPid(value); break; case "Process Name": audit.Process = value; break; case "Access Mask": audit.AccessMask = value; break; case "Access Reasons": line = ParseAccessReasons(reader, value, audit, buffer, domainBuffer, userBuffer); consumeAgain = line != null; break; case "Original Security Descriptor": audit.OriginalDaclFlags = ParseDescriptorsInto(value, audit.OriginalRights, buffer, domainBuffer, userBuffer); L.Log(LogType.FILE, LogLevel.DEBUG, "Original:[" + value + "]"); if (audit.OriginalDaclFlags == null) return false; break; case "New Security Descriptor": L.Log(LogType.FILE, LogLevel.DEBUG, "Original:[" + value + "]"); audit.NewDaclFlags = ParseDescriptorsInto(value, audit.NewRights, buffer, domainBuffer, userBuffer); if (audit.NewDaclFlags == null) return false; break; } } } } return true; } } catch (Exception e) { L.Log(LogType.FILE, LogLevel.ERROR, "ParseDescriptionForAudit Error:" + e.Message); return false; } }
private void ParseAuditOperations2(ref Rec rec, AuditInfo audit, StringBuilder buffer, StringBuilder domainBuffer, StringBuilder userBuffer, ref int sentItems) { try { if (string.IsNullOrEmpty(rec.Description)) return; using (var reader = new StringReader(rec.Description)) { string line; var state = -1; var mask = 0; var values = new string[9]; while (true) { using (Benchmark("ParseAuditOperations2 ReadLine")) { line = reader.ReadLine(); } if (line == null) break; Match m; switch (state) { case -1: m = RegLine.Match(line); if (m.Success) { state = m.Groups[1].Success ? 2 : 3; /* for (state = 1; state < m.Groups.Count && !m.Groups[state].Success; ++state) { } if (state == m.Groups.Count) state = -1; else ++state; * */ } break; default: m = ((Regex)RegExps[state][0]).Match(line); if (m.Success) { //WriteLine(line); var i = 1; var ms = 1; while (i < m.Groups.Count) { if (m.Groups[i].Success) { values[i / 2] = m.Groups[i + 1].Value; mask |= ms; break; } i += 2; ms <<= 1; } if (mask == ((int)RegExps[state][1])) { var username = string.IsNullOrEmpty(values[1]) || string.IsNullOrEmpty(values[2]) ? UserWithDomain(values[0], buffer, domainBuffer, userBuffer) : values[1] + "\\" + values[2]; AuditLogonEnv2 env; lock (_handles2) { if (!_handles2.TryGetValue(values[3], out env)) { env = new AuditLogonEnv2(values[3]); _handles2[env.LogonId] = env; } } if (state == 3) { using (Benchmark("ParseAuditOperations2 DeleteHandle2")) { AuditDeleteHandle2(ref rec, env, username, values[0], values[4], values[5], ref sentItems); } } else if (audit.ObjectType == "File") { //Console.WriteLine(rec.Description); //var ln = Console.ReadLine(); //if (ln.Equals("d")) // DEBUG_BREAK = true; //else if (ln.Equals("q")) // DEBUG_BREAK = false; using (Benchmark("ParseAuditOperations2 AuditObjectRequestHandle2")) { AuditObjectRequestHandle2(ref rec, env, values[3], username, values[0], values[5], values[6], values[8], values[4], values[7], ref sentItems); } } return; } } break; } } } } catch (Exception e) { L.Log(LogType.FILE, LogLevel.ERROR, "Error while parsing audit operations:" + e); } }
private void ParseAuditOperations(ref Rec rec, AuditInfo audit, StringBuilder buffer, StringBuilder domainBuffer, StringBuilder userBuffer, ref int sentItems) { try { if (string.IsNullOrEmpty(rec.Description)) return; using (var reader = new StringReader(rec.Description)) { string line; var state = -1; var mask = 0; var values = new string[9]; while ((line = reader.ReadLine()) != null) { Match m; switch (state) { case -1: m = RegLine.Match(line); if (m.Success) { for (state = 1; state < m.Groups.Count && !m.Groups[state].Success; ++state) { } if (state == m.Groups.Count) state = -1; else --state; } break; default: m = ((Regex)RegExps[state][0]).Match(line); if (m.Success) { //WriteLine(line); var i = 1; var ms = 1; while (i < m.Groups.Count) { if (m.Groups[i].Success) { values[i / 2] = m.Groups[i + 1].Value; mask |= ms; break; } i += 2; ms <<= 1; } if (mask == ((int)RegExps[state][1])) { var username = string.IsNullOrEmpty(values[1]) || string.IsNullOrEmpty(values[2]) ? UserWithDomain(values[0], buffer, domainBuffer, userBuffer) : values[1] + "\\" + values[2]; AuditLogonEnv env; if (!_handles.TryGetValue(values[3], out env)) { env = new AuditLogonEnv(values[3]); _handles[env.LogonId] = env; } try { switch (state) { case 0: AuditCloseHandle(ref rec, env, username, values[0], values[4], values[5], values[6], ref sentItems); return; case 1: AuditDuplicateHandle(ref rec, env, values[3], username, values[0], values[4], values[5], values[6], values[7], ref sentItems); return; case 2: if (audit.ObjectType == "File") AuditObjectRequestHandle(ref rec, env, values[3], username, values[0], values[5], values[6], values[8], values[4], values[7], ref sentItems); return; case 3: AuditDeleteHandle(ref rec, env, username, values[0], values[4], values[5], values[6], ref sentItems); return; } } finally { if (env.Handles.Count == 0) _handles.Remove(env.LogonId); //WriteLine("==================================================="); } } } break; } } } } catch (Exception e) { L.Log(LogType.FILE, LogLevel.ERROR, "Error while parsing audit operations:" + e); } }
private string ParseAccessReasons(StringReader reader, string value, AuditInfo audit, StringBuilder buffer, StringBuilder domainBuffer, StringBuilder userBuffer) { while (!string.IsNullOrEmpty(value)) { var m = RegGrantedByField.Match(value); if (!m.Success) return value; value = m.Groups[2].Value.Trim(); var index = value.IndexOf("\t", StringComparison.CurrentCultureIgnoreCase); if (index >= 0) value = value.Substring(index).Trim(); var reason = new AccessReason() { AccessRight = m.Groups[1].Value, GrantedBy = value }; if (index >= 0) reason.GrantedByUser = ParseGrantedBy(reason, buffer, domainBuffer, userBuffer); audit.Reasons.Add(reason); value = reader.ReadLine(); } return null; }