def define(response_1, response_2, param, value, wordlist): factors = { 'same_code': False, # if http status code is same, contains that code 'same_body': False, # if http body is same, contains that body 'same_plaintext': False, # if http body isn't same but is same after removing html, contains that non-html text 'lines_diff': False, # if http-body or plaintext aren't and there are more than two lines, contain which lines are same 'common_string': False, # if there is just one line, contains the longest common string 'same_headers': False, # if the headers are same, contains those headers 'same_redirect': False, # if both requests redirect in similar manner, contains that redirection 'param_missing': False, # if param name is missing from the body, contains words that are already there 'value_missing': False # contains whether param value is missing from the body } if (response_1 and response_2) != None: body_1, body_2 = response_1.text, response_2.text if response_1.status_code == response_2.status_code: factors['same_code'] = response_1.status_code if response_1.headers.keys() == response_2.headers.keys(): factors['same_headers'] = list(response_1.headers.keys()) if response_1.url == response_2.url: factors['same_redirect'] = response_1.url if response_1.text == response_2.text: factors['same_body'] = response_1.text elif param not in response_2.text: factors['param_missing'] = [word for word in wordlist if word in response_2.text] elif value not in response_2.text: factors['value_missing'] = True elif removeTags(body_1) == removeTags(body_2): factors['same_plaintext'] = removeTags(body_1) elif body_1 and body_2: if body_1.count('\\n') == 1: factors['common_string'] = lcs(body_1, body_2) elif body_1.count('\\n') == body_2.count('\\n'): factors['lines_diff'] = diff_map(body_1, body_2) return factors
def quickBruter(params, originalResponse, originalCode, reflections, factors, include, delay, headers, url, GET): joined = joiner(params, include) newResponse = requester(url, joined, headers, GET, delay) if newResponse.status_code == 429: if core.config.globalVariables['stable']: print('%s Hit rate limit, stabilizing the connection..') time.sleep(30) return params else: print( '%s Target has rate limiting in place, please use --stable switch' % bad) raise ConnectionError if newResponse.status_code != originalCode: return params elif factors['sameHTML'] and len( newResponse.text) != (len(originalResponse)): return params elif factors['samePlainText'] and len(removeTags(originalResponse)) != len( removeTags(newResponse.text)): return params elif True: for param, value in joined.items(): if param not in include and newResponse.text.count( value) != reflections: return params else: return False
def initialize(url, include, headers, GET, delay, paramList, threadCount): url = stabilize(url) if not url: return {} else: firstResponse = requester(url, include, headers, GET, delay) originalFuzz = randomString(6) data = {originalFuzz: originalFuzz[::-1]} data.update(include) response = requester(url, data, headers, GET, delay) reflections = response.text.count(originalFuzz[::-1]) originalResponse = response.text originalCode = response.status_code newLength = len(response.text) plainText = removeTags(originalResponse) plainTextLength = len(plainText) factors = {'sameHTML': False, 'samePlainText': False} if len(firstResponse.text) == len(originalResponse): factors['sameHTML'] = True elif len(removeTags(firstResponse.text)) == len(plainText): factors['samePlainText'] = True heuristic(firstResponse.text, paramList) fuzz = randomString(8) data = {fuzz: fuzz[::-1]} data.update(include) toBeChecked = slicer(paramList, 50) foundParamsTemp = [] while True: toBeChecked = narrower(toBeChecked, url, include, headers, GET, delay, originalResponse, originalCode, reflections, factors, threadCount) toBeChecked = unityExtracter(toBeChecked, foundParamsTemp) if not toBeChecked: break foundParams = [] for param in foundParamsTemp: exists = quickBruter([param], originalResponse, originalCode, reflections, factors, include, delay, headers, url, GET) if exists: foundParams.append(param) for each in foundParams: print('%s?%s' % (url, each)) if not foundParams: pass return foundParams
def quickBruter(params, originalResponse, originalCode, factors, include, delay, headers, url, GET): newResponse = requester(url, joiner(params, include), headers, GET, delay) if newResponse.status_code != originalCode: return params elif not factors['sameHTML'] and len(newResponse.text) != (len(originalResponse)): return params elif not factors['samePlainText'] and len(removeTags(originalResponse)) != len(removeTags(newResponse.text)): return params else: return False
def quickBruter(params, originalResponse, originalCode, reflections, factors, include, delay, headers, url, GET): joined = joiner(params, include) newResponse = requester(url, joined, headers, GET, delay) if newResponse.status_code != originalCode: return params elif factors['sameHTML'] and len(newResponse.text) != (len(originalResponse)): return params elif factors['samePlainText'] and len(removeTags(originalResponse)) != len(removeTags(newResponse.text)): return params elif True: for param, value in joined.items(): if param not in include and newResponse.text.count(value) != reflections: return params else: return False
def compare(response, factors, params): if factors['same_code'] and response.status_code != factors['same_code']: return ('http code', params) if factors['same_headers'] and list( response.headers.keys()) != factors['same_headers']: return ('http headers', params) if factors['same_redirect'] and response.url != factors['same_redirect']: return ('redirection', params) if factors['same_body'] and response.text != factors['same_body']: return ('body length', params) if factors['same_plaintext'] and removeTags( response.text) != factors['same_plaintext']: return ('text length', params) if factors['lines_diff']: for line in factors['lines']: if line not in response.text: return ('lines', params) if factors['common_string'] and factors[ 'common_string'] not in response.text: return ('constant string', params) if type(factors['param_missing']) == list: for param in params.keys(): if param in response.text and param not in factors['param_missing']: return ('param name reflection', params) if factors['value_missing']: for value in params.values(): if value in response.text: return ('value value reflection', params) return ('', [])
def quickBruter(params, originalResponse, originalCode, reflections, factors, include, delay, headers, url, GET): joined = joiner(params, include) newResponse = requester(url, joined, headers, GET, delay) if newResponse.status_code == 429: print ('%s Target has rate limiting in place, please use -t 2 -d 5.' % bad) raise ConnectionError if newResponse.status_code != originalCode: return params elif factors['sameHTML'] and len(newResponse.text) != (len(originalResponse)): return params elif factors['samePlainText'] and len(removeTags(originalResponse)) != len(removeTags(newResponse.text)): return params elif True: for param, value in joined.items(): if param not in include and newResponse.text.count(value) != reflections: return params else: return False
def bruter(param, originalResponse, originalCode, factors, include, reflections, delay, headers, url, GET): fuzz = randomString(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(removeTags(response.text)) != (len(removeTags(originalResponse))): reason = 'Different plain-text content length' if reason: return {param : reason} else: return None
print ('%s Now lets see how target deals with a non-existent parameter' % run) originalFuzz = randomString(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 = removeTags(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(removeTags(firstResponse.text)) == len(plainText): factors['samePlainText'] = True print ('%s Parsing webpage for potenial parameters' % run) heuristic(firstResponse.text, paramList) fuzz = randomString(8) data = {fuzz : fuzz[::-1]}
def initialize(url, include, headers, GET, delay, paramList, threadCount): url = stabilize(url) if not url: return {} else: print('%s Analysing the content of the webpage' % run) firstResponse = requester(url, include, headers, GET, delay) print('%s Analysing behaviour for a non-existent parameter' % run) originalFuzz = randomString(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 = removeTags(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(removeTags(firstResponse.text)) == len(plainText): factors['samePlainText'] = True print('%s Parsing webpage for potential parameters' % run) heuristic(firstResponse.text, paramList) fuzz = randomString(8) data = {fuzz: fuzz[::-1]} data.update(include) print('%s Performing heuristic level checks' % run) toBeChecked = slicer(paramList, 50) foundParamsTemp = [] while True: toBeChecked = narrower(toBeChecked, url, include, headers, GET, delay, originalResponse, originalCode, reflections, factors, threadCount) toBeChecked = unityExtracter(toBeChecked, foundParamsTemp) if not toBeChecked: break foundParams = [] for param in foundParamsTemp: exists = quickBruter([param], originalResponse, originalCode, reflections, factors, include, delay, headers, url, GET) if exists: foundParams.append(param) print('%s Scan Completed ' % info) for each in foundParams: print('%s Valid parameter found: %s%s%s' % (good, green, each, end)) if not foundParams: print( '%s Unable to verify existence of parameters detected by heuristic.' % bad) return foundParams
def initialize(url, include, headers, GET, delay, paramList, threadCount): url = stabilize(url) log('%s Analysing the content of the webpage' % run) firstResponse = requester(url, include, headers, GET, delay) log('%s Analysing behaviour for a non-existent parameter' % run) originalFuzz = randomString(6) data = {originalFuzz : originalFuzz[::-1]} data.update(include) response = requester(url, data, headers, GET, delay) reflections = response.text.count(originalFuzz[::-1]) log('%s Reflections: %s%i%s' % (info, green, reflections, end)) originalResponse = response.text originalCode = response.status_code log('%s Response Code: %s%i%s' % (info, green, originalCode, end)) newLength = len(response.text) plainText = removeTags(originalResponse) plainTextLength = len(plainText) log('%s Content Length: %s%i%s' % (info, green, newLength, end)) log('%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(removeTags(firstResponse.text)) == len(plainText): factors['samePlainText'] = True log('%s Parsing webpage for potential parameters' % run) heuristic(firstResponse.text, paramList) fuzz = randomString(8) data = {fuzz : fuzz[::-1]} data.update(include) log('%s Performing heuristic level checks' % run) toBeChecked = slicer(paramList, 50) foundParams = [] while True: toBeChecked = narrower(toBeChecked, url, include, headers, GET, delay, originalResponse, originalCode, reflections, factors, threadCount) toBeChecked = unityExtracter(toBeChecked, foundParams) if not toBeChecked: break if foundParams: log('%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()) log('%s Progress: %i/%i' % (info, i + 1, len(paramList)), mode='run') log('%s Scan Completed ' % info) for each in finalResult: for param, reason in each.items(): log('%s Valid parameter found: %s%s%s' % (good, green, param, end)) log('%s Reason: %s' % (info, reason)) jsonResult.append({"param": param, "reason": reason}) if not jsonResult: log('%s Unable to verify existence of parameters detected by heuristic' % bad) return jsonResult