def test_narrow_skip_no_changelog(self): self.scanner.enumerate_file_hash = self.mock_xml(self.xml_file, "7.27") self.scanner.enumerate_version_changelog = m = MagicMock() self.scanner.vf = VersionsFile(self.xml_file) self.scanner.enumerate_version(self.base_url) assert not m.called self.scanner.vf = VersionsFile(self.xml_file_changelog) self.scanner.enumerate_version(self.base_url) assert m.called
def setUp(self): super(FingerprintTests, self).setUp() self.add_argv(['scan', 'drupal']) self.add_argv(['--method', 'forbidden']) self.add_argv(self.param_version) self._init_scanner() self.v = VersionsFile(self.xml_file)
def __init__(self, PluginClass=None): """ @param PluginClass: as returned by handler.list('controller'). Must extend BasePlugin. """ plugin = PluginClass() if plugin: self.name = plugin._meta.label if plugin.can_enumerate_plugins: self.plugins_can_enumerate = True self.plugins_wordlist_size = file_len(plugin.plugins_file) if plugin.can_enumerate_themes: self.themes_can_enumerate = True self.themes_wordlist_size = file_len(plugin.themes_file) if plugin.can_enumerate_interesting: self.interesting_can_enumerate = True self.interesting_url_size = len(plugin.interesting_urls) if plugin.can_enumerate_version: versions_file = VersionsFile(plugin.versions_file) self.version_can_enumerate = True hvm = versions_file.highest_version_major(plugin.update_majors) self.version_highest = ', '.join(hvm.values())
def test_files_get_all_chlg(self): changelog_file = 'CHANGELOG.txt' vf = VersionsFile(self.update_versions_xml) files = vf.files_get() files_all = vf.files_get_all() assert len(files) == len(files_all) - 1 assert changelog_file in files_all assert not changelog_file in files
def test_determines_version_similar(self): real_version = '6.15' self.scanner.enumerate_file_hash = self.mock_xml(self.xml_file, real_version) self.scanner.vf = VersionsFile(self.xml_file) returned_version, is_empty = self.scanner.enumerate_version(self.base_url) assert len(returned_version) == 2 assert real_version in returned_version assert is_empty == False
def test_determines_version(self): real_version = '7.26' self.scanner.enumerate_file_hash = self.mock_xml(self.xml_file, real_version) self.scanner.vf = VersionsFile(self.xml_file) version, is_empty = self.scanner.enumerate_version(self.base_url) assert version[0] == real_version assert is_empty == False
def test_narrow_down_changelog(self): mock_versions = ['7.26', '7.27', '7.28'] self.scanner.vf = VersionsFile(self.xml_file_changelog) self.scanner.enumerate_file_hash = self.mock_xml(self.xml_file_changelog, "7.27") result = self.scanner.enumerate_version_changelog(self.base_url, mock_versions) assert result == ['7.27']
def test_multiple_changelogs_or(self): mock_versions = ["8.0", "8.1", "8.2"] xml_multi_changelog = 'dscan/tests/resources/versions_multiple_changelog.xml' self.scanner.vf = VersionsFile(xml_multi_changelog) self.scanner.enumerate_file_hash = self.mock_xml(xml_multi_changelog, "8.0") result = self.scanner.enumerate_version_changelog(self.base_url, mock_versions) assert result == ["8.0"]
def test_narrow_down_ignore_incorrect_changelog(self): mock_versions = ['7.26', '7.27', '7.28'] v_changelog = VersionsFile(self.xml_file_changelog) self.scanner.enumerate_file_hash = self.mock_xml(self.xml_file_changelog, "7.22") result = self.scanner.enumerate_version_changelog(self.base_url, mock_versions, v_changelog) # Changelog is possibly outdated, can't rely on it. assert result == mock_versions
def _general_init(self, opts, out=None): """ Initializes a variety of variables depending on user input. @return: a tuple containing a boolean value indicating whether progressbars should be hidden, functionality and enabled functionality. """ self.session = Session() if out: self.out = out else: self.out = self._output(opts) is_cms_plugin = self._meta.label != "scan" # if self._meta.label == "drupal": # print("drupal") #sc.isVulnerable("http://68.183.237.96/", "8.2.3") if is_cms_plugin: self.vf = VersionsFile(self.versions_file) # http://stackoverflow.com/questions/23632794/in-requests-library-how-can-i-avoid-httpconnectionpool-is-full-discarding-con try: a = requests.adapters.HTTPAdapter(pool_maxsize=5000) self.session.mount('http://', a) self.session.mount('https://', a) self.session.cookies.set_policy(BlockAll()) except AttributeError: old_req = """Running a very old version of requests! Please `pip install -U requests`.""" self.out.warn(old_req) self.session.verify = False self.session.headers['User-Agent'] = self.DEFAULT_UA debug_requests = opts['debug_requests'] if debug_requests: hide_progressbar = True opts['threads_identify'] = 1 opts['threads_scan'] = 1 opts['threads_enumerate'] = 1 self.session = RequestsLogger(self.session) else: if opts['hide_progressbar']: hide_progressbar = True else: hide_progressbar = False functionality = self._functionality(opts) enabled_functionality = self._enabled_functionality(functionality, opts) return (hide_progressbar, functionality, enabled_functionality)
def get_vf(): global _vf if _vf: return _vf plugins = plugins_base_get() vf = {} for plugin in plugins: v = VersionsFile(dscan.PWD + "plugins/%s/versions.xml" % plugin.Meta.label) vf[plugin.Meta.label] = v _vf = vf return vf
def test_equal_number_per_major(self): """ Drupal fails hard after updating with auto updater of versions.xml This is because misc/tableheader.js had newer versions and not older versions of the 7.x branch. I've removed these manually, but if this is not auto fixed, then it opens up some extremely buggy-looking behaviour. So, in conclusion, each version should have the same number of files (as defined in versions.xml file) as all other versions in the same major branch. E.g. All drupal 7.x versions should reference 3 files. If one of them has more than 3, the detection algorithm will fail. """ fails = [] for xml_path in glob(dscan.PWD + 'plugins/*/versions.xml'): vf = VersionsFile(xml_path) controller_name = xml_path.split('/')[-2] controller = self.controller_get(controller_name) major_numbers = len(controller.update_majors[0].split('.')) fpvm = vf.files_per_version_major(major_numbers) number = 0 for major in fpvm: for version in fpvm[major]: nb = len(fpvm[major][version]) if number == 0: number = nb example_number = version if nb != number: msg = """All majors should have the same number of files, and version %s has %s, versus %s on other files (e.g. %s).""" % (version, nb, number, example_number) fails.append(" ".join(msg.split())) number = 0 if len(fails) > 0: for fail in fails: print(fail) assert False
def test_updates_changelog(self): weird_hash = '13371337133713371337133713371337' vf = VersionsFile(self.update_versions_xml) hashes = { '6.34': { 'misc/ajax.js': 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', 'CHANGELOG.txt': weird_hash, 'misc/drupal.js': 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', 'misc/tabledrag.js': 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' } } vf.update(hashes) out = vf.str_pretty() assert weird_hash in str(out)
def test_update_calls_plugin(self): md5 = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' files = ['misc/drupal.js', 'misc/tabledrag.js', 'misc/ajax.js'] self.mock_md5_file.return_value = md5 vf = VersionsFile(self.update_versions_xml) versions = ['7.34', '6.34'] ret_val = (self.gr, vf, versions) with patch('dscan.common.update_api.github_repo_new', return_value=ret_val, autospec=True) as m: fpv_before = vf.files_per_version() out = self.scanner.update_version() fpv_after = vf.files_per_version() assert len(fpv_before) == len(fpv_after) - len(versions) for v in versions: assert v in fpv_after assert fpv_after[v] == files
def test_version_has_changelog(self): v_with_changelog = VersionsFile(self.xml_file_changelog) assert not self.v.has_changelog() assert v_with_changelog.has_changelog()