no-ansi option & minor refactor

This commit is contained in:
sundowndev 2019-01-14 10:29:09 +01:00
parent 347d0e87bf
commit 31eb7425c6
1 changed files with 126 additions and 60 deletions

View File

@ -15,6 +15,7 @@ except:
print('[!] Missing requirements. Try running python3 -m pip install -r requirements.txt')
sys.exit()
def banner():
print(" ___ _ _____ __ ")
print(" / _ \ |__ ___ _ __ ___ \_ \_ __ / _| ___ __ _ __ _ ")
@ -26,14 +27,14 @@ def banner():
print(" Coded by Sundowndev")
print("\n")
banner()
if sys.version_info[0] < 3:
print("\033[1m\033[93m(!) Please run the tool using Python 3" + Style.RESET_ALL)
sys.exit()
parser = argparse.ArgumentParser(description=
"Advanced information gathering tool for phone numbers (https://github.com/sundowndev/PhoneInfoga) version {}".format(__version__),
parser = argparse.ArgumentParser(description="Advanced information gathering tool for phone numbers (https://github.com/sundowndev/PhoneInfoga) version {}".format(__version__),
usage='%(prog)s -n <number> [options]')
parser.add_argument('-n', '--number', metavar='number', type=str,
@ -54,12 +55,17 @@ parser.add_argument('--osint', action='store_true',
parser.add_argument('-u', '--update', action='store_true',
help='Update the project')
parser.add_argument('--no-ansi', action='store_true',
help='Disable colored output')
args = parser.parse_args()
def resetColors():
if not args.output:
print(Style.RESET_ALL)
# Reset text color at exit
atexit.register(resetColors)
@ -108,16 +114,19 @@ if args.update:
print('Actual version: {}'.format(__version__))
# Fetching last github tag
new_version = json.loads(requests.get('https://api.github.com/repos/sundowndev/PhoneInfoga/tags').content)[0]['name']
new_version = json.loads(requests.get(
'https://api.github.com/repos/sundowndev/PhoneInfoga/tags').content)[0]['name']
print('Last version: {}'.format(new_version))
osintFiles = ['disposable_num_providers.json', 'individuals.json', 'reputation.json', 'social_medias.json']
osintFiles = ['disposable_num_providers.json',
'individuals.json', 'reputation.json', 'social_medias.json']
try:
print('[*] Updating OSINT files')
for file in osintFiles:
url = 'https://raw.githubusercontent.com/sundowndev/PhoneInfoga/master/osint/{}'.format(file)
url = 'https://raw.githubusercontent.com/sundowndev/PhoneInfoga/master/osint/{}'.format(
file)
output_directory = 'osint/{}'.format(file)
download_file(url, output_directory)
@ -137,23 +146,30 @@ scanners = ['any', 'all', 'numverify', 'ovh']
uagent = []
uagent.append("Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.0) Opera 12.14")
uagent.append("Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:26.0) Gecko/20100101 Firefox/26.0")
uagent.append("Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.3) Gecko/20090913 Firefox/3.5.3")
uagent.append("Mozilla/5.0 (Windows; U; Windows NT 6.1; en; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729)")
uagent.append(
"Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:26.0) Gecko/20100101 Firefox/26.0")
uagent.append(
"Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.3) Gecko/20090913 Firefox/3.5.3")
uagent.append(
"Mozilla/5.0 (Windows; U; Windows NT 6.1; en; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729)")
uagent.append("Mozilla/5.0 (Windows NT 6.2) AppleWebKit/535.7 (KHTML, like Gecko) Comodo_Dragon/16.1.1.0 Chrome/16.0.912.63 Safari/535.7")
uagent.append("Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729)")
uagent.append("Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.1) Gecko/20090718 Firefox/3.5.1")
uagent.append("Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:63.0) Gecko/20100101 Firefox/63.0")
uagent.append(
"Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729)")
uagent.append(
"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.1) Gecko/20090718 Firefox/3.5.1")
uagent.append(
"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:63.0) Gecko/20100101 Firefox/63.0")
number = '' # Full number format
localNumber = '' # Local number format
internationalNumber = '' # International number format
numberCountryCode = '' # Dial code; e.g:"+33"
numberCountry = '' # Country; e.g:France
number = '' # Full number format
localNumber = '' # Local number format
internationalNumber = '' # International number format
numberCountryCode = '' # Dial code; e.g:"+33"
numberCountry = '' # Country; e.g:France
googleAbuseToken = ''
customFormatting = ''
def search(req, stop):
global googleAbuseToken
global uagent
@ -173,12 +189,14 @@ def search(req, stop):
}
try:
URL = 'https://www.google.com/search?tbs=li:1&q={}&amp;gws_rd=ssl'.format(req)
URL = 'https://www.google.com/search?tbs=li:1&q={}&amp;gws_rd=ssl'.format(
req)
r = s.get(URL + googleAbuseToken, headers=headers)
while r.status_code == 503:
print(code_warning + 'You are temporary blacklisted from Google search. Complete the captcha at the following URL and copy/paste the content of GOOGLE_ABUSE_EXEMPTION cookie : {}'.format(URL))
print('\n' + code_info + 'Need help ? Read https://github.com/sundowndev/PhoneInfoga#dealing-with-google-captcha')
print('\n' + code_info +
'Need help ? Read https://github.com/sundowndev/PhoneInfoga#dealing-with-google-captcha')
token = input('\nGOOGLE_ABUSE_EXEMPTION=')
googleAbuseToken = '&google_abuse=' + token
r = s.get(URL + googleAbuseToken, headers=headers)
@ -210,9 +228,11 @@ def search(req, stop):
except:
print(code_error + 'Request failed. Please retry or open an issue on GitHub.')
def formatNumber(InputNumber):
return re.sub("(?:\+)?(?:[^[0-9]*)", "", InputNumber)
def localScan(InputNumber):
global number
global localNumber
@ -232,20 +252,26 @@ def localScan(InputNumber):
if not phonenumbers.is_valid_number(PhoneNumberObject):
return False
number = phonenumbers.format_number(PhoneNumberObject, phonenumbers.PhoneNumberFormat.E164).replace('+', '')
numberCountryCode = phonenumbers.format_number(PhoneNumberObject, phonenumbers.PhoneNumberFormat.INTERNATIONAL).split(' ')[0]
number = phonenumbers.format_number(
PhoneNumberObject, phonenumbers.PhoneNumberFormat.E164).replace('+', '')
numberCountryCode = phonenumbers.format_number(
PhoneNumberObject, phonenumbers.PhoneNumberFormat.INTERNATIONAL).split(' ')[0]
countryRequest = json.loads(requests.request('GET', 'https://restcountries.eu/rest/v2/callingcode/{}'.format(numberCountryCode.replace('+', ''))).content)
countryRequest = json.loads(requests.request(
'GET', 'https://restcountries.eu/rest/v2/callingcode/{}'.format(numberCountryCode.replace('+', ''))).content)
numberCountry = countryRequest[0]['alpha2Code']
localNumber = phonenumbers.format_number(PhoneNumberObject, phonenumbers.PhoneNumberFormat.E164).replace(numberCountryCode, '')
internationalNumber = phonenumbers.format_number(PhoneNumberObject, phonenumbers.PhoneNumberFormat.INTERNATIONAL)
localNumber = phonenumbers.format_number(
PhoneNumberObject, phonenumbers.PhoneNumberFormat.E164).replace(numberCountryCode, '')
internationalNumber = phonenumbers.format_number(
PhoneNumberObject, phonenumbers.PhoneNumberFormat.INTERNATIONAL)
print(code_result + 'International format: {}'.format(internationalNumber))
print(code_result + 'Local format: 0{}'.format(localNumber))
print(code_result + 'Country code: {}'.format(numberCountryCode))
print(code_result + 'Location: {}'.format(geocoder.description_for_number(PhoneNumberObject, "en")))
print(code_result + 'Carrier: {}'.format(carrier.name_for_number(PhoneNumberObject, 'en')))
print(code_result +
'Carrier: {}'.format(carrier.name_for_number(PhoneNumberObject, 'en')))
print(code_result + 'Area: {}'.format(geocoder.description_for_number(PhoneNumberObject, 'en')))
for timezoneResult in timezone.time_zones_for_number(PhoneNumberObject):
print(code_result + 'Timezone: {}'.format(timezoneResult))
@ -255,6 +281,7 @@ def localScan(InputNumber):
else:
print(code_warning + 'The number is valid but might not be possible.')
def numverifyScan():
global number
@ -288,7 +315,8 @@ def numverifyScan():
'cache-control': "no-cache"
}
response = requests.request("GET", "https://numverify.com/php_helper_scripts/phone_api.php?secret_key={}&number={}".format(apiKey, number), data="", headers=headers)
response = requests.request(
"GET", "https://numverify.com/php_helper_scripts/phone_api.php?secret_key={}&number={}".format(apiKey, number), data="", headers=headers)
if response.content == "Unauthorized" or response.status_code != 200:
print((code_error + "An error occured while calling the API (bad request or wrong api key)."))
@ -300,10 +328,13 @@ def numverifyScan():
print((code_error + "Error: Please specify a valid phone number. Example: +6464806649"))
sys.exit()
InternationalNumber = '({}){}'.format(data["country_prefix"], data["local_format"])
InternationalNumber = '({}){}'.format(
data["country_prefix"], data["local_format"])
print((code_result + "Number: ({}) {}").format(data["country_prefix"],data["local_format"]))
print((code_result + "Country: {} ({})").format(data["country_name"],data["country_code"]))
print((code_result +
"Number: ({}) {}").format(data["country_prefix"], data["local_format"]))
print((code_result +
"Country: {} ({})").format(data["country_name"], data["country_code"]))
print((code_result + "Location: {}").format(data["location"]))
print((code_result + "Carrier: {}").format(data["carrier"]))
print((code_result + "Line type: {}").format(data["line_type"]))
@ -313,6 +344,7 @@ def numverifyScan():
elif data["line_type"] == 'mobile':
print((code_warning + "This is most likely a mobile number, but it can still be a VoIP number."))
def ovhScan():
global localNumber
global numberCountry
@ -322,14 +354,15 @@ def ovhScan():
print(code_info + 'Running OVH scan...')
querystring = { "country": numberCountry.lower() }
querystring = {"country": numberCountry.lower()}
headers = {
'accept': "application/json",
'cache-control': "no-cache"
}
response = requests.request("GET", "https://api.ovh.com/1.0/telephony/number/detailedZones", data="", headers=headers, params=querystring)
response = requests.request(
"GET", "https://api.ovh.com/1.0/telephony/number/detailedZones", data="", headers=headers, params=querystring)
data = json.loads(response.content)
@ -339,11 +372,14 @@ def ovhScan():
for voip_number in data:
if voip_number['number'] == askedNumber:
print((code_info + "1 result found in OVH database"))
print((code_result + "Number range: {}".format(voip_number['number'])))
print(
(code_result + "Number range: {}".format(voip_number['number'])))
print((code_result + "City: {}".format(voip_number['city'])))
print((code_result + "Zip code: {}".format(voip_number['zipCode'] if voip_number['zipCode'] is not None else '')))
print((code_result + "Zip code: {}".format(
voip_number['zipCode'] if voip_number['zipCode'] is not None else '')))
askForExit()
def replaceVariables(string):
global number
global internationalNumber
@ -355,6 +391,7 @@ def replaceVariables(string):
return string
def osintIndividualScan():
global number
global internationalNumber
@ -366,17 +403,20 @@ def osintIndividualScan():
for dork in dorks:
if dork['dialCode'] is None or dork['dialCode'] == numberCountryCode:
if customFormatting:
dorkRequest = replaceVariables(dork['request']) + ' | intext:"{}"'.format(customFormatting)
dorkRequest = replaceVariables(
dork['request']) + ' | intext:"{}"'.format(customFormatting)
else:
dorkRequest = replaceVariables(dork['request'])
print((code_info + "Searching for footprints on {}...".format(dork['site'])))
print(
(code_info + "Searching for footprints on {}...".format(dork['site'])))
for result in search(dorkRequest, stop=dork['stop']):
if result:
print((code_result + "URL: " + result))
else:
return -1
def osintReputationScan():
global number
global internationalNumber
@ -386,7 +426,8 @@ def osintReputationScan():
for dork in dorks:
if customFormatting:
dorkRequest = replaceVariables(dork['request']) + ' | intext:"{}"'.format(customFormatting)
dorkRequest = replaceVariables(
dork['request']) + ' | intext:"{}"'.format(customFormatting)
else:
dorkRequest = replaceVariables(dork['request'])
@ -395,6 +436,7 @@ def osintReputationScan():
if result:
print((code_result + "URL: " + result))
def osintSocialMediaScan():
global number
global internationalNumber
@ -404,15 +446,18 @@ def osintSocialMediaScan():
for dork in dorks:
if customFormatting:
dorkRequest = replaceVariables(dork['request']) + ' | intext:"{}"'.format(customFormatting)
dorkRequest = replaceVariables(
dork['request']) + ' | intext:"{}"'.format(customFormatting)
else:
dorkRequest = replaceVariables(dork['request'])
print((code_info + "Searching for footprints on {}...".format(dork['site'])))
print(
(code_info + "Searching for footprints on {}...".format(dork['site'])))
for result in search(dorkRequest, stop=dork['stop']):
if result:
print((code_result + "URL: " + result))
def osintDisposableNumScan():
global number
@ -421,13 +466,15 @@ def osintDisposableNumScan():
for dork in dorks:
dorkRequest = replaceVariables(dork['request'])
print((code_info + "Searching for footprints on {}...".format(dork['site'])))
print(
(code_info + "Searching for footprints on {}...".format(dork['site'])))
for result in search(dorkRequest, stop=dork['stop']):
if result:
print((code_result + "Result found: {}".format(dork['site'])))
print((code_result + "URL: " + result))
askForExit()
def osintScan():
global number
global localNumber
@ -443,9 +490,11 @@ def osintScan():
# Whitepages
print((code_info + "Generating scan URL on 411.com..."))
print(code_result + "Scan URL: https://www.411.com/phone/{}".format(internationalNumber.replace('+', '').replace(' ', '-')))
print(code_result + "Scan URL: https://www.411.com/phone/{}".format(
internationalNumber.replace('+', '').replace(' ', '-')))
askingCustomPayload = input(code_info + 'Would you like to use an additional format for this number ? (y/N) ')
askingCustomPayload = input(
code_info + 'Would you like to use an additional format for this number ? (y/N) ')
if askingCustomPayload == 'y' or askingCustomPayload == 'yes':
customFormatting = input(code_info + 'Custom format: ')
@ -454,9 +503,11 @@ def osintScan():
print((code_info + "Searching for footprints on web pages... (limit=5)"))
if customFormatting:
req = '{} | intext:"{}" | intext:"{}" | intext:"{}"'.format(number,number,internationalNumber,customFormatting)
req = '{} | intext:"{}" | intext:"{}" | intext:"{}"'.format(
number, number, internationalNumber, customFormatting)
else:
req = '{} | intext:"{}" | intext:"{}"'.format(number,number,internationalNumber)
req = '{} | intext:"{}" | intext:"{}"'.format(
number, number, internationalNumber)
for result in search(req, stop=5):
if result:
print((code_result + "Result found: " + result))
@ -464,9 +515,11 @@ def osintScan():
# Documents
print((code_info + "Searching for documents... (limit=10)"))
if customFormatting:
req = '[ext:doc | ext:docx | ext:odt | ext:pdf | ext:rtf | ext:sxw | ext:psw | ext:ppt | ext:pptx | ext:pps | ext:csv | ext:txt | ext:xls && intext:"{}"]'.format(customFormatting)
req = '[ext:doc | ext:docx | ext:odt | ext:pdf | ext:rtf | ext:sxw | ext:psw | ext:ppt | ext:pptx | ext:pps | ext:csv | ext:txt | ext:xls && intext:"{}"]'.format(
customFormatting)
else:
req = '[ext:doc | ext:docx | ext:odt | ext:pdf | ext:rtf | ext:sxw | ext:psw | ext:ppt | ext:pptx | ext:pps | ext:csv | ext:txt | ext:xls && intext:"{}" | intext:"{}"]'.format(number,internationalNumber)
req = '[ext:doc | ext:docx | ext:odt | ext:pdf | ext:rtf | ext:sxw | ext:psw | ext:ppt | ext:pptx | ext:pps | ext:csv | ext:txt | ext:xls && intext:"{}" | intext:"{}"]'.format(
number, internationalNumber)
for result in search(req, stop=10):
if result:
print((code_result + "Result found: " + result))
@ -476,20 +529,24 @@ def osintScan():
osintReputationScan()
print((code_info + "Generating URL on scamcallfighters.com..."))
print(code_result + 'http://www.scamcallfighters.com/search-phone-{}.html'.format(number))
print(code_result +
'http://www.scamcallfighters.com/search-phone-{}.html'.format(number))
tmpNumAsk = input(code_info + "Would you like to search for temporary number providers footprints ? (Y/n) ")
tmpNumAsk = input(
code_info + "Would you like to search for temporary number providers footprints ? (Y/n) ")
if tmpNumAsk.lower() != 'n' and tmpNumAsk.lower() != 'no':
print((code_info + '---- Temporary number providers footprints ----'))
try:
print((code_info + "Searching for phone number on tempophone.com..."))
response = requests.request("GET", "https://tempophone.com/api/v1/phones")
response = requests.request(
"GET", "https://tempophone.com/api/v1/phones")
data = json.loads(response.content)
for voip_number in data['objects']:
if voip_number['phone'] == formatNumber(number):
print((code_result + "Found a temporary number provider: tempophone.com"))
print(
(code_result + "Found a temporary number provider: tempophone.com"))
askForExit()
except:
print((code_error + "Unable to reach tempophone.com API. Skipping."))
@ -504,10 +561,12 @@ def osintScan():
if numberCountryCode == '+1':
print((code_info + "Generating URL on True People... "))
print(code_result + 'https://www.truepeoplesearch.com/results?phoneno={}'.format(internationalNumber.replace(' ', '')))
print(code_result + 'https://www.truepeoplesearch.com/results?phoneno={}'.format(
internationalNumber.replace(' ', '')))
osintIndividualScan()
def askForExit():
if not args.output:
user_input = input(code_info + "Continue scanning ? (y/N) ")
@ -518,8 +577,10 @@ def askForExit():
print(code_info + "Good bye!")
sys.exit()
def scanNumber(InputNumber):
print(code_title + "[!] ---- Fetching informations for {} ---- [!]".format(formatNumber(InputNumber)))
print(code_title +
"[!] ---- Fetching informations for {} ---- [!]".format(formatNumber(InputNumber)))
localScan(InputNumber)
@ -539,22 +600,18 @@ def scanNumber(InputNumber):
print(code_info + "Scan finished.")
print('\n' + Style.RESET_ALL)
if not args.no_ansi and not args.output:
print('\n' + Style.RESET_ALL)
else:
print('\n')
try:
if args.output:
if args.no_ansi or args.output:
code_info = '[*] '
code_warning = '(!) '
code_result = '[+] '
code_error = '[!] '
code_title = ''
if args.osint:
print('\033[91m[!] OSINT scanner is not available using output option (sorry).')
sys.exit()
sys.stdout = args.output
banner()
else:
code_info = Fore.RESET + Style.BRIGHT + '[*] '
code_warning = Fore.YELLOW + Style.BRIGHT + '(!) '
@ -562,6 +619,15 @@ try:
code_error = Fore.RED + Style.BRIGHT + '[!] '
code_title = Fore.YELLOW + Style.BRIGHT
if args.output:
if args.osint:
print(
'\033[91m[!] OSINT scanner is not available using output option (sorry).')
sys.exit()
sys.stdout = args.output
banner()
# Verify scanner option
if not args.scanner in scanners:
print((code_error + "Error: scanner doesn't exists."))