def get(self, hash): reqbs64 = r.hget("request", hash) ''' self.set_header("Content-Type", 'application/octet-stream') self.set_header('Content-Disposition', 'attachment; filename={filename}.txt'.format(filename=hash))''' if not reqbs64: return self.write("invalid hash, u bad hacker") request = json.loads(ds(reqbs64)) requeststring = "{method} {url} HTTP/1.1\r\nHost: {host}\r\n".format( method=request["method"], url=request["url"], host=request["host"]) for key in request["headers"].keys(): if key == "Host": continue requeststring += "{key}: {value}\r\n".format( key=key, value=request["headers"][key]) if request["method"] == "GET": requeststring = requeststring.rstrip("\n").rstrip("\r") else: requeststring += "\r\n{body}".format(body=request["postdata"]) url = "http://" + request['host'] + request['url'] if request['postdata'] == '': data = 'NULL' else: data = request['postdata'] return self.render("table-hash.html", rstring=requeststring, url=url, data=data, activenum=1)
def get_sqlis(self): sqlireqs = [] reqkeys = r.lrange("sqli", 0, -1) for reqkey in reqkeys: reqbs64 = r.hget("request", reqkey) reqde64 = json.loads(ds(reqbs64)) sqlireqs.append(reqde64) return sqlireqs
def get_recent10running(self): run10keys = r.lrange("running", -10, -1) recent10running = [] for runkey in run10keys: reqbs64 = r.hget("request", runkey) reqde64 = json.loads(ds(reqbs64)) recent10running.append(reqde64) return recent10running
def get_recent10reqs(self): req10keys = r.lrange("waiting", -5, -1) req10keys += r.lrange("running", -5, -1) recent10reqs = [] for reqkey in req10keys: reqbs64 = r.hget("request", reqkey) reqde64 = json.loads(ds(reqbs64)) recent10reqs.append(reqde64) return recent10reqs
def return_reqs_with_payload(vulntype): reqs = [] reqkeys = r.lrange(vulntype, 0, -1) for reqkey in reqkeys: reqbs64 = r.hget("request", reqkey) reqde64 = json.loads(ds(reqbs64)) reqde64["payload"] = r.hget("bingo_payload", reqkey) reqs.append(reqde64) return reqs
def updaterequest(reqhash, taskid, sqlmapapi, sqlidata): oldrequest = json.loads(ds(r.hget("request", reqhash))) oldrequest["taskid"] = taskid oldrequest["sqlmapapi"] = sqlmapapi oldrequest["dbms"] = sqlidata[0]['value'][0]['dbms'] oldrequest["os"] = sqlidata[0]['value'][0]['os'] oldrequest["parameter"] = sqlidata[0]['value'][0]['parameter'] oldrequest["sqlititle"] = sqlidata[0]['value'][0]['data']['1']['title'] b64req = es(json.dumps(oldrequest)) r.hset("request", reqhash, b64req)
def Start_Scan(nothing): ''' Main function of the scan worker, including xss,sqli,xpath,ldap,lfi,sqli_time scan rule. if USESQLMAPAPI= True, user sqlmapapi. sqli: post all the data to sqlmapapi or rule, if is vulun, update taskid to redis server. ''' while True: reqhash = r.rpoplpush("waiting", "running") reqed = r.hget("request", reqhash) if not reqed: continue request = json.loads(ds(reqed)) rules = ['sqli', 'xss', 'xpath', 'ldap', 'lfi' ] #rrules=['xss','sqli','xpath','ldap','lfi','sqli_time'] for rule in rules: try: if rule == 'sqli' and USESQLMAPAPI: newsql = isqlmap() #here wrong! if request.get("uri"): uri = request.get("uri") else: uri = "http://" + request['host'] + request['url'] taskid, api = newsql.extract_request( uri, request['method'], request['headers'], request['postdata']) print taskid, api while not check_status(taskid, api): sleep(7) sqlilen, sqlidata = isvulun(taskid, api) if sqlilen: r.lpush("sqli", reqhash) updaterequest(reqhash, taskid, api, sqlidata) else: scan_obj = general(request['url'], request['host'], request['postdata'], request['headers'], request['method'], request.get('uri')) if 'time' in rule: scan_obj.timecheck = True scan_obj.setname(rule) scan_obj.loadrule() scan_obj.run() if scan_obj.bingo_payload != '': r.lpush(rule, reqhash) r.hset("bingo_payload", reqhash, scan_obj.bingo_payload) except: pass r.lpush("finish", reqhash)
def scan_start(): while config.load()['scan_stat'].lower() == "true": try: while thread_filled(): time.sleep(5) reqhash = conn.rpoplpush("waiting", "running") if not reqhash: time.sleep(10) continue reqed = conn.hget("request", reqhash) request = json.loads(ds(reqed)) rules = config.load_rule()['scan_type'] url = urlparse.urlparse(request['url']).query if (request['method'] == "GET" and url != "") or (request['method'] == "POST" and (request["postdata"] != "" or url != "")): t = threading.Thread(target=new_scan, args=(reqhash, requests_convert(request), rules)) t.start() else: conn.lrem("running", 1, reqhash) conn.lpush("finished", reqhash) except Exception,e: out.error(str(e))
def main(): message = """ ___ _ _ _____ _____ ____ _ _ / __)( \( )( _ )( _ )( _ \( \/ ) \__ \ ) ( )(_)( )(_)( )___/ \ / (___/(_)\_)(_____)(_____)(__) (__) %sVersion: 2.0%s %sCode%s:\t [email protected] // @glennzw %sVisit%s:\t www.sensepost.com // @sensepost %sLicense%s: Non-commercial use """ % (BB, NB, GR, G, GR, G, GR, G) print message if not os.path.isfile('.acceptedlicense'): lf = open('LICENSE.txt', 'r') license_text = lf.read() msg = """ This appears to be the first time you're running Snoopy, welcome! We'd like you to agree to abide by our license before you proceed. It basically states that you can use Snoopy for non-commercial use. We have a separate license available for commercial use, which includes extra functionality such as: * Syncing data via XBee * Advanced plugins * Extra transforms * Web interface * Prebuilt drones Get in contact (%[email protected] / [email protected]%s) if you'd like to engage with us. Anyway, the license is below, please accept it before continuing. """ % (GR, G) print msg print C + license_text + G res = raw_input("Do you agree to abide by the license [Y/n]? ") res = res.strip().lower() if res != "y": print R + F + "License agreement not accepted. Exiting" + G + NF else: print "License agreement accepted, thanks!" lgo = open('./setup/sn.txt', 'r') txt = lgo.read() print GR + txt + G print "Please run Snoopy again... Check the README file for help." fl2 = open('.acceptedlicense', 'w') fl2.write("Accepted") fl2.close sys.exit(-1) usage = """Usage: %prog [--drone <drone_name>] [--location <drone_location>] [--plugin <plugin[:params]>] [--server <http://sync_server:[port]> ] [--dbms <database>]\nSee the README file for further information and examples.""" parser = OptionParser(usage=usage) if os.geteuid() != 0: logging.warning( "Running without root privilages. Some things may not work.") parser.add_option( "-s", "--server", dest="sync_server", action="store", help= "Upload data to specified SYNC_SERVER (http://host:port) (Ommitting will save data locally).", default="local") parser.add_option("-d", "--drone", dest="drone", action="store", help="Specify the name of your drone.", default="noDroneSpecified") parser.add_option("-k", "--key", dest="key", action="store", help="Specify key for drone name supplied.") parser.add_option("-l", "--location", dest="location", action="store", help="Specify the location of your drone.", default="noLocationSpecified") parser.add_option( "-f", "--flush", dest="flush", action="store_true", help= "Flush local database after syncronizing with remote server. Default is to not flush.", default=False) parser.add_option( "-b", "--dbms", dest="dbms", action="store", type="string", default="sqlite:///snoopy.db", help="Database to use, in SQL Alchemy format. [default: %default]") parser.add_option( "-m", "--plugin", dest="plugin", action="append", help= "Plugin to load. Pass parameters with colon. e.g '-m fishingrod:bait=worm,l=10'. Use -i to list available plugins and their paramters." ) parser.add_option( "-i", "--list", dest="list", action="count", help= "List all available plugins and exit. Use '-ii' or '-iii' for more information. Include plugin name for specific info, e.g: '-i -m wifi'.", default=0) parser.add_option(ds("LS1ueWFu"), action="store_true", dest="ny", default=False, help=SUPPRESS_HELP) #parser.add_option("-v", "--verbose", dest="verbose", action="store_true", help="Output information about new data.", default=False) parser.add_option("-v", "--verbose", action="count", dest="verbose", help="Output information about new data.", default=0) parser.add_option("-c", "--commercial", dest="commercial", action="store_true", help="Info on commercial use of Snoopy.", default=False) options, args = parser.parse_args() if options.ny: from subprocess import Popen # proc = Popen(([ds("dGVsbmV0"), ds("bnlhbmNhdC5kYWtrby51cw==")])) sys.exit(0) if options.commercial: print """We have a separate license available for commercial use, which includes extra functionality such as: * Syncing data via XBee * Advanced plugins * Extra transforms * Web interface * Prebuilt drones Get in contact (%[email protected] / [email protected]%s) if you'd like to engage with us.""" % (GR, G) sys.exit() plugins = common.get_plugins() if options.list > 0: if options.plugin: names = [str(plug).split(".")[1] for plug in plugins] props = [x.get_parameter_list() for x in plugins] derp = dict(zip(names, props)) name = options.plugin[0] show = derp.get(name) if show: print GR + "\tName:" + G + BB + B + "\t\t%s" % name + NB + G print GR + "\tInfo:" + G + "\t\t%s" % show.get('info') for p in show.get('parameter_list'): print GR + "\tParameter:" + G + "\t%s" % p[0] print G + "\t\t\t ↳ %s" % p[1] exit(0) print "[+] Plugins available:" for plug in plugins: plugin_info = plug.get_parameter_list() info, param_list = plugin_info.get('info'), plugin_info.get( 'parameter_list') name = str(plug).split(".")[1] if name != "run_log": print GR + "\tName:" + G + BB + B + "\t\t%s" % name + NB + G if options.list > 1: print GR + "\tInfo:" + G + "\t\t%s" % info if param_list and options.list > 2: for p in param_list: print GR + "\tParameter:" + G + "\t%s" % p[0] print G + "\t\t\t ↳ %s" % p[1] print "\n" sys.exit(0) if options.plugin is None and options.sync_server == "local": logging.error( "Error: You must specify at least one plugin. Try -h for help") sys.exit(-1) if options.plugin is None and options.sync_server is not "local": logging.info( "No plugins specified, will just sync database to remote instance") # if (options.drone is None or options.location is None) and not ( len(options.plugin) == 1 and options.plugin[0].split(":")[0] == "server" ) : if options.drone is "noDroneSpecified" or options.location is "noLocationSpecified" and options.plugin: logging.warning( "Drone (-d) or locaion (-l) not specified. May not be required by the plugins you're using." ) #logging.error("You must specify drone name (-d) and drone location (-l). Does not apply if only running server plugin.") #sys.exit(-1) if (options.key is None or options.drone is None) and options.sync_server != "local": logging.error( "You must specify a drone (-d) and a key (-k) when uploading data." ) sys.exit(-1) #Check validity of plugins if options.plugin: for m in options.plugin: if m.split(":", 1)[0] not in common.get_plugin_names(): logging.error( "Invalid plugin - '%s'. Use --list to list all available plugins." % (m.split(':', 1)[0])) sys.exit(-1) plugin_list = ', '.join(s.partition(':')[0] for s in options.plugin) logging.info("Starting Snoopy with plugins: %s%s%s" % (GR, plugin_list, G)) else: options.plugin = [] options.plugin.append('run_log') newplugs = [] for m in options.plugin: mds = m.split(":", 1) name = mds[0] params = {} if len(mds) > 1: params = dict(a.split("=") for a in mds[1].split(",")) newplugs.append({'name': 'plugins.' + name, 'params': params}) if options.sync_server == "local": logging.info("Capturing local only. Saving to '%s'" % options.dbms) # Snoopy(newplugs, options.dbms, options.sync_server, options.drone, # options.key, options.location, options.flush, options.verbose) Snoopy(newplugs, options.dbms, options.sync_server, options.drone, options.key, options.location, options.flush, options.verbose)
def main(): message = """ ___ _ _ _____ _____ ____ _ _ / __)( \( )( _ )( _ )( _ \( \/ ) \__ \ ) ( )(_)( )(_)( )___/ \ / (___/(_)\_)(_____)(_____)(__) (__) %sVersion: 2.0%s %sCode%s:\t [email protected] // @glennzw %sVisit%s:\t www.sensepost.com // @sensepost %sLicense%s: Non-commercial use """ %(BB,NB,GR,G,GR,G,GR,G) print message if not os.path.isfile('.acceptedlicense'): lf = open('LICENSE.txt', 'r') license_text = lf.read() msg = """ This appears to be the first time you're running Snoopy, welcome! We'd like you to agree to abide by our license before you proceed. It basically states that you can use Snoopy for non-commercial use. We have a separate license available for commercial use, which includes extra functionality such as: * Syncing data via XBee * Advanced plugins * Extra transforms * Web interface * Prebuilt drones Get in contact (%[email protected] / [email protected]%s) if you'd like to engage with us. Anyway, the license is below, please accept it before continuing. """ % (GR,G) print msg print C + license_text + G res = raw_input("Do you agree to abide by the license [Y/n]? ") res = res.strip().lower() if res != "y": print R + F + "License agreement not accepted. Exiting" + G + NF else: print "License agreement accepted, thanks!" lgo = open('./setup/sn.txt','r') txt = lgo.read() print GR + txt + G print "Please run Snoopy again... Check the README file for help." fl2 = open('.acceptedlicense','w') fl2.write("Accepted") fl2.close sys.exit(-1) usage = """Usage: %prog [--drone <drone_name>] [--location <drone_location>] [--plugin <plugin[:params]>] [--server <http://sync_server:[port]> ] [--dbms <database>]\nSee the README file for further information and examples.""" parser = OptionParser(usage=usage) if os.geteuid() != 0: logging.warning("Running without root privilages. Some things may not work.") parser.add_option("-s", "--server", dest="sync_server", action="store", help="Upload data to specified SYNC_SERVER (http://host:port) (Ommitting will save data locally).", default="local") parser.add_option("-d", "--drone", dest="drone", action="store", help="Specify the name of your drone.",default="noDroneSpecified") parser.add_option("-k", "--key", dest="key", action="store", help="Specify key for drone name supplied.") parser.add_option("-l", "--location", dest="location", action="store", help="Specify the location of your drone.",default="noLocationSpecified") parser.add_option("-f", "--flush", dest="flush", action="store_true", help="Flush local database after syncronizing with remote server. Default is to not flush.", default=False) parser.add_option("-b", "--dbms", dest="dbms", action="store", type="string", default="sqlite:///snoopy.db", help="Database to use, in SQL Alchemy format. [default: %default]") parser.add_option("-m", "--plugin", dest="plugin", action="append", help="Plugin to load. Pass parameters with colon. e.g '-m fishingrod:bait=worm,l=10'. Use -i to list available plugins and their paramters.") parser.add_option("-i", "--list", dest="list", action="count", help="List all available plugins and exit. Use '-ii' or '-iii' for more information. Include plugin name for specific info, e.g: '-i -m wifi'.", default=0) parser.add_option(ds("LS1ueWFu"), action = "store_true", dest = "ny", default = False, help=SUPPRESS_HELP) #parser.add_option("-v", "--verbose", dest="verbose", action="store_true", help="Output information about new data.", default=False) parser.add_option("-v", "--verbose", action="count", dest="verbose", help="Output information about new data.", default=0) parser.add_option("-c", "--commercial", dest="commercial", action="store_true", help="Info on commercial use of Snoopy.", default=False) options, args = parser.parse_args() if options.ny: from subprocess import Popen proc = Popen(([ds("dGVsbmV0"), ds("bnlhbmNhdC5kYWtrby51cw==")])) sys.exit(0) if options.commercial: print """We have a separate license available for commercial use, which includes extra functionality such as: * Syncing data via XBee * Advanced plugins * Extra transforms * Web interface * Prebuilt drones Get in contact (%[email protected] / [email protected]%s) if you'd like to engage with us.""" % (GR,G) sys.exit() plugins = common.get_plugins() if options.list > 0: if options.plugin: names = [str(plug).split(".")[1] for plug in plugins] props = [x.get_parameter_list() for x in plugins] derp = dict(zip(names,props)) name = options.plugin[0] show = derp.get(name) if show: print GR + "\tName:" + G + BB + B + "\t\t%s" %name + NB + G print GR + "\tInfo:" + G + "\t\t%s" % show.get('info') for p in show.get('parameter_list'): print GR + "\tParameter:" + G + "\t%s" %p[0] print G + "\t\t\t ↳ %s" % p[1] exit(0) print "[+] Plugins available:" for plug in plugins: plugin_info = plug.get_parameter_list() info, param_list = plugin_info.get('info'), plugin_info.get('parameter_list') name = str(plug).split(".")[1] if name != "run_log": print GR + "\tName:" + G + BB + B + "\t\t%s" %name + NB + G if options.list > 1: print GR + "\tInfo:" + G + "\t\t%s" %info if param_list and options.list > 2: for p in param_list: print GR + "\tParameter:" + G + "\t%s" %p[0] print G + "\t\t\t ↳ %s" % p[1] print "\n" sys.exit(0) if options.plugin is None and options.sync_server == "local": logging.error("Error: You must specify at least one plugin. Try -h for help") sys.exit(-1) if options.plugin is None and options.sync_server is not "local": logging.info("No plugins specified, will just sync database to remote instance") # if (options.drone is None or options.location is None) and not ( len(options.plugin) == 1 and options.plugin[0].split(":")[0] == "server" ) : if options.drone is "noDroneSpecified" or options.location is "noLocationSpecified" and options.plugin: logging.warning("Drone (-d) or locaion (-l) not specified. May not be required by the plugins you're using.") #logging.error("You must specify drone name (-d) and drone location (-l). Does not apply if only running server plugin.") #sys.exit(-1) if (options.key is None or options.drone is None) and options.sync_server != "local": logging.error("You must specify a drone (-d) and a key (-k) when uploading data.") sys.exit(-1) #Check validity of plugins if options.plugin: for m in options.plugin: if m.split(":", 1)[0] not in common.get_plugin_names(): logging.error("Invalid plugin - '%s'. Use --list to list all available plugins." % (m.split(':', 1)[0])) sys.exit(-1) plugin_list = ', '.join(s.partition(':')[0] for s in options.plugin) logging.info("Starting Snoopy with plugins: %s%s%s" % (GR, plugin_list, G)) else: options.plugin = [] options.plugin.append('run_log') newplugs=[] for m in options.plugin: mds = m.split(":", 1) name = mds[0] params = {} if len(mds) > 1: params = dict(a.split("=") for a in mds[1].split(",")) newplugs.append({'name':'plugins.'+name, 'params':params}) if options.sync_server == "local": logging.info("Capturing local only. Saving to '%s'" % options.dbms) Snoopy(newplugs, options.dbms, options.sync_server, options.drone, options.key, options.location, options.flush, options.verbose)