mirror of
https://github.com/andreacristaldi/DefenderRuleParser
synced 2026-06-16 13:55:00 +00:00
156 lines
6.1 KiB
C#
156 lines
6.1 KiB
C#
// DefenderRuleParser
|
|
// Author: Andrea Cristaldi 2025 - https://github.com/andreacristaldi/DefenderRuleParser
|
|
// This project is licensed under the Apache 2.0 License.
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Linq;
|
|
|
|
namespace DefenderRuleParser2
|
|
{
|
|
internal class Program
|
|
{
|
|
static void Main(string[] args)
|
|
{
|
|
|
|
Logger.Info("DefenderRuleParser\nhttps://github.com/andreacristaldi/DefenderRuleParser\n\n");
|
|
|
|
if (args.Length < 1)
|
|
{
|
|
Logger.Info("Usage:");
|
|
Logger.Info(" DefenderRuleParser <fileOrFolder> [--recursive] [--skip-existing] [--debug] [--debug-hex] [--quiet]");
|
|
Logger.Info("");
|
|
Logger.Info("Options:");
|
|
Logger.Info(" --recursive Process folders recursively");
|
|
//Logger.Info(" --skip-existing Skip .json if already present");
|
|
Logger.Info(" --debug Enable verbose logs");
|
|
//Logger.Info(" --quiet Suppress console logs (modules can still check Logger flags)");
|
|
return;
|
|
}
|
|
|
|
string inputPath = args[0];
|
|
bool recursive = args.Contains("--recursive", StringComparer.OrdinalIgnoreCase);
|
|
bool skipExisting = args.Contains("--skip-existing", StringComparer.OrdinalIgnoreCase);
|
|
bool debug = args.Contains("--debug", StringComparer.OrdinalIgnoreCase);
|
|
bool quiet = args.Contains("--quiet", StringComparer.OrdinalIgnoreCase);
|
|
|
|
|
|
Logger.DebugEnabled = debug;
|
|
|
|
Logger.Verbose($"[cfg] recursive={recursive} skipExisting={skipExisting} debug={debug} quiet={quiet}");
|
|
|
|
Logger.Info("[+] Loading threat dictionary from 'defender.csv'...");
|
|
string filePath = "defender.csv";
|
|
if (!File.Exists(filePath))
|
|
{
|
|
Logger.Warn("Threat dictionary not found. Attempting to retrieve using PowerShell...");
|
|
|
|
try
|
|
{
|
|
var psi = new ProcessStartInfo()
|
|
{
|
|
FileName = "powershell.exe",
|
|
Arguments = "Get-MpThreatCatalog | Export-Csv -Path ./defender.csv -NoTypeInformation",
|
|
UseShellExecute = false,
|
|
RedirectStandardOutput = true,
|
|
RedirectStandardError = true,
|
|
CreateNoWindow = true
|
|
};
|
|
|
|
using (var process = new Process())
|
|
{
|
|
process.StartInfo = psi;
|
|
process.Start();
|
|
|
|
string output = process.StandardOutput.ReadToEnd();
|
|
string error = process.StandardError.ReadToEnd();
|
|
|
|
process.WaitForExit();
|
|
|
|
if (process.ExitCode != 0 || !File.Exists(filePath))
|
|
{
|
|
Logger.Error("PowerShell execution failed or defender.csv not created.");
|
|
Logger.Verbose(error);
|
|
Logger.Info("Ensure PowerShell is available, Windows Defender is installed, and you have sufficient permissions.");
|
|
return;
|
|
}
|
|
|
|
Logger.Info("Threat catalog successfully retrieved.");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.Error("Error executing PowerShell: " + ex.Message);
|
|
Logger.Info("Make sure PowerShell is installed and accessible, and that script execution is not restricted.");
|
|
return;
|
|
}
|
|
}
|
|
|
|
ThreatDatabase.Load(filePath);
|
|
|
|
var binFiles = new List<string>();
|
|
|
|
if (File.Exists(inputPath) && inputPath.EndsWith(".bin", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
binFiles.Add(inputPath);
|
|
}
|
|
else if (Directory.Exists(inputPath))
|
|
{
|
|
var searchOption = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
|
|
var allBins = Directory.GetFiles(inputPath, "*.bin", searchOption);
|
|
|
|
foreach (var bin in allBins)
|
|
{
|
|
string jsonPath = Path.ChangeExtension(bin, ".json");
|
|
|
|
if (skipExisting && File.Exists(jsonPath))
|
|
{
|
|
Logger.Info($"[>] Skipping {Path.GetFileName(bin)} (JSON already exists)");
|
|
continue;
|
|
}
|
|
|
|
binFiles.Add(bin);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Logger.Error("[!] Invalid file or folder path.");
|
|
return;
|
|
}
|
|
|
|
foreach (string binPath in binFiles)
|
|
{
|
|
Logger.Info($"\n[+] Processing: {binPath}");
|
|
Logger.OutputFolder = Path.GetFullPath(binPath);
|
|
try
|
|
{
|
|
using (var fs = new FileStream(binPath, FileMode.Open, FileAccess.Read))
|
|
using (var reader = new BinaryReader(fs))
|
|
{
|
|
SignatureReader.ExtractSignatures(reader, binPath);
|
|
}
|
|
|
|
string outputJson = Path.Combine(
|
|
Path.GetDirectoryName(binPath),
|
|
Path.GetFileNameWithoutExtension(binPath) + ".json"
|
|
);
|
|
|
|
//Exporter.SaveAllThreats(Path.GetDirectoryName(outputJson), Path.GetFileNameWithoutExtension(outputJson));
|
|
//Logger.Info($"[V] Exported: {outputJson}");
|
|
//File.Delete(binPath);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.Error($"[!] Failed to process {binPath}: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
Logger.Info("\n[V] Parsing completed. Press any key to exit.");
|
|
Console.ReadKey();
|
|
}
|
|
}
|
|
}
|
|
|