def main(params=None): """ Main function to launch phonefy. The function is created in this way so as to let other applications make use of the full configuration capabilities of the application. The parameters received are used as parsed by this modules `getParser()`. Args: ----- params: A list with the parameters as grabbed by the terminal. It is None when this is called by an entry_point. If it is called by osrf the data is already parsed. Returns: -------- A list of i3visio entities. """ if params == None: parser = getParser() args = parser.parse_args(params) else: args = params results = [] if not args.quiet: print(general.title(banner.text)) sayingHello = """ Mailfy | Copyright (C) Yaiza Rubio & Félix Brezo (i3visio) 2014-2018 This program comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. For additional info, visit <{}>. """.format(general.LICENSE_URL) print(general.info(sayingHello)) # Displaying a warning if this is being run in a windows system if sys.platform == 'win32': print( general.warning( """OSRFramework has detected that you are running mailfy.py in a Windows system. As the "emailahoy" library is NOT working properly there, "validate_email" will be used instead. Verification may be slower though.""")) if args.license: general.showLicense() else: # processing only the given domains and excluding the ones provided extra_domains = [] for d in args.domains: if d not in args.exclude and not d == "all": extra_domains.append(d) # Two different arrays are mantained since there are some domains that cannot be safely verified if args.create_emails: potentially_existing_emails = grabEmails( nicksFile=args.create_emails, domains=EMAIL_DOMAINS + extra_domains, excludeDomains=args.exclude) potentially_leaked_emails = grabEmails( nicksFile=args.create_emails, domains=LEAKED_DOMAINS + extra_domains, excludeDomains=args.exclude) else: potentially_existing_emails = grabEmails( emails=args.emails, emailsFile=args.emails_file, nicks=args.nicks, nicksFile=args.nicks_file, domains=EMAIL_DOMAINS + extra_domains, excludeDomains=args.exclude) potentially_leaked_emails = grabEmails(emails=args.emails, emailsFile=args.emails_file, nicks=args.nicks, nicksFile=args.nicks_file, domains=LEAKED_DOMAINS + extra_domains, excludeDomains=args.exclude) emails = list( set(potentially_leaked_emails + potentially_existing_emails)) # Showing the execution time... if not args.quiet: startTime = dt.datetime.now() print("{}\tStarting search of {} different emails:\n{}\n".format( str(startTime), general.emphasis(str(len(emails))), json.dumps(emails, indent=2, sort_keys=True))) if not args.quiet: now = dt.datetime.now() print( "\n{}\tStep 1. Trying to determine if the emails provided do exist...\n" .format(str(now))) print(general.emphasis("\tPress <Ctrl + C> to stop...\n")) # Perform searches, using different Threads results = performSearch(potentially_existing_emails, nThreads=args.threads) if not args.quiet: now = dt.datetime.now() print( "\n{}\tStep 2. Checking if the emails have been used to register socialmedia accounts...\n" .format(str(now))) print(general.emphasis("\tPress <Ctrl + C> to stop...\n")) registered = processMailList(platformNames=args.platforms, emails=potentially_existing_emails) results += registered if not args.quiet: if len(results) > 0: for r in registered: print("\t[*] Registered account found: {}".format( general.success(r["value"]))) else: print("\t[*] Registered account found: {}".format( general.error("None"))) now = dt.datetime.now() print( "\n{}\tStep 3. Verifying if the provided emails have been leaked somewhere?\n" .format(str(now))) print(general.emphasis("\tPress <Ctrl + C> to stop...\n")) # Verify the existence of the mails found as leaked emails. for query in potentially_leaked_emails: # Iterate through the different leak platforms leaks = hibp.checkIfEmailWasHacked(query) if len(leaks) > 0: if not args.quiet: if len(leaks) > 0: print( "\t[*] '{}' has been found in at least {} different leaks." .format(general.success(query), general.success(str(len(leaks))))) else: print("\t[*] '{}' has NOT been found in any leak.". format(general.error(query))) else: if not args.quiet: print("\t[*] '{}' has NOT been found on any leak yet.". format(general.error(query))) results += leaks # Trying to store the information recovered if args.output_folder != None: if not os.path.exists(args.output_folder): os.makedirs(args.output_folder) # Grabbing the results fileHeader = os.path.join(args.output_folder, args.file_header) for ext in args.extension: # Generating output files general.exportUsufy(results, ext, fileHeader) # Showing the information gathered if requested if not args.quiet: now = dt.datetime.now() print("\n{}\tResults obtained:\n".format(str(now))) print(general.success(general.usufyToTextExport(results))) now = dt.datetime.now() print( "\n" + str(now) + "\tYou can find all the information collected in the following files:" ) for ext in args.extension: # Showing the output files print(general.emphasis("\t" + fileHeader + "." + ext)) # Showing the execution time... if not args.quiet: endTime = dt.datetime.now() print("\n" + str(endTime) + "\tFinishing execution...\n") print("Total time used:\t" + general.emphasis(str(endTime - startTime))) print("Average seconds/query:\t" + general.emphasis( str((endTime - startTime).total_seconds() / len(emails))) + " seconds\n") if not args.quiet: # Urging users to place an issue on Github... print(banner.footer) if params: return results
def main(args): """ Main function to launch phonefy. The function is created in this way so as to let other applications make use of the full configuration capabilities of the application. The parameters received are used as parsed by this modules `getParser()`. Args: ----- args: The parameters as processed by this modules `getParser()`. Results: -------- Returns a list with i3visio entities. """ results = [] if not args.quiet: print(general.title(banner.text)) sayingHello = """ mailfy.py Copyright (C) F. Brezo and Y. Rubio (i3visio) 2016-2017 This program comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. For additional info, visit """ + general.LICENSE_URL + "\n" print(general.title(sayingHello)) # Displaying a warning if this is being run in a windows system if sys.platform == 'win32': print( general.warning( """OSRFramework has detected that you are running mailfy.py in a Windows system. As the "emailahoy" library is NOT working properly there, "validate_email" will be used instead. Verification may be slower though.""")) if args.license: general.showLicense() else: # Grabbing the list of global domains if args.is_leaked: domains = LEAKED_DOMAINS # Processing the options returned to remove the "all" option elif "all" in args.domains: domains = EMAIL_DOMAINS else: # processing only the given domains and excluding the ones provided domains = [] for d in args.domains: if d not in args.exclude: domains.append(d) if args.create_emails: emails = grabEmails(nicksFile=args.create_emails, domains=domains, excludeDomains=args.exclude) else: emails = grabEmails(emails=args.emails, emailsFile=args.emails_file, nicks=args.nicks, nicksFile=args.nicks_file, domains=domains, excludeDomains=args.exclude) startTime = dt.datetime.now() if not args.is_leaked: # Showing the execution time... if not args.quiet: print( str(startTime) + "\tStarting search in " + general.emphasis(str(len(emails))) + " different emails:\n" + json.dumps(emails, indent=2, sort_keys=True) + "\n") print(general.emphasis("\tPress <Ctrl + C> to stop...\n")) # Perform searches, using different Threads tmp = performSearch(emails, args.threads) # We make a strict copy of the object results = list(tmp) if not args.quiet: now = dt.datetime.now() print( str(now) + "\tMailfy has found " + general.emphasis(str(len(results))) + " existing email(s). Has it been leaked somewhere?") # Verify the existence of the mails found as leaked emails. for r in tmp: # We assume that the first attribute is always the email query = r["attributes"][0]["value"] leaks = hibp.checkIfEmailWasHacked(query) if len(leaks) > 0: if not args.quiet: print( general.success("\t" + query + " has been found in at least " + str(len(leaks)) + " different leaks.")) email, alias, domain = getMoreInfo(query) for leak in leaks: # Creating a new full entity from scratch new = {} new["type"] = "i3visio.profile" new["value"] = leak["value"] + " - " + alias["value"] new["attributes"] = [] new["attributes"].append(email) new["attributes"].append(alias) new["attributes"].append(domain) # leak contains a i3visio.platform built by HIBP new["attributes"].append(leak) results.append(new) else: if not args.quiet: print( general.warning( "\t" + query + " has NOT been found on any leak yet.")) else: if not args.quiet: print( "\n" + str(startTime) + "\tStarting search of " + general.emphasis(str(len(emails))) + " different emails in leaked databases.\nNote that this will take between 1 and 2 seconds per query due to HIBP API restrictions:\n" + json.dumps(emails, indent=2, sort_keys=True) + "\n") print(general.emphasis("\tPress <Ctrl + C> to stop...\n")) # Perform is_leaked function results = [] for i, e in enumerate(emails): if not args.quiet: print("\t" + str(i + 1) + "/" + str(len(emails)) + " - Searching if " + e + " has been leaked somewhere...") leaks = hibp.checkIfEmailWasHacked(e) if len(leaks) > 0: if not args.quiet: print( general.success("\t" + e + " has been found in at least " + str(len(leaks)) + " different leaks.")) email, alias, domain = getMoreInfo(e) for leak in leaks: # Creating a new full entity from scratch new = {} new["type"] = "i3visio.profile" new["value"] = leak["value"] + " - " + alias["value"] new["attributes"] = [] new["attributes"].append(email) new["attributes"].append(alias) new["attributes"].append(domain) # leak contains a i3visio.platform built by HIBP new["attributes"].append(leak) results.append(new) # Trying to store the information recovered if args.output_folder != None: if not os.path.exists(args.output_folder): os.makedirs(args.output_folder) # Grabbing the results fileHeader = os.path.join(args.output_folder, args.file_header) for ext in args.extension: # Generating output files general.exportUsufy(results, ext, fileHeader) # Showing the information gathered if requested if not args.quiet: now = dt.datetime.now() print( "\n" + str(now) + "\tA summary of the results obtained are shown in the following table:\n" ) print(general.success(general.usufyToTextExport(results))) now = dt.datetime.now() print( "\n" + str(now) + "\tYou can find all the information collected in the following files:" ) for ext in args.extension: # Showing the output files print(general.emphasis("\t" + fileHeader + "." + ext)) # Showing the execution time... if not args.quiet: endTime = dt.datetime.now() print("\n" + str(endTime) + "\tFinishing execution...\n") print("Total time used:\t" + general.emphasis(str(endTime - startTime))) print("Average seconds/query:\t" + general.emphasis( str((endTime - startTime).total_seconds() / len(emails))) + " seconds\n") if not args.quiet: # Urging users to place an issue on Github... print(banner.footer) return results
def emailToBreachedAccounts(email=None): ''' Method that checks if the given email is stored in the HIBP website. :param email: email to verify. ''' me = MaltegoTransform() jsonData = HIBP.checkIfEmailWasHacked(email=email) # This returns a dictionary like: # [{"Title":"Adobe","Name":"Adobe","Domain":"adobe.com","BreachDate":"2013-10-4","AddedDate":"2013-12-04T00:12Z","PwnCount":152445165,"Description":"The big one. In October 2013, 153 million Adobe accounts were breached with each containing an internal ID, username, email, <em>encrypted</em> password and a password hint in plain text. The password cryptography was poorly done and <a href=\"http://stricture-group.com/files/adobe-top100.txt\" target=\"_blank\">many were quickly resolved back to plain text</a>. The unencrypted hints also <a href=\"http://www.troyhunt.com/2013/11/adobe-credentials-and-serious.html\" target=\"_blank\">disclosed much about the passwords</a> adding further to the risk that hundreds of millions of Adobe customers already faced.","DataClasses":["Email addresses","Password hints","Passwords","Usernames"]}] newEntities = [] for breach in jsonData: # Defining the main entity aux = {} aux["type"] = "i3visio.breach" aux["value"] = str(breach["Title"]) aux["attributes"] = [] # Defining the attributes recovered att = {} att["type"] = "i3visio.domain" att["value"] = str(breach["Domain"]) att["attributes"] = [] aux["attributes"].append(att) att = {} att["type"] = "@added_date" att["value"] = str(breach["AddedDate"]) att["attributes"] = [] aux["attributes"].append(att) att = {} att["type"] = "@breach_date" att["value"] = str(breach["BreachDate"]) att["attributes"] = [] aux["attributes"].append(att) att = {} att["type"] = "@total_pwned" att["value"] = str(breach["PwnCount"]) att["attributes"] = [] aux["attributes"].append(att) att = {} att["type"] = "@description" att["value"] = str(breach["Description"]) att["attributes"] = [] aux["attributes"].append(att) # Appending the entity newEntities.append(aux) me.addListOfEntities(newEntities) # Returning the output text... me.returnOutput()