diff --git a/contrib/sigma2CSV.py b/contrib/sigma2CSV.py new file mode 100644 index 000000000..b2c99d66a --- /dev/null +++ b/contrib/sigma2CSV.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python3 +# Copyright 2021 wagga40 (https://github.com/wagga40) +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . +""" +Project: sigma2CSV.py +Date: 07 aug 2021 +Author: wagga40 (https://github.com/wagga40) +Version: 1.0 +Description: + Asked by frak113 in issue #1787 (https://github.com/SigmaHQ/sigma/issues/1787#issuecomment-894618060) + This script converts sigma rules to a CSV format for statistics puprpose. + For now, it only keeps title, description, level, tags and author fields. + Feel free to modify it according to your needs. +Requirements: + $ pip install pyyaml +""" + +import yaml +import glob +import argparse + +parser = argparse.ArgumentParser() +parser.add_argument("-r", "--rulesdirectory", help="Sub-directory generated by rules-search", required=True, type=str) +parser.add_argument("-f", "--fileext", help="Rule file extension", default="yml", type=str) +parser.add_argument("-d", "--delimiter", help="Separator", default=",", type=str) +parser.add_argument("--oneline", help="Put all tags on a single line", action="store_true") +args = parser.parse_args() + +files = glob.glob(args.rulesdirectory + "/**/*." + args.fileext, recursive=True) +# for each file in the given directory +for file in files: + d={} + with open(file, 'r') as stream: + docs = yaml.load_all(stream, Loader=yaml.FullLoader) + for doc in docs: + for k,v in doc.items(): + if k in ['title','description','tags','level','author']: # Modify here if you want to include other fields + d[k]=v + # Check for optional fields + if "author" not in d: d["author"]="" + if "level" not in d: d["level"]="" + if args.oneline: # All tags will be on a single line + if "tags" in d: + expandTags = args.delimiter.join([ tags for tags in d["tags"] if "attack" in tags ]) # Only output attack related tags + print(f'{d["title"]}{args.delimiter}{d["description"]}{args.delimiter}{d["level"]}{args.delimiter}{d["author"]}{args.delimiter}{expandTags}') + else: + print(f'{d["title"]}{args.delimiter}{d["description"]}{args.delimiter}{d["level"]}{args.delimiter}{d["author"]}') + else: + if "tags" in d: + for tag in d["tags"]: + if "attack" in tag: # Only output attack related tags + print(f'{d["title"]}{args.delimiter}{d["description"]}{args.delimiter}{d["level"]}{args.delimiter}{d["author"]}{args.delimiter}{tag}') \ No newline at end of file