mirror of
https://github.com/andreacristaldi/DefenderRuleParser
synced 2026-06-16 13:55:00 +00:00
116 lines
3.9 KiB
C#
116 lines
3.9 KiB
C#
// DefenderRuleParser
|
|
// Author: Andrea Cristaldi 2025 - https://github.com/andreacristaldi/DefenderRuleParser
|
|
// This project is licensed under the Apache 2.0 License.
|
|
/*
|
|
* Summary: NSCRIPT “cure” variant parser (clean-up/remediation recipes).
|
|
* Origin: dump-driven; step codes and parameters inferred from dumps.
|
|
* Role: Presents steps as readable pseudo-operations without execution semantics.
|
|
*/
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Text;
|
|
using DefenderRuleParser2.Models;
|
|
|
|
namespace DefenderRuleParser2.Parsers
|
|
{
|
|
public class NscriptCureParser : ISignatureParser
|
|
{
|
|
public void Parse(BinaryReader reader, int size, uint threatId)
|
|
{
|
|
long offset = reader.BaseStream.Position;
|
|
|
|
try
|
|
{
|
|
byte[] buffer = reader.ReadBytes(size);
|
|
|
|
string asciiPreview = Encoding.ASCII.GetString(buffer);
|
|
string extractedText = ExtractAsciiStrings(asciiPreview, 4);
|
|
|
|
var hexDump = new List<string>();
|
|
for (int i = 0; i < buffer.Length; i += 16)
|
|
{
|
|
string line = $"{(offset + i):X8} ";
|
|
for (int j = 0; j < 16; j++)
|
|
{
|
|
if (i + j < buffer.Length)
|
|
line += $"{buffer[i + j]:X2} ";
|
|
else
|
|
line += " ";
|
|
}
|
|
hexDump.Add(line.TrimEnd());
|
|
}
|
|
|
|
Logger.Info($"[NSCRIPT_CURE] Threat ID: {threatId}, Size: {size} bytes");
|
|
if (!string.IsNullOrWhiteSpace(extractedText))
|
|
Logger.Info(" > Embedded text: " + extractedText);
|
|
Logger.Info(" > Hex:\n" + string.Join(Environment.NewLine, hexDump));
|
|
|
|
var hexExport = new List<string>();
|
|
for (int i = 0; i < buffer.Length; i += 16)
|
|
{
|
|
string line = "";
|
|
for (int j = 0; j < 16 && i + j < buffer.Length; j++)
|
|
line += $"{buffer[i + j]:X2} ";
|
|
hexExport.Add(line.TrimEnd());
|
|
}
|
|
|
|
if (ThreatDatabase.TryGetThreat(threatId, out var threat))
|
|
{
|
|
var pattern = new List<string>();
|
|
if (!string.IsNullOrWhiteSpace(extractedText))
|
|
pattern.Add(extractedText);
|
|
pattern.AddRange(hexExport);
|
|
|
|
threat.Signatures.Add(new SignatureEntry
|
|
{
|
|
Type = "SIGNATURE_TYPE_NSCRIPT_CURE",
|
|
Offset = offset,
|
|
Pattern = pattern,
|
|
Parsed = false,
|
|
ConditionType = "PRESENT",
|
|
ConditionValue = 1
|
|
});
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.Error($"[!] NSCRIPT_CURE Error parsing at offset 0x{offset:X}: {ex.Message}");
|
|
}
|
|
finally
|
|
{
|
|
reader.BaseStream.Seek(offset + size, SeekOrigin.Begin);
|
|
}
|
|
}
|
|
|
|
private string ExtractAsciiStrings(string input, int minLen)
|
|
{
|
|
var output = new StringBuilder();
|
|
var buffer = new StringBuilder();
|
|
|
|
foreach (char c in input)
|
|
{
|
|
if (c >= 32 && c <= 126)
|
|
{
|
|
buffer.Append(c);
|
|
}
|
|
else
|
|
{
|
|
if (buffer.Length >= minLen)
|
|
{
|
|
output.AppendLine(buffer.ToString());
|
|
}
|
|
buffer.Clear();
|
|
}
|
|
}
|
|
|
|
if (buffer.Length >= minLen)
|
|
{
|
|
output.AppendLine(buffer.ToString());
|
|
}
|
|
|
|
return output.ToString().Trim();
|
|
}
|
|
}
|
|
}
|