From 40edee2b83cc68015aa195236eb1d0abf29c3219 Mon Sep 17 00:00:00 2001 From: "Namhyeon, Go" Date: Mon, 9 Sep 2024 15:26:16 +0900 Subject: [PATCH] Remove libyara.NET and a little fixes for sysmon events --- .../WelsonJS.Service/FileEventMonitor.cs | 212 ++++++------------ .../WelsonJS.Service/WelsonJS.Service.csproj | 6 +- .../WelsonJS.Service/packages.config | 3 +- 3 files changed, 71 insertions(+), 150 deletions(-) diff --git a/WelsonJS.Toolkit/WelsonJS.Service/FileEventMonitor.cs b/WelsonJS.Toolkit/WelsonJS.Service/FileEventMonitor.cs index 32ea8e9..fcd3f37 100644 --- a/WelsonJS.Toolkit/WelsonJS.Service/FileEventMonitor.cs +++ b/WelsonJS.Toolkit/WelsonJS.Service/FileEventMonitor.cs @@ -4,23 +4,20 @@ using System; using System.Diagnostics.Eventing.Reader; using System.IO; -using libyaraNET; -using System.Collections.Generic; using System.ServiceProcess; -using WelsonJS.Service.Model; -using System.Threading.Tasks; -using System.Runtime.ExceptionServices; -using System.Security; namespace WelsonJS.Service { public class FileEventMonitor { - private Rules rules; private EventLogWatcher eventLogWatcher; private ServiceMain parent; - private string ruleDirectoryPath; - private enum EventType11: int { + private enum EventType: int + { + FileCreate = 11, + NetworkConnection = 3 + }; + private enum FileCreateEvent: int { RuleName, UtcTime, ProcessGuid, @@ -30,64 +27,31 @@ namespace WelsonJS.Service CreationUtcTime, User }; + private enum NetworkConnectionEvent: int + { + RuleName, + UtcTime, + ProcessGuid, + ProcessId, + Image, + User, + Protocol, + Initiated, + SourceIsIpv6, + SourceIp, + SourceHostname, + SourcePort, + SourcePortName, + DestinationIsIpv6, + DestinationIp, + DestinationHostname, + DestinationPort, + DestinationPortName, + }; public FileEventMonitor(ServiceBase parent, string workingDirectory) { this.parent = (ServiceMain)parent; - ruleDirectoryPath = Path.Combine(workingDirectory, "app/assets/yar"); - - try - { - AddYaraRulesFromDirectory(ruleDirectoryPath); - } - catch (Exception ex) - { - this.parent.Log($"Failed to read the rules: {ex.Message}"); - } - } - - public void AddYaraRulesFromDirectory(string directoryPath) - { - if (!Directory.Exists(directoryPath)) - { - throw new FileNotFoundException($"{directoryPath} directory not found."); - } - - var ruleFiles = Directory.GetFiles(directoryPath, "*.yar"); - AddYaraRules(new List(ruleFiles)); - } - - public void AddYaraRules(List ruleFiles) - { - Dispose(); - - using (var ctx = new YaraContext()) - { - try - { - using (var compiler = new Compiler()) - { - foreach (var ruleFile in ruleFiles) - { - if (File.Exists(ruleFile)) - { - compiler.AddRuleFile(ruleFile); - parent.Log($"Added the rule: {ruleFile}"); - } - else - { - throw new FileNotFoundException($"{ruleFile} file not found."); - } - } - - rules = compiler.GetRules(); - } - } - catch (Exception ex) - { - parent.Log($"Error adding the rules: {ex.Message}"); - } - } } public void Start() @@ -96,7 +60,7 @@ namespace WelsonJS.Service { string query = @" - + "; @@ -126,31 +90,58 @@ namespace WelsonJS.Service eventLogWatcher = null; } } - - Dispose(); } private void OnEventRecordWritten(object sender, EventRecordWrittenEventArgs e) { if (e.EventRecord != null) { + int eventId = e.EventRecord.Id; + try { - string fileName = e.EventRecord.Properties[(int)EventType11.TargetFilename]?.Value?.ToString(); + if (eventId == (int)EventType.FileCreate) + { + string ruleName = e.EventRecord.Properties[(int)FileCreateEvent.RuleName]?.Value?.ToString(); + string processId = e.EventRecord.Properties[(int)FileCreateEvent.ProcessId]?.Value?.ToString(); + string image = e.EventRecord.Properties[(int)FileCreateEvent.Image]?.Value?.ToString(); + string fileName = e.EventRecord.Properties[(int)FileCreateEvent.TargetFilename]?.Value?.ToString(); - if (string.IsNullOrEmpty(fileName)) - { - throw new ArgumentException("Could not read the target filename."); - } + if (string.IsNullOrEmpty(fileName)) + { + throw new ArgumentException("Could not read the target filename."); + } - if (File.Exists(fileName)) - { - parent.Log($"File created: {fileName}"); - parent.DispatchServiceEvent("fileCreated", new string[] { fileName }); + if (File.Exists(fileName)) + { + parent.Log($"File created: {fileName}"); + parent.DispatchServiceEvent("fileCreated", new string[] { + ruleName, + processId, + image, + fileName + }); + } + else + { + throw new FileNotFoundException($"{fileName} file not found."); + } } - else + else if (eventId == (int)EventType.NetworkConnection) { - throw new FileNotFoundException($"{fileName} file not found."); + string ruleName = e.EventRecord.Properties[(int)NetworkConnectionEvent.RuleName]?.Value?.ToString(); + string processId = e.EventRecord.Properties[(int)NetworkConnectionEvent.ProcessId]?.Value?.ToString(); + string image = e.EventRecord.Properties[(int)NetworkConnectionEvent.Image]?.Value?.ToString(); + string protocol = e.EventRecord.Properties[(int)NetworkConnectionEvent.Protocol]?.Value?.ToString(); + string destinationIp = e.EventRecord.Properties[(int)NetworkConnectionEvent.DestinationIp]?.Value?.ToString(); + string desinationPort = e.EventRecord.Properties[(int)NetworkConnectionEvent.DestinationPort]?.Value?.ToString(); + + parent.DispatchServiceEvent("networkConnected", new string[] { + ruleName, + processId, + image, + $"{protocol}://{destinationIp}:{desinationPort}" + }); } } catch (Exception ex) @@ -163,72 +154,5 @@ namespace WelsonJS.Service parent.Log("The event instance was null."); } } - - private void CheckFile(string filePath) - { - if (rules == null) - { - throw new ArgumentNullException("No rules added. Skipping check the file."); - } - - using (var ctx = new YaraContext()) - { - var scanner = new Scanner(); - var results = scanner.ScanFile(filePath, rules); - - if (results.Count > 0) - { - parent.Log($"Match Found: {filePath}"); - - foreach (var result in results) - { - Dictionary> matches = result.Matches; - foreach (KeyValuePair> match in matches) - { - string ruleName = match.Key; - List ruleMatches = match.Value; - ruleMatches.ForEach((x) => - { - parent.Log($"Matched {ruleName}: {filePath}, Offset {x.Offset}"); - parent.DispatchServiceEvent("fileRuleMatched", new string[] { ruleName, filePath, x.Offset.ToString() }); - - IndexFileRuleMatched(new FileMatchResult - { - FilePath = filePath, - Offset = x.Offset, - RuleName = ruleName, - LastChecked = DateTime.Now - }); - }); - } - } - } - else - { - parent.Log($"No match found in {filePath}."); - } - } - } - - private void IndexFileRuleMatched(FileMatchResult match) - { - // TODO (Save a result to the document indexer) - } - - private void Dispose() - { - if (rules != null) - { - try - { - //rules.Dispose(); - rules = null; - } - catch (Exception) - { - rules = null; - } - } - } } } \ No newline at end of file diff --git a/WelsonJS.Toolkit/WelsonJS.Service/WelsonJS.Service.csproj b/WelsonJS.Toolkit/WelsonJS.Service/WelsonJS.Service.csproj index 23cbf39..736202e 100644 --- a/WelsonJS.Toolkit/WelsonJS.Service/WelsonJS.Service.csproj +++ b/WelsonJS.Toolkit/WelsonJS.Service/WelsonJS.Service.csproj @@ -1,7 +1,6 @@  - Debug @@ -98,8 +97,8 @@ - - ..\packages\Google.Protobuf.3.27.3\lib\net45\Google.Protobuf.dll + + ..\packages\Google.Protobuf.3.28.0\lib\net45\Google.Protobuf.dll ..\packages\Grpc.Core.2.46.6\lib\net45\Grpc.Core.dll @@ -244,7 +243,6 @@ 이 프로젝트는 이 컴퓨터에 없는 NuGet 패키지를 참조합니다. 해당 패키지를 다운로드하려면 NuGet 패키지 복원을 사용하십시오. 자세한 내용은 http://go.microsoft.com/fwlink/?LinkID=322105를 참조하십시오. 누락된 파일은 {0}입니다. - diff --git a/WelsonJS.Toolkit/WelsonJS.Service/packages.config b/WelsonJS.Toolkit/WelsonJS.Service/packages.config index d813699..158873f 100644 --- a/WelsonJS.Toolkit/WelsonJS.Service/packages.config +++ b/WelsonJS.Toolkit/WelsonJS.Service/packages.config @@ -1,6 +1,6 @@  - + @@ -11,7 +11,6 @@ -