public static InterestingSecurityFailure ParseEvent(EventRecord eventRecord) { if (eventRecord == null) { throw new ArgumentNullException(nameof(eventRecord)); } var xml = new XmlDocument(); xml.LoadXml(eventRecord.ToXml()); var ns = new XmlNamespaceManager(xml.NameTable); ns.AddNamespace("a", "http://schemas.microsoft.com/win/2004/08/events/event"); var isf = new InterestingSecurityFailure { Date = eventRecord.TimeCreated, EventId = eventRecord.Id }; switch (eventRecord.Id) { case 4625: isf.IP = (xml.SelectSingleNode("//a:Data[@Name=\"IpAddress\"]", ns))?.InnerText; isf.UserName = (xml.SelectSingleNode("//a:Data[@Name=\"TargetUserName\"]", ns))?.InnerText; isf.Domain = (xml.SelectSingleNode("//a:Data[@Name=\"TargetDomainName\"]", ns))?.InnerText; break; case 140: isf.IP = (xml.SelectSingleNode("//a:Data[@Name=\"IPString\"]", ns))?.InnerText; break; } return(isf); }
/// <summary> /// Check if blocking is necessary depending on event type and /// how many failed attempts there have been /// </summary> /// <param name="isf"></param> void BlockIpIfNecessary(InterestingSecurityFailure isf) { WriteInfo(Invariant($"[Event {isf.EventId}] IP: [{isf.IP}]")); // just straight up block event 140 ips for now!! as a test:) if (isf.EventId == 140) { TryBlockIp(isf.IP); return; } // if event 4625 check number of previous // failed attempts in past hour. int secfailures; lock (_datalock) { PruneIpInfo(); if (!_ipdeets.ContainsKey(isf.IP)) { _ipdeets[isf.IP] = new List <InterestingSecurityFailure>(); } _ipdeets[isf.IP].Add(isf); secfailures = _ipdeets[isf.IP].Count; } WriteInfo(Invariant($"[Event {isf.EventId}] Count in last hour: [{secfailures}]")); WriteInfo(Invariant($"[Event {isf.EventId}] User: [{isf.UserName}] Domain: [{isf.Domain}]")); if (secfailures >= SecFailureCountThreshold) { TryBlockIp(isf.IP); } }