Europa
Europa

Reputation: 1292

C# .NET send Windows 11 Home Defender Security Alerts as JSON to webhook to LimaCharlie

I want to send Windows Security Defender events to LimaCharlie webhook.

I am able to send Application logs now with this snippet:

// Run PowerShell command to get last 10 Application logs
ProcessStartInfo psi = new ProcessStartInfo
{
    FileName = "powershell",
    Arguments = "-Command \"Get-WinEvent -LogName Application -MaxEvents 10 | ConvertTo-Json -Depth 3\"",
    RedirectStandardOutput = true,
    UseShellExecute = false,
    CreateNoWindow = true
};

But when I am unsure on how my program can get the Windows Security Defender logs.

I have tried this but it does not work:

// Run PowerShell command to get last 10 Security logs
ProcessStartInfo psi = new ProcessStartInfo
{
    FileName = "powershell",
    Arguments = "-Command \"Get-WinEvent -LogName Application | Where-Object {$_.ProviderName -like 'Microsoft-Windows-Security-Auditing'} -MaxEvents 10 | ConvertTo-Json -Depth 3\"",
    RedirectStandardOutput = true,
    UseShellExecute = false,
    CreateNoWindow = true
};

Error;

ERROR: The output is not valid JSON. Here is the plain text output: Where-Object : A parameter cannot be found that matches parameter name 'MaxEvents'.

This is my code - Program.cs:

using System;
using System.Diagnostics;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;

class Program
{
    static async Task Main(string[] args)
    {
        // Load configuration or prompt user for details
        Config config = ConfigManager.LoadConfig() ?? ConfigManager.PromptUserForConfig();

        // Send Application Event Logs to LimaCharlie
        await SendApplicationLogs(config);
    }

    /// <summary>
    /// Fetches the last 10 Application Event logs and sends them to LimaCharlie.
    /// </summary>
    static async Task SendApplicationLogs(Config config)
    {
        try
        {
            // Run PowerShell command to get last 10 Security logs
            ProcessStartInfo psi = new ProcessStartInfo
            {
                FileName = "powershell",
                Arguments = "-Command \"Get-WinEvent -LogName Application | Where-Object {$_.ProviderName -like 'Microsoft-Windows-Security-Auditing'} -MaxEvents 10 | ConvertTo-Json -Depth 3\"",
                RedirectStandardOutput = true,
                UseShellExecute = false,
                CreateNoWindow = true
            };

            using (Process process = new Process { StartInfo = psi })
            {
                process.Start();
                string jsonData = process.StandardOutput.ReadToEnd();
                process.WaitForExit();

                // Try to deserialize the output to check if it's JSON
                try
                {
                    // Try to deserialize the output as JSON
                    var jsonObject = JsonConvert.DeserializeObject(jsonData);

                    // If deserialization succeeds, it's JSON
                    Console.WriteLine("Program·SendApplicationLogs()· Logs successfully sent to LimaCharlie.");
                }
                catch (JsonException)
                {
                    // If deserialization fails, it's not JSON (likely plain text)
                    Console.WriteLine("Program·SendApplicationLogs()· ERROR: The output is not valid JSON. Here is the plain text output:");
                    Console.WriteLine(jsonData);
                }

                // Continue with sending the logs (if it's valid JSON)
                using (HttpClient client = new HttpClient())
                {
                    // Add the authentication header
                    client.DefaultRequestHeaders.Add("lc-secret", config.WebhookSecret);

                    // Set the HTTP content type as JSON
                    HttpContent content = new StringContent(jsonData, Encoding.UTF8, "application/json");

                    // Ensure the HookURL doesn't have a duplicate domain part
                    string hookURL = config.HookURL.Contains(".hook.limacharlie.io") 
                        ? config.HookURL 
                        : $"{config.HookURL}.hook.limacharlie.io";

                    // Construct the final webhook URL
                    string webhookUrl = $"https://{hookURL}/{config.OrgId}/{config.WebhookName}";

                    // Send logs as POST request
                    HttpResponseMessage response = await client.PostAsync(webhookUrl, content);

                    // Print the response status
                    if (response.IsSuccessStatusCode)
                    {
                        Console.WriteLine($"Program·SendApplicationLogs()·Logs successfully sent to LimaCharlie.");
                    }
                    else
                    {
                        Console.WriteLine($"Program·SendApplicationLogs()·ERROR: {response.StatusCode} - {response.ReasonPhrase}");
                    }
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Program·SendApplicationLogs()·ERROR: {ex.Message}");
        }
    }
}

Config.cs:

// WinSecurityLogs/Model/Config.cs

/// <summary>
/// Stores LimaCharlie Configuration Details.
/// </summary>
public class Config
{
    public string OrgId { get; set; }
    public string HookURL {get; set;}
    public string WebhookName { get; set; }
    public string WebhookSecret { get; set; }
}

ConfigManager.cs:

// WinSecurityLogs/WinEventLogger

using System;
using System.IO;
using Newtonsoft.Json;

// Handles User Input & Config Storage

public class ConfigManager
{
    // Path to store the config file
    private static string configPath = "config.json";

    /// <summary>
    /// Loads configuration from config.json if it exists.
    /// </summary>
    public static Config LoadConfig()
    {
        if (File.Exists(configPath))
        {
            string json = File.ReadAllText(configPath);
            return JsonConvert.DeserializeObject<Config>(json);
        }

        return null;
    }

    /// <summary>
    /// Saves configuration to config.json.
    /// </summary>
    public static void SaveConfig(Config config)
    {
        string json = JsonConvert.SerializeObject(config, Formatting.Indented);
        File.WriteAllText(configPath, json);
    }

    /// <summary>
    /// Prompts user for LimaCharlie details on first run.
    /// </summary>
    public static Config PromptUserForConfig()
    {
        Console.Write("Enter LimaCharlie Organization ID (example a100a186-8a11-445a-a0cf-643a40c7fb61): ");
        string orgId = Console.ReadLine().Trim();

        Console.Write("Enter LimaCharlie Hook URL (b76093c3662d5b4f.hook.limacharlie.io): ");
        string hookURL = Console.ReadLine().Trim();

        Console.Write("Enter LimaCharlie Webhook Name (example acd-windows-security-webhook): ");
        string webhookName = Console.ReadLine().Trim();

        Console.Write("Enter LimaCharlie Webhook Secret: ");
        string webhookSecret = Console.ReadLine().Trim();

        Config config = new Config
        {
            OrgId = orgId,
            HookURL = hookURL,
            WebhookName = webhookName,
            WebhookSecret = webhookSecret
        };

        SaveConfig(config);
        return config;
    }
}

Upvotes: 1

Views: 27

Answers (0)

Related Questions