-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathmain.py
More file actions
97 lines (86 loc) · 3.51 KB
/
Copy pathmain.py
File metadata and controls
97 lines (86 loc) · 3.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#!/bin/python
import os
import argparse
import json
from datetime import datetime
from core.config import EMBEDDINGS_FILE
from core.ttp_mapper import TTPMapper
from core.report_parser import ReportParser
def main():
print("""
_______________ __ ___
/_ __/_ __/ _ \\/ |/ /__ ____ ___ ___ ____
/ / / / / ___/ /|_/ / _ `/ _ \\/ _ \\/ -_) __/
/_/ /_/ /_/ /_/ /_/\\_,_/ .__/ .__/\\__/_/
By @infosecn1nja /_/ /_/
""")
parser = argparse.ArgumentParser(
description="MITRE ATT&CK Threat Report Mapper with IOC Extraction and Summary"
)
parser.add_argument("--url", help="URL of the HTML-based threat report")
parser.add_argument("--pdf", help="Path to the local PDF report")
parser.add_argument("--output", choices=["json", "stix21"], help="Output format: json or stix21")
parser.add_argument("--verbose", action="store_true", help="Enable verbose output")
args = parser.parse_args()
mapper = TTPMapper()
parser_util = ReportParser()
# Load or generate MITRE mappings
try:
if not os.path.exists(EMBEDDINGS_FILE):
if args.verbose:
print("[*] MITRE mapping not found. Generating...")
mapper.save_mappings()
else:
mapper.load_mappings()
except Exception as e:
print(f"[!] Failed to load/generate MITRE mappings: {str(e)}")
exit(1)
# Parse report
report_content = ""
source_info = {}
try:
if args.url:
if args.verbose:
print(f"[*] Fetching and converting report from URL: {args.url}")
report_content = parser_util.fetch_and_convert_report(args.url)
source_info = {"source_type": "url", "value": args.url}
elif args.pdf:
if args.verbose:
print(f"[*] Extracting text from PDF: {args.pdf}")
report_content = parser_util.convert_pdf_to_markdown(args.pdf)
source_info = {"source_type": "pdf", "value": args.pdf}
else:
print("[!] Error: Please provide either --url or --pdf argument.")
exit(1)
except Exception as e:
print(f"[!] Failed to parse report: {str(e)}")
exit(1)
# Analyze report
try:
result = mapper.map_threat_report(report_content, verbose=args.verbose)
result["source_info"] = source_info
result["summary"] = mapper.summarize_report(report_content, verbose=args.verbose)
except Exception as e:
print(str(e))
exit(1)
# Output result
try:
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
if args.output == "stix21":
stix_bundle = mapper.generate_stix_bundle(result)
output_file = f"output/bundle_{timestamp}.json"
os.makedirs(os.path.dirname(output_file), exist_ok=True)
with open(output_file, "w", encoding="utf-8") as f:
json.dump(stix_bundle, f, indent=2 if args.verbose else None)
print(f"\n[+] STIX 2.1 bundle written to: {output_file}")
else:
output_file = f"output/result_{timestamp}.json"
os.makedirs(os.path.dirname(output_file), exist_ok=True)
with open(output_file, "w", encoding="utf-8") as f:
json.dump(result, f, indent=2 if args.verbose else None)
print(f"\n[+] JSON result written to: {output_file}")
except Exception as e:
print(f"[!] Failed to write output file: {str(e)}")
exit(1)
if __name__ == "__main__":
main()