Add files via upload
This commit is contained in:
54
bolt.py
54
bolt.py
@@ -2,11 +2,13 @@ from core.colors import green, yellow, end, run, good, info, bad, white, red
|
||||
|
||||
lightning = '\033[93;5m⚡\033[0m'
|
||||
|
||||
|
||||
def banner():
|
||||
print ('''
|
||||
%s⚡ %sBOLT%s ⚡%s
|
||||
''' % (yellow, white, yellow, end))
|
||||
|
||||
|
||||
banner()
|
||||
|
||||
try:
|
||||
@@ -43,9 +45,12 @@ parser = argparse.ArgumentParser()
|
||||
parser.add_argument('-u', help='target url', dest='target')
|
||||
parser.add_argument('-t', help='number of threads', dest='threads', type=int)
|
||||
parser.add_argument('-l', help='levels to crawl', dest='level', type=int)
|
||||
parser.add_argument('--delay', help='delay between requests', dest='delay', type=int)
|
||||
parser.add_argument('--timeout', help='http request timeout', dest='timeout', type=int)
|
||||
parser.add_argument('--headers', help='http headers', dest='add_headers', nargs='?', const=True)
|
||||
parser.add_argument('--delay', help='delay between requests',
|
||||
dest='delay', type=int)
|
||||
parser.add_argument('--timeout', help='http request timeout',
|
||||
dest='timeout', type=int)
|
||||
parser.add_argument('--headers', help='http headers',
|
||||
dest='add_headers', nargs='?', const=True)
|
||||
args = parser.parse_args()
|
||||
|
||||
if not args.target:
|
||||
@@ -70,11 +75,14 @@ weakTokens = []
|
||||
tokenDatabase = []
|
||||
insecureForms = []
|
||||
|
||||
print (' %s Phase: Crawling %s[%s1/6%s]%s' % (lightning, green, end, green, end))
|
||||
print (' %s Phase: Crawling %s[%s1/6%s]%s' %
|
||||
(lightning, green, end, green, end))
|
||||
dataset = photon(target, headers, level, threadCount)
|
||||
allForms = dataset[0]
|
||||
print ('\r%s Crawled %i URL(s) and found %i form(s).%-10s' % (info, dataset[1], len(allForms), ' '))
|
||||
print (' %s Phase: Evaluating %s[%s2/6%s]%s' % (lightning, green, end, green, end))
|
||||
print ('\r%s Crawled %i URL(s) and found %i form(s).%-10s' %
|
||||
(info, dataset[1], len(allForms), ' '))
|
||||
print (' %s Phase: Evaluating %s[%s2/6%s]%s' %
|
||||
(lightning, green, end, green, end))
|
||||
|
||||
evaluate(allForms, weakTokens, tokenDatabase, allTokens, insecureForms)
|
||||
|
||||
@@ -92,9 +100,11 @@ if insecureForms:
|
||||
action = list(insecureForm.values())[0]['action']
|
||||
form = action.replace(target, '')
|
||||
if form:
|
||||
print ('%s %s %s[%s%s%s]%s' % (bad, url, green, end, form, green, end))
|
||||
print ('%s %s %s[%s%s%s]%s' %
|
||||
(bad, url, green, end, form, green, end))
|
||||
|
||||
print (' %s Phase: Comparing %s[%s3/6%s]%s' % (lightning, green, end, green, end))
|
||||
print (' %s Phase: Comparing %s[%s3/6%s]%s' %
|
||||
(lightning, green, end, green, end))
|
||||
uniqueTokens = set(allTokens)
|
||||
if len(uniqueTokens) < len(allTokens):
|
||||
print ('%s Potential Replay Attack condition found' % good)
|
||||
@@ -103,7 +113,8 @@ if len(uniqueTokens) < len(allTokens):
|
||||
for url, token in tokenDatabase:
|
||||
for url2, token2 in tokenDatabase:
|
||||
if token == token2 and url != url2:
|
||||
print ('%s The same token was used on %s%s%s and %s%s%s' % (good, green, url, end, green, url2, end))
|
||||
print ('%s The same token was used on %s%s%s and %s%s%s' %
|
||||
(good, green, url, end, green, url2, end))
|
||||
replay = True
|
||||
if not replay:
|
||||
print ('%s Further investigation shows that it was a false positive.')
|
||||
@@ -127,6 +138,7 @@ if matches:
|
||||
for name in matches:
|
||||
print (' %s>%s %s' % (yellow, end, name))
|
||||
|
||||
|
||||
def fuzzy(tokens):
|
||||
averages = []
|
||||
for token in tokens:
|
||||
@@ -143,13 +155,16 @@ def fuzzy(tokens):
|
||||
averages.append(average)
|
||||
return statistics.mean(averages)
|
||||
|
||||
|
||||
try:
|
||||
similarity = fuzzy(allTokens)
|
||||
print ('%s Tokens are %s%i%%%s similar to each other on an average' % (info, green, similarity, end))
|
||||
print ('%s Tokens are %s%i%%%s similar to each other on an average' %
|
||||
(info, green, similarity, end))
|
||||
except statistics.StatisticsError:
|
||||
print ('%s No CSRF protection to test' % bad)
|
||||
quit()
|
||||
|
||||
|
||||
def staticParts(allTokens):
|
||||
strings = list(set(allTokens.copy()))
|
||||
commonSubstrings = {}
|
||||
@@ -165,6 +180,8 @@ def staticParts(allTokens):
|
||||
if string not in commonSubstrings[commonSubstring]:
|
||||
commonSubstrings[commonSubstring].append(string)
|
||||
return commonSubstrings
|
||||
|
||||
|
||||
result = {k: v for k, v in staticParts(allTokens).items() if v}
|
||||
|
||||
if result:
|
||||
@@ -173,9 +190,11 @@ if result:
|
||||
|
||||
simTokens = []
|
||||
|
||||
print (' %s Phase: Observing %s[%s4/6%s]%s' % (lightning, green, end, green, end))
|
||||
print (' %s Phase: Observing %s[%s4/6%s]%s' %
|
||||
(lightning, green, end, green, end))
|
||||
print ('%s 100 simultaneous requests are being made, please wait.' % info)
|
||||
|
||||
|
||||
def extractForms(url):
|
||||
response = requester(url, {}, headers, True, 0).text
|
||||
forms = zetanize(url, response)
|
||||
@@ -188,6 +207,7 @@ def extractForms(url):
|
||||
if strength(value) > 10:
|
||||
simTokens.append(value)
|
||||
|
||||
|
||||
while True:
|
||||
sample = random.choice(tokenDatabase)
|
||||
goodToken = list(sample.values())[0]
|
||||
@@ -196,7 +216,8 @@ while True:
|
||||
break
|
||||
|
||||
threadpool = concurrent.futures.ThreadPoolExecutor(max_workers=30)
|
||||
futures = (threadpool.submit(extractForms, goodCandidate) for goodCandidate in [goodCandidate] * 30)
|
||||
futures = (threadpool.submit(extractForms, goodCandidate)
|
||||
for goodCandidate in [goodCandidate] * 30)
|
||||
for i in concurrent.futures.as_completed(futures):
|
||||
pass
|
||||
|
||||
@@ -208,7 +229,8 @@ if simTokens:
|
||||
else:
|
||||
print ('%s Different tokens were issued for simultaneous requests.' % info)
|
||||
|
||||
print (' %s Phase: Testing %s[%s5/6%s]%s' % (lightning, green, end, green, end))
|
||||
print (' %s Phase: Testing %s[%s5/6%s]%s' %
|
||||
(lightning, green, end, green, end))
|
||||
|
||||
parsed = ''
|
||||
print ('%s Finding a suitable form for further testing. It may take a while.' % run)
|
||||
@@ -298,7 +320,8 @@ for index in range(len(allTokens[0])):
|
||||
else:
|
||||
difference = abs(originalLength - len(response.text))
|
||||
if difference <= tolerableDifference:
|
||||
print ('%s Last %i chars of token aren\'t being checked' % (good, index + 1))
|
||||
print ('%s Last %i chars of token aren\'t being checked' %
|
||||
(good, index + 1))
|
||||
else:
|
||||
break
|
||||
|
||||
@@ -318,7 +341,8 @@ if response.status_code == originalCode:
|
||||
else:
|
||||
print ('%s It didn\'t work' % bad)
|
||||
|
||||
print (' %s Phase: Analysing %s[%s6/6%s]%s' % (lightning, green, end, green, end))
|
||||
print (' %s Phase: Analysing %s[%s6/6%s]%s' %
|
||||
(lightning, green, end, green, end))
|
||||
|
||||
binary = stringToBinary(''.join(allTokens))
|
||||
result = isRandom(binary)
|
||||
|
||||
Reference in New Issue
Block a user