def _html_in_comment(self, comment, request, response): ''' Find HTML code in HTML comments ''' html_in_comment = self.HTML_RE.search(comment) if html_in_comment and \ (comment, response.get_url()) not in self._already_reported_interesting: # There is HTML code in the comment. comment = comment.replace('\n', '') comment = comment.replace('\r', '') desc = 'A comment with the string "%s" was found in: "%s".'\ ' This could be interesting.' desc = desc % (comment, response.get_url()) i = Info('HTML comment contains HTML code', desc, response.id, self.get_name()) i.set_dc(request.get_dc()) i.set_uri(response.get_uri()) i.add_to_highlight(html_in_comment.group(0)) kb.kb.append(self, 'html_comment_hides_html', i) om.out.information(i.get_desc()) self._already_reported_interesting.add( (comment, response.get_url()))
def grep(self, request, response): ''' Plugin entry point, find feeds. :param request: The HTTP request object. :param response: The HTTP response object :return: None ''' dom = response.get_dom() uri = response.get_uri() # In some strange cases, we fail to normalize the document if uri not in self._already_inspected and dom is not None: self._already_inspected.add(uri) # Find all feed tags element_list = self._tag_xpath(dom) for element in element_list: feed_tag = element.tag feed_type = self._feed_types[feed_tag.lower()] version = element.attrib.get('version', 'unknown') fmt = 'The URL "%s" is a %s version %s feed.' desc = fmt % (uri, feed_type, version) i = Info('Content feed resource', desc, response.id, self.get_name()) i.set_uri(uri) i.add_to_highlight(feed_type) self.kb_append_uniq(self, 'feeds', i, 'URL')
def analyze_document_links(self, request, response): ''' Find session IDs in the URI and store them in the KB. ''' try: doc_parser = parser_cache.dpc.get_document_parser_for(response) except: pass else: parsed_refs, _ = doc_parser.get_references() for link_uri in parsed_refs: if self._has_sessid(link_uri) and \ response.get_url() not in self._already_reported: # report these informations only once self._already_reported.add(response.get_url()) desc = 'The HTML content at "%s" contains a link (%s)'\ ' which holds a session id. The ID could be leaked'\ ' to third party domains through the referrer'\ ' header.' desc = desc % (response.get_url(), link_uri) # append the info object to the KB. i = Info('Session ID in URL', desc, response.id, self.get_name()) i.set_uri(response.get_uri()) self.kb_append(self, 'url_session', i) break
def grep(self, request, response): ''' Plugin entry point, search for meta tags. :param request: The HTTP request object. :param response: The HTTP response object :return: None ''' uri = response.get_uri() if not response.is_text_or_html() or uri in self._already_inspected\ or is_404(response): return self._already_inspected.add(uri) try: dp = parser_cache.dpc.get_document_parser_for(response) except w3afException: return meta_tag_list = dp.get_meta_tags() for tag in meta_tag_list: tag_name = self._find_name(tag) for key, val in tag.items(): for word in self.INTERESTING_WORDS: # Check if we have something interesting # and WHERE that thing actually is where = content = None if (word in key): where = 'name' content = key elif (word in val): where = 'value' content = val # Now... if we found something, report it =) if where is not None: # The atribute is interesting! fmt = 'The URI: "%s" sent a <meta> tag with attribute'\ ' %s set to "%s" which looks interesting.' desc = fmt % (response.get_uri(), where, content) if self.INTERESTING_WORDS.get(tag_name, None): usage = self.INTERESTING_WORDS[tag_name] desc += ' The tag is used for %s.' % usage i = Info('Interesting META tag', desc, response.id, self.get_name()) i.set_uri(response.get_uri()) i.add_to_highlight(where, content) self.kb_append_uniq(self, 'meta_tags', i, 'URL')
def grep(self, request, response): ''' Plugin entry point. :param request: The HTTP request object. :param response: The HTTP response object :return: None, all results are saved in the kb. ''' uri = response.get_uri() # 501 Code is "Not Implemented" which in some cases responds with # this in the body: # <body><h2>HTTP/1.1 501 Not Implemented</h2></body> # Which creates a false positive. if response.get_code() != 501\ and response.is_text_or_html()\ and uri not in self._already_inspected: # Don't repeat URLs self._already_inspected.add(uri) body_without_tags = response.get_clear_text_body() if body_without_tags is None: return for match, _, _, reqres in self._multi_re.query(body_without_tags): if reqres == 'REQUEST': desc = 'An HTTP request was found in the HTTP body of'\ ' a response.' i = Info('HTTP Request in HTTP body', desc, response.id, self.get_name()) i.set_uri(uri) i.add_to_highlight(match.group(0)) kb.kb.append(self, 'request', i) if reqres == 'RESPONSE': desc = 'An HTTP response was found in the HTTP body of'\ ' a response.' i = Info('HTTP Response in HTTP body', desc, response.id, self.get_name()) i.set_uri(uri) i.add_to_highlight(match.group(0)) kb.kb.append(self, 'response', i)
def crawl(self, fuzzable_request): """ Find CAPTCHA images. :param fuzzable_request: A fuzzable_request instance that contains (among other things) the URL to test. """ result, captchas = self._identify_captchas(fuzzable_request) if result: for captcha in captchas: desc = 'Found a CAPTCHA image at: "%s".' % captcha.img_src response_ids = [response.id for response in captcha.http_responses] i = Info("Captcha image detected", desc, response_ids, self.get_name()) i.set_uri(captcha.img_src) kb.kb.append(self, "CAPTCHA", i) om.out.information(i.get_desc())
def analyze_uri(self, request, response): ''' Find session IDs in the URI and store them in the KB. ''' request_uri = request.get_uri() if self._has_sessid(request_uri) and \ response.get_url() not in self._already_reported: # report these informations only once self._already_reported.add(response.get_url()) desc = 'The URL "%s" contains a session id which could be'\ ' leaked to third party domains through the referrer'\ ' header.' desc = desc % request_uri # append the info object to the KB. i = Info('Session ID in URL', desc, response.id, self.get_name()) i.set_uri(response.get_uri()) self.kb_append(self, 'url_session', i)
def _interesting_word(self, comment, request, response): ''' Find interesting words in HTML comments ''' comment = comment.lower() for word in self._multi_in.query(response.body): if (word, response.get_url()) not in self._already_reported_interesting: desc = 'A comment with the string "%s" was found in: "%s".'\ ' This could be interesting.' desc = desc % (word, response.get_url()) i = Info('Interesting HTML comment', desc, response.id, self.get_name()) i.set_dc(request.get_dc()) i.set_uri(response.get_uri()) i.add_to_highlight(word) kb.kb.append(self, 'interesting_comments', i) om.out.information(i.get_desc()) self._already_reported_interesting.add((word, response.get_url()))
def crawl(self, fuzzable_request): ''' Find CAPTCHA images. :param fuzzable_request: A fuzzable_request instance that contains (among other things) the URL to test. ''' result, captchas = self._identify_captchas(fuzzable_request) if result: for captcha in captchas: desc = 'Found a CAPTCHA image at: "%s".' % captcha.img_src response_ids = [ response.id for response in captcha.http_responses ] i = Info('Captcha image detected', desc, response_ids, self.get_name()) i.set_uri(captcha.img_src) kb.kb.append(self, 'CAPTCHA', i) om.out.information(i.get_desc())
def _interesting_word(self, comment, request, response): ''' Find interesting words in HTML comments ''' comment = comment.lower() for word in self._multi_in.query(response.body): if (word, response.get_url() ) not in self._already_reported_interesting: desc = 'A comment with the string "%s" was found in: "%s".'\ ' This could be interesting.' desc = desc % (word, response.get_url()) i = Info('Interesting HTML comment', desc, response.id, self.get_name()) i.set_dc(request.get_dc()) i.set_uri(response.get_uri()) i.add_to_highlight(word) kb.kb.append(self, 'interesting_comments', i) om.out.information(i.get_desc()) self._already_reported_interesting.add( (word, response.get_url()))
def grep(self, request, response): ''' Plugin entry point. :param request: The HTTP request object. :param response: The HTTP response object :return: None, all results are saved in the kb. ''' try: dp = parser_cache.dpc.get_document_parser_for(response) except w3afException: return # Note: # - With parsed_references I'm 100% that it's really something in the # HTML that the developer intended to add. # # - The re_references are the result of regular expressions, which in # some cases are just false positives. # parsed_references, _ = dp.get_references() for ref in parsed_references: qs = ref.querystring for param_name in qs: # This for loop is to address the repeated parameter name issue for element_index in xrange(len(qs[param_name])): if self._is_strange(request, param_name, qs[param_name][element_index])\ and (ref.uri2url(), param_name) not in self._already_reported: # Don't repeat findings self._already_reported.add((ref.uri2url(), param_name)) desc = 'The URI: "%s" has a parameter named: "%s"'\ ' with value: "%s", which is very uncommon.'\ ' and requires manual verification.' desc = desc % (response.get_uri(), param_name, qs[param_name][element_index]) i = Info('Uncommon query string parameter', desc, response.id, self.get_name()) i.set_uri(ref) i.set_var(param_name) i['parameter_value'] = qs[param_name][element_index] i.add_to_highlight(qs[param_name][element_index]) self.kb_append(self, 'strange_parameters', i) # To find this kind of vulns # http://thedailywtf.com/Articles/Oklahoma- # Leaks-Tens-of-Thousands-of-Social-Security-Numbers,-Other- # Sensitive-Data.aspx if self._is_SQL(request, param_name, qs[param_name][element_index])\ and ref not in self._already_reported: # Don't repeat findings self._already_reported.add(ref) desc = 'The URI: "%s" has a parameter named: "%s"'\ ' with value: "%s", which is a SQL query.' desc = desc % (response.get_uri(), param_name, qs[param_name][element_index]) v = Vuln('Parameter has SQL sentence', desc, severity.LOW, response.id, self.get_name()) v.set_uri(ref) v.set_var(param_name) v['parameter_value'] = qs[param_name][element_index] v.add_to_highlight(qs[param_name][element_index]) self.kb_append(self, 'strange_parameters', v)