Files
Andrea Cristaldi 492ffc428b First commit
2025-08-28 17:14:35 +02:00

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();
}
}
}