def save(self, file_name=''): """ Saves the profile to file_name. :return: None """ if not self.profile_file_name: if not file_name: raise BaseFrameworkException('Error saving profile, profile' ' file name is required.') else: # The user's specified a file_name! if not file_name.endswith(self.EXTENSION): file_name += self.EXTENSION if os.path.sep not in file_name: file_name = os.path.join(get_home_dir(), 'profiles', file_name) self.profile_file_name = file_name try: file_handler = open(self.profile_file_name, 'w') except: msg = 'Failed to open profile file: "%s"' raise BaseFrameworkException(msg % self.profile_file_name) else: self._config.write(file_handler)
def _gen_url_to_include(self, file_content, extension): """ Generate the URL to include, based on the configuration it will return a URL pointing to a XSS bug, or our local webserver. """ if self._use_XSS_vuln and self._xss_vuln: mutant = self._xss_vuln.get_mutant() mutant = mutant.copy() mutant.set_token_value(file_content) return mutant.get_uri().url_string else: # Write the php to the webroot filename = rand_alnum() filepath = os.path.join(get_home_dir(), 'webroot', filename) try: file_handler = open(filepath, 'w') file_handler.write(file_content) file_handler.close() except: raise BaseFrameworkException( 'Could not create file in webroot.') else: url_to_include = 'http://%s:%s/%s' % ( self._listen_address, self._listen_port, filename) return url_to_include
def _rm_file(self, url_to_include): """ Remove the file from the web root. PLEASE NOTE: This is duplicated code!! see the same note above. """ # Remove the file filename = url_to_include.split('/')[-1:][0] os.remove(os.path.join(get_home_dir(), 'webroot', filename))
def _rm_file(self, url_to_include): """ Remove the file in the webroot. PLEASE NOTE: This is duplicated code!! see the same note below. """ if not self._use_XSS_vuln: # Remove the file filename = url_to_include.split('/')[-1:][0] os.remove(os.path.join(get_home_dir(), 'webroot', filename))
def analyze_disk_space(self, *args): # Don't measure disk usage each time we get called, in some platforms # it's expensive to call disk_usage current_time = time() if current_time - self.last_call < self.ANALYZE_EVERY: return self.last_call = current_time # Get the disk usage, ignore any errors try: usage = disk_usage(get_home_dir()) except: return # Raise an exception if there is no enough space if usage.free < self.MIN_FREE_BYTES: free_mb = usage.free / 1024 / 1024 msg = self.LOW_DISK_SPACE_MESSAGE % (get_home_dir(), free_mb) raise IOError(errno.ENOSPC, msg)
def can_exploit(self, vuln_to_exploit=None): """ Searches the kb for vulnerabilities that this plugin can exploit, this is overloaded from AttackPlugin because I need to test for xss vulns also. This is a "complex" plugin. :param vuln_to_exploit: The id of the vulnerability to exploit. :return: True if plugin knows how to exploit a found vuln. """ if not self._listen_address and not self._use_XSS_vuln: msg = 'You need to specify a local IP address where w3af can bind'\ ' an HTTP server that can be reached by the vulnerable Web'\ ' application.' om.out.error(msg) return False rfi_vulns = kb.kb.get('rfi', 'rfi') if vuln_to_exploit is not None: rfi_vulns = [v for v in rfi_vulns if v.get_id() == vuln_to_exploit] if not rfi_vulns: return False # # Ok, I have the RFI vulnerability to exploit, but... is the # plugin configured in such a way that exploitation is possible? # usable_xss = False if self._use_XSS_vuln: usable_xss = self._verify_xss_vuln() # Using the good old webserver (if properly configured) if not self._listen_address and not usable_xss: msg = 'You need to specify a local IP address where w3af can'\ ' bind an HTTP server that can be reached by the'\ ' vulnerable Web application.' om.out.error(msg) return False if self._listen_address and self._listen_port: # Start local webserver, raise an exception if something # fails webroot_path = os.path.join(get_home_dir(), 'webroot') try: webserver.start_webserver(self._listen_address, self._listen_port, webroot_path) except socket.error, se: msg = 'Failed to start the local web server to exploit the'\ ' RFI vulnerability, the exception was: "%s".' om.out.error(msg % se) return False
class TestStartUpConfig(unittest.TestCase): CFG_FILE = os.path.join(get_home_dir(), 'unittest-startup.conf') def tearDown(self): try: os.unlink(self.CFG_FILE) except: pass def test_save(self): scfg = StartUpConfig(self.CFG_FILE) scfg.last_upd = date.today() scfg.accepted_disclaimer = True scfg.last_commit_id = '3f4808082c1943f964669af1a1c94245bab09c61' scfg.save() def test_load_not_exist(self): """ This is a test to verify that the defaults are loaded when the file does not exist. """ scfg = StartUpConfig('foo.conf') self.assertEqual(scfg.last_upd, date.today() - timedelta(days=31)) self.assertEqual(scfg.accepted_disclaimer, False) self.assertEqual(scfg.last_commit_id, '') self.assertEqual(scfg.freq, 'D') def test_load_file_exists(self): """This is a test to verify that the things we saved were persited in the actual file. """ # Save scfg = StartUpConfig(self.CFG_FILE) scfg.last_upd = date.today() scfg.accepted_disclaimer = True scfg.last_commit_id = '3f4808082c1943f964669af1a1c94245bab09c61' scfg.save() # Load scfg = StartUpConfig(self.CFG_FILE) self.assertEqual(scfg.last_upd, date.today()) self.assertEqual(scfg.accepted_disclaimer, True) self.assertEqual(scfg.last_commit_id, '3f4808082c1943f964669af1a1c94245bab09c61') self.assertEqual(scfg.freq, 'D')
def get_profile_paths(self, workdir): """ :param workdir: The working directory :yield: The directories where we might find profiles """ if workdir is not None: if os.path.exists(workdir): yield workdir profile_path = os.path.join(workdir, 'profiles') if os.path.exists(profile_path): yield profile_path profile_path = os.path.join(get_home_dir(), 'profiles') if os.path.exists(profile_path): yield profile_path
def __init__(self, mainwin, w3af): super(PluginConfigBody, self).__init__() self.w3af = w3af targetbox = gtk.HBox() # label lab = gtk.Label(_("Target:")) targetbox.pack_start(lab, expand=False, fill=False, padding=5) # entry histfile = os.path.join(get_home_dir(), "urlhistory.pkl") hint = _("http://target.example/") self.target = entries.ValidatedAdvisedEntry( hint, mainwin.scanok.change, histfile, alertmodif=mainwin.profile_changed) self.target.connect("activate", mainwin._scan_director) self.target.connect("activate", self.target.insert_url) targetbox.pack_start(self.target, expand=True, fill=True, padding=5) # start/stop button startstop = entries.SemiStockButton(_("Start"), gtk.STOCK_MEDIA_PLAY, _("Start scan")) startstop.set_sensitive(False) startstop.connect("clicked", mainwin._scan_director) startstop.connect("clicked", self.target.insert_url) mainwin.startstopbtns.addWidget(startstop) targetbox.pack_start(startstop, expand=False, fill=False, padding=5) # advanced config advbut = entries.SemiStockButton( "", gtk.STOCK_PREFERENCES, _("Advanced Target URL configuration")) advbut.connect("clicked", self._advanced_target) targetbox.pack_start(advbut, expand=False, fill=False, padding=5) targetbox.show_all() self.pack_start(targetbox, expand=False, fill=False) # the pan with all the configs self.pan = self._buildpan() self.pack_start(self.pan, padding=5) # key binding self.key_l = gtk.gdk.keyval_from_name("l") mainwin.window.connect("key-press-event", self._key) self.show()
def get_profile_list(self, directory=None): """ :param directory: The directory from which profiles are loaded :return: Two different lists: - One that contains the instances of the valid profiles that were loaded - One with the file names of the profiles that are invalid >>> path = '.' >>> p = CoreProfiles(None) >>> valid, invalid = p.get_profile_list(path) >>> valid_lower = [prof.get_name().lower() for prof in valid] >>> 'owasp_top10' in valid_lower True """ directory = directory or get_home_dir() profile_home = os.path.join(directory, 'profiles') str_profile_list = get_file_list(profile_home, extension=profile.EXTENSION) instance_list = [] invalid_profiles = [] for profile_name in str_profile_list: profile_filename = os.path.join(profile_home, profile_name + profile.EXTENSION) try: profile_instance = profile(profile_filename) except BaseFrameworkException: invalid_profiles.append(profile_filename) else: instance_list.append(profile_instance) return instance_list, invalid_profiles
""" settings.py Copyright 2006 Andres Riancho This file is part of w3af, http://w3af.org/ . w3af is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation version 2 of the License. w3af is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with w3af; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import os from w3af.core.controllers.misc.home_dir import get_home_dir # Global cache location CACHE_LOCATION = os.path.join(get_home_dir(), 'urllib2cache')
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with w3af; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import os import stat import errno import shutil from w3af.core.controllers.misc.home_dir import get_home_dir TEMP_DIR = os.path.join(get_home_dir(), 'tmp', str(os.getpid())) def get_temp_dir(): """ :return: The path where we should create the dir. """ return TEMP_DIR def create_temp_dir(): """ Create the temp directory for w3af to work inside. :return: A string that contains the temp directory to use, in Linux: "~/.w3af/tmp/<pid>"
class StartUpConfig(object): """ Wrapper class for ConfigParser.ConfigParser. Holds the configuration for the VersionMgr update/commit process """ CFG_FILE = os.path.join(get_home_dir(), 'startup.conf') ISO_DATE_FMT = '%Y-%m-%d' # Frequency constants FREQ_DAILY = 'D' # [D]aily FREQ_WEEKLY = 'W' # [W]eekly FREQ_MONTHLY = 'M' # [M]onthly # DEFAULT VALUES DEFAULTS = {'auto-update': 'true', 'frequency': 'D', 'last-update': 'None', 'last-commit': '', 'accepted-disclaimer': 'false', 'skip-dependencies-check': 'false',} def __init__(self, cfg_file=CFG_FILE): self._start_cfg_file = cfg_file self._start_section = 'STARTUP_CONFIG' self._config = ConfigParser.ConfigParser() configs = self._load_cfg() (self._autoupd, self._freq, self._lastupd, self._last_commit_id, self._accepted_disclaimer, self._skip_dependencies_check) = configs ### METHODS # def get_last_upd(self): """ Getter method. """ return self._lastupd def set_last_upd(self, datevalue): """ :param datevalue: datetime.date value """ self._lastupd = datevalue self._config.set(self._start_section, 'last-update', datevalue.isoformat()) def get_skip_dependencies_check(self): return self._skip_dependencies_check def get_accepted_disclaimer(self): return self._accepted_disclaimer def set_accepted_disclaimer(self, accepted_decision): """ :param datevalue: datetime.date value """ self._accepted_disclaimer = accepted_decision value = 'true' if accepted_decision else 'false' self._config.set(self._start_section, 'accepted-disclaimer', value) def get_last_commit_id(self): return self._last_commit_id def set_last_commit_id(self, commit_id): if not isinstance(commit_id, basestring): raise TypeError('Expected string got %s instead.' % type(commit_id)) self._last_commit_id = commit_id self._config.set(self._start_section, 'last-commit', self._last_commit_id) def get_freq(self): return self._freq def get_auto_upd(self): return self._autoupd def _get_bool_val(self, key, default=False): boolvals = {'false': 0, 'off': 0, 'no': 0, 'true': 1, 'on': 1, 'yes': 1} # pylint: disable=E1103 # E1103: Instance of '_Chainmap' has no 'lower' member # (but some types could not be inferred)", val = self._config.get(self._start_section, key, raw=True) val = bool(boolvals.get(val.lower(), default)) return val def _load_cfg(self): """ Loads configuration from config file. """ config = self._config startsection = self._start_section if not config.has_section(startsection): config.add_section(startsection) defaults = StartUpConfig.DEFAULTS for key in self.DEFAULTS: config.set(startsection, key, defaults[key]) # Read from file config.read(self._start_cfg_file) auto_upd = self._get_bool_val('auto-update') accepted_disclaimer = self._get_bool_val('accepted-disclaimer') skip_dependencies_check = self._get_bool_val('skip-dependencies-check') freq = config.get(startsection, 'frequency', raw=True).upper() if freq not in (StartUpConfig.FREQ_DAILY, StartUpConfig.FREQ_WEEKLY, StartUpConfig.FREQ_MONTHLY): freq = StartUpConfig.FREQ_DAILY lastupdstr = config.get(startsection, 'last-update', raw=True).upper() # Try to parse it try: lastupd = datetime.strptime(lastupdstr, self.ISO_DATE_FMT).date() except: # Provide default value that enforces the update to happen lastupd = date.today() - timedelta(days=31) try: lastrev = config.get(startsection, 'last-commit') except TypeError: lastrev = 0 return (auto_upd, freq, lastupd, lastrev, accepted_disclaimer, skip_dependencies_check) def save(self): """ Saves current values to cfg file """ with open(self._start_cfg_file, 'wb') as configfile: self._config.write(configfile) ### PROPERTIES # freq = property(get_freq) auto_upd = property(get_auto_upd) last_commit_id = property(get_last_commit_id, set_last_commit_id) accepted_disclaimer = property(get_accepted_disclaimer, set_accepted_disclaimer) last_upd = property(get_last_upd, set_last_upd)
def __init__(self, label=None): self.sections = {} self.options = {} if label: self.filename = os.path.join(get_home_dir(), label + '.cfg')
def __init__(self): ssl_dir = os.path.join(get_home_dir(), 'ssl') self.key_path = os.path.join(ssl_dir, 'w3af.key') self.cert_path = os.path.join(ssl_dir, 'w3af.crt') if not os.path.exists(ssl_dir): os.makedirs(ssl_dir)