def modifyRequest(self, request ): ''' Mangles the request @parameter request: urllib2.Request instance that is going to be modified by the evasion plugin ''' # First we mangle the URL path = urlParser.getPathQs( request.get_full_url() ) path = self._mutate( path ) # Now we mangle the postdata data = request.get_data() if data: # Only mangle the postdata if it is a url encoded string try: urlParser.getQueryString('http://w3af/?' + data ) except: pass else: data = self._mutate( data ) # Finally, we set all the mutants to the request in order to return it url = urlParser.getProtocol( request.get_full_url() ) url += '://' + urlParser.getNetLocation( request.get_full_url() ) + path new_req = urllib2.Request( url , data, request.headers, request.get_origin_req_host() ) return new_req
def modifyRequest(self, request ): ''' Mangles the request @parameter request: urllib2.Request instance that is going to be modified by the evasion plugin ''' # This is a test URL # http://172.16.1.132/index.asp?q=%uFF1Cscript%3Ealert(%22Hello%22)%3C/script%3E # This is the content of index.asp : # <%=Request.QueryString("q")%> # First we mangle the URL path = urlParser.getPathQs( request.get_full_url() ) path = self._mutate( path ) # Now we mangle the postdata data = request.get_data() if data: # Only mangle the postdata if it is a url encoded string try: urlParser.getQueryString('http://w3af/?' + data ) except: pass else: data = self._mutate( data ) # Finally, we set all the mutants to the request in order to return it url = urlParser.getProtocol( request.get_full_url() ) url += '://' + urlParser.getNetLocation( request.get_full_url() ) + path new_req = urllib2.Request( url , data, request.headers, request.get_origin_req_host() ) return new_req
def discover(self, fuzzableRequest ): ''' It calls the "main" from hmap and writes the results to the kb. @parameter fuzzableRequest: A fuzzableRequest instance that contains (among other things) the URL to test. ''' if not self._exec: # This will remove the plugin from the discovery plugins to be runned. raise w3afRunOnce() else: if self._runned_hmap: # Nothing else to do here. self._exec = False if not self._runned_hmap: self._runned_hmap = True msg = 'Hmap web server fingerprint is starting, this may take a while.' om.out.information( msg ) url = fuzzableRequest.getURL() protocol = urlParser.getProtocol( url ) server = urlParser.getNetLocation( url ) # Set some defaults that can be overriden later if protocol == 'https': port = 443 ssl = True else: port = 80 ssl = False # Override the defaults if server.count(':'): port = int( server.split(':')[1] ) server = server.split(':')[0] try: results = originalHmap.testServer( ssl, server, port, 1, self._genFpF ) except w3afException, w3: msg = 'A w3afException ocurred while running hmap: "' + str(w3) + '"' om.out.error( msg ) except Exception, e: msg = 'An unhandled exception ocurred while running hmap: "' + str(e) + '"' om.out.error( msg ) else:
def modifyRequest(self, request ): ''' Mangles the request @parameter request: urllib2.Request instance that is going to be modified by the evasion plugin ''' # We mangle the URL path = urlParser.getPathQs( request.get_full_url() ) path = path.replace('/','/./' ) # Finally, we set all the mutants to the request in order to return it url = urlParser.getProtocol( request.get_full_url() ) url += '://' + urlParser.getNetLocation( request.get_full_url() ) + path new_req = urllib2.Request( url , request.get_data(), request.headers, request.get_origin_req_host() ) return new_req
def modifyRequest(self, request ): ''' Mangles the request @parameter request: urllib2.Request instance that is going to be modified by the evasion plugin ''' # We mangle the URL path = urlParser.getPathQs( request.get_full_url() ) if re.match('^/', path): random_alnum = createRandAlNum() path = '/' + random_alnum + '/..' + path # Finally, we set all the mutants to the request in order to return it url = urlParser.getProtocol( request.get_full_url() ) url += '://' + urlParser.getNetLocation( request.get_full_url() ) + path new_req = urllib2.Request( url , request.get_data(), request.headers, request.get_origin_req_host() ) return new_req
def audit(self, freq ): ''' Get the cert and do some checks against it. @param freq: A fuzzableRequest ''' url = freq.getURL() if 'HTTPS' != getProtocol( url ).upper(): return domain = getDomain(url) # We need to check certificate only once per host if domain in self._already_tested_domains: return # Parse the domain:port splited = getNetLocation(url).split(':') port = 443 host = splited[0] if len( splited ) > 1: port = int(splited[1]) # Create the connection socket_obj = socket.socket() try: socket_obj.connect( ( host , port ) ) ctx = SSL.Context(SSL.SSLv23_METHOD) ssl_conn = SSL.Connection(ctx, socket_obj) # Go to client mode ssl_conn.set_connect_state() # If I don't send something here, the "get_peer_certificate" # method returns None. Don't ask me why! #ssl_conn.send('GET / HTTP/1.1\r\n\r\n') self.ssl_wrapper( ssl_conn, ssl_conn.send, ('GET / HTTP/1.1\r\n\r\n', ), {}) except Exception, e: om.out.error('Error in audit.sslCertificate: "' + repr(e) +'".')
def setOptions(self, optionsMap): """ This method sets all the options that are configured using the user interface generated by the framework using the result of getOptions(). @parameter optionsMap: A dictionary with the options for the plugin. @return: No value is returned. """ targetUrls = optionsMap["target"].getValue() for targetUrl in targetUrls: self._verifyURL(targetUrl) for targetUrl in targetUrls: if targetUrl.count("file://"): try: f = urllib2.urlopen(targetUrl) except: raise w3afException("Cannot open target file: " + targetUrl) else: for line in f: target_in_file = line.strip() self._verifyURL(target_in_file, fileTarget=False) targetUrls.append(target_in_file) f.close() targetUrls.remove(targetUrl) # Now we perform a check to see if the user has specified more than one target # domain, for example: "http://google.com, http://yahoo.com". domainList = [urlParser.getNetLocation(targetURL) for targetURL in targetUrls] domainList = list(set(domainList)) if len(domainList) > 1: msg = "You specified more than one target domain: " + ",".join(domainList) msg += " . And w3af only supports one target domain at the time." raise w3afException(msg) # Save in the config, the target URLs, this may be usefull for some plugins. cf.cf.save("targets", targetUrls) cf.cf.save("targetDomains", [urlParser.getNetLocation(i) for i in targetUrls]) cf.cf.save("baseURLs", [urlParser.baseUrl(i) for i in targetUrls]) if targetUrls: sessName = [urlParser.getNetLocation(x) for x in targetUrls] sessName = "-".join(sessName) else: sessName = "noTarget" cf.cf.save("sessionName", sessName + "-" + time.strftime("%Y-%b-%d_%H-%M-%S")) # Advanced target selection os = optionsMap["targetOS"].getValueStr() if os.lower() in self._operatingSystems: cf.cf.save("targetOS", os.lower()) else: raise w3afException("Unknown target operating system: " + os) pf = optionsMap["targetFramework"].getValueStr() if pf.lower() in self._programmingFrameworks: cf.cf.save("targetFramework", pf.lower()) else: raise w3afException("Unknown target programming framework: " + pf)
def discover(self, fuzzableRequest): ''' Discovery task. Uses scapy.traceroute function in order to determine the distance between http and https ports for the target. Intended to be executed once during the discovery process. ''' if not self._has_permission(): raise w3afException(PERM_ERROR_MSG) def set_info(name, desc): inf = info.info() inf.setPluginName(self.getName()) inf.setName(name) inf.setDesc(desc) kb.kb.append(self, 'http_vs_https_dist', inf) target_url = fuzzableRequest.getURL() domain = uparser.getDomain(target_url) http_port = self._http_port https_port = self._https_port # Use target port if specified netloc = uparser.getNetLocation(target_url) try: port = int(netloc.split(':')[-1]) except ValueError: pass # Nothing to do. else: protocol = uparser.getProtocol(target_url) if protocol == 'https': https_port = port else: # it has to be 'http' http_port = port # First try with httpS https_troute = traceroute(domain, dport=https_port)[0].get_trace() # This destination was probably 'localhost' or a host reached through # a vpn? if not https_troute: return [] https_troute = https_troute.values()[0] https_ip_tuples = https_troute.values() last_https_ip = https_ip_tuples[-1] # Then with http http_troute = traceroute(domain, dport=http_port) http_troute = http_troute[0].get_trace().values()[0] http_ip_tuples = http_troute.values() last_http_ip = http_ip_tuples[-1] # Last IP should be True; otherwise the dest wasn't reached # Tuples have the next form: ('192.168.1.1', False) if not (last_https_ip[1] and last_http_ip[1]): desc = _('The port \'%s\' is not open on target %s') if not last_https_ip[1]: om.out.error(desc % (https_port, domain)) if not last_http_ip[1]: om.out.error(desc % (http_port, domain)) else: # Are routes different if http_ip_tuples != https_ip_tuples: header = ' TCP trace to %s:%s\n%s' trace_str = lambda iptuples: '\n'.join(' %s %s' % \ (t[0], t[1][0]) for t in enumerate(iptuples)) trc1 = header % (domain, http_port, trace_str(http_ip_tuples)) trc2 = header % (domain, https_port, trace_str(https_ip_tuples)) desc = _('Routes to target \'%s\' using ports \'%s\' and ' \ '\'%s\' are different:\n%s\n%s') % (domain, http_port, https_port, trc1, trc2) set_info('HTTP vs. HTTPS Distance', desc) om.out.information(desc) return []