mirror of
https://github.com/gnh1201/welsonjs.git
synced 2025-05-14 21:51:04 +00:00
Remove libyara.NET and a little fixes for sysmon events
This commit is contained in:
parent
671007bb79
commit
40edee2b83
|
@ -4,23 +4,20 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics.Eventing.Reader;
|
using System.Diagnostics.Eventing.Reader;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using libyaraNET;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.ServiceProcess;
|
using System.ServiceProcess;
|
||||||
using WelsonJS.Service.Model;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Runtime.ExceptionServices;
|
|
||||||
using System.Security;
|
|
||||||
|
|
||||||
namespace WelsonJS.Service
|
namespace WelsonJS.Service
|
||||||
{
|
{
|
||||||
public class FileEventMonitor
|
public class FileEventMonitor
|
||||||
{
|
{
|
||||||
private Rules rules;
|
|
||||||
private EventLogWatcher eventLogWatcher;
|
private EventLogWatcher eventLogWatcher;
|
||||||
private ServiceMain parent;
|
private ServiceMain parent;
|
||||||
private string ruleDirectoryPath;
|
private enum EventType: int
|
||||||
private enum EventType11: int {
|
{
|
||||||
|
FileCreate = 11,
|
||||||
|
NetworkConnection = 3
|
||||||
|
};
|
||||||
|
private enum FileCreateEvent: int {
|
||||||
RuleName,
|
RuleName,
|
||||||
UtcTime,
|
UtcTime,
|
||||||
ProcessGuid,
|
ProcessGuid,
|
||||||
|
@ -30,64 +27,31 @@ namespace WelsonJS.Service
|
||||||
CreationUtcTime,
|
CreationUtcTime,
|
||||||
User
|
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)
|
public FileEventMonitor(ServiceBase parent, string workingDirectory)
|
||||||
{
|
{
|
||||||
this.parent = (ServiceMain)parent;
|
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<string>(ruleFiles));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddYaraRules(List<string> 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()
|
public void Start()
|
||||||
|
@ -96,7 +60,7 @@ namespace WelsonJS.Service
|
||||||
{
|
{
|
||||||
string query = @"<QueryList>
|
string query = @"<QueryList>
|
||||||
<Query Id='0' Path='Microsoft-Windows-Sysmon/Operational'>
|
<Query Id='0' Path='Microsoft-Windows-Sysmon/Operational'>
|
||||||
<Select Path='Microsoft-Windows-Sysmon/Operational'>*[System/EventID=11]</Select>
|
<Select Path='Microsoft-Windows-Sysmon/Operational'>*[System/EventID=11 or System/EventID=3]</Select>
|
||||||
</Query>
|
</Query>
|
||||||
</QueryList>";
|
</QueryList>";
|
||||||
|
|
||||||
|
@ -126,31 +90,58 @@ namespace WelsonJS.Service
|
||||||
eventLogWatcher = null;
|
eventLogWatcher = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Dispose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnEventRecordWritten(object sender, EventRecordWrittenEventArgs e)
|
private void OnEventRecordWritten(object sender, EventRecordWrittenEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.EventRecord != null)
|
if (e.EventRecord != null)
|
||||||
{
|
{
|
||||||
|
int eventId = e.EventRecord.Id;
|
||||||
|
|
||||||
try
|
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))
|
if (string.IsNullOrEmpty(fileName))
|
||||||
{
|
{
|
||||||
throw new ArgumentException("Could not read the target filename.");
|
throw new ArgumentException("Could not read the target filename.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (File.Exists(fileName))
|
if (File.Exists(fileName))
|
||||||
{
|
{
|
||||||
parent.Log($"File created: {fileName}");
|
parent.Log($"File created: {fileName}");
|
||||||
parent.DispatchServiceEvent("fileCreated", new string[] { 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)
|
catch (Exception ex)
|
||||||
|
@ -163,72 +154,5 @@ namespace WelsonJS.Service
|
||||||
parent.Log("The event instance was null.");
|
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<string, List<Match>> matches = result.Matches;
|
|
||||||
foreach (KeyValuePair<string, List<Match>> match in matches)
|
|
||||||
{
|
|
||||||
string ruleName = match.Key;
|
|
||||||
List<Match> 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<Import Project="..\packages\Grpc.Tools.2.66.0\build\Grpc.Tools.props" Condition="Exists('..\packages\Grpc.Tools.2.66.0\build\Grpc.Tools.props')" />
|
<Import Project="..\packages\Grpc.Tools.2.66.0\build\Grpc.Tools.props" Condition="Exists('..\packages\Grpc.Tools.2.66.0\build\Grpc.Tools.props')" />
|
||||||
<Import Project="..\packages\Microsoft.O365.Security.Native.libyara.NET.4.5.1\build\net462\Microsoft.O365.Security.Native.libyara.NET.props" Condition="Exists('..\packages\Microsoft.O365.Security.Native.libyara.NET.4.5.1\build\net462\Microsoft.O365.Security.Native.libyara.NET.props')" />
|
|
||||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
@ -98,8 +97,8 @@
|
||||||
<StartupObject />
|
<StartupObject />
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="Google.Protobuf, Version=3.27.3.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
|
<Reference Include="Google.Protobuf, Version=3.28.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\Google.Protobuf.3.27.3\lib\net45\Google.Protobuf.dll</HintPath>
|
<HintPath>..\packages\Google.Protobuf.3.28.0\lib\net45\Google.Protobuf.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Grpc.Core, Version=2.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
|
<Reference Include="Grpc.Core, Version=2.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\Grpc.Core.2.46.6\lib\net45\Grpc.Core.dll</HintPath>
|
<HintPath>..\packages\Grpc.Core.2.46.6\lib\net45\Grpc.Core.dll</HintPath>
|
||||||
|
@ -244,7 +243,6 @@
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<ErrorText>이 프로젝트는 이 컴퓨터에 없는 NuGet 패키지를 참조합니다. 해당 패키지를 다운로드하려면 NuGet 패키지 복원을 사용하십시오. 자세한 내용은 http://go.microsoft.com/fwlink/?LinkID=322105를 참조하십시오. 누락된 파일은 {0}입니다.</ErrorText>
|
<ErrorText>이 프로젝트는 이 컴퓨터에 없는 NuGet 패키지를 참조합니다. 해당 패키지를 다운로드하려면 NuGet 패키지 복원을 사용하십시오. 자세한 내용은 http://go.microsoft.com/fwlink/?LinkID=322105를 참조하십시오. 누락된 파일은 {0}입니다.</ErrorText>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Error Condition="!Exists('..\packages\Microsoft.O365.Security.Native.libyara.NET.4.5.1\build\net462\Microsoft.O365.Security.Native.libyara.NET.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.O365.Security.Native.libyara.NET.4.5.1\build\net462\Microsoft.O365.Security.Native.libyara.NET.props'))" />
|
|
||||||
<Error Condition="!Exists('..\packages\Grpc.Core.2.46.6\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.2.46.6\build\net45\Grpc.Core.targets'))" />
|
<Error Condition="!Exists('..\packages\Grpc.Core.2.46.6\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.2.46.6\build\net45\Grpc.Core.targets'))" />
|
||||||
<Error Condition="!Exists('..\packages\Grpc.Tools.2.66.0\build\Grpc.Tools.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Tools.2.66.0\build\Grpc.Tools.props'))" />
|
<Error Condition="!Exists('..\packages\Grpc.Tools.2.66.0\build\Grpc.Tools.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Tools.2.66.0\build\Grpc.Tools.props'))" />
|
||||||
<Error Condition="!Exists('..\packages\Grpc.Tools.2.66.0\build\Grpc.Tools.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Tools.2.66.0\build\Grpc.Tools.targets'))" />
|
<Error Condition="!Exists('..\packages\Grpc.Tools.2.66.0\build\Grpc.Tools.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Tools.2.66.0\build\Grpc.Tools.targets'))" />
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="Google.Protobuf" version="3.27.3" targetFramework="net48" />
|
<package id="Google.Protobuf" version="3.28.0" targetFramework="net48" />
|
||||||
<package id="Grpc" version="2.46.6" targetFramework="net48" />
|
<package id="Grpc" version="2.46.6" targetFramework="net48" />
|
||||||
<package id="Grpc.Core" version="2.46.6" targetFramework="net48" />
|
<package id="Grpc.Core" version="2.46.6" targetFramework="net48" />
|
||||||
<package id="Grpc.Core.Api" version="2.65.0" targetFramework="net48" />
|
<package id="Grpc.Core.Api" version="2.65.0" targetFramework="net48" />
|
||||||
|
@ -11,7 +11,6 @@
|
||||||
<package id="Microsoft.Bcl.AsyncInterfaces" version="8.0.0" targetFramework="net48" />
|
<package id="Microsoft.Bcl.AsyncInterfaces" version="8.0.0" targetFramework="net48" />
|
||||||
<package id="Microsoft.Extensions.DependencyInjection.Abstractions" version="8.0.1" targetFramework="net48" />
|
<package id="Microsoft.Extensions.DependencyInjection.Abstractions" version="8.0.1" targetFramework="net48" />
|
||||||
<package id="Microsoft.Extensions.Logging.Abstractions" version="8.0.1" targetFramework="net48" />
|
<package id="Microsoft.Extensions.Logging.Abstractions" version="8.0.1" targetFramework="net48" />
|
||||||
<package id="Microsoft.O365.Security.Native.libyara.NET" version="4.5.1" targetFramework="net48" />
|
|
||||||
<package id="RestSharp" version="112.0.0" targetFramework="net48" />
|
<package id="RestSharp" version="112.0.0" targetFramework="net48" />
|
||||||
<package id="System.Buffers" version="4.5.1" targetFramework="net48" />
|
<package id="System.Buffers" version="4.5.1" targetFramework="net48" />
|
||||||
<package id="System.Diagnostics.DiagnosticSource" version="8.0.1" targetFramework="net48" />
|
<package id="System.Diagnostics.DiagnosticSource" version="8.0.1" targetFramework="net48" />
|
||||||
|
|
Loading…
Reference in New Issue
Block a user