def setUpClass(cls): username, password = random_string(), random_string() cls.current_user_creds = {'username': username, 'password': password} cls.current_user = cls._create_user(username, password)['user'] cls.users = [ cls._create_user(random_string(), random_string()) for _ in range(cls.users_count) ] return super().setUpClass()
def test_create(self): self.logout() res = self.client.post('/users/', data={ 'username': random_string(), 'password': random_string() }) self.assertTrue(res.status_code == status.HTTP_201_CREATED) new_user = UserModel.objects.get(id=res.data['id']) self.assertEqual(res.data, UserCreateSerializer(new_user).data, 'Got wrong serialized data') self.login()
def create(self, user, purpose, key=None, **kwargs): if key is None: salt = random_string() value = '%s-%s-%s' % (user.email, user.username, user.domain) key = salted_hmac(salt, value).hexdigest() return super(ConfirmationManager, self).create( user=user, purpose=purpose, key=key, **kwargs)
def get_multipart_form_data(self, url, post_data): output = "" boundry = "----WebKitFormBoundary%s" % random_string(15) output += "--" + boundry + "\r\n" for name in post_data: value = post_data[name] opt = '' if value == "{file}": outf = self.generate_file(url) self.needle = outf filename, match, contents = outf name = name + '"; filename="%s' % filename value = contents opt = 'Content-Type: \r\n' header = 'Content-Disposition: form-data; name="%s"\r\n' % name header += opt header += "\r\n" outstr = "%s%s\r\n" % (header, value) output += outstr output += "--" + boundry + "\r\n" output = output[:-2] + "--" return output, boundry.strip()
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
async def check_message(self, user, users_comm, another_user_comm): res = await self._send_message(user, random_string()) msg_from_user, msg_from_user1 = [ await comm.receive_json_from() for comm in users_comm ] # Check that current user and user receive a new created message self.assertEqual(msg_from_user['data'], res.data, 'user receive wrong msg data') self.assertEqual(msg_from_user1['data'], res.data, 'user receive wrong msg data') # check that another_user didnt recieve message self.assertTrue(await another_user_comm.receive_nothing(), 'user receive msg')
def bruter(param, originalResponse, originalCode, factors, include, reflections, delay, headers, url, GET): fuzz = random_string(6) data = {param: fuzz} data.update(include) response = requester(url, data, headers, GET, delay) newReflections = response.text.count(fuzz) reason = False if response.status_code != originalCode: reason = 'Different response code' elif reflections != newReflections: reason = 'Different number of reflections' elif not factors['sameHTML'] and len( response.text) != (len(originalResponse)): reason = 'Different content length' elif not factors['samePlainText'] and len(remove_tags( response.text)) != (len(remove_tags(originalResponse))): reason = 'Different plain-text content length' if reason: return {param: reason} else: return None
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
def generate_file(self, url): filename = "upload.txt" match = random_string(8) contents = match if ".php" in url: filename = random_string(8) + ".php" match = random_string(8) contents = "<?php echo '%s'; ?>" % match if ".asp" in url: # also catches aspx filename = random_string(8) + ".asp" match = random_string(8) contents = '<%% Response.Write("%s") %%>' % match if ".jsp" in url: filename = random_string(8) + ".jsp" match = random_string(8) contents = '<%% out.print("%s"); %%>' % match return filename, match, contents
def init_security(self, initial): initial['timestamp'] = int(time.time()) initial['token'] = random_string() initial['security_hash'] = self.generate_hash(initial['timestamp'], initial['token']) return initial
def inject(self, url, params, data=None, parameter_get=None, parameter_post=None): if parameter_get: tmp = dict(params) ogvalue = tmp[parameter_get] get_firstpage = self.send(url, tmp, data) firstpage_len = self.getlen(get_firstpage) get_firstpage_two = self.send(url, tmp, data) second_page = self.getlen(get_firstpage_two) if second_page != firstpage_len: # cannot check with random page length (dynamic content) return False rstring = random_string() tmp[parameter_get] = rstring check_reflection = self.send(url, params=tmp, data=data) if rstring in check_reflection.text: # query values are reflected, cannot test using only page length return False tmp[parameter_get] = ogvalue for injection in self.possibilities: injection_query = self.possibilities[injection] random_true = random.randint(9999, 999999) random_false = random_true + 1 query_true = "%d=%d" % (random_true, random_true) query_false = "%d=%d" % (random_true, random_false) injection_query_true = injection_query.replace('{original_value}', ogvalue) injection_query_true = injection_query_true.replace('{query}', query_true) tmp[parameter_get] = injection_query_true page_data = self.send(url, params=tmp, data=data) datalen_true = self.getlen(page_data) if True: # might be vulnerable because query caused original state injection_query_false = injection_query.replace('{original_value}', ogvalue) injection_query_false = injection_query_false.replace('{query}', query_false) tmp[parameter_get] = injection_query_false get_data = self.send(url, params=tmp, data=data) datalen = self.getlen(get_data) if get_data and datalen != datalen_true: return (get_data, {"injection": injection.upper(), "parameter": parameter_get, "location": "url", "query_true": injection_query_true, "query_false": injection_query_false, "states": { "true_length": datalen_true, "false_length": datalen }}) if parameter_post: tmp = dict(data) ogvalue = tmp[parameter_post] get_firstpage = self.send(url, params, tmp) firstpage_len = self.getlen(get_firstpage) get_firstpage_two = self.send(url, params, tmp) second_page = self.getlen(get_firstpage_two) if second_page != firstpage_len: # cannot check with random page length (dynamic content) return False rstring = random_string() tmp[parameter_post] = rstring check_reflection = self.send(url, params=params, data=tmp) if rstring in check_reflection.text: # query values are reflected, cannot test using only page length return False tmp[parameter_post] = ogvalue for injection in self.possibilities: injection_query = self.possibilities[injection] random_true = random.randint(9999, 999999) random_false = random_true + 1 query_true = "%d=%d" % (random_true, random_true) query_false = "%d=%d" % (random_true, random_false) injection_query_true = injection_query.replace('{original_value}', ogvalue) injection_query_true = injection_query_true.replace('{query}', query_true) tmp[parameter_post] = injection_query_true page_data = self.send(url, params=params, data=tmp) if str(random_true) in page_data.text: # query values are reflected, cannot test using only page length continue datalen_true = self.getlen(page_data) if True: # might be vulnerable because query caused original state injection_query_false = injection_query.replace('{original_value}', ogvalue) injection_query_false = injection_query_false.replace('{query}', query_false) tmp[parameter_post] = injection_query_false get_postdata = self.send(url, params=data, data=tmp) datalen = self.getlen(get_postdata) if get_postdata and datalen != datalen_true: return (get_postdata, {"injection": injection.upper(), "parameter": parameter_post, "location": "url", "query_true": injection_query_true, "query_false": injection_query_false, "states": { "true_length": datalen_true, "false_length": datalen }}) return None
def get_random_password(self, length=32): """Get a random password. :param length: The length of the random password. """ return random_string(length=length)
def main(): print('''%s _ /_| _ ' ( |/ /(//) %sv1.3%s _/ %s''' % (green, white, green, end)) parser = argparse.ArgumentParser() #defines the parser #Arguments that can be supplied parser.add_argument('-u', help='target url', dest='url', required=True) parser.add_argument('-d', help='request delay', dest='delay', type=int) parser.add_argument('-t', help='number of threads', dest='threads', type=int) parser.add_argument('-f', help='file path', dest='file') parser.add_argument('-o', help='Path for the output file', dest='output_file') parser.add_argument('--get', help='use get method', dest='GET', action='store_true') parser.add_argument('--post', help='use post method', dest='POST', action='store_true') parser.add_argument('--headers', help='http headers prompt', dest='headers', action='store_true') parser.add_argument('--include', help='include this data in every request', dest='include') args = parser.parse_args() #arguments to be parsed url = args.url params_file = args.file or './db/params.txt' headers = args.headers delay = args.delay or 0 include = args.include or {} threadCount = args.threads or 2 if headers: headers = extract_headers(prompt()) else: headers = {} if args.GET: GET = True else: GET = False include = get_params(include) paramList = [] try: with open(params_file, 'r') as params_file: for line in params_file: paramList.append(line.strip('\n')) except FileNotFoundError: print('%s The specified file doesn\'t exist' % bad) quit() url = stabilize(url) print('%s Analysing the content of the webpage' % run) firstResponse = requester(url, include, headers, GET, delay) print('%s Now lets see how target deals with a non-existent parameter' % run) originalFuzz = random_string(6) data = {originalFuzz: originalFuzz[::-1]} data.update(include) response = requester(url, data, headers, GET, delay) reflections = response.text.count(originalFuzz[::-1]) print('%s Reflections: %s%i%s' % (info, green, reflections, end)) originalResponse = response.text originalCode = response.status_code print('%s Response Code: %s%i%s' % (info, green, originalCode, end)) newLength = len(response.text) plainText = remove_tags(originalResponse) plainTextLength = len(plainText) print('%s Content Length: %s%i%s' % (info, green, newLength, end)) print('%s Plain-text Length: %s%i%s' % (info, green, plainTextLength, end)) factors = {'sameHTML': False, 'samePlainText': False} if len(firstResponse.text) == len(originalResponse): factors['sameHTML'] = True elif len(remove_tags(firstResponse.text)) == len(plainText): factors['samePlainText'] = True print('%s Parsing webpage for potential parameters' % run) heuristic(firstResponse.text, paramList) fuzz = random_string(8) data = {fuzz: fuzz[::-1]} data.update(include) print('%s Performing heuristic level checks' % run) toBeChecked = slicer(paramList, 25) foundParams = [] while True: toBeChecked = narrower(toBeChecked) toBeChecked = unity_extracter(toBeChecked, foundParams) if not toBeChecked: break if foundParams: print('%s Heuristic found %i potential parameters.' % (info, len(foundParams))) paramList = foundParams finalResult = [] jsonResult = [] threadpool = concurrent.futures.ThreadPoolExecutor(max_workers=threadCount) futures = (threadpool.submit(bruter, param, originalResponse, originalCode, factors, include, reflections, delay, headers, url, GET) for param in foundParams) for i, result in enumerate(concurrent.futures.as_completed(futures)): if result.result(): finalResult.append(result.result()) print('%s Progress: %i/%i' % (info, i + 1, len(paramList)), end='\r') print('%s Scan Completed' % info) for each in finalResult: for param, reason in each.items(): print('%s Valid parameter found: %s%s%s' % (good, green, param, end)) print('%s Reason: %s' % (info, reason)) jsonResult.append({"param": param, "reason": reason}) # Finally, export to json if args.output_file and jsonResult: print("Saving output to JSON file in %s" % args.output_file) with open(str(args.output_file), 'w') as json_output: json.dump( {"results": jsonResult}, json_output, sort_keys=True, indent=4, )