def load_stix(stix): # Just save the pain and load it if the first character is a < if sys.version_info < (3, 5): json_exception = ValueError else: json_exception = json.JSONDecodeError if isinstance(stix, STIXPackage): # Oh cool we're ok # Who tried to load this? Honestly. return stix elif hasattr(stix, 'read'): # It's a file! # But somehow, sometimes, reading it returns a bytes stream and the loader dies on python 3.4. # Luckily, STIXPackage.from_json (which is mixbox.Entity.from_json) will happily load a string. # So we're going to play dirty. data = stix.read() if isinstance(data, bytes): data = data.decode() try: # Try loading from JSON stix_package = STIXPackage.from_json(data) except json_exception: # Ok then try loading from XML # Loop zoop stix.seek(0) try: stix_package = STIXPackage.from_xml(stix) except Exception as ex: # No joy. Quit. raise STIXLoadError("Could not load stix file. {}".format(ex)) return stix_package elif isinstance(stix, str): # It's text, we'll need to use a temporary file # Create a temporary file to load from # Y'know I should probably give it a max size before jumping to disk # idk, 10MB? Sounds reasonable. f = SpooledTemporaryFile(max_size=10 * 1024) # O I have idea for sneak # Will be very sneak # Write the (probably) XML to file f.write(stix.encode("utf-8")) # Reset the file so we can read from it f.seek(0) # AHA SNEAK DIDN'T EXPECT RECURSION DID YOU return load_stix(f)
def open_stix(stix_thing): # Load the package if not hasattr(stix_thing, 'read'): stix_thing = open(stix_thing, "r") pkg = None try: pkg = STIXPackage().from_xml(stix_thing) except: try: pkg = STIXPackage.from_json(stix_thing) except: raise Exception("Could not load package!") return pkg
# Set the config file if args.config: configfile = args.config else: configfile = os.path.expanduser("~/.misptostix/misp.login") try: with open(configfile, "r") as f: CONFIG = pyaml.yaml.load(f) except FileNotFoundError: print("Could not find config file {}".format(configfile)) sys.exit(1) # This is just a file conversion # Relatively quick and easy MISP = misp.MISP(CONFIG["MISP"]["URL"], CONFIG["MISP"]["KEY"]) # We'll use my nice little misp module # Load the package try: pkg = STIXPackage().from_xml(open(args.file, "r")) except: try: pkg = STIXPackage.from_json(open(args.file, "r")) except: print("Could not load package!") sys.exit(1) MISP.push(pkg)
def load_stix(stix): # Just save the pain and load it if the first character is a < log.debug("Loading STIX...") if sys.version_info < (3, 5): json_exception = ValueError else: json_exception = json.JSONDecodeError if isinstance(stix, STIXPackage): log.debug("Argument was already STIX package, ignoring.") # Oh cool we're ok # Who tried to load this? Honestly. return stix elif hasattr(stix, 'read'): log.debug("Argument has 'read' attribute, assuming file-like.") # It's a file! # But somehow, sometimes, reading it returns a bytes stream # and the loader dies on python 3.4. # Luckily, STIXPackage.from_json (which is mixbox.Entity.from_json) # will happily load a string. # So we're going to play dirty. data = stix.read() log.debug("Read file, type %s.", type(data)) if isinstance(data, bytes): data = data.decode() try: log.debug("Attempting to load from JSON...") # Try loading from JSON stix_package = STIXPackage.from_json(data) except json_exception: log.debug("Attempting to load from XML...") # Ok then try loading from XML # Loop zoop # Read the STIX into an Etree stix.seek(0) stix_xml = etree.fromstring(stix.read()) ns_map = stix_xml.nsmap # Remove any "marking" sections because the US-Cert is evil log.debug("Removing Marking elements...") pattern = ".//{http://data-marking.mitre.org/Marking-1}Marking" for element in stix_xml.findall(pattern): element.getparent().remove(element) log.debug("Writing cleaned XML to Tempfile") f = SpooledTemporaryFile(max_size=10 * 1024) f.write(etree.tostring(stix_xml)) f.seek(0) # Pray to anything you hold sacred ns_objmap = map(lambda x: Namespace(ns_map[x], x), ns_map) for ns in ns_objmap: log.debug("Trying to add namespace %s", ns) try: nsparser.STIX_NAMESPACES.add_namespace(ns) mixbox.namespaces.register_namespace(ns) except Exception as ex: log.exception(ex) try: log.debug("Attempting to read clean XML into STIX...") stix_package = STIXPackage.from_xml(f) except Exception as ex: # No joy. Quit. log.fatal("Could not :<") log.exception(ex) f.seek(0) with open("FAILED_STIX.xml", "wb") as g: g.write(f.read()) raise STIXLoadError("Could not load stix file. {}".format(ex)) return stix_package elif isinstance(stix, (str, bytes)): if isinstance(stix, bytes): stix = stix.decode() # It's text, we'll need to use a temporary file # Create a temporary file to load from # Y'know I should probably give it a max size before jumping to disk # idk, 10MB? Sounds reasonable. f = SpooledTemporaryFile(max_size=10 * 1024) # O I have idea for sneak # Will be very sneak # Write the (probably) XML to file f.write(stix.encode("utf-8")) # Reset the file so we can read from it f.seek(0) # AHA SNEAK DIDN'T EXPECT RECURSION DID YOU return load_stix(f)