2015-11-21 16:53:23 +01:00
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Python script parsing the MISP taxonomies expressed in Machine Tags (Triple
# Tags) to list all valid tags from a specific taxonomy.
#
2016-06-21 07:53:31 +02:00
# Copyright (c) 2015-2016 Alexandre Dulaunoy - a@foo.be
2015-11-21 16:53:23 +01:00
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
# OF THE POSSIBILITY OF SUCH DAMAGE.
import json
import os . path
import argparse
2016-07-21 23:22:04 +02:00
taxonomies = [ ' admiralty-scale ' , ' adversary ' , ' tlp ' , ' circl ' , ' iep ' , ' kill-chain ' , ' veris ' , ' ecsirt ' , ' enisa ' , ' dni-ism ' , ' europol-events ' , ' europol-incident ' , ' nato ' , ' euci ' , ' osint ' , ' first_csirt_case_classification ' , ' malware ' , ' de-vs ' , ' fr-classification ' , ' eu-critical-sectors ' , ' dhs-ciip-sectors ' , ' estimative-language ' , ' ms-caro-malware ' , ' information-security-indicators ' , ' open-threat ' ]
2016-02-21 19:45:18 +01:00
argParser = argparse . ArgumentParser ( description = ' Dump Machine Tags (Triple Tags) from MISP taxonomies ' , epilog = ' Available taxonomies are {0} ' . format ( taxonomies ) )
2015-11-29 14:22:25 +01:00
argParser . add_argument ( ' -e ' , action = ' store_true ' , help = ' Include expanded tags ' )
2015-11-29 15:29:49 +01:00
argParser . add_argument ( ' -a ' , action = ' store_true ' , help = ' Generate asciidoctor document from MISP taxonomies ' )
2015-11-29 14:22:25 +01:00
argParser . add_argument ( ' -v ' , action = ' store_true ' , help = ' Include descriptions ' )
2016-02-21 19:45:18 +01:00
argParser . add_argument ( ' -n ' , default = False , help = ' Show only the specified namespace ' )
2015-11-21 16:53:23 +01:00
args = argParser . parse_args ( )
2015-11-29 15:29:49 +01:00
doc = ' '
if args . a :
doc = doc + " :toc: right \n "
doc = doc + " :icons: font \n "
2015-11-29 15:46:13 +01:00
doc = doc + " :images-cdn: https://raw.githubusercontent.com/MISP/MISP/master/INSTALL/logos/ \n "
2015-11-29 15:29:49 +01:00
doc = doc + " = MISP taxonomies and classification as machine tags \n \n "
doc = doc + " Generated from https://github.com/MISP/misp-taxonomies. \n \n "
2015-11-29 15:46:13 +01:00
doc = doc + " \n image:: { images-cdn}misp-logo.png[MISP logo] \n "
doc = doc + " Taxonomies that can be used in MISP (2.4) and other information sharing tool and expressed in Machine Tags (Triple Tags). A machine tag is composed of a namespace (MUST), a predicate (MUST) and an (OPTIONAL) value. Machine tags are often called triple tag due to their format. \n "
2015-11-29 15:29:49 +01:00
doc = doc + " \n \n "
2016-02-21 19:45:18 +01:00
if args . n :
del taxonomies [ : ]
taxonomies . append ( args . n )
2015-11-29 15:29:49 +01:00
def asciidoc ( content = False , adoc = doc , t = ' title ' ) :
if not args . a :
return False
adoc = adoc + " \n "
if t == ' title ' :
content = ' ==== ' + content
elif t == ' predicate ' :
content = ' === ' + content
elif t == ' namespace ' :
content = ' == ' + content + ' \n '
content = content + ' NOTE: ' + namespace + ' namespace available in JSON format at https://github.com/MISP/misp-taxonomies/blob/master/ ' + namespace + ' /machinetag.json[*this location*]. The JSON format can be freely reused in your application or automatically enabled in https://www.github.com/MISP/MISP[MISP] taxonomy. '
elif t == ' description ' :
content = ' \n ' + content + ' \n '
adoc = adoc + content
return adoc
2015-11-21 16:53:23 +01:00
def machineTag ( namespace = False , predicate = False , value = None ) :
if namespace is False or predicate is False :
return None
if value is None :
2016-02-11 14:10:58 +01:00
return ( u ' {0} : {1} ' . format ( namespace , predicate ) )
2015-11-21 16:53:23 +01:00
else :
2016-02-11 14:10:58 +01:00
return ( u ' {0} : {1} = \" {2} \" ' . format ( namespace , predicate , value ) )
2015-11-21 16:53:23 +01:00
for taxonomy in taxonomies :
filename = os . path . join ( " ../ " , taxonomy , " machinetag.json " )
with open ( filename ) as fp :
t = json . load ( fp )
namespace = t [ ' namespace ' ]
2016-01-10 17:03:44 +01:00
if t . get ( ' expanded ' ) :
expanded_namespace = t [ ' expanded ' ]
else :
expanded_namespace = namespace
2015-11-29 15:29:49 +01:00
if args . a :
doc = asciidoc ( content = t [ ' namespace ' ] , adoc = doc , t = ' namespace ' )
doc = asciidoc ( content = t [ ' description ' ] , adoc = doc , t = ' description ' )
2015-11-29 14:22:25 +01:00
if args . v :
print ( ' {0} ' . format ( t [ ' description ' ] ) )
2015-11-21 16:53:23 +01:00
for predicate in t [ ' predicates ' ] :
2015-11-29 15:29:49 +01:00
if args . a :
doc = asciidoc ( content = predicate [ ' value ' ] , adoc = doc , t = ' predicate ' )
2015-12-01 17:11:43 +01:00
if t . get ( ' values ' ) is None :
2015-11-29 15:29:49 +01:00
if args . a :
doc = asciidoc ( content = machineTag ( namespace = namespace , predicate = predicate [ ' value ' ] ) , adoc = doc )
doc = asciidoc ( content = machineTag ( namespace = namespace , predicate = predicate [ ' expanded ' ] ) , adoc = doc , t = ' description ' )
2015-12-01 17:37:00 +01:00
if predicate . get ( ' description ' ) :
doc = asciidoc ( content = machineTag ( namespace = namespace , predicate = predicate [ ' description ' ] ) , adoc = doc , t = ' description ' )
2015-11-29 15:29:49 +01:00
else :
print ( machineTag ( namespace = namespace , predicate = predicate [ ' value ' ] ) )
2015-11-22 08:16:09 +01:00
if args . e :
2016-01-10 17:03:44 +01:00
print ( " --> " + machineTag ( namespace = expanded_namespace , predicate = predicate [ ' expanded ' ] ) )
2015-12-01 17:11:43 +01:00
if predicate . get ( ' description ' ) :
print ( " --> " + predicate [ ' description ' ] )
2015-11-22 08:16:09 +01:00
else :
for e in t [ ' values ' ] :
if e [ ' predicate ' ] == predicate [ ' value ' ] :
2015-11-24 09:17:16 +01:00
if ' expanded ' in predicate :
expanded = predicate [ ' expanded ' ]
2015-11-22 08:16:09 +01:00
for v in e [ ' entry ' ] :
2016-06-21 07:53:31 +02:00
if args . a and ' expanded ' in v :
2015-11-29 15:29:49 +01:00
doc = asciidoc ( content = machineTag ( namespace = namespace , predicate = e [ ' predicate ' ] , value = v [ ' value ' ] ) , adoc = doc )
doc = asciidoc ( content = machineTag ( namespace = namespace , predicate = v [ ' expanded ' ] ) , adoc = doc , t = ' description ' )
else :
print ( machineTag ( namespace = namespace , predicate = e [ ' predicate ' ] , value = v [ ' value ' ] ) )
2015-11-22 08:16:09 +01:00
if args . e :
2016-06-21 07:35:55 +02:00
if ' expanded ' in v :
print ( " --> " + machineTag ( namespace = namespace , predicate = expanded , value = v [ ' expanded ' ] ) )
2015-11-29 15:29:49 +01:00
if args . a :
2016-05-06 21:16:15 +02:00
print ( doc )