Exemplo n.º 1
0
    def test_add_httpPostDataRequest(self):
        ds = disk_set()
        
        uri = url_object('http://w3af.org/?id=2')
        pdr1 = httpPostDataRequest(uri, method='GET', headers={'Referer': 'http://w3af.org/'})

        uri = url_object('http://w3af.org/?id=3')
        pdr2 = httpPostDataRequest(uri, method='GET', headers={'Referer': 'http://w3af.com/'})
        
        uri = url_object('http://w3af.org/?id=7')
        pdr3 = httpPostDataRequest(uri, method='FOO', headers={'Referer': 'http://w3af.com/'})
        
        ds.add( pdr1 )
        ds.add( pdr2 )
        ds.add( pdr2 )
        ds.add( pdr1 )
        
        self.assertEqual( ds[0] , pdr1)
        self.assertEqual( ds[1] , pdr2)
        self.assertFalse( pdr3 in ds )
        self.assertTrue( pdr2 in ds )
        self.assertEqual( len(ds) , 2)
        
        # This forces an internal change in the URL object
        pdr2.getURL().url_string
        self.assertTrue( pdr2 in ds )
Exemplo n.º 2
0
 def GET2POST( self, vuln ):
     '''
     This method changes a vulnerability mutant, so all the data that was sent in the query string,
     is now sent in the postData; of course, the HTTP method is also changed from GET to POST.
     '''
     vulnCopy = copy.deepcopy( vuln )
     mutant = vulnCopy.getMutant()
     
     #    Sometimes there is no mutant (php_sca).
     if mutant is None:
         return vulnCopy
     
     if mutant.getMethod() == 'POST':
         # No need to work !
         return vulnCopy
         
     else:
         pdr = httpPostDataRequest.httpPostDataRequest(
                                           mutant.getURL(),
                                           headers=mutant.getHeaders(),
                                           cookie=mutant.getCookie(),
                                           dc=mutant.getDc()
                                           )
         mutant.setFuzzableReq(pdr)
         return vulnCopy
Exemplo n.º 3
0
    def fastExploit(self):
        """
        Exploits a web app with [blind] sql injections vulns.
        The options are configured using the plugin options and setOptions() method.
        """
        om.out.debug("Starting sqlmap fastExploit.")
        om.out.console(SQLMAPCREATORS)

        if self._url is None or self._method is None or self._data is None or self._injvar is None:
            raise w3afException("You have to configure the plugin parameters")
        else:

            freq = None
            if self._method == "POST":
                freq = httpPostDataRequest.httpPostDataRequest()
            elif self._method == "GET":
                freq = httpQsRequest.httpQsRequest()
            else:
                raise w3afException("Method not supported.")

            freq.setURL(self._url)
            freq.setDc(urlParser.getQueryString("http://a/a.txt?" + self._data))
            freq.setHeaders({})

            bsql = blind_sqli_response_diff()
            bsql.setUrlOpener(self._urlOpener)
            bsql.setEqualLimit(self._equalLimit)
            bsql.setEquAlgorithm(self._equAlgorithm)

            vuln_obj = bsql.is_injectable(freq, self._injvar)
            if not vuln_obj:
                raise w3afException("Could not verify SQL injection " + str(vuln))
            else:
                om.out.console("SQL injection could be verified, trying to create the DB driver.")

                # Try to get a shell using all vuln
                msg = "Trying to exploit using vulnerability with id: " + str(vuln_obj.getId())
                msg += ". Please wait..."
                om.out.console(msg)
                shell_obj = self._generateShell(vuln_obj)
                if shell_obj is not None:
                    kb.kb.append(self, "shell", shell_obj)
                    return [shell_obj]

                raise w3afException("No exploitable vulnerabilities found.")
Exemplo n.º 4
0
 def fastExploit( self ):
     '''
     Exploits a web app with [blind] sql injections vulns.
     The options are configured using the plugin options and setOptions() method.
     '''
     om.out.debug( 'Starting sqlmap fastExploit.' )
     om.out.console( SQLMAPCREATORS )
     
     if self._url is None or self._method is None or self._data is None or self._injvar is None:
         raise w3afException('You have to configure the plugin parameters')
     else:
         
         freq = None
         if self._method == 'POST':
             freq = httpPostDataRequest.httpPostDataRequest()
         elif self._method == 'GET':
             freq = httpQsRequest.httpQsRequest()
         else:
             raise w3afException('Method not supported.')
         
         freq.setURL( self._url )
         freq.setDc( parse_qs( self._data ) )
         freq.setHeaders( {} )
         
         bsql = blind_sqli_response_diff()
         bsql.setUrlOpener( self._urlOpener )
         bsql.setEqualLimit( self._equalLimit )
         bsql.setEquAlgorithm( self._equAlgorithm )
         
         vuln_obj = bsql.is_injectable( freq, self._injvar )
         if not vuln_obj:
             raise w3afException('Could not verify SQL injection ' + str(vuln) )
         else:
             om.out.console('SQL injection could be verified, trying to create the DB driver.')
             
             # Try to get a shell using all vuln
             msg = 'Trying to exploit using vulnerability with id: ' + str( vuln_obj.getId() )
             msg += '. Please wait...'
             om.out.console( msg )
             shell_obj = self._generateShell( vuln_obj )
             if shell_obj is not None:
                 kb.kb.append( self, 'shell', shell_obj )
                 return [shell_obj, ]
                 
             raise w3afException('No exploitable vulnerabilities found.')
Exemplo n.º 5
0
    def fastExploit( self ):
        '''
        Exploits a web app with [blind] sql injections vulns.
        The options are configured using the plugin options and setOptions() method.
        '''
        om.out.debug( 'Starting sql_webshell fastExploit.' )
        
        if any(
             lambda attr: attr is None,
             (self._url, self._method, self._data, self._injvar)
             ):
            raise w3afException('You have to configure the plugin parameters')
        else:
            if self._method == 'POST':
                freq = httpPostDataRequest(self._url)
            elif self._method == 'GET':
                freq = HTTPQSRequest(self._url)
            else:
                raise w3afException('Method not supported.')
            
            freq.setDc(parse_qs(self._data))

            bsql = blind_sqli_response_diff(self._uri_opener)
            bsql.set_eq_limit(self._eq_limit)
            
            fake_mutants = createMutants(freq, [''], fuzzableParamList=[self._injvar,])
            for mutant in fake_mutants:            
                vuln_obj = bsql.is_injectable(mutant)
                if vuln_obj is not None:
                    om.out.console('SQL injection verified, trying to create the DB driver.')
                    
                    # Try to get a shell using all vuln
                    msg = 'Trying to exploit using vulnerability with id: ' + str(vuln_obj.getId())
                    msg += '. Please wait...'
                    om.out.console(msg)
                    shell_obj = self._generateShell(vuln_obj)
                    if shell_obj is not None:
                        kb.kb.append(self, 'shell', shell_obj)
                        return [shell_obj, ]
            else:    
                raise w3afException('No exploitable vulnerabilities found.')
def isExchangable( self, fuzzableRequest ):
    '''
    @parameter mutant: The mutant you want to test if sending using querystring or postdata is the same.
    @return: [True|False]
    '''
    if not ( isinstance( fuzzableRequest, httpQsRequest ) or isinstance( fuzzableRequest, httpPostDataRequest ) ) :
        return False
        
    # I get the mutant as it is
    response = self._sendMutant( fuzzableRequest, analyze=False )
    if fuzzableRequest.getMethod() == 'GET':
        # I have to create a httpPostDataRequest and set all the parameters to it.
        pdr = httpPostDataRequest()
        pdr.setURL( fuzzableRequest.getURL() )
        pdr.setDc( fuzzableRequest.getDc() )
        pdr.setHeaders( fuzzableRequest.getHeaders() )
        pdr.setCookie( fuzzableRequest.getCookie() )
        response2 = self._sendMutant( pdr, analyze=False )
        
        if response2.getBody() == response.getBody():
            return True
    
    elif fuzzableRequest.getMethod() == 'POST':
        # I have to create a httpQsRequest and set all the parameters to it.
        qsr = httpQsRequest()
        qsr.setURL( fuzzableRequest.getURL() )
        qsr.setDc( fuzzableRequest.getDc() )
        qsr.setHeaders( fuzzableRequest.getHeaders() )
        qsr.setCookie( fuzzableRequest.getCookie() )
        response2 = self._sendMutant( qsr, analyze=False )
        
        if response2.getBody() == response.getBody():
            return True 
    
    else:
        return False
Exemplo n.º 7
0
def createFuzzableRequests( httpResponse, request=None, add_self=True ):
    '''
    Generates the fuzzable requests based on an http response instance.
    
    @parameter httpResponse: An httpResponse instance.
    @parameter request: The HTTP request that generated the httpResponse
    @parameter add_self: If I should add the current HTTP request (@parameter request) to the result
    on not.
    
    @return: A list of fuzzable requests.
    '''
    res = []
    
    # query string
    url = httpResponse.getURL()
    QSObject = httpResponse.getURI().getQueryString()
    
    # Headers for all fuzzable requests created here:
    # And add the fuzzable headers to the dict
    headers = {}
    for header_name in cf.cf.getData('fuzzableHeaders' ):
        if header_name not in headers:
            headers[ header_name ] = ''
    
    # Get the cookie!
    cookieObj = _createCookie( httpResponse )
    
    #
    # create the fuzzable request that represents the request object passed as parameter
    #
    if add_self:
        self_headers = {}
        if request:
            self_headers = request.getHeaders()
        for header_name in cf.cf.getData('fuzzableHeaders' ):
            if header_name not in headers:
                self_headers[ header_name ] = ''

        qsr = httpQsRequest.httpQsRequest()
        qsr.setURL( url )
        qsr.setDc( QSObject )
        qsr.setHeaders( self_headers )
        qsr.setCookie( cookieObj )
        res.append( qsr )
    
    # Try to find forms in the document
    form_list = []
    try:
        dp = dpCache.dpc.getDocumentParserFor( httpResponse )
    except w3afException:
        # Failed to find a suitable parser for the document
        pass
    else:
        form_list = dp.getForms()
    
    if not form_list:
        
        # Check if its a wsdl file
        wsdlp = wsdlParser.wsdlParser()
        try:
            wsdlp.setWsdl( httpResponse.getBody() )
        except w3afException:
            pass
        else:
            webServiceList = wsdlp.getMethods()
            if len( webServiceList ) != 0:
                for remoteMethod in webServiceList:
                    wspdr = wsPostDataRequest.wsPostDataRequest()
                    wspdr.setURL( remoteMethod.getLocation() )
                    wspdr.setAction( remoteMethod.getAction() )
                    wspdr.setParameters( remoteMethod.getParameters() )
                    wspdr.setNS( remoteMethod.getNamespace() )
                    wspdr.setMethodName( remoteMethod.getMethodName() )
                    wspdr.setHeaders( headers )
                    res.append( wspdr )     
        
    else:
        # create one httpPostDataRequest for each form variant
        mode = cf.cf.getData('fuzzFormComboValues')
        for form in form_list:
            for variant in form.getVariants(mode):
                if form.getMethod().upper() == 'POST':
                    r = httpPostDataRequest.httpPostDataRequest()
                    r.setMethod(variant.getMethod())
                    r.setFileVariables(form.getFileVariables())
                else:
                    # The default is a GET request
                    r = httpQsRequest.httpQsRequest()
                r.setURL(variant.getAction())
                r.setDc(variant)
                r.setHeaders(headers)
                r.setCookie(cookieObj)
                res.append(r)
    return res
Exemplo n.º 8
0
def createFuzzableRequestRaw(method, url, postData, headers):
    '''
    Creates a fuzzable request based on a query sent FROM the browser. This is used in
    plugins like spiderMan.
    
    @parameter method: A string that represents the method ('GET', 'POST', etc)
    @parameter url: An url_object that represents the URL
    @parameter postData: A string that represents the postdata, if its a GET request, set to None.
    @parameter headers: A dict that holds the headers
    '''
    if not isinstance(url, url_object):
        msg = 'The "url" parameter of createFuzzableRequestRaw @ frFactory'
        msg += ' must be of urlParser.url_object type.'
        raise ValueError( msg )

    
    #
    # Just a query string request ! no postdata
    #
    if not postData:
        qsr = httpQsRequest.httpQsRequest()
        qsr.setURL(url)
        qsr.setMethod(method)
        qsr.setHeaders(headers)
        dc = url.getQueryString()
        qsr.setDc(dc)
        return qsr
    #
    # Seems to be something that has post data
    #
    pdr = httpPostDataRequest.httpPostDataRequest()
    pdr.setURL(url)
    pdr.setMethod(method)
    for header_name in headers.keys():
        if header_name.lower() == 'content-length':
            del headers[header_name]
    pdr.setHeaders(headers)
    #
    #   Parse the content
    #   Case #1, multipart form data
    #
    conttype = headers.get('content-type', '')
    if conttype and conttype.startswith('multipart/form-data'):
        tmp, pdict = cgi.parse_header(conttype)
        try:
            dc = cgi.parse_multipart(StringIO(postData), pdict)
        except:
            om.out.debug('Multipart form data is invalid, the browser sent something weird.')
        else:
            resultDc = queryString()
            for i in dc.keys():
                resultDc[i] = dc[i]
            # We process multipart requests as x-www-form-urlencoded
            # TODO We need native support of multipart requests!
            headers['content-type'] = 'application/x-www-form-urlencoded'
            pdr.setDc(resultDc)
            pdr.setHeaders(headers)
            return pdr
    #
    #   Case #2, JSON request
    #
    try:
        dc = json.loads(postData)
    except:
        pass
    else:
        # It's json! welcome to the party dude!
        pdr = jsonPostDataRequest.jsonPostDataRequest()
        pdr.setURL(url)
        pdr.setMethod(method)
        pdr.setHeaders(headers)
        pdr.setDc(dc)
        return pdr
    #
    #   Case #3, XMLRPC request
    #
    postDataLower = postData.lower()
    stopWords = [
            '<methodcall>',
            '<methodname>',
            '<params>',
            '</methodcall>',
            '</methodname>',
            '</params>'
            ]
    allStopWords = True
    for word in stopWords:
        if word not in postDataLower:
            allStopWords = False
    if allStopWords:
        xmlrpc_request = xmlrpcRequest.xmlrpcRequest(postData)
        xmlrpc_request.setURL( url )
        xmlrpc_request.setMethod( method )
        xmlrpc_request.setHeaders( headers )
        return xmlrpc_request
    #
    #   Case #4, the "default".
    #
    # NOT a JSON or XMLRPC request!, let's try the simple url encoded post data...
    #
    try:
        dc = parse_qs(postData)
        pdr.setDc( dc )
    except:
        om.out.debug('Failed to create a data container that can store this data: "' + postData + '".')
    else:
        return pdr
Exemplo n.º 9
0
def createFuzzableRequestRaw(method, url, postData, headers):
    """
    Creates a fuzzable request based on a query sent FROM the browser. This is used in
    plugins like spiderMan.
    
    @parameter method: A string that represents the method ('GET', 'POST', etc)
    @parameter url: A string that represents the URL
    @parameter postData: A string that represents the postdata, if its a GET request, set to None.
    @parameter headers: A dict that holds the headers
    """
    #
    # Just a query string request ! no postdata
    #
    if not postData:
        qsr = httpQsRequest.httpQsRequest()
        qsr.setURL(url)
        qsr.setMethod(method)
        qsr.setHeaders(headers)
        dc = urlParser.getQueryString(url)
        qsr.setDc(dc)
        return qsr
    #
    # Seems to be something that has post data
    #
    pdr = httpPostDataRequest.httpPostDataRequest()
    pdr.setURL(url)
    pdr.setMethod(method)
    for header_name in headers.keys():
        if header_name.lower() == "content-length":
            del headers[header_name]
    pdr.setHeaders(headers)
    #
    #   Parse the content
    #   Case #1, multipart form data
    #
    if "content-type" in headers.keys() and headers["content-type"].startswith("multipart/form-data"):
        tmp, pdict = cgi.parse_header(headers["content-type"])
        try:
            dc = cgi.parse_multipart(StringIO(postData), pdict)
        except:
            om.out.debug("Multipart form data is invalid, the browser sent something wierd.")
        else:
            resultDc = queryString()
            for i in dc.keys():
                resultDc[i] = dc[i]
            # We process multipart requests as x-www-form-urlencoded
            # TODO We need native support of multipart requests!
            headers["content-type"] = "application/x-www-form-urlencoded"
            pdr.setDc(resultDc)
            pdr.setHeaders(headers)
            return pdr
    #
    #   Case #2, JSON request
    #
    try:
        dc = json.loads(postData)
    except:
        pass
    else:
        # It's json! welcome to the party dude!
        pdr = jsonPostDataRequest.jsonPostDataRequest()
        pdr.setURL(url)
        pdr.setMethod(method)
        pdr.setHeaders(headers)
        pdr.setDc(dc)
        return pdr
    #
    #   Case #3, XMLRPC request
    #
    postDataLower = postData.lower()
    stopWords = ["<methodcall>", "<methodname>", "<params>", "</methodcall>", "</methodname>", "</params>"]
    allStopWords = True
    for word in stopWords:
        if word not in postDataLower:
            allStopWords = False
    if allStopWords:
        xmlrpc_request = xmlrpcRequest.xmlrpcRequest(postData)
        xmlrpc_request.setURL(url)
        xmlrpc_request.setMethod(method)
        xmlrpc_request.setHeaders(headers)
        return xmlrpc_request
    #
    #   Case #4, the "default".
    #
    # NOT a JSON or XMLRPC request!, let's try the simple url encoded post data...
    #
    try:
        dc = urlParser.getQueryString("http://w3af/?" + postData)
        pdr.setDc(dc)
    except:
        om.out.debug('Failed to create a data container that can store this data: "' + postData + '".')
    else:
        return pdr