def do_mailfy(self, query, **kwargs): """Verifying a mailfy query in this platform This might be redefined in any class inheriting from Platform. The only condition is that any of this should return an equivalent array. Args: query: The element to be searched. Returns: A list of elements to be appended. A sample output format is as follows: [ { "attributes": [ { "attributes": [], "type": "com.i3visio.Email", "value": "*****@*****.**" }, { "attributes": [], "type": "com.i3visio.Alias", "value": "contacto" }, { "attributes": [], "type": "com.i3visio.Domain", "value": "i3visio.com" }, { "attributes": [], "type": "com.i3visio.Platform", "value": "Twitter" } ], "type": "com.i3visio.Profile", "value": "Twitter - [email protected]" } ] """ if self.check_mailfy(query, **kwargs): expandedEntities = general.expand_entities_from_email(query) r = { "type": "com.i3visio.Profile", "value": self.platformName + " - " + query, "attributes": expandedEntities + [{ "type": "com.i3visio.Platform", "value": self.platformName, "attributes": [] }] } return [r] return []
def check_if_email_was_hacked(email=None, sleep_seconds=1): """Method that checks if the given email is stored in the Dehashed website. Args: email (str): Email to verify. sleep_seconds (int): Number of seconds to wait between calls. Returns: A python structure for the json received. If nothing was found, it will return an empty list. """ leaks = [] # Sleeping just a little bit time.sleep(sleep_seconds) target_url = f"https://www.dehashed.com/search?query=\"{email}\"" # Building API query resp = requests.get(target_url, verify=True) platforms_leaked = re.findall("found in (.+) dump", resp.text) # Reading the text data onto python structures try: for leak in platforms_leaked: # Building the i3visio like structure new = {} new["value"] = f"(Dehashed) {leak} - {email}" new["type"] = "com.i3visio.Profile" new["attributes"] = [{ "type": "com.i3visio.Platform.Leaked", "value": leak, "attributes": [] }, { "type": "@source", "value": "dehashed.com", "attributes": [] }, { "type": "@source_uri", "value": target_url, "attributes": [] }] + general.expand_entities_from_email(email) leaks.append(new) except ValueError: return [] except Exception: print("ERROR: Something happenned when using Dehashed.com.") return [] return leaks
def do_searchfy(self, query, **kwargs): """Verifying a searchfy query in this platform This might be redefined in any class inheriting from Platform. Performing additional procesing may be possible by iterating the requested profiles to extract more entities from the URI would be slow. Sample code may be: if kwargs["process"]: r["attributes"] += json.loads(self.get_info(process=True, mode="usufy", qURI=uri, query=i)) Args: query: The element to be searched. Returns: A list of elements to be appended. """ results = [] print( f"[*] Launching search using the {self.__class__.__name__} module..." ) test = self.check_searchfy(query, **kwargs) if test: # Add flexibility try: try: regexp = self.searchfyAliasRegexp entity_type = "com.i3visio.Alias" except AttributeError: regexp = self.searchfyEmailRegexp entity_type = "com.i3visio.Email" # Recovering all the found aliases in the traditional way ids = re.findall(regexp, test, re.DOTALL) except: # Version 2 of the wrappers verifier = self.modes.get("searchfy") if verifier and verifier.get("alias_regexp"): entity_type = "com.i3visio.Alias" ids = re.findall(verifier.get("alias_regexp"), test, re.DOTALL) if verifier and verifier.get("email_regexp"): entity_type = "com.i3visio.Email" ids = re.findall(verifier.get("email_regexp"), test, re.DOTALL) for j, alias in enumerate(ids): r = { "type": "com.i3visio.Profile", "value": self.platformName + " - " + alias, "attributes": [] } # Appending platform name aux = {} aux["type"] = "com.i3visio.Platform" aux["value"] = self.platformName aux["attributes"] = [] r["attributes"].append(aux) # Appending the alias aux = {} aux["type"] = entity_type aux["value"] = alias aux["attributes"] = [] r["attributes"].append(aux) # Appending the query performed to grab this items aux = {} aux["type"] = "com.i3visio.Search" aux["value"] = query aux["attributes"] = [] r["attributes"].append(aux) # Appending platform URI try: aux = {} aux["type"] = "com.i3visio.URI" uri = self.create_url(word=alias, mode="base") aux["value"] = uri aux["attributes"] = [] r["attributes"].append(aux) except AttributeError: aux = {} aux["type"] = "com.i3visio.URI" uri = self.create_url(word=alias, mode="usufy") aux["value"] = uri aux["attributes"] = [] r["attributes"].append(aux) if entity_type == "com.i3visio.Email": r["attributes"] += general.expand_entities_from_email( alias) # Appending the result to results: in this case only one profile will be grabbed""" results.append(r) return results
def check_if_email_was_hacked(email=None, sleep_seconds=1, api_key=None): """Method that checks if the given email is stored in the HIBP website. This function automatically waits a second to avoid problems with the API rate limit. An example of the json received: ``` [{"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"]}] ``` Args: email (str): Email to verify in HIBP. sleep_seconds (int): Number of seconds to wait between calls. api_key (str): API key for Have I Been Pwned Returns: A python structure for the json received. If nothing was found, it will return an empty list. """ leaks = [] # Sleeping just a little bit time.sleep(sleep_seconds) print("\t[*] Bypassing Cloudflare Restriction...") ua = 'osrframework 0.20.0' if api_key is None: api_key = input("Insert the HIBP API KEY here:\t") headers = {'hibp-api-key': api_key, 'User-Agent': ua} try: cookies, user_agent = cfscrape.get_tokens( 'https://haveibeenpwned.com/api/v3/breachedaccount/[email protected]', user_agent=ua) except requests.exceptions.HTTPError as e: print(f"\t[*] Unauthorised: '{str(e)}'") return leaks api_url = f"https://haveibeenpwned.com/api/v3/breachedaccount/{email}" # Accessing the HIBP API time.sleep(sleep_seconds) # Building API query try: resp = requests.get(api_url, headers=headers, cookies=cookies, verify=True) data = resp.text except requests.exceptions.HTTPError as e: print(f"\t[*] Unauthorised: '{str(e)}'") return leaks # Reading the text data onto python structures try: jsonData = json.loads(data) for e in jsonData: # Building the i3visio like structure new = {} new["value"] = "(HIBP) " + e.get("Name") + " - " + email new["type"] = "com.i3visio.Profile" new["attributes"] = [{ "type": "com.i3visio.Platform.Leaked", "value": e.get("Name"), "attributes": [] }, { "type": "@source", "value": "haveibeenpwned.com", "attributes": [] }, { "type": "@source_uri", "value": api_url, "attributes": [] }, { "type": "@pwn_count", "value": e.get("PwnCount"), "attributes": [] }, { "type": "com.i3visio.Date.Known", "value": e.get("AddedDate"), "attributes": [] }, { "type": "com.i3visio.Date.Breached", "value": e.get("BreachDate"), "attributes": [] }, { "type": "@description", "value": e.get("Description"), "attributes": [] }] + general.expand_entities_from_email(email) leaks.append(new) except ValueError: return [] except Exception: print("ERROR: Something happenned when using HIBP API.") return [] return leaks
def do_mailfy(self, query, **kwargs): """Verifying a mailfy query in this platform This might be redefined in any class inheriting from Platform. The only condition is that any of this should return an equivalent array. Args: query: The element to be searched. Returns: A list of elements to be appended. A sample output format is as follows: [ { "attributes": [ { "attributes": [], "type": "com.i3visio.Email", "value": "*****@*****.**" }, { "attributes": [], "type": "com.i3visio.Alias", "value": "contacto" }, { "attributes": [], "type": "com.i3visio.Domain", "value": "i3visio.com" }, { "attributes": [], "type": "com.i3visio.Platform", "value": "Twitter" } ], "type": "com.i3visio.Profile", "value": "Twitter - [email protected]" } ] """ info = self.check_mailfy(query, **kwargs) results = [] if info: emails = set(re.findall(' <([^\&]+)>', info)) for i, email in enumerate(emails): try: expandedEntities = general.expand_entities_from_email( email) r = { "type": "com.i3visio.Profile", "value": self.platformName + " - " + email, "attributes": expandedEntities + [{ "type": "com.i3visio.Platform", "value": self.platformName, "attributes": [] }] } results.append(r) except IndexError: # A result does not contain a @. pass return results
def pool_function(args): """A wrapper for being able to launch all the threads We will use python-emailahoy library for the verification. Args: args: reception of the parameters for getPageWrapper as a tuple. Returns: dict. A dictionary representing whether the verification was ended successfully. The format is as follows: ``` {"platform": "str(domain["value"])", "status": "DONE", "data": aux} ``` """ def confirm_found(email, status): """Method that confirms the existence of an email This method is needed since different email providers may behave differently. Args: email (str): The email to search. status (int): emailahoy3 returned status. Returns: bool. """ # Dependening on the email ok_is_1 = [ "protonmail.ch", # Expected value on successful matches "protonmail.com", ] for domain in ok_is_1: if domain in args and status == 1: return True ok_is_0 = [ "ya.ru", "yandex.com", ] if args in ok_is_0: if domain in args and status == 0: return True return False try: status = verify_email_address(args) is_valid = confirm_found(args, status) if is_valid: print( f"\t[*] Verification of '{general.success(args)}' status: {general.success(f'Email found ({status})')}" ) else: print( f"\t[*] Verification of '{general.error(args)}' status: {general.error(f'Email not found ({status})')}" ) except Exception as e: print( general.warning( "WARNING. An error was found when performing the search. You can omit this message.\n" + str(e))) is_valid = False entities = general.expand_entities_from_email(args) platform = entities[2]["value"].title() if is_valid: aux = {} aux["type"] = "com.i3visio.Profile" aux["value"] = "Email - " + args aux["attributes"] = entities aux["attributes"].append({ "type": "com.i3visio.Platform", "value": platform, "attributes": [] }) return {"platform": platform, "status": "DONE", "data": aux} else: return {"platform": platform, "status": "ERROR", "data": {}}