mirror of
https://github.com/usnistgov/macos_security.git
synced 2026-02-03 14:03:24 +00:00
feat[utils]generate_checklist
Added json export ability
This commit is contained in:
@@ -6,18 +6,26 @@ import argparse
|
||||
from collections import OrderedDict
|
||||
import re
|
||||
import os
|
||||
import uuid
|
||||
import platform
|
||||
import json
|
||||
|
||||
|
||||
def do_regex(stig_id, stig_title, result, stig, exempt, exempt_reason, ruleid):
|
||||
def do_regex(stig_id, stig_title, result, stig, exempt, exempt_reason, ruleid, json=False,stiguuid="", ref_identifer=""):
|
||||
checklist_xml = '''
|
||||
<VULN>'''
|
||||
rules_json = {}
|
||||
group_tree_dict = {}
|
||||
regex = r"<Group id=\"(V-..*\d)\">.*.{}".format(stig_id)
|
||||
#Vulnerability ID
|
||||
matches = re.search(regex,stig)
|
||||
if matches:
|
||||
|
||||
checklist_xml = checklist_xml + '''
|
||||
if json:
|
||||
rules_json["group_id_src"] = matches.group(1)
|
||||
group_tree_dict["id"] = matches.group(1)
|
||||
rules_json["group_id"] = matches.group(1)
|
||||
else:
|
||||
checklist_xml = checklist_xml + '''
|
||||
<STIG_DATA>
|
||||
<VULN_ATTRIBUTE>Vuln_Num</VULN_ATTRIBUTE>
|
||||
<ATTRIBUTE_DATA>{}</ATTRIBUTE_DATA>
|
||||
@@ -27,8 +35,10 @@ def do_regex(stig_id, stig_title, result, stig, exempt, exempt_reason, ruleid):
|
||||
#severity
|
||||
matches = re.search(regex,stig)
|
||||
if matches:
|
||||
|
||||
checklist_xml = checklist_xml + '''
|
||||
if json:
|
||||
rules_json["severity"] = matches.group(1)
|
||||
else:
|
||||
checklist_xml = checklist_xml + '''
|
||||
<STIG_DATA>
|
||||
<VULN_ATTRIBUTE>Severity</VULN_ATTRIBUTE>
|
||||
<ATTRIBUTE_DATA>{}</ATTRIBUTE_DATA>
|
||||
@@ -38,8 +48,11 @@ def do_regex(stig_id, stig_title, result, stig, exempt, exempt_reason, ruleid):
|
||||
matches = re.search(regex,stig)
|
||||
#SRG
|
||||
if matches:
|
||||
|
||||
checklist_xml = checklist_xml + '''
|
||||
if json:
|
||||
group_tree_dict["title"] = matches.group(1)
|
||||
group_tree_dict["description"] = "<GroupDescription></GroupDescription>"
|
||||
else:
|
||||
checklist_xml = checklist_xml + '''
|
||||
<STIG_DATA>
|
||||
<VULN_ATTRIBUTE>Group_Title</VULN_ATTRIBUTE>
|
||||
<ATTRIBUTE_DATA>{}</ATTRIBUTE_DATA>
|
||||
@@ -50,15 +63,19 @@ def do_regex(stig_id, stig_title, result, stig, exempt, exempt_reason, ruleid):
|
||||
matches = re.search(regex,stig)
|
||||
#RuleID
|
||||
if matches:
|
||||
|
||||
checklist_xml = checklist_xml + '''
|
||||
if json:
|
||||
rules_json["rule_id"] = matches.group(1).split("_")[0]
|
||||
rules_json["rule_id_src"] = matches.group(1)
|
||||
rules_json["rule_version"] = stig_id
|
||||
else:
|
||||
checklist_xml = checklist_xml + '''
|
||||
<STIG_DATA>
|
||||
<VULN_ATTRIBUTE>Rule_ID</VULN_ATTRIBUTE>
|
||||
<ATTRIBUTE_DATA>{}</ATTRIBUTE_DATA>
|
||||
</STIG_DATA>'''.format(matches.group(1))
|
||||
|
||||
|
||||
checklist_xml = checklist_xml + '''
|
||||
checklist_xml = checklist_xml + '''
|
||||
<STIG_DATA>
|
||||
<VULN_ATTRIBUTE>Rule_Ver</VULN_ATTRIBUTE>
|
||||
<ATTRIBUTE_DATA>{}</ATTRIBUTE_DATA>
|
||||
@@ -69,8 +86,10 @@ def do_regex(stig_id, stig_title, result, stig, exempt, exempt_reason, ruleid):
|
||||
#Title
|
||||
matches = re.search(regex,stig)
|
||||
if matches:
|
||||
|
||||
checklist_xml = checklist_xml + '''
|
||||
if json:
|
||||
rules_json["group_title"] = matches.group(1)
|
||||
else:
|
||||
checklist_xml = checklist_xml + '''
|
||||
<STIG_DATA>
|
||||
<VULN_ATTRIBUTE>Rule_Title</VULN_ATTRIBUTE>
|
||||
<ATTRIBUTE_DATA>{}</ATTRIBUTE_DATA>
|
||||
@@ -80,8 +99,10 @@ def do_regex(stig_id, stig_title, result, stig, exempt, exempt_reason, ruleid):
|
||||
#Vul Discussion
|
||||
matches = re.search(regex,stig)
|
||||
if matches:
|
||||
|
||||
checklist_xml = checklist_xml + '''
|
||||
if json:
|
||||
rules_json["discussion"] = matches.group(1)
|
||||
else:
|
||||
checklist_xml = checklist_xml + '''
|
||||
<STIG_DATA>
|
||||
<VULN_ATTRIBUTE>Vuln_Discuss</VULN_ATTRIBUTE>
|
||||
<ATTRIBUTE_DATA>{}</ATTRIBUTE_DATA>
|
||||
@@ -97,8 +118,10 @@ def do_regex(stig_id, stig_title, result, stig, exempt, exempt_reason, ruleid):
|
||||
matches = re.search(regex, stig)
|
||||
if matches:
|
||||
#Check Content
|
||||
|
||||
checklist_xml = checklist_xml + '''
|
||||
if json:
|
||||
rules_json["check_content"] = matches.group(2)
|
||||
else:
|
||||
checklist_xml = checklist_xml + '''
|
||||
<STIG_DATA>
|
||||
<VULN_ATTRIBUTE>Check_Content</VULN_ATTRIBUTE>
|
||||
<ATTRIBUTE_DATA>{}</ATTRIBUTE_DATA>
|
||||
@@ -107,7 +130,10 @@ def do_regex(stig_id, stig_title, result, stig, exempt, exempt_reason, ruleid):
|
||||
#fix_text
|
||||
matches = re.search(regex,stig)
|
||||
if matches:
|
||||
checklist_xml = checklist_xml + '''
|
||||
if json:
|
||||
rules_json["fix_text"] = matches.group(1)
|
||||
else:
|
||||
checklist_xml = checklist_xml + '''
|
||||
<STIG_DATA>
|
||||
<VULN_ATTRIBUTE>Fix_Text</VULN_ATTRIBUTE>
|
||||
<ATTRIBUTE_DATA>{}</ATTRIBUTE_DATA>
|
||||
@@ -117,8 +143,10 @@ def do_regex(stig_id, stig_title, result, stig, exempt, exempt_reason, ruleid):
|
||||
#weight
|
||||
matches = re.search(regex,stig)
|
||||
if matches:
|
||||
|
||||
checklist_xml = checklist_xml + '''
|
||||
if json:
|
||||
rules_json["weight"] = matches.group(1)
|
||||
else:
|
||||
checklist_xml = checklist_xml + '''
|
||||
<STIG_DATA>
|
||||
<VULN_ATTRIBUTE>False_Positives</VULN_ATTRIBUTE>
|
||||
<ATTRIBUTE_DATA></ATTRIBUTE_DATA>
|
||||
@@ -191,6 +219,7 @@ def do_regex(stig_id, stig_title, result, stig, exempt, exempt_reason, ruleid):
|
||||
regex = r"{}(\n|.)*?(<ident system=\".*.\">CCI-.*\d)<\/ident>".format(stig_id)
|
||||
matches = re.finditer(regex, stig, re.MULTILINE)
|
||||
comment = str()
|
||||
json_ccis = []
|
||||
for matchNum, match in enumerate(matches, start=1):
|
||||
|
||||
for groupNum in range(1, 2):
|
||||
@@ -200,7 +229,7 @@ def do_regex(stig_id, stig_title, result, stig, exempt, exempt_reason, ruleid):
|
||||
pattern = r'CCI-(\d+)'
|
||||
matches = re.findall(pattern, cci_group)
|
||||
cci_numbers = ['CCI-' + match for match in matches]
|
||||
|
||||
json_ccis = cci_numbers
|
||||
for cci in cci_numbers:
|
||||
checklist_xml = checklist_xml + '''
|
||||
<STIG_DATA>
|
||||
@@ -208,10 +237,44 @@ def do_regex(stig_id, stig_title, result, stig, exempt, exempt_reason, ruleid):
|
||||
<ATTRIBUTE_DATA>{}</ATTRIBUTE_DATA>
|
||||
</STIG_DATA>'''.format(cci)
|
||||
|
||||
if json:
|
||||
rules_json["ccis"] = json_ccis
|
||||
if exempt:
|
||||
exempt_reason = "Exemption Reason: {}".format(exempt_reason)
|
||||
if ruleid != "":
|
||||
comment = "Checked with mscp compliance script - {}".format(ruleid)
|
||||
if json:
|
||||
if result == "NotAFinding":
|
||||
result = "not_a_finding"
|
||||
if result == "Open":
|
||||
result = "open"
|
||||
rules_json["status"] = result
|
||||
rules_json["finding_details"] = exempt_reason
|
||||
rules_json["comments"] = comment
|
||||
rules_json["uuid"] = str(uuid.uuid4())
|
||||
rules_json["stig_uuid"] = stiguuid
|
||||
rules_json["overrides"] = {}
|
||||
rules_json["check_content_ref"] = {
|
||||
"href": "macOS Security Compliance Project",
|
||||
"name": "M"
|
||||
}
|
||||
rules_json["classification"] = "Unclassified"
|
||||
rules_json["false_positives"] = ""
|
||||
rules_json["false_negatives"] = ""
|
||||
rules_json["documentable"] = "true"
|
||||
rules_json["security_override_guidance"] = ""
|
||||
rules_json["potential_impacts"] = ""
|
||||
rules_json["third_party_tools"] = "macOS Security Compliance Project"
|
||||
rules_json["ia_controls"] = ""
|
||||
rules_json["responsibility"] = ""
|
||||
rules_json["mitigations"] = ""
|
||||
rules_json["mitigation_control"] = ""
|
||||
rules_json["legacy_ids"] = ""
|
||||
rules_json["ref_identifer"] = ref_identifer
|
||||
rules_json["group_tree"] = []
|
||||
rules_json["group_tree"].append(group_tree_dict)
|
||||
|
||||
return rules_json
|
||||
checklist_xml = checklist_xml + '''
|
||||
<STATUS>{}</STATUS>
|
||||
<FINDING_DETAILS>{}</FINDING_DETAILS>
|
||||
@@ -227,10 +290,62 @@ def validate_file(arg):
|
||||
else:
|
||||
raise FileNotFoundError(arg)
|
||||
|
||||
|
||||
def json_output(hostname,stigid,filename,releaseinfo,title,data,ref_identifer,stig):
|
||||
json_checklist = {}
|
||||
json_checklist["title"] = stigid
|
||||
json_checklist["id"] = str(uuid.uuid4())
|
||||
stigs = []
|
||||
stigs_meta_data = {}
|
||||
stigs_meta_data['stig_name'] = title
|
||||
stigs_meta_data['display_name'] = title.split(")")[0] + ")"
|
||||
stigs_meta_data['stig_id'] = stigid
|
||||
stigs_meta_data['uuid'] = str(uuid.uuid4())
|
||||
stigs_meta_data['ref_identifer'] = ref_identifer
|
||||
stigs_meta_data['size'] = 159
|
||||
rules_array = []
|
||||
for entry in data:
|
||||
if entry['reference'] == "N/A":
|
||||
continue
|
||||
if entry['finding'] == 0:
|
||||
rules_array.append(do_regex(entry['reference'], title + " " + releaseinfo, "NotAFinding", stig, entry['exemption'], entry['exemption_reason'], entry['id'],json=True,stiguuid=stigs_meta_data['uuid'],ref_identifer=ref_identifer))
|
||||
# big_xml = big_xml + do_regex(entry['reference'], stigtitle + " " + release_info, "NotAFinding", stig, entry['exemption'], entry['exemption_reason'], entry['id'])
|
||||
if entry['finding'] == 1:
|
||||
rules_array.append(do_regex(entry['reference'], title + " " + releaseinfo, "Open", stig, entry['exemption'], entry['exemption_reason'], entry['id'],json=True,stiguuid=stigs_meta_data['uuid'],ref_identifer=ref_identifer))
|
||||
# big_xml = big_xml + do_regex(entry['reference'], stigtitle + " " + release_info, "Open", stig, entry['exemption'], entry['exemption_reason'], entry['id'])
|
||||
|
||||
stigs_meta_data_array = []
|
||||
stigs_meta_data["rules"] = rules_array
|
||||
stigs_meta_data_array.append(stigs_meta_data)
|
||||
json_checklist.update({
|
||||
"active": True,
|
||||
"mode": 2,
|
||||
"has_path": True,
|
||||
"target_data": {
|
||||
"target_type": "Computing",
|
||||
"host_name": platform.node(),
|
||||
"ip_address": "",
|
||||
"mac_address": "",
|
||||
"fqdn": "",
|
||||
"comments": "",
|
||||
"role": "Workstation",
|
||||
"is_web_database": False,
|
||||
"technology_area": "Workstation",
|
||||
"web_db_site": "",
|
||||
"web_db_instance": "",
|
||||
"classification": None
|
||||
}
|
||||
})
|
||||
json_checklist["stigs"] = stigs_meta_data_array
|
||||
json_object = json.dumps(json_checklist, indent = 4)
|
||||
print(json_object)
|
||||
exit(0)
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--plist', '-p', type=validate_file, help="Input plist scan", required=True)
|
||||
parser.add_argument('--disastig','-d',type=validate_file, help="DISA STIG File", required=True)
|
||||
parser.add_argument("-j", "--json", default=None, help=argparse.SUPPRESS, action="store_true")
|
||||
args = parser.parse_args()
|
||||
|
||||
with open(args.plist, 'rb') as fp:
|
||||
@@ -300,6 +415,13 @@ def main():
|
||||
if matches:
|
||||
release_info = matches.group(1).split("<")[0]
|
||||
|
||||
if args.json:
|
||||
regex = r"<dc:identifier>(.*)</dc:identifier>"
|
||||
matches = re.search(regex,stig)
|
||||
if matches:
|
||||
ref_identifer = matches.group(1)
|
||||
json_output(platform.node(),stig_title_id,os.path.basename(args.disastig),release_info,stigtitle,data,ref_identifer,stig)
|
||||
|
||||
big_xml = '''<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--DISA STIG Viewer :: 2.12-->
|
||||
<CHECKLIST>
|
||||
|
||||
Reference in New Issue
Block a user