Merge PR #5402 from @ariel-anieli - feat: add JSON output format for deprecated rule summary

chore: tests/deprecated_rules.py - add json output format
chore: add deprecated/deprecated.json
chore: update README and workflow job accordingly

---------

Signed-off-by: Ariel Otilibili <otilibil@eurecom.fr>
Co-authored-by: phantinuss <79651203+phantinuss@users.noreply.github.com>
This commit is contained in:
Ariel Otilibili
2025-06-13 10:59:34 +02:00
committed by GitHub
parent dfed136f16
commit a1c9827a35
5 changed files with 1141 additions and 72 deletions
+44 -28
View File
@@ -1,50 +1,66 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Create the summary of all the deprecated rules in the deprecated.csv file
Create the summary of all the deprecated rules in deprecated.csv or deprecated.json
Run using the command
# python deprecated_rules.py
# python deprecated_rules.py --format {json, csv}
"""
from sigma.collection import SigmaCollection
from sigma.rule import SigmaStatus,SigmaLevel
import datetime
from sigma.rule import SigmaStatus, SigmaLevel
import argparse
import csv
import json
parser = argparse.ArgumentParser()
parser.add_argument("-f", "--format", choices=["csv", "json"], default="csv")
args = parser.parse_args()
path_to_rules = [
"deprecated",
]
name_csv_export = "./deprecated/deprecated.csv"
def save_csv(rules):
with open(name_csv_export, encoding="UTF-8", mode="w", newline="") as csv_file:
fieldnames = ["id", "title", "date", "modified","level"]
writer = csv.DictWriter(csv_file, fieldnames=fieldnames)
writer.writeheader()
def get_level(rule):
return rule.level if rule.status else SigmaLevel.MEDIUM
raw_info = []
for rule in rules:
if rule.status is SigmaStatus.DEPRECATED:
modified = rule.modified if rule.modified else datetime.date.today()
level = rule.level if rule.status else SigmaLevel.MEDIUM
raw_info.append(
{
"id": rule.id,
"title": rule.title,
"date": rule.date,
"modified": modified,
"level": level
}
)
sort_info = sorted(raw_info, key=lambda d: d['modified'])
writer.writerows(sort_info)
def get_modified_time(rule):
return rule.modified if rule.modified else rule.date
def format_rule(rule):
return {
"id": str(rule.id),
"title": rule.title,
"date": str(rule.date),
"modified": str(get_modified_time(rule)),
"level": str(get_level(rule)),
}
def save_file(rules, _format):
is_rule_deprecated = lambda rule: rule.status is SigmaStatus.DEPRECATED
filename_export = f"./deprecated/deprecated.{_format}"
raw_info = map(format_rule, filter(is_rule_deprecated, rules))
sort_info_secondary = sorted(raw_info, key=lambda d: d["id"])
sort_info = sorted(sort_info_secondary, key=lambda d: d["modified"])
with open(filename_export, encoding="UTF-8", mode="w", newline="") as _file:
if _format == "csv":
fieldnames = ["id", "title", "date", "modified", "level"]
writer = csv.DictWriter(_file, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(sort_info)
elif _format == "json":
json.dump(sort_info, _file, indent=4)
if __name__ == "__main__":
rule_paths = SigmaCollection.resolve_paths(path_to_rules)
rule_collection = SigmaCollection.load_ruleset(rule_paths, collect_errors=True)
save_csv(rule_collection)
save_file(rule_collection, args.format)