Пример #1
0
def create_stix_hash_observable(namespace, indicator):
    """
    Create STIX file observable.
    Args:
        namespace: The XML namespace.
        indicator: The Demisto File indicator.

    Returns:
        STIX File observable.
    """

    id_ = f'{namespace}:observable-{uuid.uuid4()}'
    value = indicator.get('value', '')
    type_ = indicator.get('indicator_type', '')

    file_object = cybox.objects.file_object.File()
    file_object.add_hash(indicator)

    observable = Observable(
        title=f'{value}: {type_}',
        id_=id_,
        item=file_object
    )

    return [observable]
Пример #2
0
def create_stix_email_observable(namespace: str, indicator: dict) -> List[Observable]:
    """
    Create STIX Email observable.
    Args:
        namespace: The XML namespace.
        indicator: The Demisto Email indicator.

    Returns:
        STIX Email observable.
    """
    category = cybox.objects.address_object.Address.CAT_EMAIL
    type_ = indicator.get('indicator_type', '')
    value = indicator.get('value', '')
    id_ = f'{namespace}:observable-{uuid.uuid4()}'

    email_object = cybox.objects.address_object.Address(
        address_value=indicator.get('value', ''),
        category=category
    )

    observable = Observable(
        title=f'{type_}: {value}',
        id_=id_,
        item=email_object
    )

    return [observable]
Пример #3
0
def create_stix_url_observable(namespace, indicator):
    """
    Create STIX URL observable.
    Args:
        namespace: The XML namespace.
        indicator: The Demisto URL indicator.

    Returns:
        STIX URL observable.
    """
    id_ = f'{namespace}:observable-{uuid.uuid4()}'
    value = indicator.get('value', '')

    uri_object = cybox.objects.uri_object.URI(
        value=value,
        type_=cybox.objects.uri_object.URI.TYPE_URL
    )

    observable = Observable(
        title=f'URL: {value}',
        id_=id_,
        item=uri_object
    )

    return [observable]
Пример #4
0
def create_stix_ip_observable(namespace: str, indicator: dict) -> List[Observable]:
    """
    Create STIX IP observable.
    Args:
        namespace: The XML namespace .
        indicator: The Demisto IP indicator.

    Returns:
        STIX IP observable.
    """
    category = cybox.objects.address_object.Address.CAT_IPV4
    type_ = indicator.get('indicator_type', '')
    value = indicator.get('value', '')

    if type_ in [FeedIndicatorType.IPv6, FeedIndicatorType.IPv6CIDR]:
        category = cybox.objects.address_object.Address.CAT_IPV6

    indicator_values = [value]
    if '-' in value:
        # looks like an IP Range, let's try to make it a CIDR
        a1, a2 = value.split('-', 1)
        if a1 == a2:
            # same IP
            indicator_values = [a1]
        else:
            # use netaddr builtin algo to summarize range into CIDR
            iprange = netaddr.IPRange(a1, a2)
            cidrs = iprange.cidrs()
            indicator_values = list(map(str, cidrs))

    observables = []
    for indicator_value in indicator_values:
        id_ = f'{namespace}:observable-{uuid.uuid4()}'
        address_object = cybox.objects.address_object.Address(
            address_value=indicator_value,
            category=category
        )

        observable = Observable(
            title=f'{type_}: {indicator_value}',
            id_=id_,
            item=address_object
        )

        observables.append(observable)

    return observables
Пример #5
0
def create_stix_domain_observable(namespace, indicator):
    """
    Create STIX Domain observable.
    Args:
        namespace: The XML namespace.
        indicator: The Demisto Domain indicator.

    Returns:
        STIX Domain observable.
    """
    id_ = f'{namespace}:observable-{uuid.uuid4()}'
    value = indicator.get('value', '')

    domain_object = cybox.objects.domain_name_object.DomainName()
    domain_object.value = value
    domain_object.type_ = 'FQDN'

    observable = Observable(title=f'FQDN: {value}',
                            id_=id_,
                            item=domain_object)

    return [observable]
Пример #6
0
def get_stix_indicator(indicator: dict) -> stix.core.STIXPackage:
    """
    Convert a Demisto indicator to STIX.
    Args:
        indicator: The Demisto indicator.

    Returns:
        The STIX indicator as XML string.
    """
    set_id_namespace(NAMESPACE_URI, NAMESPACE)

    type_ = indicator.get('indicator_type', '')
    type_mapper: dict = TYPE_MAPPING.get(type_, {})

    value = indicator.get('value', '')
    source = indicator.get('sourceBrands', [])
    sources = ','.join(source)

    handling = None

    # Add TLP if available
    share_level = indicator.get('trafficlightprotocol', '').upper()
    if share_level and share_level in ['WHITE', 'GREEN', 'AMBER', 'RED']:
        marking_specification = stix.data_marking.MarkingSpecification()
        marking_specification.controlled_structure = "//node() | //@*"

        tlp = stix.extensions.marking.tlp.TLPMarkingStructure()
        tlp.color = share_level
        marking_specification.marking_structures.append(tlp)

        handling = stix.data_marking.Marking()
        handling.add_marking(marking_specification)

    header = None
    if handling is not None:
        header = stix.core.STIXHeader(handling=handling)

    # Create the STIX package
    package_id = f'{NAMESPACE}:observable-{uuid.uuid4()}'
    stix_package = stix.core.STIXPackage(id_=package_id, stix_header=header)

    # Get the STIX observables according to the indicator mapper
    observables = type_mapper['mapper'](NAMESPACE, indicator)

    # Create the STIX indicator
    for observable in observables:
        id_ = f'{NAMESPACE}:indicator-{uuid.uuid4()}'

        if type_ == 'URL':
            indicator_value = werkzeug.urls.iri_to_uri(value,
                                                       safe_conversion=True)
        else:
            indicator_value = value

        stix_indicator = stix.indicator.indicator.Indicator(
            id_=id_,
            title=f'{type_}: {indicator_value}',
            description=f'{type_} indicator from {sources}',
            timestamp=datetime.utcnow().replace(tzinfo=pytz.utc))

        # Confidence is mapped by the indicator score
        confidence = 'Low'
        indicator_score = indicator.get('score')
        if indicator_score is None:
            demisto.error(f'indicator without score: {value}')
            stix_indicator.confidence = "Unknown"
        else:
            score = int(indicator.get('score', 0))
            if score < 2:
                pass
            elif score < 3:
                confidence = 'Medium'
            else:
                confidence = 'High'

        stix_indicator.confidence = confidence

        stix_indicator.add_indicator_type(type_mapper['indicator_type'])

        stix_indicator.add_observable(observable)

        stix_package.add_indicator(stix_indicator)

    return stix_package