def __main__(): """ In the case of converting a stix pattern to datasource query, arguments will take the form of... <module> <translate_type> <data> The module and translate_type will determine what module and method gets called """ # process arguments parser = argparse.ArgumentParser(description='stix_shifter') subparsers = parser.add_subparsers(dest='command') # translate parser translate_parser = subparsers.add_parser( 'translate', help= 'Translate a query or result set using a specific translation module') # positional arguments translate_parser.add_argument('module', choices=stix_shifter.MODULES, help='what translation module to use') translate_parser.add_argument( 'translate_type', choices=[stix_shifter.RESULTS, stix_shifter.QUERY], help='what translation action to perform') translate_parser.add_argument( 'data_source', help='STIX identity object representing a datasource') translate_parser.add_argument('data', type=str, help='the data to be translated') # optional arguments translate_parser.add_argument( '-x', '--stix-validator', action='store_true', help='run stix2 validator against the converted results') translate_parser.add_argument('-m', '--data-mapper', help='module to use for the data mapper') args = parser.parse_args() if args.command is None: parser.print_help(sys.stderr) sys.exit(1) options = {} if args.stix_validator: options['stix_validator'] = args.stix_validator if args.data_mapper: options['data_mapper'] = args.data_mapper shifter = stix_shifter.StixShifter() result = shifter.translate(args.module, args.translate_type, args.data_source, args.data, options=options) print(result) exit(0)
def translate(pattern: str, search_platform=SearchPlatforms.ELASTIC, data_model=DataModels.CAR): options = {'data_mapper': data_model.value} shifter = stix_shifter.StixShifter() return shifter.translate(search_platform.value, stix_shifter.QUERY, {}, pattern, options=options)
def test_custom_mapping(self): data_source = "{\"type\": \"identity\", \"id\": \"identity--3532c56d-ea72-48be-a2ad-1a53f4c9c6d3\", \"name\": \"QRadar\", \"identity_class\": \"events\"}" data = "[{\"custompayload\": \"SomeBase64Payload\", \"url\": \"www.example.com\", \"filename\": \"somefile.exe\", \"username\": \"someuserid2018\"}]" options = { "mapping": { "username": { "key": "user-account.user_id" }, "identityip": { "key": "x_com_ibm_ariel.identity_ip", "cybox": False }, "qidname": { "key": "x_com_ibm_ariel.qid_name", "cybox": False }, "url": { "key": "url.value" }, "custompayload": { "key": "artifact.payload_bin" } } } shifter = stix_shifter.StixShifter() result = shifter.translate('qradar', 'results', data_source, data, options) result_bundle = json.loads(result) result_bundle_objects = result_bundle['objects'] observed_data = result_bundle_objects[1] assert ('objects' in observed_data) objects = observed_data['objects'] file_object = TestTransform.get_first_of_type(objects.values(), 'file') assert ( file_object is None ), 'default file object type was returned even though it was not included in the custom mapping' curr_obj = TestTransform.get_first_of_type(objects.values(), 'artifact') assert (curr_obj is not None), 'artifact object type not found' assert (curr_obj.keys() == {'type', 'payload_bin'}) assert (curr_obj['payload_bin'] == "SomeBase64Payload")
def __main__(): """ In the case of converting a stix pattern to datasource query, arguments will take the form of... <module> <translate_type> <data> <options> The module and translate_type will determine what module and method gets called Options argument comes in as: "{ "select_fields": <string array of fields in the datasource select statement>}, "mapping": <mapping hash for either stix pattern to datasource or data results to stix observation objects>, "result_limit": <integer limit number for max results in the data source query>, "timerange": <integer time window in minutes used in the data source query when START STOP qualifiers are absent> }" """ # process arguments parser = argparse.ArgumentParser(description='stix_shifter') subparsers = parser.add_subparsers(dest='command') # translate parser translate_parser = subparsers.add_parser( 'translate', help= 'Translate a query or result set using a specific translation module') # positional arguments translate_parser.add_argument('module', choices=stix_shifter.MODULES, help='what translation module to use') translate_parser.add_argument( 'translate_type', choices=[stix_shifter.RESULTS, stix_shifter.QUERY], help='what translation action to perform') translate_parser.add_argument( 'data_source', help='STIX identity object representing a datasource') translate_parser.add_argument('data', type=str, help='the data to be translated') translate_parser.add_argument('options', nargs='?', help='options that can be passed in') # optional arguments translate_parser.add_argument( '-x', '--stix-validator', action='store_true', help='run stix2 validator against the converted results') translate_parser.add_argument('-m', '--data-mapper', help='module to use for the data mapper') args = parser.parse_args() if args.command is None: parser.print_help(sys.stderr) sys.exit(1) options = json.loads(args.options) if bool(args.options) else {} if args.stix_validator: options['stix_validator'] = args.stix_validator if args.data_mapper: options['data_mapper'] = args.data_mapper shifter = stix_shifter.StixShifter() result = shifter.translate(args.module, args.translate_type, args.data_source, args.data, options=options) print(result) exit(0)
"ipv6": "40", "rsvp": "46", "gre": "47", "esp": "50", "ah": "51", "narp": "54", "ospfigp": "89", "ipip": "94", "any": "99", "sctp": "132" } default_limit = "limit 10000" default_time = "last 5 minutes" shifter = stix_shifter.StixShifter() class TestStixToAql(unittest.TestCase, object): def test_ipv4_query(self): stix_pattern = "[ipv4-addr:value = '192.168.122.83' or ipv4-addr:value = '192.168.122.84']" query = shifter.translate('qradar', 'query', '{}', stix_pattern) where_statement = "WHERE (sourceip = '192.168.122.84' OR destinationip = '192.168.122.84' OR identityip = '192.168.122.84') OR (sourceip = '192.168.122.83' OR destinationip = '192.168.122.83' OR identityip = '192.168.122.83') {} {}".format(default_limit, default_time) parsed_stix = [{'attribute': 'ipv4-addr:value', 'comparison_operator': '=', 'value': '192.168.122.84'}, {'attribute': 'ipv4-addr:value', 'comparison_operator': '=', 'value': '192.168.122.83'}] assert query == {'queries': [selections + from_statement + where_statement], 'parsed_stix': parsed_stix} def test_ipv6_query(self): stix_pattern = "[ipv6-addr:value = '192.168.122.83']" query = shifter.translate('qradar', 'query', '{}', stix_pattern)