Merge remote-tracking branch 'origin/master' into restructure_take1

pull/350/head
Christopher K. Hoadley 5 years ago
commit 0a455339c2

@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2018 Siddharth Dushantha Copyright (c) 2019 Sherlock Project
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

@ -69,7 +69,7 @@ usage: sherlock.py [-h] [--version] [--verbose] [--rank]
[--timeout TIMEOUT] [--print-found] [--timeout TIMEOUT] [--print-found]
USERNAMES [USERNAMES ...] USERNAMES [USERNAMES ...]
Sherlock: Find Usernames Across Social Networks (Version 0.9.13) Sherlock: Find Usernames Across Social Networks (Version 0.9.14)
positional arguments: positional arguments:
USERNAMES One or more usernames to check with social networks. USERNAMES One or more usernames to check with social networks.
@ -211,5 +211,5 @@ list of sites to ignore (one site name per line).
## License ## License
MIT © [Yahya SayadArbabi](https://theyahya.com)<br/> MIT © Sherlock Project<br/>
Original Creator - [Siddharth Dushantha](https://github.com/sdushantha) Original Creator - [Siddharth Dushantha](https://github.com/sdushantha)

@ -1,51 +0,0 @@
#!/bin/bash
# Determine which is the default package manager
APT=$(which apt)
PACMAN=$(which pacman)
DNF=$(which dnf)
YUM=$(which yum)
ZYPPER=$(which zypper)
# install python3 and pip3 if not exist
if [ ${#APT} -gt 0 ]; then
sudo apt-get install python3
sudo apt-get install python3-pip
elif [ ${#PACMAN} -gt 0 ]; then
sudo pacman -S python3
sudo pacman -S python3-pip
elif [ ${#DNF} -gt 0 ]; then
sudo dnf install python3
sudo dnf install python3-pip
elif [ ${#YUM} -gt 0 ]; then
sudo yum install python3
sudo yum install python3-pip
elif [ ${#ZYPPER} -gt 0 ]; then
sudo zypper install python3
sudo zypper install python3-pip
else
echo "Unknown package manager. Download one of the following:"
echo " apt, pacman, dnf, yum or zypper"
echo ""
echo "or use README.md for instructions."
exit 1
fi
# install the all the necessary packages and requirements
echo ''
echo ''
while true; do
echo 'Do you want dependencies to be installed globally (or locally) [Y/n]?'
read ans
if [[ ${#ans} -eq 0 || $ans = "Y" || $ans = "y" ]]; then
sudo pip3 install --upgrade setuptools
sudo pip3 install -r requirements.txt
elif [[ $ans = "N" || $ans = "n" ]]; then
sudo pip3 install --user --upgrade setuptools
sudo pip3 install --user -r requirements.txt
fi
[[ ${#ans} -eq 0 || $ans = "Y" || $ans = "y" || $ans = "N" || $ans = "n" ]] && break;
done

@ -183,6 +183,15 @@
"username_claimed": "blue", "username_claimed": "blue",
"username_unclaimed": "noonewouldeverusethis7" "username_unclaimed": "noonewouldeverusethis7"
}, },
"BodyBuilding": {
"errorType": "response_url",
"errorUrl": "https://bodyspace.bodybuilding.com/",
"rank": 2134,
"url": "https://bodyspace.bodybuilding.com/{}",
"urlMain": "https://bodyspace.bodybuilding.com/",
"username_claimed": "blue",
"username_unclaimed": "noonewouldeverusethis7"
},
"Bookcrossing": { "Bookcrossing": {
"errorType": "status_code", "errorType": "status_code",
"rank": 52645, "rank": 52645,
@ -256,9 +265,9 @@
"CashMe": { "CashMe": {
"errorType": "status_code", "errorType": "status_code",
"rank": 6238340, "rank": 6238340,
"url": "https://cash.me/{}", "url": "https://cash.me/${}",
"urlMain": "https://cash.me/", "urlMain": "https://cash.me/",
"username_claimed": "jenny", "username_claimed": "Jenny",
"username_unclaimed": "noonewouldeverusethis7" "username_unclaimed": "noonewouldeverusethis7"
}, },
"Cent": { "Cent": {
@ -2085,5 +2094,188 @@
"urlMain": "https://www.toster.ru/", "urlMain": "https://www.toster.ru/",
"username_claimed": "blue", "username_claimed": "blue",
"username_unclaimed": "noonewouldeverusethis7" "username_unclaimed": "noonewouldeverusethis7"
},
"spletnik": {
"errorType": "status_code",
"rank": 6944,
"url": "https://spletnik.ru/user/{}",
"urlMain": "https://spletnik.ru/",
"username_claimed": "blue",
"username_unclaimed": "noonewouldeverusethis7"
},
"OurDJTalk": {
"errorType": "message",
"errorMsg": "The specified member cannot be found",
"rank": 1740723,
"url": "https://ourdjtalk.com/members?username={}",
"urlMain": "https://ourdjtalk.com/",
"username_claimed": "steve",
"username_unclaimed": "noonewouldeverusethis"
},
"NICommunityForum": {
"errorType": "message",
"errorMsg": "The specified member cannot be found",
"rank": 7957,
"url": "https://www.native-instruments.com/forum/members?username={}",
"urlMain": "https://www.native-instruments.com/forum/",
"username_claimed": "blue",
"username_unclaimed": "noonewouldeverusethis"
},
"CloudflareCommunity": {
"errorType": "status_code",
"rank": 1107,
"url": "https://community.cloudflare.com/u/{}",
"urlMain": "https://community.cloudflare.com/",
"username_claimed": "blue",
"username_unclaimed": "noonewouldeverusethis"
},
"babyRU": {
"errorMsg": "Упс, страница, которую вы искали, не существует",
"errorType": "message",
"rank": 9328,
"url": "https://www.baby.ru/u/{}/",
"urlMain": "https://www.baby.ru/",
"username_claimed": "blue",
"username_unclaimed": "noonewouldeverusethis"
},
"babyblogRU": {
"errorType": "status_code",
"rank": 10867,
"url": "https://www.babyblog.ru/user/info/{}",
"urlMain": "https://www.babyblog.ru/",
"username_claimed": "blue",
"username_unclaimed": "noonewouldeverusethis"
},
"TrashboxRU": {
"errorMsg": "Пользователь не найден",
"errorType": "message",
"rank": 17945,
"url": "https://trashbox.ru/users/{}",
"urlMain": "https://trashbox.ru/",
"username_claimed": "blue",
"username_unclaimed": "noonewouldeverusethis"
},
"HackTheBox": {
"errorType": "status_code",
"rank": 39236,
"url": "https://forum.hackthebox.eu/profile/{}",
"urlMain": "https://forum.hackthebox.eu/",
"username_claimed": "angar",
"username_unclaimed": "noonewouldeverusethis"
},
"leasehackr": {
"errorType": "status_code",
"rank": 41594,
"url": "https://forum.leasehackr.com/u/{}/summary/",
"urlMain": "https://forum.leasehackr.com/",
"username_claimed": "adam",
"username_unclaimed": "noonewouldeverusethis"
},
"akniga": {
"errorType": "status_code",
"rank": 25616,
"url": "https://akniga.org/profile/{}",
"urlMain": "https://akniga.org/profile/blue/",
"username_claimed": "blue",
"username_unclaimed": "noonewouldeverusethis"
},
"GunsAndAmmo": {
"errorType": "status_code",
"rank": 212975,
"url": "https://forums.gunsandammo.com/profile/{}",
"urlMain": "https://gunsandammo.com/",
"username_claimed": "adam",
"username_unclaimed": "noonewouldeverusethis7"
},
"Redbubble": {
"errorType": "status_code",
"rank": 1469,
"url": "https://www.redbubble.com/people/{}",
"urlMain": "https://www.redbubble.com/",
"username_claimed": "blue",
"username_unclaimed": "noonewouldeverusethis77777"
},
"warriorforum": {
"errorType": "status_code",
"rank": 4678,
"url": "https://www.warriorforum.com/members/{}.html",
"urlMain": "https://www.warriorforum.com/",
"username_claimed": "blue",
"username_unclaimed": "noonewouldeverusethis77777"
},
"AdobeForums": {
"errorType": "status_code",
"rank": 53,
"url": "https://forums.adobe.com/people/{}",
"urlMain": "https://forums.adobe.com/",
"username_claimed": "jack",
"username_unclaimed": "noonewouldeverusethis77777"
},
"radio_echo_msk": {
"errorType": "status_code",
"rank": 2164,
"url": "https://echo.msk.ru/users/{}",
"urlMain": "https://echo.msk.ru/",
"username_claimed": "blue",
"username_unclaimed": "noonewouldeverusethis7"
},
"dailykos": {
"errorType": "status_code",
"rank": 5890,
"url": "https://www.dailykos.com/user/{}",
"urlMain": "https://www.dailykos.com",
"username_claimed": "blue",
"username_unclaimed": "noonewouldeverusethis7"
},
"travellerspoint": {
"errorMsg": "Wooops. Sorry!",
"errorType": "message",
"rank": 45696,
"url": "https://www.travellerspoint.com/users/{}",
"urlMain": "https://www.travellerspoint.com",
"username_claimed": "blue",
"username_unclaimed": "noonewouldeverusethis7"
},
"sparkpeople": {
"errorMsg": "We couldn't find that user",
"errorType": "message",
"rank": 16130,
"url": "https://www.sparkpeople.com/mypage.asp?id={}",
"urlMain": "https://www.sparkpeople.com",
"username_claimed": "adam",
"username_unclaimed": "noonewouldeverusethis7"
},
"fixya": {
"errorType": "status_code",
"rank": 3824,
"url": "https://www.fixya.com/users/{}",
"urlMain": "https://www.fixya.com",
"username_claimed": "adam",
"username_unclaimed": "noonewouldeverusethis7"
},
"hackster": {
"errorType": "status_code",
"rank": 12035,
"url": "https://www.hackster.io/{}",
"urlMain": "https://www.hackster.io",
"username_claimed": "blue",
"username_unclaimed": "noonewouldeverusethis7"
},
"datingRU": {
"errorType": "status_code",
"rank": 35986,
"url": "http://dating.ru/{}",
"urlMain": "http://dating.ru",
"username_claimed": "blue",
"username_unclaimed": "noonewouldeverusethis7"
},
"labpentestit": {
"errorType": "response_url",
"errorUrl": "https://lab.pentestit.ru/{}",
"rank": 1087542,
"url": "https://lab.pentestit.ru/profile/{}",
"urlMain": "https://lab.pentestit.ru/",
"username_claimed": "CSV",
"username_unclaimed": "noonewouldeverusethis7"
} }
} }

@ -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:

Loading…
Cancel
Save