├── LICENSE ├── README.md ├── __pycache__ └── __init__.cpython-39.pyc ├── config.json ├── core ├── __init__.py ├── __pycache__ │ ├── __init__.cpython-39.pyc │ ├── _argparse.cpython-39.pyc │ ├── _logo.cpython-39.pyc │ ├── _menu.cpython-39.pyc │ ├── _modules.cpython-39.pyc │ ├── _permutations.cpython-39.pyc │ ├── _report.cpython-39.pyc │ ├── _results.cpython-39.pyc │ ├── _run.cpython-39.pyc │ └── colors.cpython-39.pyc ├── _argparse.py ├── _logo.py ├── _menu.py ├── _modules.py ├── _permutations.py ├── _report.py ├── _results.py ├── _run.py ├── colors.py ├── ressources │ ├── report.css │ ├── report.js │ └── report.tpl └── services │ ├── __pycache__ │ ├── _domain.cpython-39.pyc │ ├── _email.cpython-39.pyc │ ├── _entertainment.cpython-39.pyc │ ├── _forum.cpython-39.pyc │ ├── _money.cpython-39.pyc │ ├── _music.cpython-39.pyc │ ├── _porn.cpython-39.pyc │ ├── _programming.cpython-39.pyc │ ├── _social.cpython-39.pyc │ └── _tchat.cpython-39.pyc │ ├── _domain.py │ ├── _email.py │ ├── _entertainment.py │ ├── _forum.py │ ├── _money.py │ ├── _music.py │ ├── _porn.py │ ├── _programming.py │ ├── _social.py │ └── _tchat.py ├── modules ├── domain │ ├── __pycache__ │ │ └── domain.cpython-39.pyc │ └── domain.py └── email │ └── email.py ├── profil3r.py └── setup.py /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Rog3rSm1th 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | Find the profiles of a person on social networks, as well as their email addresses
3 |
4 |
5 |
6 |
7 |
8 |
11 | Installation 12 | | 13 | Features 14 | | 15 | Report 16 | | 17 | Contact 18 |
19 | 20 | 21 | Profil3r is an [OSINT](https://en.wikipedia.org/wiki/Open-source_intelligence) tool that allows you to find potential profiles of a person on social networks, as well as their email addresses. This program also alerts you to the presence of a data leak for the found emails. 22 | 23 |  24 | ## 💡 Prerequisite 25 | [Python 3](https://www.python.org/) 26 | 27 | ## Installation 28 | 29 | Install PyInquirer, jinja2 and bs4 : 30 | 31 | ```bash 32 | pip3 install PyInquirer jinja2 bs4 33 | ``` 34 | 35 | Install Profil3r : 36 | 37 | ```bash 38 | git clone https://github.com/amitrajputfff/Profil3r.git 39 | cd Profil3r/ 40 | sudo python3 setup.py install 41 | ``` 42 | ## Features 43 | 44 | #### 📙 Domain 45 | - [x] TLD (.com, .org, .net, etc...) 46 | 47 | #### ✉️ Emails 48 | - [x] Data leaks 49 | - [x] Emails 50 | 51 | #### 🌐 Social 52 | 53 | |Service | Profile Scraping | 54 | |-------------|------------------| 55 | | Instagram | Yes ✔️ | 56 | | Facebook | No | 57 | | Twitter | Yes ✔️ | 58 | | Tiktok | No | 59 | | Pinterest | No | 60 | | Linktr.ee | Yes ✔️ | 61 | | MySpace | Yes ✔️ | 62 | | Flickr | Yes ✔️ | 63 | | DeviantArt | No | 64 | | GoodReads | No | 65 | 66 | #### 🎵 Music 67 | 68 | |Service | Profile Scraping | 69 | |-------------|------------------| 70 | | Soundcloud | No | 71 | | Spotify | No | 72 | | Smule | No | 73 | 74 | #### 💻 Programming 75 | 76 | |Service | Profile Scraping | 77 | |-------------|------------------| 78 | | Github | Yes ✔️ | 79 | | Pastebin | Yes ✔️ | 80 | | LessWrong | Yes ✔️ | 81 | | Repl.it | No | 82 | | Cracked.to | No | 83 | 84 | #### 💬 Forum 85 | 86 | |Service | Profile Scraping | 87 | |---------------|------------------| 88 | | 0x00sec.org | No | 89 | | Hackernews | Yes ✔️ | 90 | | Jeuxvideo.com | Yes ✔ | 91 | 92 | #### 🗣️ Tchat 93 | 94 | |Service | Profile Scraping | 95 | |---------------|------------------| 96 | | Skype | No | 97 | 98 | #### 📺 Entertainment 99 | 100 | |Service | Profile Scraping | 101 | |---------------|------------------| 102 | | Dailymotion | No | 103 | | Vimeo | No | 104 | 105 | #### 🚫 Porn 106 | 107 | |Service | Profile Scraping | 108 | |---------------|------------------| 109 | | PornHub | Yes ✔ | 110 | | RedTube | No | 111 | | XVideos | No | 112 | 113 | #### 💸 Money 114 | 115 | |Service | Profile Scraping | 116 | |---------------|------------------| 117 | | BuyMeACoffee | No | 118 | | Patreon | No | 119 | 120 | #### 🕸️ Web Hosting 121 | 122 | |Service | Profile Scraping | 123 | |---------------|------------------| 124 | | AboutMe | Yes ✔ | 125 | | SlideShare | Yes ✔ | 126 | | WordPress | No | 127 | 128 | #### 🎮 Gaming 129 | 130 | |Service | Profile Scraping | 131 | |---------------|------------------| 132 | | Gaming | No | 133 | 134 | #### 📰 Medias 135 | 136 | |Service | Profile Scraping | 137 | |---------------|------------------| 138 | | Medium | No | 139 | 140 | 141 | ## Report 142 | 143 | #### JSON 144 | 145 | A report in JSON format is automatically generated in the `reports/json` folder 146 | 147 | #### CSV 148 | 149 | A report in CSV format is automatically generated in the `reports/csv` folder 150 | 151 | #### HTML 152 | 153 | A report in HTML format is automatically generated in the `reports/html` folder, you can access it in your webbrowser 154 | 155 |  156 | 157 | ## ⚙️ The config.json file 158 | 159 | You can modify the paths of the reports, the separators and the services Profil3r will search by default in the `config.json` file 160 | 161 | | Field | Type | Default | Description | 162 | |-----------------|--------|------------------------------------|-----------------------------------------------------------------------------------------------------| 163 | | report_elements | Array | `["email", "facebook", "twitter"]` | List of the services for which profil3r will search | 164 | | json_report_path | String | `"./reports/json/{}.json"` | The path of the report's JSON file, this path must include a {} which corresponds to the file name | 165 | | html_report_path | String | `"./reports/html/{}.html"` | The path of the report's HTML file, this path must include a {} which corresponds to the file name | 166 | | csv_report_path | String | `"./reports/csv/{}.csv"` | The path of the report's CSV file, this path must include a {} which corresponds to the file name | 167 | separators |Object|`{"Dot": ".", "Dash": "-", "Underscore": "_"}`| List of separators to separate items, for example: `john.doe`, `john-doe`, `john_doe`| 168 | 169 | ## 📚 Example 170 | 171 | ```bash 172 | python3 profil3r.py -p john doe 173 | ``` 174 | 175 | ## 📝 License 176 | 177 | This project is under the MIT license. 178 | 179 | ## Contact 180 | 181 | for any remark, suggestion or job offer, you can contact me at AmitR3245@gmail.com or on twitter [@AmitRaj51760706](https://twitter.com/AmitRaj51760706) 182 | -------------------------------------------------------------------------------- /__pycache__/__init__.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amitrajputfff/Profil3r/c556d195d04db1ad9281f27dd2ed2c55f161753d/__pycache__/__init__.cpython-39.pyc -------------------------------------------------------------------------------- /config.json: -------------------------------------------------------------------------------- 1 | { 2 | "config_path": "./config.json", 3 | "separators": { 4 | "Dot": ".", 5 | "Dash": "-", 6 | "Underscore": "_" 7 | }, 8 | "report_elements": [ 9 | "email", 10 | "facebook", 11 | "twitter" 12 | ], 13 | "json_report_path": "./reports/json/{}.json", 14 | "html_report_path": "./reports/html/{}.html", 15 | "csv_report_path": "./reports/csv/{}.csv", 16 | "plateform": { 17 | "domain": { 18 | "rate_limit": 100, 19 | "format": "http://{permutation}.{domain}", 20 | "TLD": [ 21 | "org", 22 | "com", 23 | "net" 24 | ], 25 | "type": "domain" 26 | }, 27 | "email": { 28 | "rate_limit": 1500, 29 | "domains": [ 30 | "gmail.com", 31 | "yahoo.com", 32 | "hotmail.com" 33 | ], 34 | "format": "{permutation}@{domain}", 35 | "type": "email" 36 | }, 37 | "facebook": { 38 | "rate_limit": 1000, 39 | "format": "https://facebook.com/{permutation}", 40 | "type": "social" 41 | }, 42 | "twitter": { 43 | "rate_limit": 1000, 44 | "format": "https://twitter.com/{permutation}", 45 | "type": "social" 46 | }, 47 | "tiktok": { 48 | "rate_limit": 1500, 49 | "format": "https://www.tiktok.com/@{permutation}?", 50 | "type": "social" 51 | }, 52 | "instagram": { 53 | "rate_limit": 1000, 54 | "format": "https://instagram.com/{permutation}", 55 | "type": "social" 56 | }, 57 | "soundcloud": { 58 | "rate_limit": 1000, 59 | "format": "https://soundcloud.com/{permutation}", 60 | "type": "music" 61 | }, 62 | "github": { 63 | "rate_limit": 1000, 64 | "format": "https://github.com/{permutation}", 65 | "type": "programming" 66 | }, 67 | "0x00sec": { 68 | "rate_limit": 1000, 69 | "format": "https://0x00sec.org/u/{permutation}", 70 | "type": "forum" 71 | }, 72 | "jeuxvideo.com": { 73 | "rate_limit": 1000, 74 | "format": "https://www.jeuxvideo.com/profil/{permutation}?mode=infos", 75 | "type": "forum" 76 | }, 77 | "skype": { 78 | "rate_limit": 1000, 79 | "format": "{permutation}", 80 | "type": "tchat" 81 | }, 82 | "dailymotion": { 83 | "rate_limit": 1000, 84 | "format": "https://dailymotion.com/{permutation}", 85 | "type": "entertainment" 86 | }, 87 | "pastebin": { 88 | "rate_limit": 1000, 89 | "format": "https://pastebin.com/u/{permutation}", 90 | "type": "programming" 91 | }, 92 | "spotify": { 93 | "rate_limit": 1000, 94 | "format": "https://open.spotify.com/user/{permutation}", 95 | "type": "music" 96 | }, 97 | "pinterest": { 98 | "rate_limit": 1000, 99 | "format": "https://pinterest.fr/{permutation}", 100 | "type": "social" 101 | }, 102 | "hackernews": { 103 | "rate_limit": 1000, 104 | "format": "https://news.ycombinator.com/user?id={permutation}", 105 | "type": "forum" 106 | }, 107 | "pornhub": { 108 | "rate_limit": 1000, 109 | "format": "https://pornhub.com/users/{permutation}", 110 | "type": "porn" 111 | }, 112 | "redtube": { 113 | "rate_limit": 1000, 114 | "format": "https://redtube.com/users/{permutation}", 115 | "type": "porn" 116 | }, 117 | "replit": { 118 | "rate_limit": 1000, 119 | "format": "https://replit.com/@{permutation}", 120 | "type": "programming" 121 | }, 122 | "linktree": { 123 | "rate_limit": 1000, 124 | "format": "https://linktr.ee/{permutation}", 125 | "type": "social" 126 | }, 127 | "buymeacoffee": { 128 | "rate_limit": 1000, 129 | "format": "https://buymeacoffee.com/{permutation}", 130 | "type": "money" 131 | }, 132 | "xvideos": { 133 | "rate_limit": 1000, 134 | "format": "https://www.xvideos.com/profiles/{permutation}", 135 | "type": "porn" 136 | }, 137 | "myspace": { 138 | "rate_limit": 1000, 139 | "format": "https://myspace.com/{permutation}", 140 | "type": "social" 141 | }, 142 | "crackedto": { 143 | "rate_limit": 1000, 144 | "format": "https://cracked.to/{permutation}", 145 | "type": "forum" 146 | }, 147 | "vimeo": { 148 | "rate_limit": 1000, 149 | "format": "https://vimeo.com/{permutation}", 150 | "type": "entertainment" 151 | }, 152 | "patreon": { 153 | "rate_limit": 1000, 154 | "format": "https://www.patreon.com/{permutation}", 155 | "type": "money" 156 | } 157 | } 158 | } -------------------------------------------------------------------------------- /core/__init__.py: -------------------------------------------------------------------------------- 1 | from profil3r.modules.email import email 2 | import json 3 | 4 | class Core(object): 5 | 6 | from ._menu import menu 7 | from ._permutations import get_permutations 8 | from ._results import print_results 9 | from ._run import run 10 | from ._report import generate_report, generate_json_report, generate_HTML_report, generate_csv_report 11 | from ._modules import modules_update, get_report_modules 12 | from ._logo import print_logo 13 | from ._argparse import parse_arguments 14 | 15 | from .services._social import facebook, twitter, instagram, tiktok, pinterest, linktree, myspace 16 | from .services._forum import zeroxzerozerosec, jeuxvideo, hackernews, crackedto 17 | from .services._programming import github, pastebin, replit 18 | from .services._tchat import skype 19 | from .services._music import soundcloud, spotify 20 | from .services._entertainment import dailymotion, vimeo 21 | from .services._email import email 22 | from .services._porn import pornhub, redtube, xvideos 23 | from .services._money import buymeacoffee, patreon 24 | from .services._domain import domain 25 | 26 | def __init__(self, config_path): 27 | self.version = "1.3.5" 28 | 29 | with open(config_path, 'r') as f: 30 | self.CONFIG = json.load(f) 31 | 32 | self.separators = [] 33 | self.result = {} 34 | self.permutations_list = [] 35 | self.modules = { 36 | # Emails 37 | "email": {"method" : self.email }, 38 | # Social 39 | "facebook": {"method" : self.facebook}, 40 | "twitter": {"method" : self.twitter}, 41 | "tiktok": {"method" : self.tiktok}, 42 | "instagram": {"method" : self.instagram}, 43 | "pinterest": {"method" : self.pinterest}, 44 | "linktree": {"method" : self.linktree}, 45 | "myspace": {"method" : self.myspace}, 46 | # Music 47 | "soundcloud": {"method" : self.soundcloud}, 48 | "spotify": {"method" : self.spotify}, 49 | # Programming 50 | "github": {"method" : self.github}, 51 | "pastebin": {"method" : self.pastebin}, 52 | "replit": {"method" : self.replit}, 53 | # Forums: 54 | "0x00sec": {"method" : self.zeroxzerozerosec}, 55 | "jeuxvideo.com": {"method" : self.jeuxvideo}, 56 | "hackernews": {"method" : self.hackernews}, 57 | "crackedto": {"method" : self.crackedto}, 58 | # Tchat 59 | "skype": {"method" : self.skype}, 60 | # Entertainment 61 | "dailymotion": {"method" : self.dailymotion}, 62 | "vimeo": {"method" : self.vimeo}, 63 | # Porn 64 | "pornhub": {"method" : self.pornhub}, 65 | "redtube": {"method" : self.redtube}, 66 | "xvideos": {"method" : self.xvideos}, 67 | # Money 68 | "buymeacoffee": {"method" : self.buymeacoffee}, 69 | "patreon": {"method" : self.patreon}, 70 | # Domain 71 | "domain": {"method" : self.domain} 72 | } -------------------------------------------------------------------------------- /core/__pycache__/__init__.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amitrajputfff/Profil3r/c556d195d04db1ad9281f27dd2ed2c55f161753d/core/__pycache__/__init__.cpython-39.pyc -------------------------------------------------------------------------------- /core/__pycache__/_argparse.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amitrajputfff/Profil3r/c556d195d04db1ad9281f27dd2ed2c55f161753d/core/__pycache__/_argparse.cpython-39.pyc -------------------------------------------------------------------------------- /core/__pycache__/_logo.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amitrajputfff/Profil3r/c556d195d04db1ad9281f27dd2ed2c55f161753d/core/__pycache__/_logo.cpython-39.pyc -------------------------------------------------------------------------------- /core/__pycache__/_menu.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amitrajputfff/Profil3r/c556d195d04db1ad9281f27dd2ed2c55f161753d/core/__pycache__/_menu.cpython-39.pyc -------------------------------------------------------------------------------- /core/__pycache__/_modules.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amitrajputfff/Profil3r/c556d195d04db1ad9281f27dd2ed2c55f161753d/core/__pycache__/_modules.cpython-39.pyc -------------------------------------------------------------------------------- /core/__pycache__/_permutations.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amitrajputfff/Profil3r/c556d195d04db1ad9281f27dd2ed2c55f161753d/core/__pycache__/_permutations.cpython-39.pyc -------------------------------------------------------------------------------- /core/__pycache__/_report.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amitrajputfff/Profil3r/c556d195d04db1ad9281f27dd2ed2c55f161753d/core/__pycache__/_report.cpython-39.pyc -------------------------------------------------------------------------------- /core/__pycache__/_results.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amitrajputfff/Profil3r/c556d195d04db1ad9281f27dd2ed2c55f161753d/core/__pycache__/_results.cpython-39.pyc -------------------------------------------------------------------------------- /core/__pycache__/_run.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amitrajputfff/Profil3r/c556d195d04db1ad9281f27dd2ed2c55f161753d/core/__pycache__/_run.cpython-39.pyc -------------------------------------------------------------------------------- /core/__pycache__/colors.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amitrajputfff/Profil3r/c556d195d04db1ad9281f27dd2ed2c55f161753d/core/__pycache__/colors.cpython-39.pyc -------------------------------------------------------------------------------- /core/_argparse.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | 3 | # Usage : profil3r.py [-h] -p PROFILE [PROFILE ...] 4 | # Parse arguments from the command line using argparse 5 | def parse_arguments(self): 6 | parser = argparse.ArgumentParser(description='Profil3r is an OSINT tool that allows you to find the differents social accounts, domains and emails used by a person') 7 | parser = argparse.ArgumentParser() 8 | 9 | parser.add_argument('-p', '--profile', required=True, nargs='+', help="parts of the username that you are looking for, e.g. : john doe") 10 | args = parser.parse_args() 11 | 12 | # Items passed from the command line 13 | self.items = args.profile -------------------------------------------------------------------------------- /core/_logo.py: -------------------------------------------------------------------------------- 1 | from profil3r.core.colors import Colors 2 | 3 | def print_logo(self): 4 | print(Colors.OKGREEN + Colors.BOLD + ''' 5 | ____ _____ _______ 6 | / __ \_________ / __(_) /__ /_____ 7 | / /_/ / ___/ __ \/ /_/ / / /_ ___/ 8 | / ____/ / / /_/ / __/ / /___/ / / 9 | /_/ /_/ \____/_/ /_/_//____/_/ 10 | 11 | ''' + Colors.ENDC) 12 | 13 | print(Colors.HEADER + "Version {version} - Developped by Rog3rSm1th".format(version=self.version)) 14 | print("You can buy me a coffee at : https://www.buymeacoffee.com/givocefo\n" + Colors.ENDC) -------------------------------------------------------------------------------- /core/_menu.py: -------------------------------------------------------------------------------- 1 | from PyInquirer import prompt, Separator 2 | 3 | # The menu displays a list of checkboxes, which allows the user to select the separators and modules he wants to use 4 | def menu(self): 5 | # 6 | # SEPARATORS 7 | # 8 | 9 | # Get a list of all existing separators 10 | separators = self.CONFIG["separators"] 11 | 12 | separators_menu = [ 13 | { 14 | 'type': 'checkbox', 15 | 'qmark': '⚙️ ', 16 | 'message': 'Select separators', 17 | 'name': 'separators', 18 | 'choices': [] 19 | } 20 | ] 21 | 22 | for separator, value in separators.items(): 23 | # Separator title 24 | separators_menu[0]["choices"].append(Separator("{} - Exemple : john{}doe".format(separator, value))) 25 | # Separator 26 | separators_menu[0]["choices"].append({"name": value}) 27 | 28 | self.separators = prompt(separators_menu)["separators"] 29 | 30 | # 31 | # SERVICES 32 | # 33 | 34 | # Get a list of all existing modules 35 | modules_list = sorted([module for module in self.CONFIG["plateform"]]) 36 | # Create a list of all existing categories 37 | categories = sorted(list(set([content["type"] for module, content in self.CONFIG["plateform"].items()]))) 38 | 39 | services_menu = [ 40 | { 41 | 'type': 'checkbox', 42 | 'qmark': '⚙️ ', 43 | 'message': 'Select services', 44 | 'name': 'modules', 45 | 'choices': [ 46 | 47 | ], 48 | 'validate': lambda answer: 'You must choose at least one service !' \ 49 | if len(answer) == 0 else True 50 | } 51 | ] 52 | 53 | for category in categories: 54 | # Category title 55 | services_menu[0]["choices"].append(Separator(category.upper())) 56 | # Append category items 57 | for module in modules_list: 58 | if self.CONFIG["plateform"][module]["type"] == category: 59 | services_menu[0]["choices"].append( 60 | { 61 | 'name': module, 62 | # Checked by default 63 | 'checked': module in self.CONFIG["report_elements"] 64 | }) 65 | 66 | modules = prompt(services_menu)["modules"] 67 | self.modules_update(modules) -------------------------------------------------------------------------------- /core/_modules.py: -------------------------------------------------------------------------------- 1 | import json 2 | import os 3 | 4 | # Change the "report_elements" array in the config.json file 5 | # input is an array, for exemple : ["facebook", "twitter"] 6 | def modules_update(self, modules): 7 | new_config = self.CONFIG 8 | new_config["report_elements"] = modules 9 | 10 | try: 11 | with open(self.CONFIG["config_path"], 'w') as fp: 12 | json.dump(new_config, fp, indent=4) 13 | except Exception as e: 14 | print(e) 15 | 16 | # Remove modules that do not exist 17 | def get_report_modules(self): 18 | return list( set(self.CONFIG["report_elements"]) & set(list(self.CONFIG["plateform"].keys())) ) -------------------------------------------------------------------------------- /core/_permutations.py: -------------------------------------------------------------------------------- 1 | from itertools import chain, combinations, permutations 2 | 3 | # return all possible permutation for a username 4 | # exemple : ["john", "doe"] -> ("john", "doe", "johndoe", "doejohn", "john.doe", "doe.john") 5 | def get_permutations(self): 6 | [self.items.append(separator) for separator in self.separators] 7 | 8 | combinations_list = list(chain(*map(lambda x: combinations(self.items, x), range(1, len(self.items) + 1)))) 9 | for combination in combinations_list: 10 | for perm in list(permutations(combination)): 11 | 12 | # True if there are two consecutive separators in the permutation, for exemple : ["john", ".", "-", "doe"] 13 | consecutives_separators = False in [(not perm[i] in self.separators) or (not perm[i + 1] in self.separators) for i in range(len(perm) - 1)] 14 | 15 | # Remove combinations that start or end by a dot or have consecutives separators 16 | if not perm[0] in self.separators and not perm[-1] in self.separators and not consecutives_separators: 17 | self.permutations_list.append("".join(perm)) -------------------------------------------------------------------------------- /core/_report.py: -------------------------------------------------------------------------------- 1 | from profil3r.core.colors import Colors 2 | import json 3 | import os 4 | from jinja2 import Template 5 | import datetime 6 | import csv 7 | 8 | # Generate a report in JSON format containing the collected data 9 | # Report will be in "./reports/json" 10 | # You can modify th path in the config.json file 11 | def generate_json_report(self): 12 | # Create ./reports/json directory if not exists 13 | if not os.path.exists('reports/json'): 14 | os.makedirs('reports/json') 15 | 16 | separators = [value for key, value in self.CONFIG["separators"].items()] 17 | 18 | file_name = self.CONFIG["json_report_path"].format("_".join([item for item in self.items if item not in separators])) 19 | try: 20 | with open(file_name, 'w') as fp: 21 | json.dump(self.result, fp, indent=2) 22 | except Exception as e: 23 | print(e) 24 | 25 | print("\n" + Colors.BOLD + "[+] " + Colors.ENDC + "JSON report was generated in {}".format(file_name)) 26 | 27 | # Generate a report in HTML format containing the collected data 28 | # Report will be in "./reports/html" 29 | # You can modify th path in the config.json file 30 | def generate_HTML_report(self): 31 | # Create ./reports/html directory if not exists 32 | if not os.path.exists('reports/html'): 33 | os.makedirs('reports/html') 34 | 35 | separators = [value for key, value in self.CONFIG["separators"].items()] 36 | 37 | dirname = os.path.dirname(__file__) 38 | html_content = open(os.path.join(dirname, './ressources/report.tpl')).read() 39 | css_content = open(os.path.join(dirname, './ressources/report.css')).read() 40 | js_content = open(os.path.join(dirname, './ressources/report.js')).read() 41 | 42 | html_report = Template(html_content).render( 43 | title = " ".join(self.items), 44 | time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"), 45 | version = self.version, 46 | results = self.result.items(), 47 | style = css_content, 48 | script = js_content 49 | ) 50 | 51 | file_name = self.CONFIG["html_report_path"].format("_".join([item for item in self.items if item not in separators])) 52 | try: 53 | with open(file_name, 'w') as fp: 54 | fp.write(html_report) 55 | except Exception as e: 56 | print(e) 57 | 58 | print(Colors.BOLD + "[+] " + Colors.ENDC + "HTML report was generated in {}".format(file_name)) 59 | 60 | # Generate a report in CSV format containing the collected data 61 | # Report will be in "./reports/csv" 62 | # You can modify th path in the config.json file 63 | def generate_csv_report(self): 64 | # Create ./reports/csv directory if not exists 65 | if not os.path.exists('reports/csv'): 66 | os.makedirs('reports/csv') 67 | 68 | separators = [value for key, value in self.CONFIG["separators"].items()] 69 | 70 | file_name = self.CONFIG["csv_report_path"].format("_".join([item for item in self.items if item not in separators])) 71 | try: 72 | with open(file_name, 'w', newline='') as fp: 73 | writer = csv.writer(fp) 74 | # columns titles 75 | writer.writerow(["service", "category", "profile", "breached"]) 76 | 77 | for service, result in self.result.items(): 78 | result_service = service 79 | result_type = result["type"] 80 | for account in result["accounts"]: 81 | result_value = account["value"] 82 | result_breached = account["breached"] if result_type == "email" else False 83 | # row values 84 | writer.writerow([result_service, result_type, result_value, result_breached]) 85 | 86 | except Exception as e: 87 | print(e) 88 | 89 | print(Colors.BOLD + "[+] " + Colors.ENDC + "CSV report was generated in {}".format(file_name)) 90 | 91 | def generate_report(self): 92 | # Create ./reports directory if not exists 93 | if not os.path.exists('reports'): 94 | os.makedirs('reports') 95 | 96 | self.generate_json_report() 97 | self.generate_HTML_report() 98 | self.generate_csv_report() -------------------------------------------------------------------------------- /core/_results.py: -------------------------------------------------------------------------------- 1 | from profil3r.core.colors import Colors 2 | 3 | def print_results(self, element): 4 | if element in self.result: 5 | element_results = self.result[element] 6 | 7 | # Section title 8 | 9 | # No results 10 | if not element_results["accounts"]: 11 | print("\n" + Colors.BOLD + "└──" + Colors.ENDC + Colors.OKGREEN + " {} ❌".format(element.upper()) + Colors.ENDC + Colors.FAIL + " (No results)" + Colors.ENDC) 12 | return 13 | # Results 14 | else: 15 | print("\n" + Colors.BOLD + "└──" + Colors.ENDC + Colors.OKGREEN + " {} ✔️".format(element.upper()) + Colors.ENDC) 16 | 17 | # General case 18 | if element != "email": 19 | 20 | for account in element_results["accounts"]: 21 | print(Colors.BOLD + " ├──" + Colors.ENDC + Colors.HEADER + account["value"] + Colors.ENDC) 22 | 23 | # Emails case 24 | else: 25 | possible_emails_list = [account["value"] for account in element_results["accounts"]] 26 | 27 | for account in element_results["accounts"]: 28 | # We pad the emails with spaces for better visibility 29 | longest_email_length = len(max(possible_emails_list)) 30 | email = account["value"].ljust(longest_email_length + 5) 31 | 32 | # Breached account 33 | if account["breached"]: 34 | print(Colors.BOLD + " ├──" + Colors.ENDC + Colors.HEADER + email + Colors.FAIL + "[BREACHED]" + Colors.ENDC) 35 | # Safe account 36 | else: 37 | print(Colors.BOLD + " ├──" + Colors.ENDC + Colors.HEADER + email + Colors.OKGREEN + "[SAFE]" + Colors.ENDC) -------------------------------------------------------------------------------- /core/_run.py: -------------------------------------------------------------------------------- 1 | from profil3r.core.colors import Colors 2 | import threading 3 | 4 | def run(self): 5 | self.print_logo() 6 | # Get arguments from the command line 7 | self.parse_arguments() 8 | 9 | self.menu() 10 | self.get_permutations() 11 | 12 | # Number of permutations to test per service 13 | print(Colors.BOLD + "[+]" + Colors.ENDC + " {} permutations to test for each service, you can reduce this number by selecting less options if it takes too long".format(len(self.permutations_list))) 14 | 15 | modules = self.get_report_modules() 16 | 17 | print("\n" + "Profil3r will search : \n " + Colors.BOLD + "[+] " + Colors.ENDC + "{} \n".format(str('\n ' + Colors.BOLD + "[+] " + Colors.ENDC).join(modules))) 18 | 19 | for module in modules: 20 | thread = threading.Thread(target=self.modules[module]["method"]) 21 | thread.start() 22 | thread.join() 23 | self.generate_report() -------------------------------------------------------------------------------- /core/colors.py: -------------------------------------------------------------------------------- 1 | class Colors: 2 | HEADER = '\033[96m' 3 | OKBLUE = '\033[94m' 4 | OKCYAN = '\033[95m' 5 | OKGREEN = '\033[92m' 6 | WARNING = '\033[93m' 7 | FAIL = '\033[91m' 8 | ENDC = '\033[0m' 9 | BOLD = '\033[1m' 10 | UNDERLINE = '\033[4m' -------------------------------------------------------------------------------- /core/ressources/report.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: #e2e1e0; 3 | text-align: center; 4 | } 5 | 6 | .title { 7 | margin: 5px; 8 | padding: 2px; 9 | overflow-x: hidden !important; 10 | overflow-y: hidden !important; 11 | border: none; 12 | box-shadow: none !important; 13 | } 14 | 15 | a[target="_blank"]::after { 16 | content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAQElEQVR42qXKwQkAIAxDUUdxtO6/RBQkQZvSi8I/pL4BoGw/XPkh4XigPmsUgh0626AjRsgxHTkUThsG2T/sIlzdTsp52kSS1wAAAABJRU5ErkJggg==); 17 | margin: 0 3px 0 5px; 18 | } 19 | 20 | .card { 21 | background: #fff; 22 | border-radius: 2px; 23 | width: 80%; 24 | max-width: 80%; 25 | display: inline-block; 26 | margin: 1rem; 27 | position: relative; 28 | box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24); 29 | overflow-y: scroll; 30 | } 31 | 32 | .searchbar { 33 | display: block; 34 | font-weight:300; 35 | font-size: 25px; 36 | border:0px; 37 | outline: none; 38 | width: 40%; 39 | margin: 10px auto 10px auto; 40 | -webkit-box-sizing: border-box; 41 | -moz-box-sizing: border-box; 42 | box-sizing: border-box; 43 | color: #4b545f; 44 | background: #fff; 45 | padding: 10px 15px; 46 | -webkit-transition: all 0.1s ease-in-out; 47 | -moz-transition: all 0.1s ease-in-out; 48 | -ms-transition: all 0.1s ease-in-out; 49 | -o-transition: all 0.1s ease-in-out; 50 | transition: all 0.1s ease-in-out; 51 | } 52 | 53 | .searchbar:focus { 54 | border-bottom:1px solid #ddd; 55 | } 56 | 57 | table { 58 | text-align: left; 59 | } 60 | 61 | .card::-webkit-scrollbar { 62 | width: 5px; 63 | } 64 | 65 | .card::-webkit-scrollbar-track { 66 | background: #ddd; 67 | } 68 | 69 | .card::-webkit-scrollbar-thumb { 70 | background: #666; 71 | } 72 | 73 | .badge-entertainment { 74 | background-color: #6ab7ff; 75 | } 76 | 77 | .badge-email { 78 | background-color: #ffa4a2; 79 | } 80 | 81 | .badge-social { 82 | background-color: #98ee99; 83 | } 84 | 85 | .badge-forum { 86 | background-color: #efefef; 87 | } 88 | 89 | .badge-porn { 90 | background-color: #e53935; 91 | } 92 | 93 | .badge-domain { 94 | background-color: #82e9de; 95 | } 96 | 97 | .badge-money { 98 | background-color: #6ff9ff; 99 | } 100 | 101 | .badge-music { 102 | background-color: #ffa270; 103 | } 104 | 105 | .badge-programming { 106 | background-color: #ffe54c; 107 | } 108 | 109 | .badge-tchat { 110 | background-color: #df78ef; 111 | } -------------------------------------------------------------------------------- /core/ressources/report.js: -------------------------------------------------------------------------------- 1 | (function(document) { 2 | 'use strict'; 3 | 4 | var LightTableFilter = (function(Arr) { 5 | 6 | var _input; 7 | 8 | function _onInputEvent(e) { 9 | _input = e.target; 10 | var tables = document.getElementsByClassName(_input.getAttribute('data-table')); 11 | Arr.forEach.call(tables, function(table) { 12 | Arr.forEach.call(table.tBodies, function(tbody) { 13 | Arr.forEach.call(tbody.rows, _filter); 14 | }); 15 | }); 16 | } 17 | 18 | function _filter(row) { 19 | var text = row.textContent.toLowerCase(), val = _input.value.toLowerCase(); 20 | row.style.display = text.indexOf(val) === -1 ? 'none' : 'table-row'; 21 | } 22 | 23 | return { 24 | init: function() { 25 | var inputs = document.getElementsByClassName('light-table-filter'); 26 | Arr.forEach.call(inputs, function(input) { 27 | input.oninput = _onInputEvent; 28 | }); 29 | } 30 | }; 31 | })(Array.prototype); 32 | 33 | document.addEventListener('readystatechange', function() { 34 | if (document.readyState === 'complete') { 35 | LightTableFilter.init(); 36 | } 37 | }); 38 | 39 | })(document); -------------------------------------------------------------------------------- /core/ressources/report.tpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |Profiler version {{ version }} - report was generated at {{ time }}
16 |Service | 27 |Category | 28 |Profile | 29 |Breached | 30 |
---|---|---|---|
{{ service }} | 38 |{{ accounts["type"] }} | 39 |40 | {% if (accounts["type"] == "email") or (service == "skype")%} 41 | {{ account['value'] }} 42 | {% else %} 43 | {{ account['value'] }} 44 | {% endif %} 45 | | 46 |47 | {% if (accounts["type"] == "email") %} 48 | {% if account["breached"] %} 49 | ✔️ 50 | {% else %} 51 | ❌ 52 | {% endif %} 53 | {% endif %} 54 | | 55 |