Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Export to stix bundle bug #20323

Merged
merged 20 commits into from Aug 15, 2022
Merged
6 changes: 6 additions & 0 deletions Packs/CommonScripts/ReleaseNotes/1_7_20.md
@@ -0,0 +1,6 @@

#### Scripts
##### StixCreator
- Fixed an issue where export to STIX failed when more than one indicator was being exported.
- Fixed an issue where export to STIX failed when trying to export file types.
- Updated the Docker image to: *demisto/py3-tools:1.0.0.32758*.
29 changes: 23 additions & 6 deletions Packs/CommonScripts/Scripts/StixCreator/StixCreator.py
Expand Up @@ -12,10 +12,10 @@
from stix2 import Tool, CourseOfAction
from typing import Any, Callable

SCOs: dict[str, str] = {
"file md5": "file:hashes.md5",
"file sha1": "file:hashes.sha1",
"file sha256": "file:hashes.sha256",
SCOs: dict[str, str] = { # pragma: no cover
"md5": "file:hashes.md5",
"sha1": "file:hashes.sha1",
"sha256": "file:hashes.sha256",
"ssdeep": "file:hashes.ssdeep",
"ip": "ipv4-addr:value",
"cidr": "ipv4-addr:value",
Expand All @@ -29,7 +29,7 @@
"registry key": "windows-registry-key:key"
}

SDOs: dict[str, Callable] = {
SDOs: dict[str, Callable] = { # pragma: no cover
"malware": Malware,
"attack pattern": AttackPattern,
"campaign": Campaign,
Expand All @@ -43,6 +43,21 @@
}


def hash_type(value: str) -> str: # pragma: no cover
length = len(value)
if length == 32:
return 'md5'
if length == 40:
return 'sha1'
if length == 64 and ":" in value:
return 'ssdeep'
elif length == 64:
return 'sha256'
if length == 128:
return 'sha512'
return ''


def main():

user_args = demisto.args().get('indicators', 'Unknown')
Expand Down Expand Up @@ -94,6 +109,8 @@ def main():

try:
indicator_type = demisto_indicator_type.lower().replace("-", "")
if indicator_type == 'file':
indicator_type = hash_type(value)
indicator = Indicator(pattern=f"[{SCOs[indicator_type]} = '{value}']",
pattern_type='stix',
**kwargs)
Expand Down Expand Up @@ -133,7 +150,7 @@ def main():
continue

if len(indicators) > 1:
bundle = Bundle(indicators)
bundle = Bundle(indicators, allow_custom=True)
context = {
'StixExportedIndicators(val.pattern && val.pattern == obj.pattern)': json.loads(str(bundle))
}
Expand Down
11 changes: 4 additions & 7 deletions Packs/CommonScripts/Scripts/StixCreator/StixCreator.yml
Expand Up @@ -5,14 +5,12 @@ name: StixCreator
script: ''
type: python
tags: []
comment: Gets a list of indicators from the indicators argument, and generates a JSON
file in STIX 2.0 format.
comment: Gets a list of indicators from the indicators argument, and generates a JSON file in STIX 2.0 format.
enabled: true
args:
- name: indicators
required: true
description: A JSON object of all indicators and their fields, indicator index mapped
to Demisto indicator fields.
description: A JSON object of all indicators and their fields, indicator index mapped to Demisto indicator fields.
- name: doubleBackslash
default: true
description: Adds a second backslash to all existing backslashes in the value field.
Expand All @@ -31,8 +29,7 @@ outputs:
description: The STIX type (always exported as "indicator").
type: string
- contextPath: StixExportedIndicators.pattern
description: ' The type and value of indicators, for example: URL, IPv4, domain,email,
and so on. '
description: ' The type and value of indicators, for example: URL, IPv4, domain,email, and so on. '
type: string
- contextPath: StixExportedIndicators.score
description: The STIX impact score ("High", "Medium", "None", or "Not Specified")
Expand All @@ -42,7 +39,7 @@ outputs:
type: date
scripttarget: 0
runonce: false
dockerimage: demisto/py3-tools:1.0.0.31193
dockerimage: demisto/py3-tools:1.0.0.32758
subtype: python3
runas: DBotWeakRole
tests:
Expand Down
45 changes: 45 additions & 0 deletions Packs/CommonScripts/Scripts/StixCreator/StixCreator_test.py
@@ -0,0 +1,45 @@
import demistomock as demisto # noqa: F401
from CommonServerPython import * # noqa: F401
import pytest
from StixCreator import main

FILE_INDICATOR = \
{
'indicators':
{
'0': {'expirationStatus': 'active', 'firstSeen': '2022-07-31T13:26:05Z',
'indicator_type': 'File',
'lastSeen': '2022-07-31T13:26:05Z', 'score': 'good',
'timestamp': '2022-07-31T13:26:05Z',
'value': 'e14daa9c88a7ec91d770ae262758db73b6593b178527a2d7bba14159fad5f1c2'
}
}
}

DOMAIN_INDICATORS = \
{
'indicators':
{
'0': {'expirationStatus': 'active', 'firstSeen': '2022-07-31T13:24:44Z',
'indicator_type': 'cve',
'lastSeen': '2022-07-31T13:24:44Z', 'score': 'Unknown',
'timestamp': '2022-07-31T13:24:44Z',
'value': 'test.com'
},
'1': {'expirationStatus': 'active', 'firstSeen': '2022-07-31T13:24:40Z',
'indicator_type': 'attack pattern',
'lastSeen': '2022-07-31T13:24:40Z', 'score': 'suspicious',
'timestamp': '2022-07-31T13:24:40Z',
'value': 'bad.com'
}
}
}


@pytest.mark.parametrize('indicators, stix_type', [(DOMAIN_INDICATORS, 'bundle'), (FILE_INDICATOR, 'indicator')])
def test_stixCreator_with_indicators(mocker, indicators, stix_type):
mocker.patch.object(demisto, 'args', return_value=indicators)
mocker.patch.object(demisto, 'results')
main()
results = demisto.results.call_args[0]
assert stix_type in results[0]['Contents']
2 changes: 1 addition & 1 deletion Packs/CommonScripts/pack_metadata.json
Expand Up @@ -2,7 +2,7 @@
"name": "Common Scripts",
"description": "Frequently used scripts pack.",
"support": "xsoar",
"currentVersion": "1.7.19",
"currentVersion": "1.7.20",
"author": "Cortex XSOAR",
"url": "https://www.paloaltonetworks.com/cortex",
"email": "",
Expand Down