def start(source,url,ua): cmseek.info('Starting passive theme enumeration') ## plug_file = open('database/themes.json', 'r') ## plug_data = plug_file.read() ## plug_json = json.loads(plug_data) plug_regex = re.compile('wp-content/themes/(.*?)/.*?[css|js].*?ver=([0-9\.]*)') results = plug_regex.findall(source) themes = [] found = 0 for result in results: # found += 1 name = result[0].replace('-master','').replace('.min','') nc = name + ":" if nc not in str(themes): version = result[1] each_theme = name + ":" + version + "|" # look if theme zip available cmseek.statement('Looking for theme zip file!') theme_zip = url + '/wp-content/themes/' + name + '.zip' zip_status = cmseek.check_url(theme_zip, ua) if zip_status == '1': cmseek.success('Current theme can be downloaded, URL: ' + cmseek.bold + theme_zip + cmseek.cln) each_theme += '/wp-content/themes/' + name + '.zip' themes.append(each_theme) themes = set(themes) found = len(themes) if found > 0: if found == 1: cmseek.success(cmseek.bold + cmseek.fgreen + str(found) + " theme detected!") else: cmseek.success(cmseek.bold + cmseek.fgreen + str(found) + " themes detected!") else: cmseek.error('Could not detect theme!') return [found, themes]
def start(source): cmseek.info('Starting passive plugin enumeration') plug_regex = re.compile( 'wp-content/plugins/(.*?)/.*?[css|js].*?ver=([0-9\.]*)') results = plug_regex.findall(source) plugins = [] found = 0 for result in results: # found += 1 name = result[0].replace('-master', '').replace('.min', '') nc = name + ":" if nc not in str(plugins): version = result[1] each_plugin = name + ":" + version plugins.append(each_plugin) plugins = set(plugins) found = len(plugins) if found > 0: if found == 1: cmseek.success(cmseek.bold + cmseek.fgreen + str(found) + " Plugin enumerated!") else: cmseek.success(cmseek.bold + cmseek.fgreen + str(found) + " Plugins enumerated!") else: cmseek.error('No plugins enumerated!') return [found, plugins]
def start(source): cmseek.info('Starting passive theme enumeration') ## plug_file = open('database/themes.json', 'r') ## plug_data = plug_file.read() ## plug_json = json.loads(plug_data) plug_regex = re.compile( 'wp-content/themes/(.*?)/.*?[css|js].*?ver=([0-9\.]*)') results = plug_regex.findall(source) themes = [] found = 0 for result in results: # found += 1 name = result[0].replace('-master', '').replace('.min', '') nc = name + ":" if nc not in str(themes): version = result[1] each_theme = name + ":" + version themes.append(each_theme) themes = set(themes) found = len(themes) if found > 0: if found == 1: cmseek.success(cmseek.bold + cmseek.fgreen + str(found) + " theme detected!") else: cmseek.success(cmseek.bold + cmseek.fgreen + str(found) + " themes detected!") else: cmseek.error('Could not detect theme!') return [found, themes]
def start(id, url, ua, ga, source): if ga == '1': # well for now we only have one way of detecting the version - Not any more! cmseek.statement( 'Detecting version using generator meta tag [Method 1 of 2]') regex = re.findall( r'<meta name="Generator" content="Drupal (.*?) \(http(s|):\/\/(www\.|)drupal.org\)"', source) if regex != []: cmseek.success('Drupal version ' + cmseek.bold + regex[0][0] + cmseek.cln + ' detected') return regex[0][0] else: # Detect version via CHANGELOG.txt (not very accurate) cmseek.statement( 'Detecting version using CHANGELOG.txt [Method 2 of 2]') changelog = url + '/CHANGELOG.txt' changelog_source = cmseek.getsource(changelog, ua) if changelog_source[0] == '1' and 'Drupal' in changelog_source[1]: cl_array = changelog_source[1].split('\n') for line in cl_array: match = re.findall(r'Drupal (.*?),', line) if match != []: cmseek.success('Drupal version ' + cmseek.bold + match[0] + cmseek.cln + ' detected') return match[0] cmseek.error('Drupal version detection failed!') return '0' else: cmseek.error('Drupal version detection failed!') return '0' return '0'
def check(url, ua): robots = url + '/robots.txt' robots_source = cmseek.getsource(robots, ua) if robots_source[0] == '1' and robots_source[1] != '': # Check begins here robotstr = robots_source[1] if 'If the Joomla site is installed' in robotstr or 'Disallow: /administrator/' in robotstr: return ['1', 'joom'] if 'Allow: /core/*.css$' in robotstr or 'Disallow: /index.php/user/login/' in robotstr or 'Disallow: /web.config' in robotstr: return ['1', 'dru'] if 'Disallow: /wp-admin/' in robotstr or 'Allow: /wp-admin/admin-ajax.php' in robotstr: return ['1', 'wp'] if 'Disallow: /kernel/' in robotstr and 'Disallow: /language/' in robotstr and 'Disallow: /templates_c/' in robotstr: return ['1', 'xoops'] if 'Disallow: /textpattern' in robotstr: return ['1', 'tpc'] if 'Disallow: /sitecore' in robotstr or 'Disallow: /sitecore_files' in robotstr or 'Disallow: /sitecore modules' in robotstr: return ['1', 'score'] t3_regex = re.search(r'Sitemap: http(.*?)\?type=', robotstr) if t3_regex != None: return ['1', 'tp3'] return ['0', ''] else: cmseek.error('robots.txt not found or empty!') return ['0', '']
def start(ga_content, header): cmseek.statement( 'Detecting ShopFA version using generator meta tag [Method 1 of 2]') regex = re.findall(r'ShopFA (.*)', ga_content) if regex != []: version = regex[0] cmseek.success('ShopFA version ' + cmseek.bold + cmseek.fgreen + version + cmseek.cln + ' detected') return version else: cmseek.statement( 'Detecting ShopFA version using HTTP Headers [Method 2 of 2]') headers = header.split('\n') regex = [] for h in headers: if 'X-Powered-By: ShopFA' in h: regex = re.findall(r'X-Powered-By: ShopFA (.*)', h) if regex != []: version = regex[0] cmseek.success('ShopFA version ' + cmseek.bold + cmseek.fgreen + version + cmseek.cln + ' detected') return version else: cmseek.error('Version detection failed!') return '0'
def start(version, ua): if version == "0": cmseek.warning( "Skipping version vulnerability scan as WordPress Version wasn't detected" ) wpvdbres = '0' # fix for issue #3 result = "" vfc = "" else: ## So we have a version let's scan for vulnerabilities cmseek.info( "Checking version vulnerabilities [props to wpvulndb for their awesome api ;)]" ) vfc = version.replace( '.', '' ) # NOT IMPORTANT: vfc = version for check well we have to kill all the .s in the version for looking it up on wpvulndb.. kinda weird if you ask me ws = cmseek.getsource("https://wpvulndb.com/api/v2/wordpresses/" + vfc, ua) print(ws[0]) if ws[0] == "1": # wjson = json.loads(ws[1]) + vfd + "['release_date']" wpvdbres = '1' ## We have the wpvulndb results result = json.loads(ws[1])[version] else: wpvdbres = '0' result = "" cmseek.error('Error Retriving data from wpvulndb') return [wpvdbres, result, vfc]
def start(headers, url, ua, temp_src=''): cmseek.statement('Detecting Umbraco using headers [Method 1 of 2]') header = headers.split('\n') regex = [] for tail in header: if 'x-umbraco-version:' in tail.lower(): regex = re.findall(r'X-Umbraco-Version: (.*)', tail, re.IGNORECASE) if regex != [] and regex[0] != "": # detection via headers successful cmseek.success('Umbraco version ' + cmseek.bold + cmseek.fgreen + regex[0] + cmseek.cln + ' detected') return regex[0] else: cmseek.statement('Detecting Umbraco using source code [Method 2 of 2]') if temp_src == '': # no additional source code sent so we have to get it temp_url = url + '/umbraco' temp_src = cmseek.getsource(temp_url, ua) if temp_src[0] == '1': temp_src = temp_src[1] else: cmseek.error('Version detection failed!') return '0' new_regex = re.findall('"version"\: "(.*?)"', temp_src) if new_regex != [] and new_regex[0] != "": # detection via headers successful cmseek.success('Umbraco version ' + cmseek.bold + cmseek.fgreen + new_regex[0] + cmseek.cln + ' detected') return new_regex[0] else: cmseek.error('Version detection failed!') return '0'
def start(source, url, ua): regex = re.findall(r'<!--.*-->', source, re.DOTALL) if regex != []: for r in regex: if 'FlexCMP' in r and 'v.' in r: tmp = r.split('\n') for t in tmp: if 'v.' in t: kek = re.findall(r'v. (.*?) -', t) if kek != []: # coding this was actually fun idk why ;--; version = kek[0] cmseek.success('FlexCMP version ' + cmseek.bold + cmseek.fgreen + version + cmseek.cln + ' detected from source') return version else: kurama = cmseek.getsource(url, ua) header = kurama[2].split('\n') regex = [] for tail in header: if 'X-Powered-By' in tail and 'FlexCMP' in tail: regex = re.findall( r'X-Powered-By: FlexCMP Application Server \[v\. (.*?) - ', tail) if regex != []: cmseek.success('FlexCMP version ' + cmseek.bold + cmseek.fgreen + regex[0] + cmseek.cln + ' detected from header') return regex[0] else: cmseek.error('Version detection failed!') return '0'
def start(source): regex = re.search(r'Powered by(.*?)YaBB (\d.*?)( |</a>)', source, re.DOTALL) if regex != None: try: version = regex.group(2) cmseek.success('YaBB version ' + cmseek.bold + cmseek.fgreen + version + cmseek.cln + ' detected') return version except Exception as e: regex = re.findall(r'<!-- YaBB (\d.*?) ', source) if regex != []: if regex[0] != '' and regex[0] != ' ': version = regex[0] cmseek.success('YaBB version ' + cmseek.bold + cmseek.fgreen + version + cmseek.cln + ' detected') return version else: regex = re.findall(r'<!-- YaBB (\d.*?) ', source) if regex != []: if regex[0] != '' and regex[0] != ' ': version = regex[0] cmseek.success('YaBB version ' + cmseek.bold + cmseek.fgreen + version + cmseek.cln + ' detected') return version cmseek.error('Version detection failed!') return '0'
def start(id, url, ua, ga, source): version = '0' cmseek.statement('Detecting Version and vulnerabilities') if ga == '1' or ga == '2' or ga == '3': ## something good was going to happen but my sleep messed it up TODO: will fix it later cmseek.statement('Generator Tag Available... Trying version detection using generator meta tag') rr = re.findall(r'<meta name=\"generator\" content=\"WordPress (.*?)\"', source) if rr != []: version = rr[0] cmseek.success(cmseek.bold + cmseek.fgreen + "Version Detected, WordPress Version %s" % version + cmseek.cln) else: cmseek.warning("Generator tag was a big failure.. looking up /feed/") fs = cmseek.getsource(url + '/feed/', ua) if fs[0] != '1': # Something messed up real bad cmseek.warning("Couldn't get feed source code, Error: %s" % fs[1]) else: fv = re.findall(r'<generator>https://wordpress.org/\?v=(.*?)</generator>', fs[1]) if fv != []: # Not empty good news xD version = fv[0] cmseek.success(cmseek.bold + cmseek.fgreen + "Version Detected, WordPress Version %s" % version + cmseek.cln) else: cmseek.warning("Well even feed was a failure... let's lookup wp-links-opml then") opmls = cmseek.getsource(url + '/wp-links-opml.php', ua) if opmls[0] != '1': # Something messed up real bad cmseek.warning("Couldn't get wp-links-links source code, Error: %s" % opmls[1]) else: fv = re.findall(r'generator=\"wordpress/(.*?)\"', opmls[1]) if fv != []: # Not empty good news xD || you can guess it's copied right? version = fv[0] cmseek.success(cmseek.bold + cmseek.fgreen + "Version Detected, WordPress Version %s" % version + cmseek.cln) else: ## new version detection methods will be added in the future updates cmseek.error("Couldn't Detect Version") #sorry master thingy removed... sounded kinda cheesy -_- version = '0' return version
def start(ga_content): regex = re.findall(r'XpressEngine (.*)', ga_content) if regex != []: cmseek.success('XpressEngine version ' + cmseek.bold + cmseek.fgreen + regex[0] + cmseek.cln + ' detected') return regex[0] else: cmseek.error('Version detection failed!') return '0'
def start(ga_content): regex = re.findall(r'Contensis CMS Version (.*)', ga_content) if regex != []: version = regex[0] cmseek.success('Contensis CMS version ' + cmseek.bold + cmseek.fgreen + version + cmseek.cln + ' detected') return version else: cmseek.error('Version detection failed!') return '0'
def start(source): regex = re.findall(r'Powered By AEF (\d.*?)</a>', source) if regex != []: if regex[0] != '' and regex[0] != ' ': version = regex[0] cmseek.success('AEF version ' + cmseek.bold + cmseek.fgreen + version + cmseek.cln + ' detected') return version cmseek.error('Version detection failed!') return '0'
def start(ga_content): ga_content = ga_content.lower() regex = re.findall(r'sitefinity (.*)', ga_content) if regex != []: version = regex[0] cmseek.success('Sitefinity version ' + cmseek.bold + cmseek.fgreen + version + cmseek.cln + ' detected') return version else: cmseek.error('Version detection failed!') return '0'
def start(source): regex = re.findall(r'Published by Seamless.CMS.WebUI, (.*?) -->', source) if regex != []: version = regex[0] cmseek.success('SeamlessCMS version ' + cmseek.bold + cmseek.fgreen + version + cmseek.cln + ' detected') return version else: cmseek.error('Version detection failed!') return '0'
def start(ga_content): cmseek.statement('Detecting RBS Change version using generator meta tag [Method 1 of 1]') regex = re.findall(r'RBS Change (.*)', ga_content) if regex != []: version = regex[0] cmseek.success('RBS Change version ' + cmseek.bold + cmseek.fgreen + version + cmseek.cln + ' detected') return version else: cmseek.error('Version detection failed!') return '0'
def start(ga_content): ga_content = ga_content.lower() regex = re.findall(r'impresspages cms (.*?) under', ga_content) if regex != []: version = regex[0] cmseek.success('ImpressPages version ' + cmseek.bold + cmseek.fgreen + version + cmseek.cln + ' detected') return version else: cmseek.error('Version detection failed!') return '0'
def start(source): regex = re.findall(r'<strong>Burning Board® (.*?)</strong>', source) if regex != []: if regex[0] != '' and regex[0] != ' ': version = regex[0] cmseek.success('Burning Board version ' + cmseek.bold + cmseek.fgreen + version + cmseek.cln + ' detected') return version cmseek.error('Version detection failed!') return '0'
def start(source): cmseek.statement("Detecting Al Mubda version using source code [Method 1 of 1]") regex = re.findall(r'Powered by Al Mubda version (\d.*?)</a>', source) if regex != []: if regex[0] != '' and regex[0] != ' ': version = regex[0] cmseek.success('Al Mubda version ' + cmseek.bold + cmseek.fgreen + version + cmseek.cln + ' detected') return version cmseek.error('Version detection failed!') return '0'
def check(url, ua): robots = url + '/robots.txt' robots_source = cmseek.getsource(robots, ua) # print(robots_source[1]) if robots_source[0] == '1' and robots_source[1] != '': # Check begins here robotstr = robots_source[1] if 'If the Joomla site is installed' in robotstr or 'Disallow: /administrator/' in robotstr: return ['1', 'joom'] if 'Allow: /core/*.css$' in robotstr or 'Disallow: /index.php/user/login/' in robotstr or 'Disallow: /web.config' in robotstr: return ['1', 'dru'] if 'Disallow: /wp-admin/' in robotstr or 'Allow: /wp-admin/admin-ajax.php' in robotstr: return ['1', 'wp'] if 'Disallow: /kernel/' in robotstr and 'Disallow: /language/' in robotstr and 'Disallow: /templates_c/' in robotstr: return ['1', 'xoops'] if 'Disallow: /textpattern' in robotstr: return ['1', 'tpc'] if 'Disallow: /sitecore' in robotstr or 'Disallow: /sitecore_files' in robotstr or 'Disallow: /sitecore modules' in robotstr: return ['1', 'score'] if 'Disallow: /phpcms' in robotstr or 'robots.txt for PHPCMS' in robotstr: return ['1', 'phpc'] if 'Disallow: /*mt-content*' in robotstr or 'Disallow: /mt-includes/' in robotstr: return ['1', 'moto'] if 'Disallow: /jcmsplugin/' in robotstr: return ['1', 'jcms'] if 'Disallow: /ip_cms/' in robotstr or 'ip_backend_frames.php' in robotstr or 'ip_backend_worker.php' in robotstr: return ['1', 'impage'] if 'Disallow: /flex/tmp/' in robotstr or 'flex/Logs/' in robotstr: return ['1', 'flex'] if 'Disallow: /e107_admin/' in robotstr or 'e107_handlers' in robotstr or 'e107_files/cache' in robotstr: return ['1', 'e107'] t3_regex = re.search(r'Sitemap: http(.*?)\?type=', robotstr) if t3_regex != None: return ['1', 'tp3'] return ['0', ''] else: cmseek.error('robots.txt not found or empty!') return ['0', '']
def start(url, ua): kurama = cmseek.getsource(url, ua) header = kurama[2].split('\n') regex = [] for tail in header: if 'MicrosoftSharePointTeamServices' in tail: regex = re.findall(r'MicrosoftSharePointTeamServices: (.*)', tail) if regex != []: cmseek.success('SharePoint version ' + cmseek.bold + cmseek.fgreen + regex[0] + cmseek.cln + ' detected') return regex[0] else: cmseek.error('Version detection failed!') return '0'
def start(url, ua): kurama = cmseek.getsource(url, ua) # was listening to https://soundcloud.com/ahmed-a-zidan/naruto-sad-music no better came to mind header = kurama[2].split('\n') regex = [] for tail in header: if 'X-CMS-Version' in tail: regex = re.findall(r'X-CMS-Version: (.*)', tail) if regex != []: cmseek.success('UMI.CMS version ' + cmseek.bold + cmseek.fgreen + regex[0] + cmseek.cln + ' detected') return regex[0] else: cmseek.error('Version detection failed!') return '0'
def start(source): cmseek.statement( 'Detecting Amiro.CMS version using page source [Method 1 of 1]') regex = re.findall(r'_cv=(.*?)("|&|\')', source)[0] if regex != []: if regex[0] != '' and regex[0] != ' ': version = regex[0] cmseek.success('Amiro.CMS version ' + cmseek.bold + cmseek.fgreen + version + cmseek.cln + ' detected') return version cmseek.error('Version detection failed!') return '0'
def start(source): regex = re.search(r'MercuryBoard(.*?)\[v(\d.*?)\]', source) if regex != None: try: version = regex.group(2) cmseek.success('MercuryBoard version ' + cmseek.bold + cmseek.fgreen + version + cmseek.cln + ' detected') return version except Exception as e: cmseek.error('Version detection failed!') return '0' cmseek.error('Version detection failed!') return '0'
def start(url, ua): kurama = cmseek.getsource(url, ua) header = kurama[2].split('\n') regex = [] for tail in header: if 'Server' in tail and 'OpenCms' in tail: regex = re.findall(r'Server: OpenCms/(.*)', tail) if regex != []: cmseek.success('OpenCms version ' + cmseek.bold + cmseek.fgreen + regex[0] + cmseek.cln + ' detected') return regex[0] else: cmseek.error('Version detection failed!') return '0'
def start(source): regex = re.search(r'Powered by(.*?)JForum (\d.*?)</a>', source) if regex != None: try: version = regex.group(2) cmseek.success('JForum version ' + cmseek.bold + cmseek.fgreen + version + cmseek.cln + ' detected') return version except Exception as e: cmseek.error('Version detection failed!') return '0' cmseek.error('Version detection failed!') return '0'
def start(url, ua): kurama = cmseek.getsource(url, ua) header = kurama[2].split('\n') regex = [] for tail in header: if 'X-Powered-By: CMS Danneo' in tail: regex = re.findall(r'X-Powered-By: CMS Danneo (.*)', tail) if regex != []: cmseek.success('Danneo CMS version ' + cmseek.bold + cmseek.fgreen + regex[0] + cmseek.cln + ' detected') return regex[0] else: cmseek.error('Version detection failed!') return '0'
def init(cmseek_dir, report_dir=""): ''' Creates/Updates result index Needed Parameters: cmseek_dir = CMSeeK directory / access_directory report_dir = path to report directory leave empty if default ''' # Create a json list of all the sites scanned and save it to <cmseek_dir>/reports.json cmseek.info('Updating CMSeeK result index...') if os.path.isdir(cmseek_dir): index_file = os.path.join(cmseek_dir, 'reports.json') if report_dir == "": report_dir = os.path.join(cmseek_dir, 'Result') if os.path.isdir(report_dir): result_index = {} result_dirs = os.listdir(report_dir) for result_dir in result_dirs: scan_file = os.path.join(report_dir, result_dir, 'cms.json') if os.path.isfile(scan_file): try: with open(scan_file, 'r', encoding='utf8') as sf: scan_content = json.loads(sf.read()) scan_url = scan_content['url'] result_index[scan_url] = { "cms_id": scan_content['cms_id'], "date": scan_content['last_scanned'], "report": scan_file } except Exception as e: logging.error(traceback.format_exc()) cmseek.statement('Skipping invalid CMSeeK result: ' + scan_file) # Write index result_index = { "last_updated": str(datetime.datetime.now()), "results": [result_index] } inf = open(index_file, 'w+') inf.write(json.dumps(result_index, sort_keys=False, indent=4)) inf.close() cmseek.success('Report index updated successfully!') cmseek.report_index = result_index return ['1', 'Report index updated successfully!'] else: cmseek.error('Result directory does not exist!') return [0, 'Result directory does not exist'] else: cmseek.error('Invalid CMSeeK directory passed!') return [0, 'CMSeeK directory does not exist']
def start(url, ua): kurama = cmseek.getsource(url, ua) header = kurama[2].split('\n') regex = [] for tail in header: if 'X-Garden-Version: Vanilla' in tail: regex = re.findall(r'X-Garden-Version: Vanilla (\d.*)', tail) if regex != []: cmseek.success('Vanilla version ' + cmseek.bold + cmseek.fgreen + regex[0] + cmseek.cln + ' detected') return regex[0] else: cmseek.error('Version detection failed!') return '0'