mirror of
https://github.com/andreacristaldi/DefenderRuleParser
synced 2026-06-16 13:55:00 +00:00
87 lines
2.9 KiB
C#
87 lines
2.9 KiB
C#
// DefenderRuleParser
|
|
// Author: Andrea Cristaldi 2025 - https://github.com/andreacristaldi/DefenderRuleParser
|
|
// This project is licensed under the Apache 2.0 License.
|
|
/*
|
|
* Summary: Parses embedded LUA-like script fragments when present.
|
|
* Origin: dump-driven; string/range harvesting from observed script chunks.
|
|
* Role: Surfaces script markers and literals for intel.
|
|
*/
|
|
using DefenderRuleParser2;
|
|
using DefenderRuleParser2.Models;
|
|
using System;
|
|
using System.IO;
|
|
using System.Text;
|
|
using System.Collections.Generic;
|
|
|
|
namespace DefenderRuleParser2.Parsers
|
|
{
|
|
public class LuaParser : ISignatureParser
|
|
{
|
|
private static readonly byte[] LuaHeader = new byte[] { 0x1B, 0x4C, 0x75, 0x61 };
|
|
|
|
public void Parse(BinaryReader reader, int size, uint threatId)
|
|
{
|
|
long offset = reader.BaseStream.Position;
|
|
|
|
try
|
|
{
|
|
byte[] buffer = reader.ReadBytes(size);
|
|
int headerIndex = FindLuaHeader(buffer);
|
|
|
|
if (headerIndex == -1)
|
|
{
|
|
Logger.Info($"[LUA] Threat ID: {threatId} | Lua header not found.");
|
|
return;
|
|
}
|
|
|
|
byte[] luaCode = new byte[buffer.Length - headerIndex];
|
|
Array.Copy(buffer, headerIndex, luaCode, 0, luaCode.Length);
|
|
|
|
string luaPath = Logger.OutputFolder + $"lua_script_{threatId}.lua";
|
|
File.WriteAllBytes(luaPath, luaCode);
|
|
|
|
Logger.Info($"[LUA] Threat ID: {threatId} | Extracted Lua script to: {luaPath}");
|
|
|
|
if (ThreatDatabase.TryGetThreat(threatId, out var threat))
|
|
{
|
|
threat.Signatures.Add(new SignatureEntry
|
|
{
|
|
Type = "SIGNATURE_TYPE_LUASTANDALONE",
|
|
Offset = offset,
|
|
Pattern = new List<string> { $"Extracted: {luaPath}" },
|
|
Parsed = true,
|
|
ConditionType = "PRESENT",
|
|
ConditionValue = 1
|
|
});
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.Error($"[LUA] Error parsing at offset 0x{offset:X}: {ex.Message}");
|
|
}
|
|
finally
|
|
{
|
|
reader.BaseStream.Seek(offset + size, SeekOrigin.Begin);
|
|
}
|
|
}
|
|
|
|
private int FindLuaHeader(byte[] data)
|
|
{
|
|
for (int i = 0; i <= data.Length - LuaHeader.Length; i++)
|
|
{
|
|
bool match = true;
|
|
for (int j = 0; j < LuaHeader.Length; j++)
|
|
{
|
|
if (data[i + j] != LuaHeader[j])
|
|
{
|
|
match = false;
|
|
break;
|
|
}
|
|
}
|
|
if (match) return i;
|
|
}
|
|
return -1;
|
|
}
|
|
}
|
|
}
|