NIST 800-53 reference
Eric Smith
eric.smith at gtri.gatech.edu
Wed Dec 18 20:48:22 UTC 2013
On 12/16/2013 10:44 PM, Shawn Wells wrote:
> On 12/16/13, 4:07 PM, Eric Smith wrote:
>> On 12/16/2013 04:00 PM, Kordell, Luke T wrote:
>>> Hello,
>>>
>>> Is there a flag or setting that can be changed to include the
>>> NIST 800-53 number on SCAP scan output or guide generation in-place
>>> of the CCE number? I know the guides contain a reference to the NIST
>>> 800-53 pdf file but it doesn't appear to list the control it satisfies.
> They're included in the guide, e.g.:
> http://people.redhat.com/swells/scap-security-guide/RHEL6/output/rhel6-guide-custom.html#sshd_use_approved_ciphers
>
>
> Maps back to IA-5(1)(c), AU-10(5), etc.
>
>> Hi Luke,
>> I wrote a python script recently that can post process your results
>> to include the NIST 800-53 security controls in addition to the CCE
>> number. Let me know if you want I'll send you a copy of the script.
> That'd be omgz awesome. Could you share with the list?
> _______________________________________________
> scap-security-guide mailing list
> scap-security-guide at lists.fedorahosted.org
> https://lists.fedorahosted.org/mailman/listinfo/scap-security-guide
Here you go Shawn, I doubt it's the most efficient code but it gets the
job done.
-------------- next part --------------
from lxml import etree
import sys
import string
import types
import json
def getReference(element, sec_id_map):
"""
Find all JSIG control IDs for a given test_name
"""
for child in element:
tag = etree.QName(child.tag)
attributes = dict(child.attrib)
if str(tag.localname) == 'reference':
for key, value in attributes.iteritems():
if key == 'href' and '800-53' in value and not isinstance(child.text, types.NoneType):
if sec_id_map['800-53'] == '':
sec_id_map['800-53'] = sec_id_map['800-53'] + child.text
else:
sec_id_map['800-53'] = sec_id_map['800-53'] + ',' + child.text
elif str(tag.localname) == 'ident':
if sec_id_map['cce'] == '':
sec_id_map['cce'] = sec_id_map['cce'] + child.text
else:
sec_id_map['cce'] = sec_id_map['cce'] + ',' + child.text
def jsonifyRules(tree):
"""
Create the following JSON payload from XML:
{ "test_map": {
"test_name": [
{ "800-53", <jsig-control-id> },
{ "cce", <cce-id> }
]
}
}
Where:
test_name = The SCAP rule ID
<jsig-control-id> = All associated JSIG controls
<cce-id> = The CCE number from http://cce.mitre.org
"""
map = ''
for child in tree.iter(tag=etree.Element):
tag = etree.QName(child.tag)
if str(tag.localname) == 'Rule':
sec_id_map = {}
sec_id_map['id'] = ''
sec_id_map['800-53'] = ''
sec_id_map['cce'] = ''
sec_id_map['id'] = child.get("id")
getReference(child, sec_id_map)
if map == '':
map = '{"test_map": [{"' + sec_id_map['id'] + '": {"800-53": "' + sec_id_map['800-53'] + '", "cce": "' + sec_id_map['cce'] + '"}}'
else:
map = map + ',{"' + sec_id_map['id'] + '": {"800-53": "' + sec_id_map['800-53'] + '", "cce": "' + sec_id_map['cce'] + '"}}'
map = map + ']}'
return json.loads(map)
def modTitle(tree, table):
"""
Modify the title of the OSCAP results XML to include the rule ID
"""
for child in tree.iter(tag=etree.Element):
tag = etree.QName(child.tag)
if str(tag.localname) == 'Rule':
for test in table['test_map']:
for key in test.keys():
if child.get("id") == key:
for gchild in child:
if str(etree.QName(gchild.tag).localname) == 'title':
currTitle = gchild.text
gchild.text = key + ' - ' + currTitle
def modResult(tree, table):
"""
Modify the rule detail security control reference to include JSIG controls
"""
for child in tree.iter(tag=etree.Element):
tag = etree.QName(child.tag)
if str(tag.localname) == 'rule-result':
for test in table['test_map']:
for key in test.keys():
if child.get("idref") == key:
for gchild in child:
if str(etree.QName(gchild.tag).localname) == 'ident':
currIdent = gchild.text
gchild.text = 'CCE: ' + currIdent + ' NIST 800-53: ' + test[key]['800-53']
tree = etree.parse(sys.argv[1])
root = tree.getroot()
table = jsonifyRules(root)
modTitle(root, table)
modResult(root, table)
tree.write(sys.argv[1])
More information about the scap-security-guide
mailing list