|
|
@ -26,7 +26,7 @@ from torrequest import TorRequest
|
|
|
|
from load_proxies import load_proxies_from_csv, check_proxy_list
|
|
|
|
from load_proxies import load_proxies_from_csv, check_proxy_list
|
|
|
|
|
|
|
|
|
|
|
|
module_name = "Sherlock: Find Usernames Across Social Networks"
|
|
|
|
module_name = "Sherlock: Find Usernames Across Social Networks"
|
|
|
|
__version__ = "0.9.13"
|
|
|
|
__version__ = "0.9.16"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
global proxy_list
|
|
|
|
global proxy_list
|
|
|
@ -96,50 +96,65 @@ class SherlockFuturesSession(FuturesSession):
|
|
|
|
*args, **kwargs)
|
|
|
|
*args, **kwargs)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def print_info(title, info):
|
|
|
|
def print_info(title, info, color=True):
|
|
|
|
print(Style.BRIGHT + Fore.GREEN + "[" +
|
|
|
|
if color:
|
|
|
|
Fore.YELLOW + "*" +
|
|
|
|
print(Style.BRIGHT + Fore.GREEN + "[" +
|
|
|
|
Fore.GREEN + f"] {title}" +
|
|
|
|
Fore.YELLOW + "*" +
|
|
|
|
Fore.WHITE + f" {info}" +
|
|
|
|
Fore.GREEN + f"] {title}" +
|
|
|
|
Fore.GREEN + " on:")
|
|
|
|
Fore.WHITE + f" {info}" +
|
|
|
|
|
|
|
|
Fore.GREEN + " on:")
|
|
|
|
def print_error(err, errstr, var, verbose=False):
|
|
|
|
else:
|
|
|
|
print(Style.BRIGHT + Fore.WHITE + "[" +
|
|
|
|
print(f"[*] {title} {info} on:")
|
|
|
|
Fore.RED + "-" +
|
|
|
|
|
|
|
|
Fore.WHITE + "]" +
|
|
|
|
def print_error(err, errstr, var, verbose=False, color=True):
|
|
|
|
Fore.RED + f" {errstr}" +
|
|
|
|
if color:
|
|
|
|
Fore.YELLOW + f" {err if verbose else var}")
|
|
|
|
print(Style.BRIGHT + Fore.WHITE + "[" +
|
|
|
|
|
|
|
|
Fore.RED + "-" +
|
|
|
|
|
|
|
|
Fore.WHITE + "]" +
|
|
|
|
|
|
|
|
Fore.RED + f" {errstr}" +
|
|
|
|
|
|
|
|
Fore.YELLOW + f" {err if verbose else var}")
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
print(f"[-] {errstr} {err if verbose else var}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def format_response_time(response_time, verbose):
|
|
|
|
def format_response_time(response_time, verbose):
|
|
|
|
return f" [{round(response_time * 1000)} ms]" if verbose else ""
|
|
|
|
return f" [{round(response_time * 1000)} ms]" if verbose else ""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def print_found(social_network, url, response_time, verbose=False):
|
|
|
|
def print_found(social_network, url, response_time, verbose=False, color=True):
|
|
|
|
print((Style.BRIGHT + Fore.WHITE + "[" +
|
|
|
|
if color:
|
|
|
|
Fore.GREEN + "+" +
|
|
|
|
print((Style.BRIGHT + Fore.WHITE + "[" +
|
|
|
|
Fore.WHITE + "]" +
|
|
|
|
Fore.GREEN + "+" +
|
|
|
|
format_response_time(response_time, verbose) +
|
|
|
|
Fore.WHITE + "]" +
|
|
|
|
Fore.GREEN + f" {social_network}:"), url)
|
|
|
|
format_response_time(response_time, verbose) +
|
|
|
|
|
|
|
|
Fore.GREEN + f" {social_network}:"), url)
|
|
|
|
def print_not_found(social_network, response_time, verbose=False):
|
|
|
|
else:
|
|
|
|
print((Style.BRIGHT + Fore.WHITE + "[" +
|
|
|
|
print(f"[+]{format_response_time(response_time, verbose)} {social_network}: {url}")
|
|
|
|
Fore.RED + "-" +
|
|
|
|
|
|
|
|
Fore.WHITE + "]" +
|
|
|
|
def print_not_found(social_network, response_time, verbose=False, color=True):
|
|
|
|
format_response_time(response_time, verbose) +
|
|
|
|
if color:
|
|
|
|
Fore.GREEN + f" {social_network}:" +
|
|
|
|
print((Style.BRIGHT + Fore.WHITE + "[" +
|
|
|
|
Fore.YELLOW + " Not Found!"))
|
|
|
|
Fore.RED + "-" +
|
|
|
|
|
|
|
|
Fore.WHITE + "]" +
|
|
|
|
|
|
|
|
format_response_time(response_time, verbose) +
|
|
|
|
|
|
|
|
Fore.GREEN + f" {social_network}:" +
|
|
|
|
|
|
|
|
Fore.YELLOW + " Not Found!"))
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
print(f"[-]{format_response_time(response_time, verbose)} {social_network}: Not Found!")
|
|
|
|
|
|
|
|
|
|
|
|
def print_invalid(social_network, msg):
|
|
|
|
def print_invalid(social_network, msg, color=True):
|
|
|
|
"""Print invalid search result."""
|
|
|
|
"""Print invalid search result."""
|
|
|
|
print((Style.BRIGHT + Fore.WHITE + "[" +
|
|
|
|
if color:
|
|
|
|
Fore.RED + "-" +
|
|
|
|
print((Style.BRIGHT + Fore.WHITE + "[" +
|
|
|
|
Fore.WHITE + "]" +
|
|
|
|
Fore.RED + "-" +
|
|
|
|
Fore.GREEN + f" {social_network}:" +
|
|
|
|
Fore.WHITE + "]" +
|
|
|
|
Fore.YELLOW + f" {msg}"))
|
|
|
|
Fore.GREEN + f" {social_network}:" +
|
|
|
|
|
|
|
|
Fore.YELLOW + f" {msg}"))
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
print(f"[-] {social_network} {msg}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_response(request_future, error_type, social_network, verbose=False, retry_no=None):
|
|
|
|
def get_response(request_future, error_type, social_network, verbose=False, retry_no=None, color=True):
|
|
|
|
|
|
|
|
|
|
|
|
global proxy_list
|
|
|
|
global proxy_list
|
|
|
|
|
|
|
|
|
|
|
@ -148,7 +163,7 @@ def get_response(request_future, error_type, social_network, verbose=False, retr
|
|
|
|
if rsp.status_code:
|
|
|
|
if rsp.status_code:
|
|
|
|
return rsp, error_type, rsp.elapsed
|
|
|
|
return rsp, error_type, rsp.elapsed
|
|
|
|
except requests.exceptions.HTTPError as errh:
|
|
|
|
except requests.exceptions.HTTPError as errh:
|
|
|
|
print_error(errh, "HTTP Error:", social_network, verbose)
|
|
|
|
print_error(errh, "HTTP Error:", social_network, verbose, color)
|
|
|
|
|
|
|
|
|
|
|
|
# In case our proxy fails, we retry with another proxy.
|
|
|
|
# In case our proxy fails, we retry with another proxy.
|
|
|
|
except requests.exceptions.ProxyError as errp:
|
|
|
|
except requests.exceptions.ProxyError as errp:
|
|
|
@ -158,20 +173,20 @@ def get_response(request_future, error_type, social_network, verbose=False, retr
|
|
|
|
new_proxy = f'{new_proxy.protocol}://{new_proxy.ip}:{new_proxy.port}'
|
|
|
|
new_proxy = f'{new_proxy.protocol}://{new_proxy.ip}:{new_proxy.port}'
|
|
|
|
print(f'Retrying with {new_proxy}')
|
|
|
|
print(f'Retrying with {new_proxy}')
|
|
|
|
request_future.proxy = {'http':new_proxy,'https':new_proxy}
|
|
|
|
request_future.proxy = {'http':new_proxy,'https':new_proxy}
|
|
|
|
get_response(request_future,error_type, social_network, verbose,retry_no=retry_no-1)
|
|
|
|
get_response(request_future,error_type, social_network, verbose,retry_no=retry_no-1, color=color)
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
print_error(errp, "Proxy error:", social_network, verbose)
|
|
|
|
print_error(errp, "Proxy error:", social_network, verbose, color)
|
|
|
|
except requests.exceptions.ConnectionError as errc:
|
|
|
|
except requests.exceptions.ConnectionError as errc:
|
|
|
|
print_error(errc, "Error Connecting:", social_network, verbose)
|
|
|
|
print_error(errc, "Error Connecting:", social_network, verbose, color)
|
|
|
|
except requests.exceptions.Timeout as errt:
|
|
|
|
except requests.exceptions.Timeout as errt:
|
|
|
|
print_error(errt, "Timeout Error:", social_network, verbose)
|
|
|
|
print_error(errt, "Timeout Error:", social_network, verbose, color)
|
|
|
|
except requests.exceptions.RequestException as err:
|
|
|
|
except requests.exceptions.RequestException as err:
|
|
|
|
print_error(err, "Unknown error:", social_network, verbose)
|
|
|
|
print_error(err, "Unknown error:", social_network, verbose, color)
|
|
|
|
return None, "", -1
|
|
|
|
return None, "", -1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def sherlock(username, site_data, verbose=False, tor=False, unique_tor=False,
|
|
|
|
def sherlock(username, site_data, verbose=False, tor=False, unique_tor=False,
|
|
|
|
proxy=None, print_found_only=False, timeout=None):
|
|
|
|
proxy=None, print_found_only=False, timeout=None, color=True):
|
|
|
|
"""Run Sherlock Analysis.
|
|
|
|
"""Run Sherlock Analysis.
|
|
|
|
|
|
|
|
|
|
|
|
Checks for existence of username on various social media sites.
|
|
|
|
Checks for existence of username on various social media sites.
|
|
|
@ -186,6 +201,7 @@ def sherlock(username, site_data, verbose=False, tor=False, unique_tor=False,
|
|
|
|
proxy -- String indicating the proxy URL
|
|
|
|
proxy -- String indicating the proxy URL
|
|
|
|
timeout -- Time in seconds to wait before timing out request.
|
|
|
|
timeout -- Time in seconds to wait before timing out request.
|
|
|
|
Default is no timeout.
|
|
|
|
Default is no timeout.
|
|
|
|
|
|
|
|
color -- Boolean indicating whether to color terminal output
|
|
|
|
|
|
|
|
|
|
|
|
Return Value:
|
|
|
|
Return Value:
|
|
|
|
Dictionary containing results from report. Key of dictionary is the name
|
|
|
|
Dictionary containing results from report. Key of dictionary is the name
|
|
|
@ -199,7 +215,7 @@ def sherlock(username, site_data, verbose=False, tor=False, unique_tor=False,
|
|
|
|
response_text: Text that came back from request. May be None if
|
|
|
|
response_text: Text that came back from request. May be None if
|
|
|
|
there was an HTTP error when checking for existence.
|
|
|
|
there was an HTTP error when checking for existence.
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
print_info("Checking username", username)
|
|
|
|
print_info("Checking username", username, color)
|
|
|
|
|
|
|
|
|
|
|
|
# Allow 1 thread for each external service, so `len(site_data)` threads total
|
|
|
|
# Allow 1 thread for each external service, so `len(site_data)` threads total
|
|
|
|
executor = ThreadPoolExecutor(max_workers=len(site_data))
|
|
|
|
executor = ThreadPoolExecutor(max_workers=len(site_data))
|
|
|
@ -246,7 +262,7 @@ def sherlock(username, site_data, verbose=False, tor=False, unique_tor=False,
|
|
|
|
if regex_check and re.search(regex_check, username) is None:
|
|
|
|
if regex_check and re.search(regex_check, username) is None:
|
|
|
|
# No need to do the check at the site: this user name is not allowed.
|
|
|
|
# No need to do the check at the site: this user name is not allowed.
|
|
|
|
if not print_found_only:
|
|
|
|
if not print_found_only:
|
|
|
|
print_invalid(social_network, "Illegal Username Format For This Site!")
|
|
|
|
print_invalid(social_network, "Illegal Username Format For This Site!", color)
|
|
|
|
|
|
|
|
|
|
|
|
results_site["exists"] = "illegal"
|
|
|
|
results_site["exists"] = "illegal"
|
|
|
|
results_site["url_user"] = ""
|
|
|
|
results_site["url_user"] = ""
|
|
|
@ -333,7 +349,8 @@ def sherlock(username, site_data, verbose=False, tor=False, unique_tor=False,
|
|
|
|
error_type=error_type,
|
|
|
|
error_type=error_type,
|
|
|
|
social_network=social_network,
|
|
|
|
social_network=social_network,
|
|
|
|
verbose=verbose,
|
|
|
|
verbose=verbose,
|
|
|
|
retry_no=3)
|
|
|
|
retry_no=3,
|
|
|
|
|
|
|
|
color=color)
|
|
|
|
|
|
|
|
|
|
|
|
# Attempt to get request information
|
|
|
|
# Attempt to get request information
|
|
|
|
try:
|
|
|
|
try:
|
|
|
@ -349,21 +366,21 @@ def sherlock(username, site_data, verbose=False, tor=False, unique_tor=False,
|
|
|
|
error = net_info.get("errorMsg")
|
|
|
|
error = net_info.get("errorMsg")
|
|
|
|
# Checks if the error message is in the HTML
|
|
|
|
# Checks if the error message is in the HTML
|
|
|
|
if not error in r.text:
|
|
|
|
if not error in r.text:
|
|
|
|
print_found(social_network, url, response_time, verbose)
|
|
|
|
print_found(social_network, url, response_time, verbose, color)
|
|
|
|
exists = "yes"
|
|
|
|
exists = "yes"
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
if not print_found_only:
|
|
|
|
if not print_found_only:
|
|
|
|
print_not_found(social_network, response_time, verbose)
|
|
|
|
print_not_found(social_network, response_time, verbose, color)
|
|
|
|
exists = "no"
|
|
|
|
exists = "no"
|
|
|
|
|
|
|
|
|
|
|
|
elif error_type == "status_code":
|
|
|
|
elif error_type == "status_code":
|
|
|
|
# Checks if the status code of the response is 2XX
|
|
|
|
# Checks if the status code of the response is 2XX
|
|
|
|
if not r.status_code >= 300 or r.status_code < 200:
|
|
|
|
if not r.status_code >= 300 or r.status_code < 200:
|
|
|
|
print_found(social_network, url, response_time, verbose)
|
|
|
|
print_found(social_network, url, response_time, verbose, color)
|
|
|
|
exists = "yes"
|
|
|
|
exists = "yes"
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
if not print_found_only:
|
|
|
|
if not print_found_only:
|
|
|
|
print_not_found(social_network, response_time, verbose)
|
|
|
|
print_not_found(social_network, response_time, verbose, color)
|
|
|
|
exists = "no"
|
|
|
|
exists = "no"
|
|
|
|
|
|
|
|
|
|
|
|
elif error_type == "response_url":
|
|
|
|
elif error_type == "response_url":
|
|
|
@ -374,16 +391,16 @@ def sherlock(username, site_data, verbose=False, tor=False, unique_tor=False,
|
|
|
|
# forward to some odd redirect).
|
|
|
|
# forward to some odd redirect).
|
|
|
|
if 200 <= r.status_code < 300:
|
|
|
|
if 200 <= r.status_code < 300:
|
|
|
|
#
|
|
|
|
#
|
|
|
|
print_found(social_network, url, response_time, verbose)
|
|
|
|
print_found(social_network, url, response_time, verbose, color)
|
|
|
|
exists = "yes"
|
|
|
|
exists = "yes"
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
if not print_found_only:
|
|
|
|
if not print_found_only:
|
|
|
|
print_not_found(social_network, response_time, verbose)
|
|
|
|
print_not_found(social_network, response_time, verbose, color)
|
|
|
|
exists = "no"
|
|
|
|
exists = "no"
|
|
|
|
|
|
|
|
|
|
|
|
elif error_type == "":
|
|
|
|
elif error_type == "":
|
|
|
|
if not print_found_only:
|
|
|
|
if not print_found_only:
|
|
|
|
print_invalid(social_network, "Error!")
|
|
|
|
print_invalid(social_network, "Error!", color)
|
|
|
|
exists = "error"
|
|
|
|
exists = "error"
|
|
|
|
|
|
|
|
|
|
|
|
# Save exists flag
|
|
|
|
# Save exists flag
|
|
|
@ -496,6 +513,10 @@ def main():
|
|
|
|
action="store_true", dest="print_found_only", default=False,
|
|
|
|
action="store_true", dest="print_found_only", default=False,
|
|
|
|
help="Do not output sites where the username was not found."
|
|
|
|
help="Do not output sites where the username was not found."
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
parser.add_argument("--no-color",
|
|
|
|
|
|
|
|
action="store_true", dest="no_color", default=False,
|
|
|
|
|
|
|
|
help="Don't color terminal output"
|
|
|
|
|
|
|
|
)
|
|
|
|
parser.add_argument("username",
|
|
|
|
parser.add_argument("username",
|
|
|
|
nargs='+', metavar='USERNAMES',
|
|
|
|
nargs='+', metavar='USERNAMES',
|
|
|
|
action="store",
|
|
|
|
action="store",
|
|
|
@ -524,7 +545,7 @@ def main():
|
|
|
|
global proxy_list
|
|
|
|
global proxy_list
|
|
|
|
|
|
|
|
|
|
|
|
if args.proxy_list != None:
|
|
|
|
if args.proxy_list != None:
|
|
|
|
print_info("Loading proxies from", args.proxy_list)
|
|
|
|
print_info("Loading proxies from", args.proxy_list, not args.color)
|
|
|
|
|
|
|
|
|
|
|
|
proxy_list = load_proxies_from_csv(args.proxy_list)
|
|
|
|
proxy_list = load_proxies_from_csv(args.proxy_list)
|
|
|
|
|
|
|
|
|
|
|
@ -651,7 +672,8 @@ def main():
|
|
|
|
unique_tor=args.unique_tor,
|
|
|
|
unique_tor=args.unique_tor,
|
|
|
|
proxy=args.proxy,
|
|
|
|
proxy=args.proxy,
|
|
|
|
print_found_only=args.print_found_only,
|
|
|
|
print_found_only=args.print_found_only,
|
|
|
|
timeout=args.timeout)
|
|
|
|
timeout=args.timeout,
|
|
|
|
|
|
|
|
color=not args.no_color)
|
|
|
|
|
|
|
|
|
|
|
|
exists_counter = 0
|
|
|
|
exists_counter = 0
|
|
|
|
for website_name in results:
|
|
|
|
for website_name in results:
|
|
|
|