welsonjs/WelsonJS.Toolkit/WelsonJS.Service/FileEventMonitor.cs

196 lines
7.7 KiB
C#
Raw Normal View History

2024-08-12 03:47:19 +00:00
// FileEventMonitor.cs
2024-08-26 16:24:11 +00:00
// Namhyeon Go <abuse@catswords.net>
2024-08-12 03:47:19 +00:00
// https://github.com/gnh1201/welsonjs
using System;
using System.Diagnostics.Eventing.Reader;
using System.IO;
using System.ServiceProcess;
namespace WelsonJS.Service
{
public class FileEventMonitor
{
private EventLogWatcher eventLogWatcher;
private ServiceMain parent;
private enum EventType: int
{
FileCreate = 11,
2024-09-09 08:09:31 +00:00
NetworkConnection = 3,
RegistryEvent_1 = 12,
RegistryEvent_2 = 13,
RegistryEvent_3 = 14
};
private enum FileCreateEvent: int {
RuleName,
UtcTime,
ProcessGuid,
ProcessId,
Image,
TargetFilename,
CreationUtcTime,
User
};
private enum NetworkConnectionEvent: int
{
RuleName,
UtcTime,
ProcessGuid,
ProcessId,
Image,
User,
Protocol,
Initiated,
SourceIsIpv6,
SourceIp,
SourceHostname,
SourcePort,
SourcePortName,
DestinationIsIpv6,
DestinationIp,
DestinationHostname,
DestinationPort,
DestinationPortName,
};
2024-09-09 08:09:31 +00:00
private enum RegistryEvent: int
{
RuleName,
EventType,
UtcTime,
ProcessGuid,
ProcessId,
Image,
TargetObject,
Details,
User
}
2024-08-12 03:47:19 +00:00
public FileEventMonitor(ServiceBase parent, string workingDirectory)
{
this.parent = (ServiceMain)parent;
}
public void Start()
{
2024-08-12 04:00:04 +00:00
try
{
string query = @"<QueryList>
<Query Id='0' Path='Microsoft-Windows-Sysmon/Operational'>
<Select Path='Microsoft-Windows-Sysmon/Operational'>*[System/EventID=11 or System/EventID=3]</Select>
2024-08-12 04:00:04 +00:00
</Query>
</QueryList>";
2024-08-12 03:47:19 +00:00
2024-08-12 04:00:04 +00:00
EventLogQuery eventLogQuery = new EventLogQuery("Microsoft-Windows-Sysmon/Operational", PathType.LogName, query);
eventLogWatcher = new EventLogWatcher(eventLogQuery);
2024-08-12 03:47:19 +00:00
2024-08-12 04:00:04 +00:00
eventLogWatcher.EventRecordWritten += new EventHandler<EventRecordWrittenEventArgs>(OnEventRecordWritten);
eventLogWatcher.Enabled = true;
}
catch (Exception ex)
{
2024-08-26 16:24:11 +00:00
parent.Log($"Failed to connect the Windows EventLog Service: {ex.Message}");
2024-08-12 04:00:04 +00:00
}
2024-08-12 03:47:19 +00:00
}
public void Stop()
{
if (eventLogWatcher != null)
{
2024-08-12 04:36:27 +00:00
try
{
eventLogWatcher.Dispose();
eventLogWatcher = null;
}
catch (Exception)
{
eventLogWatcher = null;
}
2024-08-12 03:47:19 +00:00
}
}
private void OnEventRecordWritten(object sender, EventRecordWrittenEventArgs e)
{
if (e.EventRecord != null)
{
int eventId = e.EventRecord.Id;
2024-08-12 03:47:19 +00:00
try
{
2024-09-09 08:09:31 +00:00
switch (eventId)
{
2024-09-09 08:09:31 +00:00
case (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();
parent.Log($"> Detected the file creation: {fileName}");
parent.Log(parent.DispatchServiceEvent("fileCreated", new string[] {
ruleName,
processId,
image,
fileName
}));
break;
}
case (int)EventType.NetworkConnection:
{
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();
string dstinationAddress = $"{protocol}://{destinationIp}:{desinationPort}";
parent.Log($"> Detected the network connection: {dstinationAddress}");
parent.Log(parent.DispatchServiceEvent("networkConnected", new string[] {
ruleName,
processId,
image,
dstinationAddress
}));
break;
}
case (int)EventType.RegistryEvent_1:
case (int)EventType.RegistryEvent_2:
case (int)EventType.RegistryEvent_3:
{
string ruleName = e.EventRecord.Properties[(int)RegistryEvent.RuleName]?.Value?.ToString();
string processId = e.EventRecord.Properties[(int)RegistryEvent.ProcessId]?.Value?.ToString();
string image = e.EventRecord.Properties[(int)RegistryEvent.Image]?.Value?.ToString();
string eventType = e.EventRecord.Properties[(int)RegistryEvent.EventType]?.Value?.ToString();
string targetObject = e.EventRecord.Properties[(int)RegistryEvent.TargetObject]?.Value?.ToString();
parent.Log($"> Detected the registry modification: {targetObject}");
parent.Log(parent.DispatchServiceEvent("registryModified", new string[] {
ruleName,
processId,
image,
eventType,
targetObject
}));
break;
}
default:
throw new ArgumentException("Not supported event type");
2024-08-12 03:47:19 +00:00
}
}
catch (Exception ex)
{
parent.Log($"Error processing event: {ex.Message}");
}
}
else
{
parent.Log("The event instance was null.");
}
}
}
}