예제 #1
0
def setTLP(target, distribution, tags, sort=False):
    marking_specification = MarkingSpecification()
    marking_specification.controlled_structure = "../../../descendant-or-self::node()"
    tlp = TLPMarkingStructure()
    attrColors = fetchColors(tags.get('attributes')) if ('attributes'
                                                         in tags) else []
    if attrColors:
        color = setColor(attrColors)
    else:
        eventColors = fetchColors(tags.get('event')) if ('event'
                                                         in tags) else []
        if eventColors:
            color = setColor(eventColors)
        else:
            color = TLP_mapping.get(distribution, None)
    #for tag in tags:
    #    if tag["name"].startswith("tlp:") and tag["name"].count(':') == 1:
    #        new_colour = tag["name"][4:].upper()
    #        if colour and sort:
    #            if TLP_order[colour] < TLP_order[new_colour]:
    #                colour = new_colour
    #        else:
    #            colour = new_colour
    if color is None:
        return target
    tlp.color = color
    marking_specification.marking_structures.append(tlp)
    handling = Marking()
    handling.add_marking(marking_specification)
    target.handling = handling
예제 #2
0
 def _get_tlp_marking_structure(self, feed):
     tlp_marking_structure = TLPMarkingStructure()
     tlp_marking_structure.color = feed.tlp
     marking_specification = MarkingSpecification()
     marking_specification.marking_structures = tlp_marking_structure
     marking_specification.controlled_structure = '../../../../descendant-or-self::node() | ../../../../descendant-or-self::node()/@*'
     return marking_specification
예제 #3
0
def genObject_MarkingSpecification(data=None):

    from stix.extensions.marking.terms_of_use_marking import TermsOfUseMarkingStructure
    objTOU = TermsOfUseMarkingStructure()
    try:
        objTOU.terms_of_use = open('tou.txt').read()
    except:
        objTOU.terms_of_use = None

    from stix.extensions.marking.simple_marking import SimpleMarkingStructure
    objSimpleMarkingStructure = SimpleMarkingStructure()
    objSimpleMarkingStructure.statement = data['source'][
        "stix.extensions.marking.simple_marking.SimpleMarkingStructure.statement"]

    from stix.extensions.marking.tlp import TLPMarkingStructure
    objTLP = TLPMarkingStructure()
    objTLP.color = data['source'][
        'stix.extensions.marking.tlp.TLPMarkingStructure.color']

    from stix.data_marking import MarkingSpecification
    objMarkingSpecification = MarkingSpecification()
    objMarkingSpecification.idref = None
    objMarkingSpecification.version = None
    objMarkingSpecification.marking_structures = []

    objMarkingSpecification.marking_structures.append(
        objSimpleMarkingStructure)
    objMarkingSpecification.marking_structures.append(objTLP)
    objMarkingSpecification.marking_structures.append(objTOU)

    ### Externally Modified
    # objMarkingSpecification.controlled_structure = None

    return (objMarkingSpecification)
def main():
    alpha_package = STIXPackage()
    alpha_package.stix_header = STIXHeader()
    alpha_package.stix_header.title = "Report on Adversary Alpha's Campaign against the Industrial Control Sector"
    alpha_package.stix_header.package_intents = "Campaign Characterization"
    alpha_package.stix_header.handling = Marking()

    alpha_marking = MarkingSpecification()
    alpha_marking.controlled_structure = "../../../../node()"
    alpha_tlp_marking = TLPMarkingStructure()
    alpha_tlp_marking.color = "AMBER"
    alpha_marking.marking_structures.append(alpha_tlp_marking)
    alpha_package.stix_header.handling.add_marking(alpha_marking)

    rat_package = STIXPackage()
    rat_package.stix_header = STIXHeader()
    rat_package.stix_header.title = "Indicators for Malware DrownedRat"
    rat_package.stix_header.package_intents = "Indicators - Malware Artifacts"
    rat_package.stix_header.handling = Marking()

    rat_marking = MarkingSpecification()
    rat_marking.controlled_structure = "../../../../node()"
    rat_tlp_marking = TLPMarkingStructure()
    rat_tlp_marking.color = "RED"
    alpha_marking.marking_structures.append(rat_tlp_marking)
    rat_package.stix_header.handling.add_marking(rat_marking)

    stix_package = STIXPackage()
    info_src = InformationSource()
    info_src.identity = Identity(name="Government Sharing Program - GSP")
    stix_package.stix_header = STIXHeader(information_source=info_src)
    stix_package.related_packages.append(alpha_package)
    stix_package.related_packages.append(rat_package)

    print stix_package.to_xml()
예제 #5
0
def stix_pkg(config, src, endpoint, payload, title='random test data',
             description='random test data',
             package_intents='Indicators - Watchlist',
             tlp_color='WHITE', dest=None):
    '''package observables'''
    # setup the xmlns...
    xmlns_url = config['edge']['sites'][dest]['stix']['xmlns_url']
    xmlns_name = config['edge']['sites'][dest]['stix']['xmlns_name']
    set_stix_id_namespace({xmlns_url: xmlns_name})
    set_cybox_id_namespace(Namespace(xmlns_url, xmlns_name))
    # construct a stix package...
    stix_package = STIXPackage()
    stix_header = STIXHeader()
    stix_header.title = title
    stix_header.description = description
    stix_header.package_intents = package_intents
    marking = MarkingSpecification()
    marking.controlled_structure = '../../../../descendant-or-self::node()'
    tlp_marking = TLPMarkingStructure()
    tlp_marking.color = tlp_color
    marking.marking_structures.append(tlp_marking)
    stix_package.stix_header = stix_header
    stix_package.stix_header.handling = Marking()
    stix_package.stix_header.handling.add_marking(marking)
    if isinstance(payload, Observable):
        stix_package.add_observable(payload)
    elif isinstance(payload, Indicator):
        stix_package.add_indicator(payload)
    elif isinstance(payload, Incident):
        stix_package.add_incident(payload)
    return(stix_package)
예제 #6
0
 def _make_marking_specification_statement(self, key, value, controlled_structure=None):
     simple_marking_structres = SimpleMarkingStructure()
     statement = '%s: %s' % (key, value)
     simple_marking_structres.statement = statement
     marking_specification = MarkingSpecification()
     marking_specification.marking_structures = simple_marking_structres
     marking_specification.controlled_structure = controlled_structure
     return marking_specification
예제 #7
0
def main():
    mydata = loaddata()
    '''
    Your Namespace
    '''
    #    NAMESPACE = {sanitizer(mydata["NSXURL"]) : (mydata["NS"])}
    #    set_id_namespace(NAMESPACE)
    NAMESPACE = Namespace(sanitizer(mydata['NSXURL']), sanitizer(mydata['NS']))
    set_id_namespace(NAMESPACE)  # new ids will be prefixed by "myNS"

    wrapper = STIXPackage()
    info_src = InformationSource()
    info_src.identity = Identity(name=sanitizer(mydata["Identity"]))

    marking_specification = MarkingSpecification()
    marking_specification.controlled_structure = "//node() | //@*"
    tlp = TLPMarkingStructure()
    tlp.color = sanitizer(mydata["TLP_COLOR"])
    marking_specification.marking_structures.append(tlp)

    handling = Marking()
    handling.add_marking(marking_specification)

    timestamp = datetime.datetime.fromtimestamp(
        time.time()).strftime('%Y-%m-%d %H:%M:%S')
    MyTITLE = sanitizer(mydata["Title"])
    SHORT = timestamp

    DESCRIPTION = sanitizer(mydata["Description"])

    wrapper.stix_header = STIXHeader(information_source=info_src,
                                     title=MyTITLE,
                                     description=DESCRIPTION,
                                     short_description=SHORT)
    wrapper.stix_header.handling = handling

    indiDom = Indicator()
    indiDom.title = MyTITLE
    indiDom.add_indicator_type("IP Watchlist")

    for key in mydata["IOC"].keys():
        myip = Address(address_value=sanitizer(key), category=Address.CAT_IPV4)
        myip.condition = "Equals"

        obsu = Observable(myip)

        #if mydata[key].size:
        for idx, mydata["IOC"][key] in enumerate(mydata["IOC"][key]):
            ioc = File()
            ioc.add_hash(sanitizer(mydata["IOC"][key]))

            myip.add_related(ioc, "Downloaded")

        indiDom.add_observable(obsu)

    wrapper.add_indicator(indiDom)

    print(wrapper.to_xml())
예제 #8
0
def convert_marking_definition(marking20):
    definition = marking20["definition"]
    marking_spec = MarkingSpecification()
    if marking20["definition_type"] == "statement":
        tou = TermsOfUseMarkingStructure(terms_of_use=definition["statement"])
        tou.id_ = convert_id20(marking20["id"])
        marking_spec.marking_structures.append(tou)
    elif marking20["definition_type"] == "tlp":
        tlp = TLPMarkingStructure(color=definition["tlp"])
        tlp.id_ = convert_id20(marking20["id"])
        marking_spec.marking_structures.append(tlp)
    elif marking20["definition_type"] == "ais":
        identity20_tuple = _EXPLICIT_OBJECT_USED[marking20["created_by_ref"]]
        color = definition["tlp"].upper()

        if definition["is_proprietary"] == "true":
            proprietary = IsProprietary()
            consent = "EVERYONE"
        else:
            proprietary = NotProprietary()
            consent = definition["consent"].upper()

        proprietary.ais_consent = AISConsentType(consent=consent)
        proprietary.tlp_marking = TLPMarkingType(color=color)
        ais_marking = AISMarkingStructure()
        ais_marking.id_ = convert_id20(marking20["id"])

        if isinstance(proprietary, IsProprietary):
            ais_marking.is_proprietary = proprietary
        else:
            ais_marking.not_proprietary = proprietary

        marking_spec.controlled_structure = "//node() | //@*"
        marking_spec.marking_structures.append(ais_marking)
        marking_spec.information_source = create_information_source(
            identity20_tuple)

        # Remove marking to CIQ identity. Special case for AIS.
        for mark_spec in CONTAINER.get_markings(identity20_tuple[0]):
            mark_struct = mark_spec.marking_structures[0]
            if mark_struct.idref and mark_struct.idref == ais_marking.id_:
                CONTAINER.remove_marking(identity20_tuple[0], mark_spec, True)

    record_id_object_mapping(marking20["id"],
                             marking_spec.marking_structures[0])
    if "object_marking_refs" in marking20:
        for m_id in marking20["object_marking_refs"]:
            ms = create_marking_specification(m_id)
            if ms:
                CONTAINER.add_marking(marking_spec, ms, descendants=True)
    if "granular_markings" in marking20:
        error(
            "Granular Markings present in '%s' are not supported by stix2slider",
            604, marking20["id"])
    return marking_spec
예제 #9
0
def setTLP(target, distribution):
    marking_specification = MarkingSpecification()
    marking_specification.controlled_structure = "../../../descendant-or-self::node()"
    tlp = TLPMarkingStructure()
    colour = TLP_mapping.get(distribution, None)
    if colour is None:
        return target
    tlp.color = colour
    marking_specification.marking_structures.append(tlp)
    handling = Marking()
    handling.add_marking(marking_specification)
    target.handling = handling
예제 #10
0
def setTLP(target, distribution):
    marking_specification = MarkingSpecification()
    marking_specification.controlled_structure = "../../../descendant-or-self::node()"
    tlp = TLPMarkingStructure()
    colour = TLP_mapping.get(distribution, None)
    if colour is None:
        return target
    tlp.color = colour
    marking_specification.marking_structures.append(tlp)
    handling = Marking()
    handling.add_marking(marking_specification)
    target.handling = handling
 def _marking(self):
     """Define the TLP marking and the inheritance."""
     marking_specification = MarkingSpecification()
     tlp = TLPMarkingStructure()
     tlp.color = self.pulse["TLP"].upper()
     marking_specification.marking_structures.append(tlp)
     marking_specification.controlled_structure = "../../../../descendant-or-self::node() | ../../../../descendant-or-self::node()/@*"
     simple = SimpleMarkingStructure()
     simple.statement = "Automated ingest from AlienVault OTX."
     marking_specification.marking_structures.append(simple)
     handling = Marking()
     handling.add_marking(marking_specification)
     return handling
예제 #12
0
def _marking():
    """Define the TLP marking and the inheritance."""
    marking_specification = MarkingSpecification()
    tlp = TLPMarkingStructure()
    tlp.color = "WHITE"
    marking_specification.marking_structures.append(tlp)
    marking_specification.controlled_structure = "../../../../descendant"\
        "-or-self::node() | ../../../../descendant-or-self::node()/@*"
    simple = SimpleMarkingStructure()
    simple.statement = HNDL_ST
    marking_specification.marking_structures.append(simple)
    handling = Marking()
    handling.add_marking(marking_specification)
    return handling
예제 #13
0
def _marking():
    """Define the TLP marking and the inheritance."""
    marking_specification = MarkingSpecification()
    tlp = TLPMarkingStructure()
    tlp.color = SETTINGS['stix']['tlp']
    marking_specification.marking_structures.append(tlp)
    marking_specification.controlled_structure = SETTINGS[
        'stix']['controlled_structure']
    simple = SimpleMarkingStructure()
    simple.statement = SETTINGS['stix']['statement']
    marking_specification.marking_structures.append(simple)
    handling = Marking()
    handling.add_marking(marking_specification)
    return handling
예제 #14
0
def marking():
    """Define the TLP marking and the inheritence."""
    marking_specification = MarkingSpecification()
    marking_specification.controlled_structure = "../../../../descendant"\
        "-or-self::node() | ../../../../descendant-or-self::node()/@*"
    simple = SimpleMarkingStructure()
    simple.statement = HNDL_ST
    marking_specification.marking_structures.append(simple)
    tlp = TLPMarkingStructure()
    tlp.color = "WHITE"
    marking_specification.marking_structures.append(tlp)
    handling = Marking()
    handling.add_marking(marking_specification)
    return handling
예제 #15
0
def _marking():
    """Define the TLP marking and the inheritance."""
    marking_specification = MarkingSpecification()
    tlp = TLPMarkingStructure()
    tlp.color = SETTINGS['stix']['tlp']
    marking_specification.marking_structures.append(tlp)
    marking_specification.controlled_structure = SETTINGS['stix'][
        'controlled_structure']
    simple = SimpleMarkingStructure()
    simple.statement = SETTINGS['stix']['statement']
    marking_specification.marking_structures.append(simple)
    handling = Marking()
    handling.add_marking(marking_specification)
    return handling
예제 #16
0
def to_stix_tlp(obj):

    from stix.data_marking import Marking, MarkingSpecification
    from stix.extensions.marking.tlp import TLPMarkingStructure

    marking_specification = MarkingSpecification()
    marking_specification.controlled_structure = "//node() | //@*"

    tlp = TLPMarkingStructure()
    tlp.color = obj.tlp
    marking_specification.marking_structures.append(tlp)

    handling = Marking()
    handling.add_marking(marking_specification)

    return handling
예제 #17
0
def gen_stix_indicator_sample(
    config,
    target=None,
    datatype=None,
    title="random test data",
    description="random test data",
    package_intents="Indicators - Watchlist",
    tlp_color="WHITE",
    observables_list=None,
):
    """generate sample stix data comprised of indicator_count
    indicators of type datatype"""
    # setup the xmlns...
    xmlns_url = config["edge"]["sites"][target]["stix"]["xmlns_url"]
    xmlns_name = config["edge"]["sites"][target]["stix"]["xmlns_name"]
    set_stix_id_namespace({xmlns_url: xmlns_name})
    set_cybox_id_namespace(Namespace(xmlns_url, xmlns_name))
    # construct a stix package...
    stix_package = STIXPackage()
    stix_header = STIXHeader()
    stix_header.title = title
    stix_header.description = description
    stix_header.package_intents = package_intents
    marking = MarkingSpecification()
    marking.controlled_structure = "../../../../descendant-or-self::node()"
    tlp_marking = TLPMarkingStructure()
    tlp_marking.color = tlp_color
    marking.marking_structures.append(tlp_marking)
    stix_package.stix_header = stix_header
    stix_package.stix_header.handling = Marking()
    stix_package.stix_header.handling.add_marking(marking)
    indicator_ = Indicator()
    indicator_.title = str(uuid.uuid4()) + "_sample_indicator"
    indicator_.confidence = "Unknown"
    indicator_.add_indicator_type("Malware Artifacts")
    observable_composition_ = ObservableComposition()
    observable_composition_.operator = indicator_.observable_composition_operator
    for observable_id in observables_list:
        observable_ = Observable()
        observable_.idref = observable_id
        observable_composition_.add(observable_)
    indicator_.observable = Observable()
    indicator_.observable.observable_composition = observable_composition_
    stix_package.add_indicator(indicator_)
    return stix_package
예제 #18
0
    def convert(self, stix_id_prefix='', published_only=True, **kw_arg):
        self.parse(**kw_arg)

        stix_packages = []
        for event in self.events:
            if published_only:
                if not event.published:
                    continue
            # id generator
            package_id = self.get_misp_pacakge_id(stix_id_prefix, event)
            stix_package = STIXPackage(timestamp=event.dt, id_=package_id)
            stix_header = STIXHeader()

            # set identity information
            identity = Identity(name=self.identity_name)
            information_source = InformationSource(identity=identity)
            stix_header.information_source = information_source

            tlp = None
            for tag in event.tags:
                if tag.tlp is not None:
                    tlp = tag.tlp
                    break

            if tlp is not None:
                # TLP for Generic format
                tlp_marking_structure = TLPMarkingStructure()
                tlp_marking_structure.color = tlp
                marking_specification = MarkingSpecification()
                marking_specification.marking_structures = tlp_marking_structure
                marking_specification.controlled_structure = '../../../../descendant-or-self::node() | ../../../../descendant-or-self::node()/@*'

                marking = Marking()
                marking.add_marking(marking_specification)
                stix_header.handling = marking

            stix_header.title = event.info
            stix_header.description = event.info
            stix_header.short_description = event.info
            for attribute in event.attributes:
                stix_package.add_indicator(attribute.convert())
            stix_package.stix_header = stix_header
            stix_packages.append(stix_package)

        return stix_packages
예제 #19
0
def gen_stix_indicator_sample(config,
                              target=None,
                              datatype=None,
                              title='random test data',
                              description='random test data',
                              package_intents='Indicators - Watchlist',
                              tlp_color='WHITE',
                              observables_list=None):
    '''generate sample stix data comprised of indicator_count
    indicators of type datatype'''
    # setup the xmlns...
    xmlns_url = config['edge']['sites'][target]['stix']['xmlns_url']
    xmlns_name = config['edge']['sites'][target]['stix']['xmlns_name']
    set_stix_id_namespace({xmlns_url: xmlns_name})
    set_cybox_id_namespace(Namespace(xmlns_url, xmlns_name))
    # construct a stix package...
    stix_package = STIXPackage()
    stix_header = STIXHeader()
    stix_header.title = title
    stix_header.description = description
    stix_header.package_intents = package_intents
    marking = MarkingSpecification()
    marking.controlled_structure = '../../../../descendant-or-self::node()'
    tlp_marking = TLPMarkingStructure()
    tlp_marking.color = tlp_color
    marking.marking_structures.append(tlp_marking)
    stix_package.stix_header = stix_header
    stix_package.stix_header.handling = Marking()
    stix_package.stix_header.handling.add_marking(marking)
    indicator_ = Indicator()
    indicator_.title = str(uuid.uuid4()) + '_sample_indicator'
    indicator_.confidence = 'Unknown'
    indicator_.add_indicator_type('Malware Artifacts')
    observable_composition_ = ObservableComposition()
    observable_composition_.operator = \
        indicator_.observable_composition_operator
    for observable_id in observables_list:
        observable_ = Observable()
        observable_.idref = observable_id
        observable_composition_.add(observable_)
    indicator_.observable = Observable()
    indicator_.observable.observable_composition = observable_composition_
    stix_package.add_indicator(indicator_)
    return (stix_package)
예제 #20
0
def main():
    # Create a new stixmarx MarkingContainer with a
    # new STIXPackage object contained within it.
    container = stixmarx.new()

    # Get the associated STIX Package
    package = container.package

    # Create an Indicator object
    indicator = Indicator(title='Indicator Title',
                          description='Gonna Mark This')

    # Add the Indicator object to our STIX Package
    package.add(indicator)

    # Build MarkingSpecification and add TLP MarkingStructure
    red_marking = MarkingSpecification(marking_structures=TLP(color="RED"))
    amber_marking = MarkingSpecification(marking_structures=TLP(color="AMBER"))
    green_marking = MarkingSpecification(marking_structures=TLP(color="GREEN"))

    # Mark the indicator with our TLP RED marking
    # This is the equivalent of a component marking. Applies to all descendants
    # nodes, text and attributes.
    container.add_marking(indicator, red_marking, descendants=True)

    # Mark the indicator with TLP GREEN. If descendants is false, the marking
    # will only apply to the indicator node. Does NOT include text, attributes
    # or descendants.
    container.add_marking(indicator, green_marking)

    # Mark the description text.
    # >>> type(indicator.description.value)  <type 'str'>
    indicator.description.value = container.add_marking(
        indicator.description.value, amber_marking)
    # >>> type(indicator.description.value)  <class 'stixmarx.api.types.MarkableBytes'>

    # Mark the indicator timestamp attribute.
    # >>> type(indicator.description.value)  <type 'datetime.datetime'>
    indicator.timestamp = container.add_marking(indicator.timestamp,
                                                amber_marking)
    # >>> type(indicator.description.value)  <type 'stixmarx.api.types.MarkableDateTime'>

    # Print the XML!
    print(container.to_xml().decode("utf-8"))
예제 #21
0
def main():
    # Make the ISA Markings structure
    isa = ISAMarkings()
    isa.create_date_time = dates.now()
    isa.identifier = "this:is:a:test"

    # Wire up the STIX marking types
    marking_spec = MarkingSpecification()
    marking_spec.controlled_structure = "//node | //@*"
    marking_spec.marking_structures.append(isa)  # Add the ISA marking structure

    handling = Marking()
    handling.marking.append(marking_spec)

    # Create the STIX Package and add our data markings to the handling section.
    package = STIXPackage()
    package.stix_header = STIXHeader(title="ISA Markings Test")
    package.stix_header.handling = handling

    print(package.to_xml(include_schemalocs=True))
예제 #22
0
def setTLP(target, distribution, tags, sort=False):
    marking_specification = MarkingSpecification()
    marking_specification.controlled_structure = "../../../descendant-or-self::node()"
    tlp = TLPMarkingStructure()
    colour = TLP_mapping.get(distribution, None)
    for tag in tags:
        if tag["name"].startswith("tlp:") and tag["name"].count(':') == 1:
            new_colour = tag["name"][4:].upper()
            if colour and sort:
                if TLP_order[colour] < TLP_order[new_colour]:
                    colour = new_colour
            else:
                colour = new_colour
    if colour is None:
        return target
    tlp.color = colour
    marking_specification.marking_structures.append(tlp)
    handling = Marking()
    handling.add_marking(marking_specification)
    target.handling = handling
예제 #23
0
def create_marking_specification(id20):
    if id20 in _ID_OBJECT_MAPPING:
        marking1x = _ID_OBJECT_MAPPING[id20]
        if isinstance(marking1x, AISMarkingStructure):
            return  # This is a special case for AIS.

    marking_spec = MarkingSpecification()
    marking_struct = MarkingStructure()
    marking_struct.idref = convert_id20(id20)
    marking_spec.marking_structures.append(marking_struct)
    return marking_spec
예제 #24
0
def generate_stix_header(self):
    handling_markings = extract_handling_markings(self)
    stix_header = STIXHeader(
        handling=Marking([
            MarkingSpecification(
                controlled_structure=PackageXPath.make_marking_xpath_by_node_relative(),
                marking_structures=generate_marking_structure(self, handling_markings),
            )
        ]),
    )
    return stix_header
예제 #25
0
def gen_stix_indicator_sample(config, target=None, datatype=None,
                              title='random test data',
                              description='random test data',
                              package_intents='Indicators - Watchlist',
                              tlp_color='WHITE', observables_list=None):
    '''generate sample stix data comprised of indicator_count
    indicators of type datatype'''
    # setup the xmlns...
    xmlns_url = config['edge']['sites'][target]['stix']['xmlns_url']
    xmlns_name = config['edge']['sites'][target]['stix']['xmlns_name']
    set_stix_id_namespace({xmlns_url: xmlns_name})
    set_cybox_id_namespace(Namespace(xmlns_url, xmlns_name))
    # construct a stix package...
    stix_package = STIXPackage()
    stix_header = STIXHeader()
    stix_header.title = title
    stix_header.description = description
    stix_header.package_intents = package_intents
    marking = MarkingSpecification()
    marking.controlled_structure = '../../../../descendant-or-self::node()'
    tlp_marking = TLPMarkingStructure()
    tlp_marking.color = tlp_color
    marking.marking_structures.append(tlp_marking)
    stix_package.stix_header = stix_header
    stix_package.stix_header.handling = Marking()
    stix_package.stix_header.handling.add_marking(marking)
    indicator_ = Indicator()
    indicator_.title = str(uuid.uuid4()) + '_sample_indicator'
    indicator_.confidence = 'Unknown'
    indicator_.add_indicator_type('Malware Artifacts')
    observable_composition_ = ObservableComposition()
    observable_composition_.operator = \
        indicator_.observable_composition_operator
    for observable_id in observables_list:
        observable_ = Observable()
        observable_.idref = observable_id
        observable_composition_.add(observable_)
    indicator_.observable = Observable()
    indicator_.observable.observable_composition = observable_composition_
    stix_package.add_indicator(indicator_)
    return(stix_package)
예제 #26
0
 def set_tlp(self, target, distribution, tags):
     marking_specification = MarkingSpecification()
     marking_specification.controlled_structure = "../../../descendant-or-self::node()"
     tlp = TLPMarkingStructure()
     attr_colors = self.fetch_colors(tags.get('attributes')) if 'attributes' in tags else []
     if attr_colors:
         color = self.set_color(attr_colors)
     else:
         event_colors = self.fetch_colors(tags.get('event')) if 'event' in tags else []
         if event_colors:
             color = self.set_color(event_colors)
         else:
             color = TLP_mapping.get(str(distribution), None)
     if color is None:
         return target
     tlp.color = color
     marking_specification.marking_structures.append(tlp)
     handling = Marking()
     handling.add_marking(marking_specification)
     target.handling = handling
     return target
예제 #27
0
    def test_global_marking_on_observables(self):
        """Test that global markings apply to Obseravbles"""
        container = stixmarx.new()
        package = container.package
        red_marking = generate_marking_spec(generate_red_marking_struct())
        container.add_global(red_marking)

        observable = generate_observable()
        package.add_observable(observable)

        self.assertTrue(container.is_marked(observable, red_marking))
        self.assertFalse(
            container.is_marked(observable, MarkingSpecification()))
예제 #28
0
    def __map_stix_header(self, event):
        self.init()
        stix_header = STIXHeader(title=event.title)
        stix_header.description = event.description
        stix_header.short_description = event.title
        identifiy = self.create_stix_identity(event)
        time = self.cybox_mapper.get_time(produced_time=event.created_at,
                                          received_time=event.modified_on)
        info_source = InformationSource(identity=identifiy, time=time)
        stix_header.information_source = info_source

        # Add TLP
        marking = Marking()
        marking_spec = MarkingSpecification()
        marking.add_marking(marking_spec)

        tlp_marking_struct = TLPMarkingStructure()
        tlp_marking_struct.color = event.tlp.upper()
        tlp_marking_struct.marking_model_ref = 'http://govcert.lu/en/docs/POL_202_V2.2_rfc2350.pdf'
        marking_spec.marking_structures = list()
        marking_spec.marking_structures.append(tlp_marking_struct)
        stix_header.handling = marking

        return stix_header
예제 #29
0
def stix_pkg(config,
             src,
             endpoint,
             payload,
             title='random test data',
             description='random test data',
             package_intents='Indicators - Watchlist',
             tlp_color='WHITE',
             dest=None):
    '''package observables'''
    # setup the xmlns...
    xmlns_url = config['edge']['sites'][dest]['stix']['xmlns_url']
    xmlns_name = config['edge']['sites'][dest]['stix']['xmlns_name']
    set_stix_id_namespace({xmlns_url: xmlns_name})
    set_cybox_id_namespace(Namespace(xmlns_url, xmlns_name))
    # construct a stix package...
    stix_package = STIXPackage()
    stix_header = STIXHeader()
    stix_header.title = title
    stix_header.description = description
    stix_header.package_intents = package_intents
    marking = MarkingSpecification()
    marking.controlled_structure = '../../../../descendant-or-self::node()'
    tlp_marking = TLPMarkingStructure()
    tlp_marking.color = tlp_color
    marking.marking_structures.append(tlp_marking)
    stix_package.stix_header = stix_header
    stix_package.stix_header.handling = Marking()
    stix_package.stix_header.handling.add_marking(marking)
    if isinstance(payload, Observable):
        stix_package.add_observable(payload)
    elif isinstance(payload, Indicator):
        stix_package.add_indicator(payload)
    elif isinstance(payload, Incident):
        stix_package.add_incident(payload)
    return (stix_package)
예제 #30
0
def index2stix(local_index, orig_stix):
	#=============
        # Build package metadata
        #=============

        new_stix = STIXPackage()
        new_stix.stix_header = STIXHeader()
        new_stix.stix_header.title = "TG3390 - Enrichment"
        new_stix.stix_header.description = "Enrichment stix file to the Dell SecureWorks Counter Threat Unit(TM) (CTU) researchers investigated activities associated with Threat Group-3390[1] (TG-3390) - http://www.secureworks.com/cyber-threat-intelligence/threats/threat-group-3390-targets-organizations-for-cyberespionage/"

        marking_specification = MarkingSpecification()
        marking_specification.controlled_structure = "../../../../descendant-or-self::node()"

        tlp = TLPMarkingStructure()
        tlp.color = "WHITE"
        marking_specification.marking_structures.append(tlp)

        handling = Marking()
        handling.add_marking(marking_specification)

        new_stix.stix_header.handling = handling

	enrich_IPs = Indicator(title="Suspected TG3390 IP Addresses obtained through automated enrichment")
        enrich_IPs.add_indicator_type("IP Watchlist")
        enrich_IPs.confidence = "Low"

	related_IPs = Indicator(title="Related indicator wrapper for source of enrichment")
        related_IPs.add_indicator_type("IP Watchlist")
        related_IPs.confidence = "Medium"

	enrich_Domains = Indicator(title="Suspected TG3390 Domains obtained through automated enrichment")
        enrich_Domains.add_indicator_type("Domain Watchlist")
        enrich_Domains.confidence = "Low"

	related_Domains = Indicator(title="Related indicator wrapper for source of enrichment")
        related_Domains.add_indicator_type("Domain Watchlist")
        related_Domains.confidence = "Medium"

	# START with the ones that already have ids:
	#if verbose:
		#print_chain(local_index)
	new_ref_created = True
	while new_ref_created:
		new_ref_created = False
		for ind_type in local_index:
			for obs in local_index[ind_type]:
				id_tobe_referenced = local_index[ind_type][obs][0]
				#print id_tobe_referenced[:10]
				if id_tobe_referenced[:10] != '{{no_ref}}':
					ref_obs = Observable()
					ref_obs.id_ = id_tobe_referenced.replace("{{no_ref}}","")
                                        ref_obs.description = 'Source of enrichment for: '
					create_ref_obs = False
					for entry in local_index[ind_type][obs]:
						if type(entry) is list:
							if len(entry)>0:
								for item in entry:
									ref, child_ind_type = get_ref_from_obs(item, local_index)
									#print item
									
									if ref == '{{no_ref}}' or ref == '':
										create_ref_obs = True
										new_ref_created = True
										#print 'Create new, complete, observable for ' + item
										#print child_ind_type
										#Create the new observable for item and add as object to appropriate Indicator
										if child_ind_type == 'DomainName':
											append_ind = enrich_Domains
											related_ind = related_Domains
											new_obj = DomainName()
                						                        new_obj.value = item
	                                        					#enrich_Domains.add_object(domain_obj)
										elif child_ind_type == 'Address':
											append_ind = enrich_IPs
											related_ind = related_IPs
											new_obj = Address()
						                                        new_obj.category = "ipv4-addr"
						                                        new_obj.address_value = item
											#enrich_IPs.add_object(ipv4_obj)
										else:
											print 'Unsupported indicator type: ' + child_ind_type
										new_obs = Observable(new_obj)
                                                                                new_obs_ref = new_obs.id_
										append_ind.add_observable(new_obs)
										ref = new_obs_ref
										#local_index[item][0] = ref
										set_obs_ref(item, new_obs_ref, local_index)
									#print 'Adding ref to: ' + ref_obs.id_ + ' of ' + ref
									ref_obs.description = str(ref_obs.description) + ref.replace("{{no_ref}}","") + ', '
					if create_ref_obs:
						#Add the new ref obs to Related Indicators
						related_ind.add_observable(ref_obs)
						#print related_ind.to_xml()
						create_ref_obs = False

	related_ind1 = RelatedIndicator(related_IPs, relationship='Source of enrichment for IPs')
	related_ind2 = RelatedIndicator(related_Domains, relationship='Source of enrichment for Domains')
	enrich_IPs.related_indicators.append(related_ind1)
	enrich_Domains.related_indicators.append(related_ind2)

	new_stix.add_indicator(enrich_IPs)
	new_stix.add_indicator(enrich_Domains)

	#new_stix_json = json.loads(new_stix.to_json())
	#new_stix_xml = new_stix.to_xml()
	#if verbose:
		#print new_stix.to_xml()

	return new_stix
예제 #31
0
def csv2stix(outFormat,inFile):

	#=============
	# Build package metadata
	#=============

	stix_package = STIXPackage()
	stix_package.stix_header = STIXHeader()
	stix_package.stix_header.title = "TG3390"
	stix_package.stix_header.description = "Dell SecureWorks Counter Threat Unit(TM) (CTU) researchers investigated activities associated with Threat Group-3390[1] (TG-3390) - http://www.secureworks.com/cyber-threat-intelligence/threats/threat-group-3390-targets-organizations-for-cyberespionage/"

	marking_specification = MarkingSpecification()
	marking_specification.controlled_structure = "../../../../descendant-or-self::node()"

	tlp = TLPMarkingStructure()
	tlp.color = "WHITE"
	marking_specification.marking_structures.append(tlp)

	handling = Marking()
	handling.add_marking(marking_specification)

	stix_package.stix_header.handling = handling

        #=============
        # Build package structure
        #=============

	ta_tg3390 = ThreatActor(title="TG3390")
	ta_tg3390.identity = Identity(name="TG3390")

	attack_pattern = AttackPattern()
	attack_pattern.description = ("Infrastructure Building")
	ttp_infrastructure = TTP(title="Infrastructure Building")
	ttp_infrastructure.behavior = Behavior()
	ttp_infrastructure.behavior.add_attack_pattern(attack_pattern)
	ttp_infrastructure.add_intended_effect("Unauthorized Access")
	infra_domainInd = Indicator(title="Domains associated with TG3390 Infrastructure")
	infra_domainInd.add_indicator_type("Domain Watchlist")
	infra_domainInd.confidence = "High"
	infra_domainInd.add_indicated_ttp(TTP(idref=ttp_infrastructure.id_))

	infra_IPInd = Indicator(title="[H] IP Addresses associated with TG3390 Infrastructure")
	infra_IPInd.add_indicator_type("IP Watchlist")
	infra_IPInd.confidence = "High"
	infra_IPInd.add_indicated_ttp(TTP(idref=ttp_infrastructure.id_))

	infra_IPInd_M = Indicator(title="[M] IP Addresses associated with TG3390 Infrastructure")
        infra_IPInd_M.add_indicator_type("IP Watchlist")
	infra_IPInd_M.confidence = "Medium"
        infra_IPInd_M.add_indicated_ttp(TTP(idref=ttp_infrastructure.id_))


	httpBrowserObj = MalwareInstance()
	httpBrowserObj.add_name("HTTP Browser")
	ttp_httpB = TTP(title="HTTP Browser")
	ttp_httpB.behavior = Behavior()
	ttp_httpB.behavior.add_malware_instance(httpBrowserObj)
	ttp_httpB.add_intended_effect("Theft - Intellectual Property")
	httpB_hashInd = Indicator(title="File hashes for HTTP Browser")
	httpB_hashInd.add_indicator_type("File Hash Watchlist")
	httpB_hashInd.confidence = "High"
	httpB_hashInd.add_indicated_ttp(TTP(idref=ttp_httpB.id_))

	httpBrowserDropperObj = MalwareInstance()
	httpBrowserDropperObj.add_name("HTTP Browser Dropper")
	ttp_httpBDpr = TTP(title="HTTP Browser Dropper")
	ttp_httpBDpr.behavior = Behavior()
	ttp_httpBDpr.behavior.add_malware_instance(httpBrowserDropperObj)
	ttp_httpBDpr.add_intended_effect("Theft - Intellectual Property")
	httpBDpr_hashInd = Indicator(title="File hashes for HTTP Browser Dropper")
	httpBDpr_hashInd.add_indicator_type("File Hash Watchlist")
	httpBDpr_hashInd.confidence = "High"
	httpBDpr_hashInd.add_indicated_ttp(TTP(idref=ttp_httpBDpr.id_))


	plugXObj = MalwareInstance()
	plugXObj.add_name("PlugX Dropper")
	ttp_plugX = TTP(title="PlugX Dropper")
	ttp_plugX.behavior = Behavior()
	ttp_plugX.behavior.add_malware_instance(plugXObj)
	ttp_plugX.add_intended_effect("Theft - Intellectual Property")
	plugX_hashInd = Indicator(title="File hashes for PlugX Dropper")
	plugX_hashInd.add_indicator_type("File Hash Watchlist")
	plugX_hashInd.confidence = "High"
	plugX_hashInd.add_indicated_ttp(TTP(idref=ttp_plugX.id_))

        #=============
        # Process content in to structure
        #=============
	ip_rules = []
	ip_rules_M = []
	domain_rules = []
	with open(inFile, 'rb') as f:
                reader = csv.reader(f)
		for row in reader:
                        obs = row[0]
                        obsType = row[1]
                        description = row[2]
                        confidence = row[3]
			#print obs,obsType,description,confidence
			if description == 'TG-3390 infrastructure':
				if obsType == 'Domain name':
					domain_obj = DomainName()
        	                        domain_obj.value = obs
					#domain_obj.title = description
	                                infra_domainInd.add_object(domain_obj)
					domain_rule = generate_snort([obs], 'DomainName', str(infra_domainInd.id_).split(':',1)[1].split('-',1)[1])
					domain_rules.append(domain_rule)
				elif obsType == 'IP address':
					ipv4_obj = Address()
                	                ipv4_obj.category = "ipv4-addr"
        	                        ipv4_obj.address_value = obs
					ipv4_obj.title = description
					ind_ref = str(infra_IPInd.id_).split(':',1)[1].split('-',1)[1]
					if confidence == "High":
	                                	infra_IPInd.add_object(ipv4_obj)
						ip_rules.append(obs)
					else:
						infra_IPInd_M.add_object(ipv4_obj)
						ip_rules_M.append(obs)
				else:
					print "TTP Infra: obsType is wrong"
			elif description == 'HttpBrowser RAT dropper':
				file_obj = File()
				file_obj.add_hash(Hash(obs))
				file_obj.title = description
				httpBDpr_hashInd.add_observable(file_obj)
			elif description == 'HttpBrowser RAT':
				file_obj = File()
                                file_obj.add_hash(Hash(obs))
				file_obj.title = description
                                httpB_hashInd.add_observable(file_obj)
			elif description == 'PlugX RAT dropper':
				file_obj = File()
                                file_obj.add_hash(Hash(obs))
				file_obj.title = description
                                plugX_hashInd.add_observable(file_obj)
			else:
				print "TTP not found"
	#print ip_rules
	ip_rule = generate_snort(ip_rules, 'Address', str(infra_IPInd.id_).split(':',1)[1].split('-',1)[1])
	ip_rule_M = generate_snort(ip_rules_M, 'Address', str(infra_IPInd_M.id_).split(':',1)[1].split('-',1)[1])

	ip_tm = SnortTestMechanism()
	ip_tm.rules = [ip_rule]
	ip_tm.efficacy = "High"
	ip_tm.producer = InformationSource(identity=Identity(name="Auto"))
	infra_IPInd.test_mechanisms = [ip_tm]

	ip_M_tm = SnortTestMechanism()
        ip_M_tm.rules = [ip_rule_M]
        ip_M_tm.efficacy = "Medium"
        ip_M_tm.producer = InformationSource(identity=Identity(name="Auto"))
	infra_IPInd_M.test_mechanisms = [ip_M_tm]

	domain_tm = SnortTestMechanism()
        domain_tm.rules = domain_rules
        domain_tm.efficacy = "High"
        domain_tm.producer = InformationSource(identity=Identity(name="Auto"))
        infra_domainInd.test_mechanisms = [domain_tm]
	
        #=============
        # Add the composed content to the structure
        #=============

	stix_package.add_indicator(infra_domainInd)
	stix_package.add_indicator(infra_IPInd)
	stix_package.add_indicator(infra_IPInd_M)
	stix_package.add_indicator(httpBDpr_hashInd)
	stix_package.add_indicator(httpB_hashInd)
	stix_package.add_indicator(plugX_hashInd)

	stix_package.add_ttp(ttp_infrastructure)
	stix_package.add_ttp(ttp_httpB)
	stix_package.add_ttp(ttp_httpBDpr)
	stix_package.add_ttp(ttp_plugX)
					
				
	"""
	if outFormat =='dict':
		print stix_package.to_dict()
	if outFormat =='json':
		parsed = stix_package.to_json()
		jsonpkg = json.loads(parsed)
		pprint.pprint(jsonpkg)
	if outFormat =='stix':
		print stix_package.to_xml()
	"""
	#if verbose:
		#print stix_package.to_xml()
	#pprint(stix_package.to_json())
	return stix_package
def adptr_dict2STIX(srcObj, data):
    sTxt = "Called... "
    sndMSG(sTxt, 'INFO', 'adptr_dict2STIX()')
    stixObj = None

    ### Input Check
    if srcObj == None or data == None:
        #TODO: Needs error msg: Missing srcData Object
        return (False)

    ### Generate NameSpace id tags
    STIX_NAMESPACE = {"http://hailataxii.com": "opensource"}
    OBS_NAMESPACE = Namespace("http://hailataxii.com", "opensource")
    stix_set_id_namespace(STIX_NAMESPACE)
    obs_set_id_namespace(OBS_NAMESPACE)

    ### Building STIX Wrapper
    stix_package = STIXPackage()
    objIndicator = Indicator()

    ### Bulid Object Data
    for sKey in data:
        objIndicator = Indicator()
        listOBS = []

        oObsSrcData = genObsSrcData(srcObj, data[sKey])
        ### Parsing IP Address
        sAddr = data[sKey]['attrib']['ip']
        if len(sAddr) > 0:
            objAddr = Address()
            objAddr.is_destination = True
            objAddr.address_value = sAddr
            objAddr.address_value.condition = 'Equals'
            if isIPv4(sAddr):
                objAddr.type = 'ipv4-addr'
            elif isIPv6(sAddr):
                objAddr.type = 'ipv6-addr'
            else:
                continue

            obsAddr = Observable(objAddr)
            objAddr = None
            obsAddr.sighting_count = 1
            oObsSrcData.sighting_count = 1
            obsAddr.observable_source.append(oObsSrcData)

            sTitle = 'IP: ' + sAddr
            obsAddr.title = sTitle
            sDscpt = 'ipv4-addr' + ': ' + sAddr + " | "
            sDscpt += "is_destination: True | "
            if data[sKey]['attrib']['first']:
                sDscpt += "firstSeen: " + data[sKey]['attrib']['first'] + " | "
            if data[sKey]['attrib']['last']:
                sDscpt += "lastSeen: " + data[sKey]['attrib']['last'] + " | "
            obsAddr.description = "<![CDATA[" + sDscpt + "]]>"
            listOBS.append(obsAddr)
            obsAddr = None

        ### Parsing Network Address
        sAddr = data[sKey]['attrib']['inetnum']
        if sAddr:
            objAddr = Address()
            objAddr.is_destination = True
            sAddrNet = sAddr.split("-")
            objAddr.address_value = sAddrNet[0].strip(
            ) + "##comma##" + sAddrNet[1].strip()
            objAddr.address_value.condition = 'InclusiveBetween'

            objAddr.category = 'ipv4-net'

            obsAddr = Observable(objAddr)
            objAddr = None
            obsAddr.sighting_count = 1
            oObsSrcData.sighting_count = 1
            obsAddr.observable_source.append(oObsSrcData)

            sTitle = 'NETWORK_range: ' + sAddr
            obsAddr.title = sTitle
            sDscpt = 'ipv4-net' + ': ' + sAddr + " | "
            if data[sKey]['attrib']['netname']:
                sDscpt += 'netName' + ': ' + data[sKey]['attrib'][
                    'netname'] + " | "
            obsAddr.description = "<![CDATA[" + sDscpt + "]]>"
            listOBS.append(obsAddr)
            obsAddr = None

        ### Parsing Email Address
        sEMAIL = data[sKey]['attrib']['email']
        if sEMAIL:
            objEmail = EmailAddress()
            #objEmail.is_source = True
            objEmail.address_value = sEMAIL
            objEmail.address_value.condition = 'Equals'

            objEmail.category = 'e-mail'

            obsEmail = Observable(objEmail)
            objEmail = None
            obsEmail.sighting_count = 1
            oObsSrcData.sighting_count = 1
            if len(data[sKey]['attrib']['source']) > 0:
                oObsSrcData.name = data[sKey]['attrib']['source']
            obsEmail.observable_source.append(oObsSrcData)

            sTitle = 'REGISTRAR_email: ' + sEMAIL
            obsEmail.title = sTitle
            sDscrpt = 'REGISTRAR_email: ' + sEMAIL
            if data[sKey]['attrib']['descr']:
                sDscrpt += " | REGISTRAR_name: " + data[sKey]['attrib'][
                    'descr'] + " | "

            obsEmail.description = "<![CDATA[" + sDscrpt + "]]>"
            listOBS.append(obsEmail)
            obsEmail = None

        ### Parsing Domain
        sDomain = data[sKey]['attrib']['domain']
        if len(sDomain) > 0:
            objDomain = DomainName()
            objDomain.value = sDomain
            objDomain.value.condition = 'Equals'
            objDomain.is_destination = True
            if isFQDN(sDomain):
                objDomain.type = 'FQDN'
            elif isTLD(sDomain):
                objDomain.type = 'TLD'
            else:
                continue

            obsDomain = Observable(objDomain)
            objDomain = None
            obsDomain.sighting_count = 1
            oObsSrcData.sighting_count = 1
            obsDomain.observable_source.append(oObsSrcData)
            obsDomain.title = 'Domain: ' + sDomain
            sDscpt = 'Domain: ' + sDomain + " | "
            sDscpt += "isDestination: True | "
            if data[sKey]['attrib']['first']:
                sDscpt += "firstSeen: " + data[sKey]['attrib']['first'] + " | "
            if data[sKey]['attrib']['last']:
                sDscpt += "lastSeen: " + data[sKey]['attrib']['last'] + " | "

            #if
            obsDomain.description = "<![CDATA[" + sDscpt + "]]>"
            listOBS.append(obsDomain)
            obsDomain = None
            objIndicator.add_indicator_type("Domain Watchlist")

        #Parser URI
        sURI = data[sKey]['attrib']['url']
        if len(sURI) > 0:
            objURI = URI()
            objURI.value = sURI
            objURI.value.condition = 'Equals'
            objURI.type_ = URI.TYPE_URL
            obsURI = Observable(objURI)
            objURI = None
            obsURI.sighting_count = 1
            oObsSrcData.sighting_count = 1
            obsURI.observable_source.append(oObsSrcData)
            obsURI.title = 'URI: ' + sURI
            sDscpt = 'URI: ' + sURI + " | "
            sDscpt += "Type: URL | "
            obsURI.description = "<![CDATA[" + sDscpt + "]]>"
            listOBS.append(obsURI)
            obsURI = None
            objIndicator.add_indicator_type("URL Watchlist")

        sDscrpt = None
        sCntry_code = None
        sCntry_name = None
        sRgstra_email = None
        sRgstra_name = None

        # add Phishing Email Target
        # add Phishing email Details phishtank_ID

        if data[sKey]['attrib']['country']:
            sCntry_code = data[sKey]['attrib']['country']
            if sCntry_code in dictCC2CN:
                sCntry_name = dictCC2CN[sCntry_code]

        if data[sKey]['attrib']['email'] > 0:
            sRgstra_email = data[sKey]['attrib']['email']

        if data[sKey]['attrib']['descr']:
            sRgstra_name = data[sKey]['attrib']['descr']

        sDscrpt = " clean-mx.de has identified this "
        if isIPv4(data[sKey]['attrib']['domain']):
            sDscrpt += "ip address " + data[sKey]['attrib']['domain'] + " "
        else:
            sDscrpt += "domain " + data[sKey]['attrib']['domain'] + " "

        sDscrpt += "as malicious "
        if data[sKey]['attrib']['target']:
            sDscrpt += "and uses phishing email(s) targeting " + data[sKey][
                'attrib']['target'] + " users with "
        else:
            sDscrpt += "and sent out "

        sDscrpt += "email containg this url <-Do Not Connect-> {" + data[sKey][
            'attrib']['url'] + "} <-Do Not Connect-> link. "

        if data[sKey]['attrib']['phishtank']:
            sDscrpt += "For more detail on the specific phisihing email use this phishtank ID [" + data[
                sKey]['attrib']['phishtank'] + "]. "

        if sCntry_code:
            sDscrpt += " This url appears to originated in " + sCntry_code
            if sCntry_name:
                sDscrpt += " (" + sCntry_name + ")"
        if sCntry_code and (sRgstra_email or sRgstra_name):
            sDscrpt += " and is "
        if sRgstra_email:
            sDscrpt += "register to " + sRgstra_email
        if sRgstra_email and sRgstra_name:
            sDscrpt += " of " + sRgstra_name
        elif sRgstra_name:
            sDscrpt += "register to " + sRgstra_name
        sDscrpt += "."

        if sCntry_code or sRgstra_email or sRgstra_name:
            objIndicator.description = "<![CDATA[" + sDscrpt + "]]>"

        sTitle = 'Phishing ID:' + sKey + " "
        if data[sKey]['attrib']["target"]:
            sTitle += "Target: " + data[sKey]['attrib']["target"] + " "

        if data[sKey]['attrib']["url"]:
            sTitle += "URL: " + data[sKey]['attrib']["url"] + " "

        objIndicator.title = sTitle

        ### Add Generated observable to Indicator
        objIndicator.add_indicator_type("IP Watchlist")
        objIndicator.observable_composition_operator = 'OR'
        objIndicator.observables = listOBS

        #Parsing Producer
        sProducer = srcObj.Domain
        if len(sProducer) > 0:
            objIndicator.set_producer_identity(sProducer)

        objIndicator.set_produced_time(data[sKey]['attrib']['first'])
        objIndicator.set_received_time(data[sKey]['dateDL'])

        stix_package.add_indicator(objIndicator)
        objIndicator = None

    ### STIX Package Meta Data
    stix_header = STIXHeader()
    stix_header.title = srcObj.pkgTitle
    stix_header.description = "<![CDATA[" + srcObj.pkgDscrpt + "]]>"

    ### Understanding markings http://stixproject.github.io/idioms/features/data-markings/
    marking_specification = MarkingSpecification()

    classLevel = SimpleMarkingStructure()
    classLevel.statement = "Unclassified (Public)"
    marking_specification.marking_structures.append(classLevel)

    objTOU = TermsOfUseMarkingStructure()
    #sTOU = open('tou.txt').read()
    objTOU.terms_of_use = sProducer + " | " + srcObj.srcTOU
    marking_specification.marking_structures.append(objTOU)

    tlp = TLPMarkingStructure()
    tlp.color = "WHITE"
    marking_specification.marking_structures.append(tlp)
    marking_specification.controlled_structure = "//node()"

    handling = Marking()
    handling.add_marking(marking_specification)
    stix_header.handling = handling

    stix_package.stix_header = stix_header
    stix_header = None

    ### Generate STIX XML File
    locSTIXFile = 'STIX_' + srcObj.fileName.split('.')[0] + '.xml'
    sndFile(stix_package.to_xml(), locSTIXFile)

    return (stix_package)
예제 #33
0
    def create_cybox_object(self, jdict, whitelist, config):
        listObservables = []
        NS = cybox.utils.Namespace("cert.siemens.com", "siemens_cert")
        cybox.utils.set_id_namespace(NS)

        """ store information about malware binary that was analyzed """
        if 'target' in jdict and 'category' in jdict['target'] and jdict['target']['category'] == 'file':
            log.debug("handling File information ...")
            main_file_object = self.__create_cybox_main_file(jdict['target']['file'])
            file_md5 = jdict['target']['file']['md5']
        elif 'target' in jdict and 'category' in jdict['target'] and jdict['target']['category'] == 'url':
            log.warning("Not a file analysis report! URL reports not handled")
            return
        else:
            log.error("No target information in report ... skipping")
            return

        """ try to find email that dropped this attachment """
        if config["attachemail"] or config["referenceemail"]:
            log.info("handling email attack vector information ...")
            email_object_properties, email_observables_list, email_stix_path_tuple_list = self.__check_malware_mailing_list(file_md5, log, config)
            if email_object_properties and len(email_object_properties)>0:
                for email_object in email_object_properties:
                    main_file_object.add_related(email_object, "Contained_Within", inline=False)
            else:
                log.warning("failed linking mail object (no objects to link)")
                email_stix_path_tuple_list = []
        else:
            email_object = None
            email_observables = []
            email_stix_path_tuple_list = []

        """ store extended information about malware file """
        if 'static' in jdict:
            log.debug("handling extended File information ...")
            win_executable_extension = self.__create_cybox_win_executable(jdict['target']['file'], jdict['static'])
            if win_executable_extension:
                main_file_object.add_related(win_executable_extension, "Characterized_By", inline=False)
            win_executable_extension = [win_executable_extension]
        else:
            log.warning("No extended File information found")
            win_executable_extension = []

        """ store domains connected to """
        if 'network' in jdict and 'domains' in jdict['network']:
            log.debug("handling Domain information ...")
            domains, addresses = self.__create_cybox_domains(jdict['network']['domains'], whitelist)
            for dom in domains:
                main_file_object.add_related(dom, 'Connected_To', inline=False)
        else:
            domains = []
            addresses = []

        """ store http session information """
        if 'network' in jdict and 'http' in jdict['network']:
            log.debug("handling HTTP information ...")
            http_requests = self.__create_cybox_https(jdict['network']['http'], whitelist)
            for session in http_requests:
                main_file_object.add_related(session, 'Connected_To', inline=False)
        else:
            http_requests = []

        """ store dns queries information about the malware """
        if 'network' in jdict and 'dns' in jdict['network']:
            log.debug("handling DNS information ...")
            queries = self.__create_cybox_dns_queries(jdict['network']['dns'], whitelist)
            for query in queries:
                main_file_object.add_related(query, 'Connected_To', inline=False)
        else:
            queries = []

        """ store information about dropped files """
        if 'dropped' in jdict:
            log.debug('handling dropped files ...')
            dropped = self.__create_cybox_dropped_files(jdict['dropped'], jdict['target']['file']['sha256'])
            for drop in dropped:
                main_file_object.add_related(drop, 'Dropped', inline=False)
        else:
            dropped = []

        """ store virustotal information """
        if 'virustotal' in jdict and 'positives' in jdict['virustotal']:
            log.debug('handling virustotal information ...')
            vtInformationTools = self.__create_stix_virustotal(jdict['virustotal'], log, config)
            vtFound = True
        else:
            vtInformationTools = []
            vtFound = False

        """ create observables """
        if config["attachemail"] and len(email_observables)>0:
            obs = Observables([main_file_object]+email_observables+win_executable_extension+domains+addresses+http_requests+dropped+queries)
        else:
            obs = Observables([main_file_object]+win_executable_extension+domains+addresses+http_requests+dropped+queries)
        """ generate stix id with siemens namespace """
        if config:
            stix_id_generator = stix.utils.IDGenerator(namespace={config["xmlns"]: config["namespace"]})
        else:
            stix_id_generator = stix.utils.IDGenerator(namespace={"cert.siemens.com": "siemens_cert"})
        """ create stix package """
        stix_id = stix_id_generator.create_id()
        stix_package = STIXPackage(observables=obs, id_=stix_id)
        stix_header = STIXHeader()
        stix_header.title = "Analysis report: %s" % (str(main_file_object.file_name).decode('utf8', errors='xmlcharrefreplace'))
        if 'info' in jdict and 'started' in jdict['info']:
            sandbox_report_date = dateparser.parse(jdict['info']['started']+' CET').isoformat()
        else:
            sandbox_report_date = datetime.datetime.now(pytz.timezone('Europe/Berlin')).isoformat()
        stix_header.description = 'Summarized analysis results for file "%s" with MD5 hash "%s" created on %s.' % (str(main_file_object.file_name).decode('utf8', errors='xmlcharrefreplace'), main_file_object.hashes.md5, sandbox_report_date)
        stix_header.add_package_intent("Malware Characterization")
        """ create markings """
        spec = MarkingSpecification()
        spec.idref = stix_id
        spec.controlled_structure = "//node()"
        tlpmark = TLPMarkingStructure()
        if config:
            if not vtFound:
                tlpmark.color = config["color"]
            else:
                tlpmark.color = "GREEN"
        elif vtFound:
            tlpmark.color = "GREEN"
        else:
            tlpmark.color = "AMBER"
        spec.marking_structure = [tlpmark]
        """ attach to header """
        stix_header.handling = Marking([spec])
        stix_information_source = InformationSource()
        stix_information_source.time = Time(produced_time=sandbox_report_date)
        stix_information_source.tools = ToolInformationList([ToolInformation(tool_name="SIEMENS-ANALYSIS-TOOL-ID-12", tool_vendor="ANALYSIS-ID: %s" % (jdict['info']['id']))]+vtInformationTools)
        stix_header.information_source = stix_information_source
        stix_package.stix_header = stix_header
        """ write result xml file """
        xml_file_name = "stix-%s-malware-report.xml" % (file_md5)
        xml_report_file_path = os.path.join(self.reports_path, xml_file_name)
        fp = open(xml_report_file_path, 'w')
        if config:
            fp.write(stix_package.to_xml(ns_dict={config["xmlns"]: config["namespace"]}))
        else:
            fp.write(stix_package.to_xml(ns_dict={'cert.siemens.com': 'siemens_cert'}))
        fp.close()
        if config["copytoshare"]:
            self.__copy_xml_to_ti_share(xml_report_file_path, xml_file_name, config)
            for item in email_stix_path_tuple_list:
                self.__copy_xml_to_ti_share(item[0], item[1], config, "email")
        else:
            log.warning("copy to TI share is disabled: %s" % (config["copytoshare"]))
        return
def adptr_dict2STIX(srcObj, data):
    sTxt = "Called... "
    sndMSG(sTxt, 'INFO', 'adptr_dict2STIX()')
    stixObj = None

    ### Input Check
    if srcObj == None or data == None:
        #TODO: Needs error msg: Missing srcData Object
        return (False)

    ### Generate NameSpace id tags
    STIX_NAMESPACE = {"http://hailataxii.com": "opensource"}
    OBS_NAMESPACE = Namespace("http://hailataxii.com", "opensource")
    stix_set_id_namespace(STIX_NAMESPACE)
    obs_set_id_namespace(OBS_NAMESPACE)

    ### Building STIX Wrapper
    stix_package = STIXPackage()
    objIndicator = Indicator()

    ### Bulid Object Data
    for sKey in data:
        objIndicator = Indicator()
        listOBS = []

        ### Parsing IP Address
        sAddr = data[sKey]['attrib']['ipAddr']
        if len(sAddr) > 0:
            objAddr = Address()
            objAddr.is_source = True
            objAddr.address_value = sAddr
            objAddr.address_value.condition = 'Equals'
            if isIPv4(sAddr):
                objAddr.category = 'ipv4-addr'
            elif isIPv6(sAddr):
                objAddr.category = 'ipv6-addr'
            else:
                continue

            obsAddr = Observable(objAddr)
            objAddr = None
            obsAddr.sighting_count = 1
            obsAddr.title = 'IP: ' + sAddr
            sDscrpt = 'IPv4' + ': ' + sAddr + " | "
            sDscrpt += "isSource: True | "
            obsAddr.description = "<![CDATA[" + sDscrpt + "]]>"
            listOBS.append(obsAddr)
            obsAddr = None
            objIndicator.add_indicator_type("IP Watchlist")

        ### Parsing Domain
        sDomain = data[sKey]['attrib']['domain']
        if len(sDomain) > 0:
            objDomain = DomainName()
            objDomain.value = sDomain
            objDomain.value.condition = 'Equals'
            if isFQDN(sDomain):
                objDomain.type = 'FQDN'
            elif isTLD(sDomain):
                objDomain.type = 'TLD'
            else:
                continue

            obsDomain = Observable(objDomain)
            objDomain = None
            obsDomain.sighting_count = 1
            obsDomain.title = 'Domain: ' + sDomain
            sDscrpt = 'Domain: ' + sDomain + " | "
            sDscrpt += "isFQDN: True | "
            obsDomain.description = "<![CDATA[" + sDscrpt + "]]>"
            listOBS.append(obsDomain)
            obsDomain = None
            objIndicator.add_indicator_type("Domain Watchlist")

        #Parser URI
        sURI = data[sKey]['attrib']['URI']
        if len(sURI) > 0:
            objURI = URI()
            objURI.value = sURI
            objURI.value.condition = 'Equals'
            objURI.type_ = URI.TYPE_URL
            obsURI = Observable(objURI)
            objURI = None
            obsURI.sighting_count = 1
            obsURI.title = 'URI: ' + sURI
            sDscrpt = 'URI: ' + sURI + " | "
            sDscrpt += "Type: URL | "
            obsURI.description = "<![CDATA[" + sDscrpt + "]]>"
            listOBS.append(obsURI)
            obsURI = None
            objIndicator.add_indicator_type("URL Watchlist")

        #Parser File Hash
        sHash = data[sKey]['attrib']['hash']
        if len(sHash) > 0:
            objFile = File()
            sFileName = data[sKey]['attrib']['fileName']
            if len(sFileName) > 0:
                objFile.file_name = sFileName
                objFile.file_format = sFileName.split('.')[1]

            objFile.add_hash(Hash(sHash, exact=True))
            obsFile = Observable(objFile)
            objFile = None
            obsFile.sighting_count = 1
            obsFile.title = 'File: ' + sFileName
            sDscrpt = 'FileName: ' + sFileName + " | "
            sDscrpt += "FileHash: " + sHash + " | "
            obsFile.description = "<![CDATA[" + sDscrpt + "]]>"
            listOBS.append(obsFile)
            obsFile = None
            objIndicator.add_indicator_type("File Hash Watchlist")

        ### Add Generated observable to Indicator
        objIndicator.observables = listOBS
        objIndicator.observable_composition_operator = 'OR'

        #Parsing Producer
        sProducer = srcObj.Domain
        if len(sProducer) > 0:
            objIndicator.set_producer_identity(sProducer)

        objIndicator.set_produced_time(data[sKey]['attrib']['dateVF'])
        objIndicator.set_received_time(data[sKey]['dateDL'])

        ### Old Title / Description Generator
        #objIndicator.title = data[sKey]['attrib']['title'];
        #objIndicator.description = "<![CDATA[" + data[sKey]['attrib']['dscrpt'] + "]]>";

        ### Generate Indicator Title based on availbe data
        sTitle = 'ZeuS Tracker (' + data[sKey]['attrib'][
            'status'] + ')| ' + data[sKey]['attrib']['title']
        if len(sAddr) > 0:
            sAddLine = "This IP address has been identified as malicious"
        if len(sDomain) > 0:
            sAddLine = "This domain has been identified as malicious"
        if len(sAddLine) > 0:
            sTitle = sTitle + " | " + sAddLine
        if len(srcObj.Domain) > 0:
            sTitle = sTitle + " by " + srcObj.Domain
        else:
            sTitle = sTitle + "."
        if len(sTitle) > 0:
            objIndicator.title = sTitle

        #Generate Indicator Description based on availbe data
        sDscrpt = ""
        if len(sAddr) > 0:
            sAddLine = "This IP address " + sAddr
        if len(sDomain) > 0:
            sAddLine = "This domain " + sDomain
        if len(sAddr) > 0 and len(sDomain) > 0:
            sAddLine = "This domain " + sDomain + " (" + sAddr + ")"
        if len(sAddLine) > 0:
            sDscrpt = sDscrpt + sAddLine

        sDscrpt = sDscrpt + " has been identified as malicious"
        if len(srcObj.Domain) > 0:
            sDscrpt = sDscrpt + " by " + srcObj.Domain
        else:
            sDscrpt = sDscrpt + "."
        sDscrpt = sDscrpt + ". For more detailed infomation about this indicator go to [CAUTION!!Read-URL-Before-Click] [" + data[
            sKey]['attrib']['link'] + "]."

        if len(sDscrpt) > 0:
            objIndicator.description = "<![CDATA[" + sDscrpt + "]]>"

        #Parse TTP
        objMalware = MalwareInstance()
        objMalware.add_name("ZeuS")
        objMalware.add_name("Zbot")
        objMalware.add_name("Zeus")
        objMalware.add_type("Remote Access Trojan")
        objMalware.short_description = "Zeus, ZeuS, or Zbot is Trojan horse computer malware effects Microsoft Windows operating system"
        objMalware.description = "Zeus, ZeuS, or Zbot is Trojan horse computer malware that runs on computers running under versions of the Microsoft Windows operating system. While it is capable of being used to carry out many malicious and criminal tasks, it is often used to steal banking information by man-in-the-browser keystroke logging and form grabbing. It is also used to install the CryptoLocker ransomware.[1] Zeus is spread mainly through drive-by downloads and phishing schemes. (2014(http://en.wikipedia.org/wiki/Zeus_%28Trojan_horse%29))"

        objTTP = TTP(title="ZeuS")
        objTTP.behavior = Behavior()
        objTTP.behavior.add_malware_instance(objMalware)
        objIndicator.add_indicated_ttp(objTTP)
        #objIndicator.add_indicated_ttp(TTP(idref=objTTP.id_))
        #stix_package.add_ttp(objTTP)

        stix_package.add_indicator(objIndicator)
        objIndicator = None

    ### STIX Package Meta Data
    stix_header = STIXHeader()
    stix_header.title = srcObj.pkgTitle
    stix_header.description = "<![CDATA[" + srcObj.pkgDscrpt + "]]>"

    ### Understanding markings http://stixproject.github.io/idioms/features/data-markings/
    marking_specification = MarkingSpecification()

    classLevel = SimpleMarkingStructure()
    classLevel.statement = "Unclassified (Public)"
    marking_specification.marking_structures.append(classLevel)

    objTOU = TermsOfUseMarkingStructure()
    sTOU = open('tou.txt').read()
    objTOU.terms_of_use = sProducer + " | " + sTOU
    marking_specification.marking_structures.append(objTOU)

    tlp = TLPMarkingStructure()
    tlp.color = "WHITE"
    marking_specification.marking_structures.append(tlp)
    marking_specification.controlled_structure = "//node()"

    handling = Marking()
    handling.add_marking(marking_specification)
    stix_header.handling = handling

    stix_package.stix_header = stix_header
    stix_header = None

    ### Generate STIX XML File
    locSTIXFile = 'STIX_' + srcObj.fileName.split('.')[0] + '.xml'
    sndFile(stix_package.to_xml(), locSTIXFile)

    return (stix_package)
예제 #35
0
def gen_stix_observable_sample(config, target=None, datatype=None,
                               title='random test data',
                               description='random test data',
                               package_intents='Indicators - Watchlist',
                               tlp_color='WHITE'):
    '''generate sample stix data comprised of indicator_count
    indicators of type datatype'''
    # setup the xmlns...
    xmlns_url = config['edge']['sites'][target]['stix']['xmlns_url']
    xmlns_name = config['edge']['sites'][target]['stix']['xmlns_name']
    set_stix_id_namespace({xmlns_url: xmlns_name})
    set_cybox_id_namespace(Namespace(xmlns_url, xmlns_name))
    # construct a stix package...
    stix_package = STIXPackage()
    stix_header = STIXHeader()
    stix_header.title = title
    stix_header.description = description
    stix_header.package_intents = package_intents
    marking = MarkingSpecification()
    marking.controlled_structure = '../../../../descendant-or-self::node()'
    tlp_marking = TLPMarkingStructure()
    tlp_marking.color = tlp_color
    marking.marking_structures.append(tlp_marking)
    stix_package.stix_header = stix_header
    stix_package.stix_header.handling = Marking()
    stix_package.stix_header.handling.add_marking(marking)
    # ...and stuff it full of random sample data :-)
    if datatype == 'ip':
        addr = Address(address_value=datagen.generate_random_ip_address(),
                       category='ipv4-addr')
        addr.condition = 'Equals'
        stix_package.add_observable(Observable(addr))
    elif datatype == 'domain':
        domain = DomainName()
        domain.type_ = 'FQDN'
        domain.value = datagen.generate_random_domain(config)
        domain.condition = 'Equals'
        stix_package.add_observable(Observable(domain))
    elif datatype == 'filehash':
        file_object = File()
        file_object.file_name = str(uuid.uuid4()) + '.exe'
        hashes = datagen.generate_random_hashes()
        for hash in hashes.keys():
            file_object.add_hash(Hash(hashes[hash], type_=hash.upper()))
            for i in file_object.hashes:
                i.simple_hash_value.condition = "Equals"
        stix_package.add_observable(Observable(file_object))
    elif datatype == 'email':
        try:
            msg = datagen.get_random_spam_msg(config)
            email = EmailMessage()
            email.header = EmailHeader()
            header_map = {'Subject': 'subject', 'To': 'to', 'Cc':
                          'cc', 'Bcc': 'bcc', 'From': 'from_',
                          'Sender': 'sender', 'Date': 'date',
                          'Message-ID': 'message_id', 'Reply-To':
                          'reply_to', 'In-Reply-To': 'in_reply_to',
                          'Content-Type': 'content_type', 'Errors-To':
                          'errors_to', 'Precedence': 'precedence',
                          'Boundary': 'boundary', 'MIME-Version':
                          'mime_version', 'X-Mailer': 'x_mailer',
                          'User-Agent': 'user_agent',
                          'X-Originating-IP': 'x_originating_ip',
                          'X-Priority': 'x_priority'}
            # TODO handle received_lines
            for key in header_map.keys():
                val = msg.get(key, None)
                if val:
                    email.header.__setattr__(header_map[key], val)
                    email.header.__getattribute__(header_map[key]).condition = \
                        'Equals'
            # TODO handle email bodies (it's mostly all there except for
            #      handling weird text encoding problems that were making
            #      libcybox stacktrace)
            # body = get_email_payload(random_spam_msg)
            # if body:
            #     email.raw_body = body
            stix_package.add_observable(Observable(email))
        except:
            return(None)
    observable_id = stix_package.observables.observables[0].id_
    return(observable_id, stix_package)
예제 #36
0
def add_ais_marking(stix_package, proprietary, consent, color, **kwargs):
    """
    This utility functions aids in the creation of an AIS marking and appends
    it to the provided STIX package.

    Args:
        stix_package: A stix.core.STIXPackage object.
        proprietary: True if marking uses IsProprietary, False for
            NotProprietary.
        consent: A string with one of the following values: "EVERYONE", "NONE"
            or "USG".
        color: A string that corresponds to TLP values: "WHITE", "GREEN" or
            "AMBER".
        **kwargs: Six required keyword arguments that are used to create a CIQ
            identity object. These are: country_name_code,
            country_name_code_type, admin_area_name_code,
            admin_area_name_code_type, organisation_name, industry_type.

    Raises:
        ValueError: When keyword arguments are missing. User did not supply
            correct values for: proprietary, color and consent.

    Note:
        The following line is required to register the AIS extension::

            >>> import stix.extensions.marking.ais

        Any Markings under STIX Header will be removed. Please follow the
        guidelines for `AIS`_.

        The industry_type keyword argument accepts: a list of string based on
        defined sectors, a pipe-delimited string of sectors, or a single
        sector.

    .. _AIS:
        https://www.us-cert.gov/ais

    """
    from stix.common import InformationSource
    from stix.extensions.identity.ciq_identity_3_0 import (
        CIQIdentity3_0Instance, STIXCIQIdentity3_0, PartyName, Address,
        Country, NameElement, OrganisationInfo, AdministrativeArea)
    from stix.core.stix_header import STIXHeader
    from stix.data_marking import MarkingSpecification, Marking

    args = ('country_name_code', 'country_name_code_type', 'industry_type',
            'admin_area_name_code', 'admin_area_name_code_type',
            'organisation_name')

    diff = set(args) - set(kwargs.keys())

    if diff:
        msg = 'All keyword arguments must be provided. Missing: {0}'
        raise ValueError(msg.format(tuple(diff)))

    party_name = PartyName()
    party_name.add_organisation_name(kwargs['organisation_name'])

    country = Country()
    country_name = NameElement()
    country_name.name_code = kwargs['country_name_code']
    country_name.name_code_type = kwargs['country_name_code_type']
    country.add_name_element(country_name)

    admin_area = AdministrativeArea()
    admin_area_name = NameElement()
    admin_area_name.name_code = kwargs['admin_area_name_code']
    admin_area_name.name_code_type = kwargs['admin_area_name_code_type']
    admin_area.add_name_element(admin_area_name)

    address = Address()
    address.country = country
    address.administrative_area = admin_area

    org_info = OrganisationInfo()
    org_info.industry_type = _validate_and_create_industry_type(kwargs['industry_type'])

    id_spec = STIXCIQIdentity3_0()
    id_spec.party_name = party_name
    id_spec.add_address(address)
    id_spec.organisation_info = org_info

    identity = CIQIdentity3_0Instance()
    identity.specification = id_spec

    if proprietary is True:
        proprietary_obj = IsProprietary()
        consent = 'EVERYONE'
    elif proprietary is False:
        proprietary_obj = NotProprietary()
    else:
        raise ValueError('proprietary expected True or False.')

    proprietary_obj.ais_consent = AISConsentType(consent=consent)
    proprietary_obj.tlp_marking = TLPMarkingType(color=color)

    ais_marking = AISMarkingStructure()

    if isinstance(proprietary_obj, IsProprietary):
        ais_marking.is_proprietary = proprietary_obj
    else:
        ais_marking.not_proprietary = proprietary_obj

    marking_spec = MarkingSpecification()
    marking_spec.controlled_structure = '//node() | //@*'
    marking_spec.marking_structures.append(ais_marking)
    marking_spec.information_source = InformationSource()
    marking_spec.information_source.identity = identity

    if not stix_package.stix_header:
        stix_package.stix_header = STIXHeader()

    # Removes any other Markings if present.
    stix_package.stix_header.handling = Marking()
    stix_package.stix_header.handling.add_marking(marking_spec)
def adptr_dict2STIX(srcObj, data):
    sTxt = "Called... "
    sndMSG(sTxt, 'INFO', 'adptr_dict2STIX()')
    stixObj = None

    ### Input Check
    if srcObj == None or data == None:
        #TODO: Needs error msg: Missing srcData Object
        return (False)

    ### Generate NameSpace id tags
    STIX_NAMESPACE = {"http://hailataxii.com": "opensource"}
    OBS_NAMESPACE = Namespace("http://hailataxii.com", "opensource")
    stix_set_id_namespace(STIX_NAMESPACE)
    obs_set_id_namespace(OBS_NAMESPACE)

    ### Building STIX Wrapper
    stix_package = STIXPackage()
    objIndicator = Indicator()

    ### Bulid Object Data
    for sKey in data:
        objIndicator = Indicator()
        listOBS = []

        oObsSrcData = genObsSrcData(srcObj, data[sKey])

        ### Parsing IP Address
        sAddr = sKey
        if len(sAddr) > 0:
            objAddr = Address()
            objAddr.is_source = True
            objAddr.address_value = sAddr
            objAddr.address_value.condition = 'InclusiveBetween'

            objAddr.category = 'ipv4-net'

            obsAddr = Observable(objAddr)
            objAddr = None
            obsAddr.sighting_count = int(data[sKey]['attrib']['Attacks'])
            oObsSrcData.sighting_count = int(data[sKey]['attrib']['Attacks'])
            obsAddr.observable_source.append(oObsSrcData)

            sTitle = 'NETWORK_range: ' + sAddr
            obsAddr.title = sTitle
            sDscpt = 'ipv4-net' + ': ' + sAddr + " | "
            sDscpt += "is_source: True | "
            sDscpt += "Attack_Count: " + data[sKey]['attrib']['Attacks'] + " | "
            sDscpt += "Attack_DateRange: " + data[sKey]['attrib'][
                'dateRange'] + " | "
            obsAddr.description = sDscpt
            listOBS.append(obsAddr)
            obsAddr = None

        ### Parsing Registrar Information
        if data[sKey]['attrib']['email']:
            objEmail = EmailAddress()
            objEmail.address_value = data[sKey]['attrib']['email']
            objEmail.address_value.condition = 'Equals'
            objEmail.category = 'e-mail'

            objWhoisReg = WhoisRegistrar()
            if len(data[sKey]['attrib']['Name']) > 1:
                objWhoisReg.name = data[sKey]['attrib']['Name']
            objWhoisReg.email_address = objEmail
            objEmail = None

            objWhois = WhoisEntry()
            objWhois.registrar_info = objWhoisReg

            obsWhois = Observable(objWhois)
            #print obsWhois.id_
            objWhois = None
            obsWhois.sighting_count = 1

            sTitle = 'REGISTRAR_email: ' + data[sKey]['attrib']['email']
            if len(data[sKey]['attrib']['Name']) > 0:
                sTitle += " | REGISTRAR_name: " + data[sKey]['attrib'][
                    'Name'] + " | "
            obsWhois.title = sTitle
            obsWhois.description = sTitle
            listOBS.append(obsWhois)
            obsWhois = None

        sDscrpt = None
        sCntry_code = None
        sCntry_name = None
        sRgstra_email = None
        sRgstra_name = None

        if len(data[sKey]['attrib']['Country']) > 0:
            sCntry_code = data[sKey]['attrib']['Country']
            if sCntry_code in dictCC2CN:
                sCntry_name = dictCC2CN[sCntry_code]

        if 'email' in data[sKey]['attrib']:
            sRgstra_email = data[sKey]['attrib']['email']

        if len(data[sKey]['attrib']['Name']) > 0:
            sRgstra_name = data[sKey]['attrib']['Name']

        sDscrpt = "This IP block appears to have "
        if sCntry_code:
            sDscrpt += "originated in " + sCntry_code
            if sCntry_name:
                sDscrpt += "(" + sCntry_name + ")"
        if sCntry_code and (sRgstra_email or sRgstra_name):
            sDscrpt += " and is "
        if sRgstra_email:
            sDscrpt += "register to " + sRgstra_email
        if sRgstra_email and sRgstra_name:
            sDscrpt += " of " + sRgstra_name
        elif sRgstra_name:
            sDscrpt += "register to " + sRgstra_name
        sDscrpt += "."

        if sCntry_code or sRgstra_email or sRgstra_name:
            objIndicator.description = "<![CDATA[" + sDscrpt + "]]>"

        objIndicator.title = sAddr.replace('##comma##',
                                           ' - ') + " | " + srcObj.pkgTitle

        ### Add Generated observable to Indicator
        objIndicator.add_indicator_type("IP Watchlist")
        objIndicator.observable_composition_operator = 'OR'
        objIndicator.observables = listOBS

        #Parsing Producer
        sProducer = srcObj.Domain
        if len(sProducer) > 0:
            objIndicator.set_producer_identity(sProducer)

        objIndicator.set_produced_time(data[sKey]['attrib']['dateVF'])
        objIndicator.set_received_time(data[sKey]['dateDL'])

        stix_package.add_indicator(objIndicator)
        objIndicator = None

    ### STIX Package Meta Data
    stix_header = STIXHeader()
    stix_header.title = srcObj.pkgTitle
    stix_header.description = "<![CDATA[" + srcObj.pkgDscrpt + "]]>"

    ### Understanding markings http://stixproject.github.io/idioms/features/data-markings/
    marking_specification = MarkingSpecification()

    classLevel = SimpleMarkingStructure()
    classLevel.statement = "Unclassified (Public)"
    marking_specification.marking_structures.append(classLevel)

    objTOU = TermsOfUseMarkingStructure()
    #sTOU = open('tou.txt').read()
    objTOU.terms_of_use = sProducer + " | " + srcObj.srcTOU
    marking_specification.marking_structures.append(objTOU)

    tlp = TLPMarkingStructure()
    tlp.color = "WHITE"
    marking_specification.marking_structures.append(tlp)
    marking_specification.controlled_structure = "//node()"

    handling = Marking()
    handling.add_marking(marking_specification)
    stix_header.handling = handling

    stix_package.stix_header = stix_header
    stix_header = None

    ### Generate STIX XML File
    locSTIXFile = 'STIX_' + srcObj.fileName.split('.')[0] + '.xml'
    sndFile(stix_package.to_xml(), locSTIXFile)

    return (stix_package)
예제 #38
0
def main(argv):
    ######################################################################
    # Se non impostati da command line vengono utilizzati i seguenti valori per TITLE, DESCRIPTION, IDENTITY
    # Il title e' ID univoco della minaccia (es. Cobalt / Danabot / APT28)
    TITLE = "Test"

    # La description strutturiamola come segue
    # <IOC PRODUCER> - <Descrizione della minaccia/campagna> - <URL (if any)>
    DESCRIPTION = "Cyber Saiyan - Test - https://infosharing.cybersaiyan.it"

    # La sorgente che ha generato l'IoC con riferimento a Cyber Saiyan Community 
    IDENTITY = "Cyber Saiyan Community"

    # File degli IoC
    IOCFILE = "CS-ioc.txt"

    # Prefisso STIX output files STIX 1.2 e STIX 2
    OUTFILEPREFIX = "package"

    # Short Description - UNUSED
    SHORT = "unused"
    ######################################################################

    VERBOSE = 0

    # Parse ARGV[]
    try:
        opts, args = getopt.getopt(argv, "ht:d:i:f:o:v")
    except getopt.GetoptError:
        print(
            "CS_build_stix-from_files.py [-t TITLE] [-d DESCRIPTION] [-i IDENTITY] [-f IOC_FILE] [-o STIX_FILES_PREFIX]")
        sys.exit(2)

    for opt, arg in opts:
        if opt == "-h":
            print(
                "CS_build_stix-from_files.py [-t TITLE] [-d DESCRIPTION] [-i IDENTITY] [-f IOC_FILE] [-o STIX_FILES_PREFIX]")
            sys.exit()
        elif opt == "-t":
            TITLE = arg
        elif opt == "-d":
            DESCRIPTION = arg
        elif opt == "-i":
            IDENTITY = arg
        elif opt == "-f":
            IOCFILE = arg
        elif opt == "-o":
            OUTFILEPREFIX = arg
        elif opt == "-v":
            VERBOSE = 1

    print("---------------------")
    print("TITLE: " + TITLE)
    print("DESCRIPTION: " + DESCRIPTION)
    print("IDENTITY: " + IDENTITY)
    print("IOC FILE: " + IOCFILE)
    print("---------------------")

    ########################
    # Commond data
    timestamp = datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S")

    ########################
    # Build STIX 1.2 file
    info_src = InformationSource()
    info_src.identity = Identity(name=IDENTITY)

    NAMESPACE = Namespace("https://infosharing.cybersaiyan.it", "CYBERSAIYAN")
    set_id_namespace(NAMESPACE)

    wrapper = STIXPackage()

    marking_specification = MarkingSpecification()
    marking_specification.controlled_structure = "//node() | //@*"
    tlp = TLPMarkingStructure()
    tlp.color = "white"
    marking_specification.marking_structures.append(tlp)

    handling = Marking()
    handling.add_marking(marking_specification)

    wrapper.stix_header = STIXHeader(information_source=info_src,
                                     title=TITLE,
                                     description=DESCRIPTION,
                                     short_description=SHORT)
    wrapper.stix_header.handling = handling

    # HASH indicators
    indicatorHASH = Indicator()
    indicatorHASH.title = TITLE + " - HASH"
    indicatorHASH.add_indicator_type("File Hash Watchlist")

    # DOMAIN indicators
    indiDOMAIN = Indicator()
    indiDOMAIN.title = TITLE + " - DOMAIN"
    indiDOMAIN.add_indicator_type("Domain Watchlist")

    # URL indicators
    indiURL = Indicator()
    indiURL.title = TITLE + " - URL"
    indiURL.add_indicator_type("URL Watchlist")

    # IP indicators
    indiIP = Indicator()
    indiIP.title = TITLE + " - IP"
    indiIP.add_indicator_type("IP Watchlist")

    # EMAIL indicators
    indiEMAIL = Indicator()
    indiEMAIL.title = TITLE + " - EMAIL"
    indiEMAIL.add_indicator_type("Malicious E-mail")

    ########################
    # Build STIX 2 file
    pattern_sha256 = []
    pattern_md5 = []
    pattern_sha1 = []
    pattern_domain = []
    pattern_url = []
    pattern_ip = []
    pattern_email = []

    # Marking
    marking_def_white = stix2.TLP_WHITE

    # campagna
    # [TODO] aggiungere tutti i campi dello STIX 1.2 (es. IDENTITY)
    campaign_MAIN = stix2.Campaign(
        created=timestamp,
        modified=timestamp,
        name=TITLE,
        description=DESCRIPTION,
        first_seen=timestamp,
        objective="TBD"
    )

    ########################
    # Read IoC file
    loaddata(IOCFILE)

    if (VERBOSE): print("Reading IoC file " + IOCFILE + "...")
    ioccount = 0

    # sha256
    for ioc in listSHA256:
        # STIX 1.2
        filei = File()
        filei.add_hash(Hash(ioc))

        obsi = Observable(filei)
        indicatorHASH.add_observable(obsi)
        if (VERBOSE): print("SHA256: " + ioc)

        ioccount += 1

        # STIX 2
        pattern_sha256.append("[file:hashes.'SHA-256' = '" + ioc + "'] OR ")

    # md5
    for ioc in listMD5:
        # STIX 1.2
        filej = File()
        filej.add_hash(Hash(ioc))

        obsj = Observable(filej)
        indicatorHASH.add_observable(obsj)
        if (VERBOSE): print("MD5: " + ioc)

        ioccount += 1

        # STIX 2
        pattern_md5.append("[file:hashes.'MD5' = '" + ioc + "'] OR ")

    # sha1
    for ioc in listSHA1:
        # STIX 1.2
        filek = File()
        filek.add_hash(Hash(ioc))

        obsk = Observable(filek)
        indicatorHASH.add_observable(obsk)
        if (VERBOSE): print("SHA1: " + ioc)

        ioccount += 1

        # STIX 2
        pattern_sha1.append("[file:hashes.'SHA1' = '" + ioc + "'] OR ")

    # domains
    for ioc in listDOMAIN:
        # STIX 1.2
        url = URI()
        url.value = ioc
        url.type_ = URI.TYPE_DOMAIN
        url.condition = "Equals"

        obsu = Observable(url)
        indiDOMAIN.add_observable(obsu)
        if (VERBOSE): print("DOMAIN: " + ioc)

        ioccount += 1

        # STIX 2
        pattern_domain.append("[domain-name:value = '" + ioc + "'] OR ")

    # url
    for ioc in listURL:
        # STIX 1.2
        url = URI()
        url.value = ioc
        url.type_ = URI.TYPE_URL
        url.condition = "Equals"

        obsu = Observable(url)
        indiURL.add_observable(obsu)
        if (VERBOSE): print("URL: " + ioc)

        ioccount += 1

        # STIX 2
        pattern_url.append("[url:value = '" + ioc + "'] OR ")

    # ip
    for ioc in listIP:
        # STIX 1.2
        ip = Address()
        ip.address_value = ioc

        obsu = Observable(ip)
        indiIP.add_observable(obsu)
        if (VERBOSE): print("IP: " + ioc)

        ioccount += 1

        # STIX 2
        pattern_ip.append("[ipv4-addr:value = '" + ioc + "'] OR ")

    # email
    for ioc in listEMAIL:
        # STIX 1.2
        email = EmailAddress()
        email.address_value = ioc

        obsu = Observable(email)
        indiEMAIL.add_observable(obsu)

        if (VERBOSE): print("Email: " + ioc)
        ioccount += 1

        # STIX 2
        pattern_email.append("[email-message:from_ref.value = '" + ioc + "'] OR ")

    # subject
    for ioc in listSUBJECT:
        # STIX 1.2
        emailsubject = EmailMessage()
        emailsubject.subject = ioc

        obsu = Observable(emailsubject)
        indiEMAIL.add_observable(obsu)

        if (VERBOSE): print("Subject: " + ioc)
        ioccount += 1

        # STIX 2 (http://docs.oasis-open.org/cti/stix/v2.0/stix-v2.0-part5-stix-patterning.html)
        # Replace all quotes in a subject string with escaped quotes
        pattern_email.append("[email-message:subject = '" + ioc.replace("'", "\\'") + "'] OR ")

    ########################
    # add all indicators to STIX 1.2
    wrapper.add_indicator(indicatorHASH)
    wrapper.add_indicator(indiDOMAIN)
    wrapper.add_indicator(indiURL)
    wrapper.add_indicator(indiIP)
    wrapper.add_indicator(indiEMAIL)

    ########################
    # prepare for STIX 2
    bundle_objects = [campaign_MAIN, marking_def_white]

    if len(pattern_sha256) != 0:
        stix2_sha256 = "".join(pattern_sha256)
        stix2_sha256 = stix2_sha256[:-4]

        indicator_SHA256 = stix2.Indicator(
            name=TITLE + " - SHA256",
            created=timestamp,
            modified=timestamp,
            description=DESCRIPTION,
            labels=["malicious-activity"],
            pattern=stix2_sha256,
            object_marking_refs=[marking_def_white]
        )
        relationship_indicator_SHA256 = stix2.Relationship(indicator_SHA256, "indicates", campaign_MAIN)
        bundle_objects.append(indicator_SHA256)
        bundle_objects.append(relationship_indicator_SHA256)

    if len(pattern_md5) != 0:
        stix2_md5 = "".join(pattern_md5)
        stix2_md5 = stix2_md5[:-4]

        indicator_MD5 = stix2.Indicator(
            name=TITLE + " - MD5",
            created=timestamp,
            modified=timestamp,
            description=DESCRIPTION,
            labels=["malicious-activity"],
            pattern=stix2_md5,
            object_marking_refs=[marking_def_white]
        )
        relationship_indicator_MD5 = stix2.Relationship(indicator_MD5, "indicates", campaign_MAIN)
        bundle_objects.append(indicator_MD5)
        bundle_objects.append(relationship_indicator_MD5)

    if len(pattern_sha1) != 0:
        stix2_sha1 = "".join(pattern_sha1)
        stix2_sha1 = stix2_sha1[:-4]

        indicator_SHA1 = stix2.Indicator(
            name=TITLE + " - SHA1",
            created=timestamp,
            modified=timestamp,
            description=DESCRIPTION,
            labels=["malicious-activity"],
            pattern=stix2_sha1,
            object_marking_refs=[marking_def_white]
        )
        relationship_indicator_SHA1 = stix2.Relationship(indicator_SHA1, "indicates", campaign_MAIN)
        bundle_objects.append(indicator_SHA1)
        bundle_objects.append(relationship_indicator_SHA1)

    if len(pattern_domain) != 0:
        stix2_domain = "".join(pattern_domain)
        stix2_domain = stix2_domain[:-4]

        indicator_DOMAINS = stix2.Indicator(
            name=TITLE + " - DOMAINS",
            created=timestamp,
            modified=timestamp,
            description=DESCRIPTION,
            labels=["malicious-activity"],
            pattern=stix2_domain,
            object_marking_refs=[marking_def_white]
        )
        relationship_indicator_DOMAINS = stix2.Relationship(indicator_DOMAINS, "indicates", campaign_MAIN)
        bundle_objects.append(indicator_DOMAINS)
        bundle_objects.append(relationship_indicator_DOMAINS)

    if len(pattern_url) != 0:
        stix2_url = "".join(pattern_url)
        stix2_url = stix2_url[:-4]

        indicator_URLS = stix2.Indicator(
            name=TITLE + " - URL",
            created=timestamp,
            modified=timestamp,
            description=DESCRIPTION,
            labels=["malicious-activity"],
            pattern=stix2_url,
            object_marking_refs=[marking_def_white]
        )
        relationship_indicator_URLS = stix2.Relationship(indicator_URLS, "indicates", campaign_MAIN)
        bundle_objects.append(indicator_URLS)
        bundle_objects.append(relationship_indicator_URLS)

    if len(pattern_ip) != 0:
        stix2_ip = "".join(pattern_ip)
        stix2_ip = stix2_ip[:-4]

        indicator_IPS = stix2.Indicator(
            name=TITLE + " - IPS",
            created=timestamp,
            modified=timestamp,
            description=DESCRIPTION,
            labels=["malicious-activity"],
            pattern=stix2_ip,
            object_marking_refs=[marking_def_white]
        )
        relationship_indicator_IPS = stix2.Relationship(indicator_IPS, "indicates", campaign_MAIN)
        bundle_objects.append(indicator_IPS)
        bundle_objects.append(relationship_indicator_IPS)

    if len(pattern_email) != 0:
        stix2_email = "".join(pattern_email)
        stix2_email = stix2_email[:-4]

        indicator_EMAILS = stix2.Indicator(
            name=TITLE + " - EMAILS",
            created=timestamp,
            modified=timestamp,
            description=DESCRIPTION,
            labels=["malicious-activity"],
            pattern=stix2_email,
            object_marking_refs=[marking_def_white]
        )
        relationship_indicator_EMAILS = stix2.Relationship(indicator_EMAILS, "indicates", campaign_MAIN)
        bundle_objects.append(indicator_EMAILS)
        bundle_objects.append(relationship_indicator_EMAILS)

    # creo il bunble STIX 2
    bundlestix2 = stix2.Bundle(objects=bundle_objects)

    if (ioccount > 0):
        ########################
        # save to STIX 1.2 file
        print("Writing STIX 1.2 package: " + OUTFILEPREFIX + ".stix")
        f = open(OUTFILEPREFIX + ".stix", "wb")
        f.write(wrapper.to_xml())
        f.close()

        ########################
        # save to STIX 2 file
        print("Writing STIX 2 package: " + OUTFILEPREFIX + ".stix2")
        g = open(OUTFILEPREFIX + ".stix2", "w")
        g.write(str(bundlestix2))
        g.close()
    else:
        print("No IoC found")
예제 #39
0
def gen_stix_observable_sample(
    config,
    target=None,
    datatype=None,
    title="random test data",
    description="random test data",
    package_intents="Indicators - Watchlist",
    tlp_color="WHITE",
):
    """generate sample stix data comprised of indicator_count
    indicators of type datatype"""
    # setup the xmlns...
    xmlns_url = config["edge"]["sites"][target]["stix"]["xmlns_url"]
    xmlns_name = config["edge"]["sites"][target]["stix"]["xmlns_name"]
    set_stix_id_namespace({xmlns_url: xmlns_name})
    set_cybox_id_namespace(Namespace(xmlns_url, xmlns_name))
    # construct a stix package...
    stix_package = STIXPackage()
    stix_header = STIXHeader()
    stix_header.title = title
    stix_header.description = description
    stix_header.package_intents = package_intents
    marking = MarkingSpecification()
    marking.controlled_structure = "../../../../descendant-or-self::node()"
    tlp_marking = TLPMarkingStructure()
    tlp_marking.color = tlp_color
    marking.marking_structures.append(tlp_marking)
    stix_package.stix_header = stix_header
    stix_package.stix_header.handling = Marking()
    stix_package.stix_header.handling.add_marking(marking)
    # ...and stuff it full of random sample data :-)
    if datatype == "ip":
        addr = Address(address_value=datagen_.generate_random_ip_address(), category="ipv4-addr")
        addr.condition = "Equals"
        stix_package.add_observable(Observable(addr))
    elif datatype == "domain":
        domain = DomainName()
        domain.type_ = "FQDN"
        domain.value = datagen_.generate_random_domain(config)
        domain.condition = "Equals"
        stix_package.add_observable(Observable(domain))
    elif datatype == "filehash":
        file_object = File()
        file_object.file_name = str(uuid.uuid4()) + ".exe"
        hashes = datagen_.generate_random_hashes()
        for hash in hashes.keys():
            file_object.add_hash(Hash(hashes[hash], type_=hash.upper()))
            for i in file_object.hashes:
                i.simple_hash_value.condition = "Equals"
        stix_package.add_observable(Observable(file_object))
    elif datatype == "email":
        try:
            msg = datagen_.get_random_spam_msg(config)
            email = EmailMessage()
            email.header = EmailHeader()
            header_map = {
                "Subject": "subject",
                "To": "to",
                "Cc": "cc",
                "Bcc": "bcc",
                "From": "from_",
                "Sender": "sender",
                "Date": "date",
                "Message-ID": "message_id",
                "Reply-To": "reply_to",
                "In-Reply-To": "in_reply_to",
                "Content-Type": "content_type",
                "Errors-To": "errors_to",
                "Precedence": "precedence",
                "Boundary": "boundary",
                "MIME-Version": "mime_version",
                "X-Mailer": "x_mailer",
                "User-Agent": "user_agent",
                "X-Originating-IP": "x_originating_ip",
                "X-Priority": "x_priority",
            }
            # TODO handle received_lines
            for key in header_map.keys():
                val = msg.get(key, None)
                if val:
                    email.header.__setattr__(header_map[key], val)
                    email.header.__getattribute__(header_map[key]).condition = "Equals"
            # TODO handle email bodies (it's mostly all there except for
            #      handling weird text encoding problems that were making
            #      libcybox stacktrace)
            # body = get_email_payload(random_spam_msg)
            # if body:
            #     email.raw_body = body
            stix_package.add_observable(Observable(email))
        except:
            return None
    observable_id = stix_package.observables.observables[0].id_
    return (observable_id, stix_package)
예제 #40
0
def adptr_dict2STIX(srcObj, data):
    sTxt = "Called... "
    sndMSG(sTxt, 'INFO', 'adptr_dict2STIX()')
    stixObj = None

    ### Input Check
    if srcObj == None or data == None:
        #TODO: Needs error msg: Missing srcData Object
        return (False)

    ### Generate NameSpace id tags
    STIX_NAMESPACE = {"http://hailataxii.com": "opensource"}
    OBS_NAMESPACE = Namespace("http://hailataxii.com", "opensource")
    stix_set_id_namespace(STIX_NAMESPACE)
    obs_set_id_namespace(OBS_NAMESPACE)

    ### Building STIX Wrapper
    stix_package = STIXPackage()
    objIndicator = Indicator()

    ### Bulid Object Data
    for sKey in data:
        objIndicator = Indicator()
        listOBS = []

        ### Parsing Domain
        sDomain = data[sKey]['attrib']['domain']
        if len(sDomain) > 0:
            objDomain = DomainName()
            objDomain.value = sDomain
            objDomain.value.condition = 'Equals'
            if isFQDN(sDomain):
                objDomain.type = 'FQDN'
            elif isTLD(sDomain):
                objDomain.type = 'TLD'
            else:
                continue

            obsDomain = Observable(objDomain)
            objDomain = None
            obsDomain.sighting_count = 1
            obsDomain.title = 'Domain: ' + sDomain
            sDscrpt = 'Domain: ' + sDomain + " | "
            sDscrpt += "isFQDN: True | "
            obsDomain.description = "<![CDATA[" + sDscrpt + "]]>"
            listOBS.append(obsDomain)
            obsDomain = None
            objIndicator.add_indicator_type("Domain Watchlist")

        ### Add Generated observable to Indicator
        objIndicator.observable_composition_operator = 'OR'
        objIndicator.observables = listOBS

        #Parsing Producer
        infoSrc = InformationSource(identity=Identity(name=srcObj.Domain))
        infoSrc.add_contributing_source(data[sKey]['attrib']['ref'])
        if len(srcObj.Domain) > 0:
            objIndicator.producer = infoSrc

        if data[sKey]['attrib']['lstDateVF']:
            objIndicator.set_produced_time(
                data[sKey]['attrib']['lstDateVF'][0])
        objIndicator.set_received_time(data[sKey]['dateDL'])

        ### Generate Indicator Title based on availbe data
        lstContainng = []
        lstIs = []
        sTitle = 'This domain ' + data[sKey]['attrib'][
            'domain'] + ' has been identified as malicious'
        if len(data[sKey]['attrib']['ref']):
            sTitle += ' by ' + data[sKey]['attrib']['ref']

        if len(data[sKey]['attrib']['type']) > 0:
            sTitle += ', via this vector [' + data[sKey]['attrib'][
                'type'] + '].'
        else:
            sTitle += '.'
        objIndicator.title = sTitle

        ### Generate Indicator Description based on availbe data
        sDscrpt = 'Lehigh.edu site has added this domain ' + data[sKey][
            'attrib']['domain']
        sDscrpt += ' to recommend block list.'
        sDscrpt += ' This site has been identified as malicious'
        sDscrpt += ' by ' + data[sKey]['attrib']['ref']
        sDscrpt += ' and was still attive on the following dates ' + str(
            data[sKey]['attrib']['lstDateVF']) + "."
        objIndicator.description = "<![CDATA[" + sDscrpt + "]]>"

        #Parse TTP
        objMalware = MalwareInstance()
        objMalware.add_type("Remote Access Trojan")

        ttpTitle = data[sKey]['attrib']['type']
        objTTP = TTP(title=ttpTitle)
        objTTP.behavior = Behavior()
        objTTP.behavior.add_malware_instance(objMalware)
        objIndicator.add_indicated_ttp(objTTP)
        #objIndicator.add_indicated_ttp(TTP(idref=objTTP.id_))
        #stix_package.add_ttp(objTTP)

        stix_package.add_indicator(objIndicator)
        objIndicator = None

    ### STIX Package Meta Data
    stix_header = STIXHeader()
    stix_header.title = srcObj.pkgTitle
    stix_header.description = "<![CDATA[" + srcObj.pkgDscrpt + "]]>"

    ### Understanding markings http://stixproject.github.io/idioms/features/data-markings/
    marking_specification = MarkingSpecification()

    classLevel = SimpleMarkingStructure()
    classLevel.statement = "Unclassified (Public)"
    marking_specification.marking_structures.append(classLevel)

    tlp = TLPMarkingStructure()
    tlp.color = "WHITE"
    marking_specification.marking_structures.append(tlp)
    marking_specification.controlled_structure = "//node()"

    objTOU = TermsOfUseMarkingStructure()
    sTOU = open('tou.txt').read()
    objTOU.terms_of_use = srcObj.Domain + " | " + sTOU
    marking_specification.marking_structures.append(objTOU)

    handling = Marking()
    handling.add_marking(marking_specification)
    stix_header.handling = handling

    stix_package.stix_header = stix_header
    stix_header = None

    ### Generate STIX XML File
    locSTIXFile = 'STIX_' + srcObj.fileName.split('.')[0] + '.xml'
    sndFile(stix_package.to_xml(), locSTIXFile)

    return (stix_package)
예제 #41
0
def stix(json):
    """
    Created a stix file based on a json file that is being handed over
    """
    # Create a new STIXPackage
    stix_package = STIXPackage()

    # Create a new STIXHeader
    stix_header = STIXHeader()

    # Add Information Source. This is where we will add the tool information.
    stix_header.information_source = InformationSource()

    # Create a ToolInformation object. Use the initialization parameters
    # to set the tool and vendor names.
    #
    # Note: This is an instance of cybox.common.ToolInformation and NOT
    # stix.common.ToolInformation.
    tool = ToolInformation(
        tool_name="viper2stix",
        tool_vendor="The Viper group http://viper.li - developed by Alexander Jaeger https://github.com/deralexxx/viper2stix"
    )
        
    #Adding your identity to the header
    identity = Identity()
    identity.name = Config.get('stix', 'producer_name')
    stix_header.information_source.identity=identity
    

    # Set the Information Source "tools" section to a
    # cybox.common.ToolInformationList which contains our tool that we
    # created above.
    stix_header.information_source.tools = ToolInformationList(tool)

    stix_header.title = Config.get('stix', 'title')
    # Set the produced time to now
    stix_header.information_source.time = Time()
    stix_header.information_source.time.produced_time = datetime.now()
    
    
    marking_specification = MarkingSpecification()
    marking_specification.controlled_structure = "../../../descendant-or-self::node()"
    tlp = TLPMarkingStructure()
    tlp.color = Config.get('stix', 'TLP')
    marking_specification.marking_structures.append(tlp)

    handling = Marking()
    handling.add_marking(marking_specification)
    

  

    # Set the header description
    stix_header.description =  Config.get('stix', 'description')

    # Set the STIXPackage header
    stix_package.stix_header = stix_header
    
    stix_package.stix_header.handling = handling
    try:
        pp = pprint.PrettyPrinter(indent=5)
        pp.pprint(json['default'])
        #for key, value in json['default'].iteritems():
        #    print key, value
        for item in json['default']:
            #logger.debug("item %s", item)
            indicator = Indicator()
            indicator.title = "File Hash"
            indicator.description = (
            "An indicator containing a File observable with an associated hash"
            )    
            # Create a CyboX File Object
            f = File()
            
            sha_value = item['sha256']
            if sha_value is not None:    
                sha256 = Hash()
                sha256.simple_hash_value = sha_value   
                h = Hash(sha256, Hash.TYPE_SHA256)
                f.add_hash(h)
            sha1_value = item['sha1']
            if sha_value is not None:    
                sha1 = Hash()
                sha1.simple_hash_value = sha1_value   
                h = Hash(sha1, Hash.TYPE_SHA1)
                f.add_hash(h)
            sha512_value = item['sha512']
            if sha_value is not None:    
                sha512 = Hash()
                sha512.simple_hash_value = sha512_value   
                h = Hash(sha512, Hash.TYPE_SHA512)
                f.add_hash(h)

            f.add_hash(item['md5'])
            
            #adding the md5 hash to the title as well
            stix_header.title+=' '+item['md5']
            #print(item['type'])
            f.size_in_bytes=item['size']
            f.file_format=item['type']
            f.file_name = item['name']
            indicator.description = "File hash served by a Viper instance"
            indicator.add_object(f)
            stix_package.add_indicator(indicator)
    except Exception, e:
        logger.error('Error: %s',format(e))
        return False
예제 #42
0
def add_ais_marking(stix_package, proprietary, consent, color, **kwargs):
    """
    This utility functions aids in the creation of an AIS marking and appends
    it to the provided STIX package.

    Args:
        stix_package: A stix.core.STIXPackage object.
        proprietary: True if marking uses IsProprietary, False for
            NotProprietary.
        consent: A string with one of the following values: "EVERYONE", "NONE"
            or "USG".
        color: A string that corresponds to TLP values: "WHITE", "GREEN" or
            "AMBER".
        **kwargs: Six required keyword arguments that are used to create a CIQ
            identity object. These are: country_name_code,
            country_name_code_type, admin_area_name_code,
            admin_area_name_code_type, organisation_name, industry_type.

    Raises:
        ValueError: When keyword arguments are missing. User did not supply
            correct values for: proprietary, color and consent.

    Note:
        The following line is required to register the AIS extension::

            >>> import stix.extensions.marking.ais

        Any Markings under STIX Header will be removed. Please follow the
        guidelines for `AIS`_.

        The industry_type keyword argument accepts: a list of string based on
        defined sectors, a pipe-delimited string of sectors, or a single
        sector.

    .. _AIS:
        https://www.us-cert.gov/ais

    """
    from stix.common import InformationSource
    from stix.extensions.identity.ciq_identity_3_0 import (
        CIQIdentity3_0Instance, STIXCIQIdentity3_0, PartyName, Address,
        Country, NameElement, OrganisationInfo, AdministrativeArea)
    from stix.core.stix_header import STIXHeader
    from stix.data_marking import MarkingSpecification, Marking

    args = ('country_name_code', 'country_name_code_type', 'industry_type',
            'admin_area_name_code', 'admin_area_name_code_type',
            'organisation_name')

    diff = set(args) - set(kwargs.keys())

    if diff:
        msg = 'All keyword arguments must be provided. Missing: {0}'
        raise ValueError(msg.format(tuple(diff)))

    party_name = PartyName()
    party_name.add_organisation_name(kwargs['organisation_name'])

    country = Country()
    country_name = NameElement()
    country_name.name_code = kwargs['country_name_code']
    country_name.name_code_type = kwargs['country_name_code_type']
    country.add_name_element(country_name)

    admin_area = AdministrativeArea()
    admin_area_name = NameElement()
    admin_area_name.name_code = kwargs['admin_area_name_code']
    admin_area_name.name_code_type = kwargs['admin_area_name_code_type']
    admin_area.add_name_element(admin_area_name)

    address = Address()
    address.country = country
    address.administrative_area = admin_area

    org_info = OrganisationInfo()
    org_info.industry_type = _validate_and_create_industry_type(
        kwargs['industry_type'])

    id_spec = STIXCIQIdentity3_0()
    id_spec.party_name = party_name
    id_spec.add_address(address)
    id_spec.organisation_info = org_info

    identity = CIQIdentity3_0Instance()
    identity.specification = id_spec

    if proprietary is True:
        proprietary_obj = IsProprietary()
        consent = 'EVERYONE'
    elif proprietary is False:
        proprietary_obj = NotProprietary()
    else:
        raise ValueError('proprietary expected True or False.')

    proprietary_obj.ais_consent = AISConsentType(consent=consent)
    proprietary_obj.tlp_marking = TLPMarkingType(color=color)

    ais_marking = AISMarkingStructure()

    if isinstance(proprietary_obj, IsProprietary):
        ais_marking.is_proprietary = proprietary_obj
    else:
        ais_marking.not_proprietary = proprietary_obj

    marking_spec = MarkingSpecification()
    marking_spec.controlled_structure = '//node() | //@*'
    marking_spec.marking_structures.append(ais_marking)
    marking_spec.information_source = InformationSource()
    marking_spec.information_source.identity = identity

    if not stix_package.stix_header:
        stix_package.stix_header = STIXHeader()

    # Removes any other Markings if present.
    stix_package.stix_header.handling = Marking()
    stix_package.stix_header.handling.add_marking(marking_spec)
예제 #43
0
def main():

    ######################################################################
    # MODIFICARE LE VARIABILI SEGUENTI

    # Il title e' ID univoco della minaccia (es. Cobalt / Danabot / APT28)
    MyTITLE = "GandCrab"

    # La description strutturiamola come segue
    # <IOC PRODUCER> - <Descrizione della minaccia/campagna> - <URL (if any)>
    DESCRIPTION = "CERT-PA - Nuova campagna di Cyber-Estorsione basata su ransomware GandCrab - https://www.cert-pa.it/notizie/nuova-campagna-di-cyber-estorsione-basata-su-ransomware-gandcrab/"

    # La sorgente che ha generato l'IoC con riferimento a Cyber Saiyan Community 
    IDENTITY = "CERT-PA via Cyber Saiyan Community"
    #
    ######################################################################

    # Build STIX file
    info_src = InformationSource()
    info_src.identity = Identity(name=IDENTITY)

    NAMESPACE = Namespace("https://infosharing.cybersaiyan.it", "CYBERSAIYAN")
    set_id_namespace(NAMESPACE)

    timestamp = datetime.datetime.fromtimestamp(time.time()).strftime('%Y-%m-%d %H:%M:%S')
    SHORT = timestamp

    wrapper = STIXPackage()
    
    marking_specification = MarkingSpecification()
    marking_specification.controlled_structure = "//node() | //@*"
    tlp = TLPMarkingStructure()
    tlp.color = "WHITE"
    marking_specification.marking_structures.append(tlp)
    
    handling = Marking()
    handling.add_marking(marking_specification)
    
    wrapper.stix_header = STIXHeader(information_source=info_src, title=MyTITLE.encode(encoding='UTF-8', errors='replace'), description=DESCRIPTION.encode(encoding='UTF-8', errors='replace'), short_description=SHORT.encode(encoding='UTF-8', errors='replace'))
    wrapper.stix_header.handling = handling
    
    # HASH indicators
    indicatorHASH = Indicator()
    indicatorHASH.title = MyTITLE + " - HASH"
    indicatorHASH.add_indicator_type("File Hash Watchlist")
    
    # DOMAIN indicators
    indiDOMAIN = Indicator()
    indiDOMAIN.title = MyTITLE + " - DOMAIN"
    indiDOMAIN.add_indicator_type("Domain Watchlist")

    # URL indicators
    indiURL = Indicator()
    indiURL.title = MyTITLE + " - URL"
    indiURL.add_indicator_type("URL Watchlist")

    # IP indicators
    indiIP = Indicator()
    indiIP.title = MyTITLE + " - IP"
    indiIP.add_indicator_type("IP Watchlist")

    # EMAIL indicators
    indiEMAIL = Indicator()
    indiEMAIL.title = MyTITLE + " - EMAIL"
    indiEMAIL.add_indicator_type("Malicious E-mail")

    # Read IoC file
    file_ioc = "CS-ioc.txt"
    ioc = loaddata(file_ioc)

    print "Reading IoC file..."
    for idx, ioc in enumerate(ioc):
        notfound = 1
        
        # sha256
        p = re.compile(r"^[0-9a-f]{64}$", re.IGNORECASE)
        m = p.match(ioc)
        if m and notfound:
            filei = File()
            filei.add_hash(Hash(ioc))
        
            obsi = Observable(filei)
            indicatorHASH.add_observable(obsi)
            print "SHA256: " + ioc
            notfound = 0

        #md5
        p = re.compile(r"^[0-9a-f]{32}$", re.IGNORECASE)
        m = p.match(ioc)
        if m and notfound:
            filej = File()
            filej.add_hash(Hash(ioc))
        
            obsj = Observable(filej)
            indicatorHASH.add_observable(obsj)
            print "MD5: " + ioc
            notfound = 0

        #sha1
        p = re.compile(r"^[0-9a-f]{40}$", re.IGNORECASE)
        m = p.match(ioc)
        if m and notfound:
            filek = File()
            filek.add_hash(Hash(ioc))
        
            obsk = Observable(filek)
            indicatorHASH.add_observable(obsk)
            print "SHA1: " + ioc
            notfound = 0

        #domains
        if validators.domain(ioc) and notfound:
            url = URI()
            url.value = ioc
            url.type_ =  URI.TYPE_DOMAIN
            url.condition = "Equals"

            obsu = Observable(url)
            indiDOMAIN.add_observable(obsu)
            print "DOMAIN: " + ioc
            notfound = 0

        #url
        if validators.url(ioc) and notfound:
            url = URI()
            url.value = ioc
            url.type_ =  URI.TYPE_URL
            url.condition = "Equals"
            
            obsu = Observable(url)
            indiURL.add_observable(obsu)
            print "URL: " + ioc
            notfound = 0

        #ip
        if validators.ipv4(ioc) and notfound:
            ip = Address()
            ip.address_value = ioc
        
            obsu = Observable(ip)
            indiIP.add_observable(obsu)
            print "IP: " + ioc
            notfound = 0

    # add all indicators to STIX
    wrapper.add_indicator(indicatorHASH)
    wrapper.add_indicator(indiDOMAIN)
    wrapper.add_indicator(indiURL)
    wrapper.add_indicator(indiIP)
    wrapper.add_indicator(indiEMAIL)
   
    # print STIX file to stdout
    print "Writing STIX package: package.stix"
    f = open ("package.stix", "w")
    f.write (wrapper.to_xml())
    f.close ()
    print 
예제 #44
0
def adptr_dict2STIX(srcObj, data):
    sTxt = "Called... "
    sndMSG(sTxt, 'INFO', 'adptr_dict2STIX()')
    stixObj = None

    ### Input Check
    if srcObj == None or data == None:
        #TODO: Needs error msg: Missing srcData Object
        return (False)

    ### Generate NameSpace id tags
    STIX_NAMESPACE = {"http://hailataxii.com": "opensource"}
    OBS_NAMESPACE = Namespace("http://hailataxii.com", "opensource")
    stix_set_id_namespace(STIX_NAMESPACE)
    obs_set_id_namespace(OBS_NAMESPACE)

    ### Building STIX Wrapper
    stix_package = STIXPackage()
    objIndicator = Indicator()

    ### Bulid Object Data
    for sKey in data:
        objIndicator = Indicator()
        listOBS = []

        ### Parsing IP Address
        sAddr = data[sKey]['attrib']['ipAddr']
        if len(sAddr) > 0:
            objAddr = Address()
            objAddr.is_destination = True
            objAddr.address_value = sAddr
            objAddr.address_value.condition = 'Equals'
            if isIPv4(sAddr):
                objAddr.category = objAddr.CAT_IPV4
            elif isIPv6(sAddr):
                objAddr.category = objAddr.CAT_IPV6
            else:
                continue

            obsAddr = Observable(objAddr)
            objAddr = None
            obsAddr.sighting_count = 1
            obsAddr.title = 'IP: ' + sAddr
            sDscrpt = 'IPv4' + ': ' + sAddr + " | "
            sDscrpt += "isDestination: True | "
            obsAddr.description = "<![CDATA[" + sDscrpt + "]]>"
            listOBS.append(obsAddr)
            obsAddr = None
            objIndicator.add_indicator_type("IP Watchlist")

        ### Parsing Domain
        sDomain = data[sKey]['attrib']['domain']
        if len(sDomain) > 0:
            objDomain = DomainName()
            objDomain.value = sDomain
            objDomain.value.condition = 'Equals'

            if isFQDN(sDomain):
                objDomain.type = 'FQDN'
            elif isTLD(sDomain):
                objDomain.type = 'TLD'
            else:
                continue

            obsDomain = Observable(objDomain)
            objDomain = None
            obsDomain.sighting_count = 1
            obsDomain.title = 'Domain: ' + sDomain
            sDscrpt = 'Domain: ' + sDomain + " | "
            sDscrpt += "isFQDN: True | "
            obsDomain.description = "<![CDATA[" + sDscrpt + "]]>"
            listOBS.append(obsDomain)
            obsDomain = None
            objIndicator.add_indicator_type("Domain Watchlist")

        #Parser URI
        sURI = data[sKey]['attrib']['title']
        if len(sURI) > 0:
            objURI = URI()
            objURI.value = sURI
            objURI.value.condition = 'Equals'
            objURI.type_ = URI.TYPE_URL
            obsURI = Observable(objURI)
            objURI = None
            obsURI.sighting_count = 1
            obsURI.title = 'URI: ' + sURI
            sDscrpt = 'URI: ' + sURI + " | "
            sDscrpt += "Type: URL | "
            obsURI.description = "<![CDATA[" + sDscrpt + "]]>"
            listOBS.append(obsURI)
            obsURI = None
            objIndicator.add_indicator_type("URL Watchlist")

        ### Add Generated observable to Indicator
        objIndicator.observables = listOBS
        objIndicator.observable_composition_operator = 'OR'

        #Parsing Producer
        sProducer = srcObj.Domain
        if len(sProducer) > 0:
            objIndicator.set_producer_identity(sProducer)

        objIndicator.set_produced_time(data[sKey]['attrib']['dateVF'])
        objIndicator.set_received_time(data[sKey]['dateDL'])

        ### Generate Indicator Title based on availbe data
        sTitle = 'C2C Site: ' + sURI
        objIndicator.title = sTitle

        #Generate Indicator Description based on availbe data
        sDscrpt = ""
        if len(sAddr) > 0:
            sAddLine = "This IP address " + sAddr
        if len(sDomain) > 0:
            sAddLine = "This domain " + sDomain
        if len(sAddr) > 0 and len(sDomain) > 0:
            sAddLine = "This domain " + sDomain + " (" + sAddr + ")"
        if len(sAddLine) > 0:
            sDscrpt += sAddLine

        sDscrpt = sDscrpt + " has been identified as a command and control site for " + data[
            sKey]['attrib']['dscrpt'] + ' malware'

        if len(srcObj.Domain) > 0:
            sDscrpt = sDscrpt + " by " + srcObj.Domain
        else:
            sDscrpt = sDscrpt + "."
        sDscrpt = sDscrpt + ". For more detailed infomation about this indicator go to [CAUTION!!Read-URL-Before-Click] [" + data[
            sKey]['attrib']['link'] + "]."

        if len(sDscrpt) > 0:
            objIndicator.description = "<![CDATA[" + sDscrpt + "]]>"
            pass

        #Parse TTP
        sType = data[sKey]['attrib']['dscrpt']
        if len(sType) > 0:
            objMalware = MalwareInstance()

            objMalware.add_name(sType)
            objMalware.add_type("Remote Access Trojan")
            objMalware.short_description = ""
            objMalware.description = ""

            objTTP = TTP(title=sType)
            objTTP.behavior = Behavior()
            objTTP.behavior.add_malware_instance(objMalware)
            objIndicator.add_indicated_ttp(objTTP)

        stix_package.add_indicator(objIndicator)
        objIndicator = None

    ### STIX Package Meta Data
    stix_header = STIXHeader()
    stix_header.title = srcObj.pkgTitle
    stix_header.description = "<![CDATA[" + srcObj.pkgDscrpt + "]]>"

    ### Understanding markings http://stixproject.github.io/idioms/features/data-markings/
    marking_specification = MarkingSpecification()

    classLevel = SimpleMarkingStructure()
    classLevel.statement = "Unclassified (Public)"
    marking_specification.marking_structures.append(classLevel)

    tlp = TLPMarkingStructure()
    tlp.color = "WHITE"
    marking_specification.marking_structures.append(tlp)
    marking_specification.controlled_structure = "//node()"

    objTOU = TermsOfUseMarkingStructure()
    sTOU = open('tou.txt').read()
    objTOU.terms_of_use = sProducer + " | " + sTOU
    marking_specification.marking_structures.append(objTOU)

    handling = Marking()
    handling.add_marking(marking_specification)
    stix_header.handling = handling

    stix_package.stix_header = stix_header
    stix_header = None

    ### Generate STIX XML File
    locSTIXFile = 'STIX_' + srcObj.fileName.split('.')[0] + '.xml'
    sndFile(stix_package.to_xml(), locSTIXFile)

    return (stix_package)