From a492d975c414f24c724c25a5001d7aa1b720aff8 Mon Sep 17 00:00:00 2001 From: Hannah Ward Date: Fri, 19 Aug 2016 17:21:12 +0100 Subject: [PATCH] Now searches within observable_compositions --- .../modules/expansion/find_subdomains.py | 62 +++++++++++++++++++ misp_modules/modules/import_mod/stiximport.py | 37 ++++++++--- 2 files changed, 90 insertions(+), 9 deletions(-) create mode 100755 misp_modules/modules/expansion/find_subdomains.py diff --git a/misp_modules/modules/expansion/find_subdomains.py b/misp_modules/modules/expansion/find_subdomains.py new file mode 100755 index 0000000..4d40acb --- /dev/null +++ b/misp_modules/modules/expansion/find_subdomains.py @@ -0,0 +1,62 @@ +import json +import os +import subprocess +import requests +import tempfile + +misperrors = {'error': 'Error'} +mispattributes = {'input': ['domain'], 'output': ['domain']} + +# possible module-types: 'expansion', 'hover' or both +moduleinfo = {'version': '1', 'author': 'Hannah Ward', + 'description': 'Attempt to brute force subdomains', + 'module-type': ['expansion']} + +# config fields that your code expects from the site admin +moduleconfig = ["use_top_n_subdomains"] + +domains = requests.get("http://hannah-ward.uk/Subdomain_List.txt").text.split("\n")[:-1] + +def handler(q=False): + global domains + + if q is False: + return False + request = json.loads(q) + + r = {"results": []} + + f = tempfile.NamedTemporaryFile(delete=False, prefix="domains", mode="w") + print("Saving domains to {}".format(f.name)) + f.write("\n".join(domains[:int(request["config"]["use_top_n_subdomains"])])) + + f.close() + + print("Searching for subdomains of {}".format(request["domain"])) + print("Using {} domains".format(request["config"]["use_top_n_subdomains"])) + + print("Turning on tor...") + #subprocess.call([".","torsocks","on"]) + proc = subprocess.Popen(["knockpy", "-w", f.name, request["domain"]], + stdout=subprocess.PIPE + ) + + os.remove(f.name) + + print("Turning off tor...") + #subprocess.call([".","torsocks","off"]) + out,err = proc.communicate() + + r["results"] = {'values':out.split("\n"), "types":'domain'} + + return r + + +def introspection(): + return mispattributes + + +def version(): + moduleinfo['config'] = moduleconfig + return moduleinfo + diff --git a/misp_modules/modules/import_mod/stiximport.py b/misp_modules/modules/import_mod/stiximport.py index 0c39288..d734f3d 100755 --- a/misp_modules/modules/import_mod/stiximport.py +++ b/misp_modules/modules/import_mod/stiximport.py @@ -4,6 +4,7 @@ import re import base64 import hashlib import tempfile +import pickle misperrors = {'error': 'Error'} userConfig = {} @@ -49,6 +50,9 @@ def handler(q=False): # Load up the package into STIX package = loadPackage(package, memsize) + # Hash it + with open("/home/hward/tmp.dat", "wb") as f: + pickle.dump( package, f) # Build all the observables if package.observables: for obs in package.observables: @@ -62,7 +66,7 @@ def handler(q=False): # Aaaand the indicators if package.indicators: for ind in package.indicators: - r["results"].append(buildIndicator(ind)) + r["results"] += buildIndicator(ind) # Are you seeing a pattern? if package.exploit_targets: @@ -76,7 +80,7 @@ def handler(q=False): # Clean up results # Don't send on anything that didn't have a value - r["results"] = [x for x in r["results"] if len(x["values"]) != 0] + r["results"] = [x for x in r["results"] if isinstance(x, dict) and len(x["values"]) != 0] return r # Quick and dirty regex for IP addresses @@ -126,11 +130,14 @@ def buildIndicator(ind): and other fun things like that """ - r = {"values": [], "types": []} - + r = [] # Try to get hashes. I hate stix - if ind.observable: - return buildObservable(ind.observable) + if ind.observables: + for i in ind.observables: + if i.observable_composition: + for j in i.observable_composition.observables: + r.append(buildObservable(j)) + r.append(buildObservable(i)) return r @@ -152,7 +159,6 @@ def buildObservable(o): and extract the value and category """ - # Life is easier with json if not isinstance(o, dict): o = json.loads(o.to_json()) @@ -168,7 +174,6 @@ def buildObservable(o): props = o["object"]["properties"] # If it has an address_value field, it's gonna be an address - # print(props) # Kinda obvious really if "address_value" in props: @@ -193,7 +198,21 @@ def buildObservable(o): for hsh in props["hashes"]: r["values"].append(hsh["simple_hash_value"]["value"]) r["types"] = identifyHash(hsh["simple_hash_value"]["value"]) - return r + + elif "xsi:type" in props: + # Cybox. Ew. + try: + type_ = props["xsi:type"] + val = props["value"] + + if type_ == "LinkObjectType": + r["types"] = ["link"] + r["values"].append(val) + else: + print("Ignoring {}".format(type_)) + except: + pass + return r def loadPackage(data, memsize=1024):