Merge pull request #32 from sundowndev/develop

Scanning improvements, readme & refactor
This commit is contained in:
Raphael 2019-02-18 16:58:42 +01:00 committed by GitHub
commit 8bac8eb377
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 252 additions and 223 deletions

View File

@ -1,15 +1,35 @@
# PhoneInfoga <h1 align="center">PhoneInfoga</h1>
[![Build Status](https://travis-ci.org/sundowndev/PhoneInfoga.svg?branch=master)](https://travis-ci.org/sundowndev/PhoneInfoga) <div align="center">
![](https://img.shields.io/badge/python-3.6-blue.svg) <a href="https://travis-ci.org/sundowndev/PhoneInfoga">
![](https://img.shields.io/github/tag/SundownDEV/PhoneInfoga.svg) <img src="https://img.shields.io/travis/sundowndev/PhoneInfoga/master.svg?style=flat-square" alt="Build Status" />
![](https://img.shields.io/badge/license-MIT-blue.svg) </a>
<a href="#">
<img src="https://img.shields.io/badge/python-3.6-blue.svg?style=flat-square" alt="Python version" />
</a>
<a href="https://github.com/sundowndev/PhoneInfoga/releases">
<img src="https://img.shields.io/github/tag/SundownDEV/PhoneInfoga.svg?style=flat-square" alt="Latest version" />
</a>
<a href="https://github.com/sundowndev/PhoneInfoga/blob/master/LICENSE">
<img src="https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square" alt="License" />
</a>
</div>
Information gathering & OSINT reconnaissance tool for phone numbers. <h4 align="center">Information gathering & OSINT reconnaissance tool for phone numbers</h4>
One of the most advanced tools to scan phone numbers using only free resources. The goal is to first gather basic information such as country, area, carrier and line type on any international phone numbers with a very good accuracy. Then try to determine the VoIP provider or search for footprints on search engines to try identify the owner. <div align="center">
<sub>For the love of open source investigations. Built with ❤︎ by
<a href="https://twitter.com/sundowndev">@sundowndev</a>
</div>
### [OSINT Tutorial: Building an OSINT Reconnaissance Tool from Scratch](https://medium.com/@SundownDEV/phone-number-scanning-osint-recon-tool-6ad8f0cac27b) <h3 align="center">
<a href="https://github.com/sundowndev/PhoneInfoga/wiki">Documentation</a> |
<a href="https://medium.com/@SundownDEV/phone-number-scanning-osint-recon-tool-6ad8f0cac27b">OSINT Tutorial</a>
</h3>
## About
PhoneInfoga is one of the most advanced tools to scan phone numbers using only free resources. The goal is to first gather basic information such as country, area, carrier and line type on any international phone numbers with a very good accuracy. Then try to determine the VoIP provider or search for footprints on search engines to try identify the owner.
## Features ## Features

File diff suppressed because one or more lines are too long

View File

@ -2,6 +2,12 @@
scriptDir=$(dirname -- "$(readlink -f -- "$BASH_SOURCE")") scriptDir=$(dirname -- "$(readlink -f -- "$BASH_SOURCE")")
python3 $scriptDir/../phoneinfoga.py -n "+86 591 2284 8571" -h
python3 $scriptDir/../phoneinfoga.py -n "+86 591 2284 8571" -s any --no-ansi
python3 $scriptDir/../phoneinfoga.py -i $scriptDir/input.txt -o $scriptDir/output_from_input.txt -s any python3 $scriptDir/../phoneinfoga.py -i $scriptDir/input.txt -o $scriptDir/output_from_input.txt -s any
python3 $scriptDir/../phoneinfoga.py -n "+86 591 2284 8571" -s all -o $scriptDir/output_single.txt python3 $scriptDir/../phoneinfoga.py -n "+86 591 2284 8571" -s all -o $scriptDir/output_single.txt
echo "Test script executed."

View File

@ -4,90 +4,84 @@
/ ___/| | | | (_) | | | | __/\/ /_ | | | | _| (_) | (_| | (_| | / ___/| | | | (_) | | | | __/\/ /_ | | | | _| (_) | (_| | (_| |
\/ |_| |_|\___/|_| |_|\___\____/ |_| |_|_| \___/ \__, |\__,_| \/ |_| |_|\___/|_| |_|\___\____/ |_| |_|_| \___/ \__, |\__,_|
|___/ |___/
PhoneInfoga Ver. v1.1.0-rc1 PhoneInfoga Ver. v1.0.0
Coded by Sundowndev Coded by Sundowndev
[!] ---- Fetching informations for 8562099453217 ---- [!] [!] ---- Fetching informations for 8562099453217 ---- [!]
[*] Running local scan... [-] Running local scan...
[+] International format: +856 20 99 453 217 [+] International format: +856 20 99 453 217
[+] Local format: 02099453217 [+] Local format: 02099453217
[+] Country code: +856 [+] Country found: Laos (+856)
[+] Location: Laos [+] City/Area: Laos
[+] Carrier: Unitel [+] Carrier: Unitel
[+] Area: Laos
[+] Timezone: Asia/Vientiane [+] Timezone: Asia/Vientiane
[*] The number is valid and possible. [-] The number is valid and possible.
[*] Scan finished. [-] Scan finished.
[!] ---- Fetching informations for 59172768361 ---- [!] [!] ---- Fetching informations for 59172768361 ---- [!]
[*] Running local scan... [-] Running local scan...
[+] International format: +591 72768361 [+] International format: +591 72768361
[+] Local format: 072768361 [+] Local format: 072768361
[+] Country code: +591 [+] Country found: Bolivia (+591)
[+] Location: Bolivia [+] City/Area: Bolivia
[+] Carrier: Entel [+] Carrier: Entel
[+] Area: Bolivia
[+] Timezone: America/La_Paz [+] Timezone: America/La_Paz
[*] The number is valid and possible. [-] The number is valid and possible.
[*] Scan finished. [-] Scan finished.
[!] ---- Fetching informations for 32474123456 ---- [!] [!] ---- Fetching informations for 32474123456 ---- [!]
[*] Running local scan... [-] Running local scan...
[+] International format: +32 474 12 34 56 [+] International format: +32 474 12 34 56
[+] Local format: 0474123456 [+] Local format: 0474123456
[+] Country code: +32 [+] Country found: Belgium (+32)
[+] Location: Belgium [+] City/Area: Belgium
[+] Carrier: Proximus [+] Carrier: Proximus
[+] Area: Belgium
[+] Timezone: Europe/Brussels [+] Timezone: Europe/Brussels
[*] The number is valid and possible. [-] The number is valid and possible.
[*] Scan finished. [-] Scan finished.
[!] ---- Fetching informations for 15417543010 ---- [!] [!] ---- Fetching informations for 15417543010 ---- [!]
[*] Running local scan... [-] Running local scan...
[+] International format: +1 541-754-3010 [+] International format: +1 541-754-3010
[+] Local format: 05417543010 [+] Local format: 05417543010
[+] Country code: +1 [+] Country found: United States (+1)
[+] Location: Corvallis, OR [+] City/Area: Corvallis, OR
[+] Carrier: [+] Carrier:
[+] Area: Corvallis, OR
[+] Timezone: America/Los_Angeles [+] Timezone: America/Los_Angeles
[*] The number is valid and possible. [-] The number is valid and possible.
[*] Scan finished. [-] Scan finished.
[!] ---- Fetching informations for 8659122848571 ---- [!] [!] ---- Fetching informations for 8659122848571 ---- [!]
[*] Running local scan... [-] Running local scan...
[+] International format: +86 591 2284 8571 [+] International format: +86 591 2284 8571
[+] Local format: 059122848571 [+] Local format: 059122848571
[+] Country code: +86 [+] Country found: China (+86)
[+] Location: Fuzhou, Fujian [+] City/Area: Fuzhou, Fujian
[+] Carrier: [+] Carrier:
[+] Area: Fuzhou, Fujian
[+] Timezone: Asia/Shanghai [+] Timezone: Asia/Shanghai
[*] The number is valid and possible. [-] The number is valid and possible.
[*] Scan finished. [-] Scan finished.
[!] ---- Fetching informations for 74964819375 ---- [!] [!] ---- Fetching informations for 74964819375 ---- [!]
[*] Running local scan... [-] Running local scan...
[+] International format: +7 496 481-93-75 [+] International format: +7 496 481-93-75
[+] Local format: 04964819375 [+] Local format: 04964819375
[+] Country code: +7 [+] Country found: Russia (+7)
[+] Location: Moscow [+] City/Area: Moscow
[+] Carrier: [+] Carrier:
[+] Area: Moscow
[+] Timezone: Europe/Moscow [+] Timezone: Europe/Moscow
[*] The number is valid and possible. [-] The number is valid and possible.
[*] Scan finished. [-] Scan finished.
[!] ---- Fetching informations for 39172768361 ---- [!] [!] ---- Fetching informations for 39172768361 ---- [!]
[*] Running local scan... [-] Running local scan...
[*] Scan finished. [-] Scan finished.

View File

@ -4,28 +4,27 @@
/ ___/| | | | (_) | | | | __/\/ /_ | | | | _| (_) | (_| | (_| | / ___/| | | | (_) | | | | __/\/ /_ | | | | _| (_) | (_| | (_| |
\/ |_| |_|\___/|_| |_|\___\____/ |_| |_|_| \___/ \__, |\__,_| \/ |_| |_|\___/|_| |_|\___\____/ |_| |_|_| \___/ \__, |\__,_|
|___/ |___/
PhoneInfoga Ver. v1.1.0-rc1 PhoneInfoga Ver. v1.0.0
Coded by Sundowndev Coded by Sundowndev
[!] ---- Fetching informations for 8659122848571 ---- [!] [!] ---- Fetching informations for 8659122848571 ---- [!]
[*] Running local scan... [-] Running local scan...
[+] International format: +86 591 2284 8571 [+] International format: +86 591 2284 8571
[+] Local format: 059122848571 [+] Local format: 059122848571
[+] Country code: +86 [+] Country found: China (+86)
[+] Location: Fuzhou, Fujian [+] City/Area: Fuzhou, Fujian
[+] Carrier: [+] Carrier:
[+] Area: Fuzhou, Fujian
[+] Timezone: Asia/Shanghai [+] Timezone: Asia/Shanghai
[*] The number is valid and possible. [-] The number is valid and possible.
[*] Running Numverify.com scan... [-] Running Numverify.com scan...
[+] Number: (+86) 059122848571 [+] Number: (+86) 059122848571
[+] Country: China (People's Republic of) (CN) [+] Country: China (People's Republic of) (CN)
[+] Location: Fuzhou [+] Location: Fuzhou
[+] Carrier: [+] Carrier:
[+] Line type: landline [+] Line type: landline
(!) This is most likely a landline, but it can still be a fixed VoIP number. (!) This is most likely a landline, but it can still be a fixed VoIP number.
[*] Running OVH scan... [-] Running OVH scan...
[*] Scan finished. [-] Scan finished.

View File

@ -4,36 +4,28 @@ __version__ = 'v1.0.0'
try: try:
import sys import sys
import signal
from colorama import Fore, Style from colorama import Fore, Style
import atexit import atexit
import argparse import argparse
import random import random
except KeyboardInterrupt: import time
print('[!] Exiting.') import hashlib
sys.exit() import json
except: import re
import requests
import urllib3
from bs4 import BeautifulSoup
import html5lib
import phonenumbers
from phonenumbers import carrier
from phonenumbers import geocoder
from phonenumbers import timezone
from urllib.parse import urlencode
except Exception as e:
print('[!] Missing requirements. Try running python3 -m pip install -r requirements.txt') print('[!] Missing requirements. Try running python3 -m pip install -r requirements.txt')
sys.exit() sys.exit()
def banner():
print(" ___ _ _____ __ ")
print(" / _ \ |__ ___ _ __ ___ \_ \_ __ / _| ___ __ _ __ _ ")
print(" / /_)/ '_ \ / _ \| '_ \ / _ \ / /\/ '_ \| |_ / _ \ / _` |/ _` |")
print(" / ___/| | | | (_) | | | | __/\/ /_ | | | | _| (_) | (_| | (_| |")
print(" \/ |_| |_|\___/|_| |_|\___\____/ |_| |_|_| \___/ \__, |\__,_|")
print(" |___/ ")
print(" PhoneInfoga Ver. {}".format(__version__))
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]') usage='%(prog)s -n <number> [options]')
@ -58,106 +50,22 @@ parser.add_argument('-u', '--update', action='store_true',
parser.add_argument('--no-ansi', action='store_true', parser.add_argument('--no-ansi', action='store_true',
help='Disable colored output') help='Disable colored output')
parser.add_argument('-v', '--version', action='store_true',
help='Show tool version')
args = parser.parse_args() args = parser.parse_args()
def resetColors():
if not args.output:
print(Style.RESET_ALL)
# Reset text color at exit
atexit.register(resetColors)
# If any param is passed, execute help command
if not len(sys.argv) > 1:
parser.print_help()
sys.exit()
try:
import time
import hashlib
import json
import re
import requests
import urllib3
from bs4 import BeautifulSoup
import html5lib
import phonenumbers
from phonenumbers import carrier
from phonenumbers import geocoder
from phonenumbers import timezone
from urllib.parse import urlencode
except KeyboardInterrupt:
print('\033[91m[!] Exiting.')
sys.exit()
except:
print('\033[91m[!] Missing requirements. Try running python3 -m pip install -r requirements.txt')
sys.exit()
requests.packages.urllib3.disable_warnings()
requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS += 'HIGH:!DH:!aNULL'
try:
requests.packages.urllib3.contrib.pyopenssl.DEFAULT_SSL_CIPHER_LIST += 'HIGH:!DH:!aNULL'
except AttributeError:
# no pyopenssl support used / needed / available
pass
if args.update:
def download_file(url, target_path):
response = requests.get(url, stream=True)
handle = open(target_path, "wb")
for chunk in response.iter_content(chunk_size=512):
if chunk: # filter out keep-alive new chunks
handle.write(chunk)
print('Updating PhoneInfoga...')
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']
print('Last version: {}'.format(new_version))
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)
output_directory = 'osint/{}'.format(file)
download_file(url, output_directory)
print('[*] Updating python script')
url = 'https://raw.githubusercontent.com/sundowndev/PhoneInfoga/master/phoneinfoga.py'
output_directory = 'phoneinfoga.py'
download_file(url, output_directory)
except:
print('Update failed. Try using git pull.')
sys.exit()
print('The tool was successfully updated.')
sys.exit()
scanners = ['any', 'all', 'numverify', 'ovh']
uagent = [] uagent = []
uagent.append("Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.0) Opera 12.14") uagent.append(
"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.0) Opera 12.14")
uagent.append( uagent.append(
"Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:26.0) Gecko/20100101 Firefox/26.0") "Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:26.0) Gecko/20100101 Firefox/26.0")
uagent.append( uagent.append(
"Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.3) Gecko/20090913 Firefox/3.5.3") "Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.3) Gecko/20090913 Firefox/3.5.3")
uagent.append( 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)") "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 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( 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)") "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( uagent.append(
@ -174,6 +82,36 @@ numberCountry = '' # Country; e.g: fr
googleAbuseToken = '' googleAbuseToken = ''
customFormatting = '' customFormatting = ''
if args.no_ansi or args.output:
code_info = '[-] '
code_warning = '(!) '
code_result = '[+] '
code_error = '[!] '
code_title = ''
else:
code_info = Fore.RESET + Style.BRIGHT + '[-] '
code_warning = Fore.YELLOW + Style.BRIGHT + '(!) '
code_result = Fore.GREEN + Style.BRIGHT + '[+] '
code_error = Fore.RED + Style.BRIGHT + '[!] '
code_title = Fore.YELLOW + Style.BRIGHT
def banner():
print(" ___ _ _____ __ ")
print(" / _ \ |__ ___ _ __ ___ \_ \_ __ / _| ___ __ _ __ _ ")
print(" / /_)/ '_ \ / _ \| '_ \ / _ \ / /\/ '_ \| |_ / _ \ / _` |/ _` |")
print(" / ___/| | | | (_) | | | | __/\/ /_ | | | | _| (_) | (_| | (_| |")
print(" \/ |_| |_|\___/|_| |_|\___\____/ |_| |_|_| \___/ \__, |\__,_|")
print(" |___/ ")
print(" PhoneInfoga Ver. {}".format(__version__))
print(" Coded by Sundowndev")
print("\n")
def resetColors():
if not args.output:
print(Style.RESET_ALL)
def search(req, stop): def search(req, stop):
global googleAbuseToken global googleAbuseToken
@ -229,10 +167,11 @@ def search(req, stop):
if re.match(r"^(?:\/search\?q\=)", url) is not None: if re.match(r"^(?:\/search\?q\=)", url) is not None:
url = 'https://google.com' + url url = 'https://google.com' + url
links.append(url) if links is not None:
return links
return links else:
except: return []
except Exception as e:
print(code_error + 'Request failed. Please retry or open an issue on https://github.com/sundowndev/PhoneInfoga.') print(code_error + 'Request failed. Please retry or open an issue on https://github.com/sundowndev/PhoneInfoga.')
@ -253,7 +192,7 @@ def localScan(InputNumber):
try: try:
PhoneNumberObject = phonenumbers.parse(FormattedPhoneNumber, None) PhoneNumberObject = phonenumbers.parse(FormattedPhoneNumber, None)
except: except Exception as e:
return False return False
else: else:
if not phonenumbers.is_valid_number(PhoneNumberObject): if not phonenumbers.is_valid_number(PhoneNumberObject):
@ -264,18 +203,6 @@ def localScan(InputNumber):
numberCountryCode = phonenumbers.format_number( numberCountryCode = phonenumbers.format_number(
PhoneNumberObject, phonenumbers.PhoneNumberFormat.INTERNATIONAL).split(' ')[0] PhoneNumberObject, phonenumbers.PhoneNumberFormat.INTERNATIONAL).split(' ')[0]
try:
countries = json.load(open('data/CountryCodes.json'))
for country in countries:
if (country['dial_code'].replace(' ', '') == numberCountryCode):
print(code_info + 'Country code found: {} ({})'.format(country['name'],country['code']))
numberCountry = country['code']
break
except:
print(code_error + 'Unable to find country code.')
print(numberCountry)
localNumber = phonenumbers.format_number( localNumber = phonenumbers.format_number(
PhoneNumberObject, phonenumbers.PhoneNumberFormat.E164).replace(numberCountryCode, '') PhoneNumberObject, phonenumbers.PhoneNumberFormat.E164).replace(numberCountryCode, '')
internationalNumber = phonenumbers.format_number( internationalNumber = phonenumbers.format_number(
@ -283,11 +210,12 @@ def localScan(InputNumber):
print(code_result + 'International format: {}'.format(internationalNumber)) print(code_result + 'International format: {}'.format(internationalNumber))
print(code_result + 'Local format: 0{}'.format(localNumber)) print(code_result + 'Local format: 0{}'.format(localNumber))
print(code_result + 'Country code: {}'.format(numberCountryCode)) print(code_result + 'Country found: {} ({})'.format(
print(code_result + 'Location: {}'.format(geocoder.description_for_number(PhoneNumberObject, "en"))) geocoder.country_name_for_number(PhoneNumberObject, "en"), numberCountryCode))
print(code_result + 'City/Area: {}'.format(
geocoder.description_for_number(PhoneNumberObject, "en")))
print(code_result + print(code_result +
'Carrier: {}'.format(carrier.name_for_number(PhoneNumberObject, 'en'))) '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): for timezoneResult in timezone.time_zones_for_number(PhoneNumberObject):
print(code_result + 'Timezone: {}'.format(timezoneResult)) print(code_result + 'Timezone: {}'.format(timezoneResult))
@ -305,9 +233,14 @@ def numverifyScan():
print(code_info + 'Running Numverify.com scan...') print(code_info + 'Running Numverify.com scan...')
requestSecret = '' try:
resp = requests.get('https://numverify.com/') requestSecret = ''
soup = BeautifulSoup(resp.text, "html5lib") resp = requests.get('https://numverify.com/')
soup = BeautifulSoup(resp.text, "html5lib")
except Exception as e:
print(code_error + 'Numverify.com is not available')
return -1
for tag in soup.find_all("input", type="hidden"): for tag in soup.find_all("input", type="hidden"):
if tag['name'] == "scl_request_secret": if tag['name'] == "scl_request_secret":
requestSecret = tag['value'] requestSecret = tag['value']
@ -334,8 +267,8 @@ def numverifyScan():
"GET", "https://numverify.com/php_helper_scripts/phone_api.php?secret_key={}&number={}".format(apiKey, number), data="", headers=headers) "GET", "https://numverify.com/php_helper_scripts/phone_api.php?secret_key={}&number={}".format(apiKey, number), data="", headers=headers)
data = json.loads(response.content.decode('utf-8')) data = json.loads(response.content.decode('utf-8'))
except: except Exception as e:
print(code_error + 'Numverify is not available') print(code_error + 'Numverify.com is not available')
return -1 return -1
if response.content == "Unauthorized" or response.status_code != 200: if response.content == "Unauthorized" or response.status_code != 200:
@ -383,7 +316,7 @@ def ovhScan():
response = requests.request( response = requests.request(
"GET", "https://api.ovh.com/1.0/telephony/number/detailedZones", data="", headers=headers, params=querystring) "GET", "https://api.ovh.com/1.0/telephony/number/detailedZones", data="", headers=headers, params=querystring)
data = json.loads(response.content.decode('utf-8')) data = json.loads(response.content.decode('utf-8'))
except: except Exception as e:
print(code_error + 'OVH API is unreachable. Maybe retry later.') print(code_error + 'OVH API is unreachable. Maybe retry later.')
return -1 return -1
@ -431,6 +364,7 @@ def osintIndividualScan():
print( print(
(code_info + "Searching for footprints on {}...".format(dork['site']))) (code_info + "Searching for footprints on {}...".format(dork['site'])))
for result in search(dorkRequest, stop=dork['stop']): for result in search(dorkRequest, stop=dork['stop']):
if result: if result:
print((code_result + "URL: " + result)) print((code_result + "URL: " + result))
@ -474,6 +408,7 @@ def osintSocialMediaScan():
print( print(
(code_info + "Searching for footprints on {}...".format(dork['site']))) (code_info + "Searching for footprints on {}...".format(dork['site'])))
for result in search(dorkRequest, stop=dork['stop']): for result in search(dorkRequest, stop=dork['stop']):
if result: if result:
print((code_result + "URL: " + result)) print((code_result + "URL: " + result))
@ -489,6 +424,7 @@ def osintDisposableNumScan():
print( print(
(code_info + "Searching for footprints on {}...".format(dork['site']))) (code_info + "Searching for footprints on {}...".format(dork['site'])))
for result in search(dorkRequest, stop=dork['stop']): for result in search(dorkRequest, stop=dork['stop']):
if result: if result:
print((code_result + "Result found: {}".format(dork['site']))) print((code_result + "Result found: {}".format(dork['site'])))
@ -496,7 +432,7 @@ def osintDisposableNumScan():
askForExit() askForExit()
def osintScan(): def osintScan(rerun=False):
global number global number
global localNumber global localNumber
global internationalNumber global internationalNumber
@ -508,15 +444,16 @@ def osintScan():
print(code_info + 'Running OSINT footprint reconnaissance...') print(code_info + 'Running OSINT footprint reconnaissance...')
# Whitepages if not rerun:
print((code_info + "Generating scan URL on 411.com...")) # Whitepages
print(code_result + "Scan URL: https://www.411.com/phone/{}".format( print((code_info + "Generating scan URL on 411.com..."))
internationalNumber.replace('+', '').replace(' ', '-'))) print(code_result + "Scan URL: https://www.411.com/phone/{}".format(
internationalNumber.replace('+', '').replace(' ', '-')))
askingCustomPayload = input( askingCustomPayload = input(
code_info + 'Would you like to use an additional format for this number ? (y/N) ') code_info + 'Would you like to use an additional format for this number ? (y/N) ')
if askingCustomPayload == 'y' or askingCustomPayload == 'yes': if rerun or askingCustomPayload == 'y' or askingCustomPayload == 'yes':
customFormatting = input(code_info + 'Custom format: ') customFormatting = input(code_info + 'Custom format: ')
print((code_info + '---- Web pages footprints ----')) print((code_info + '---- Web pages footprints ----'))
@ -568,7 +505,7 @@ def osintScan():
print( print(
(code_result + "Found a temporary number provider: tempophone.com")) (code_result + "Found a temporary number provider: tempophone.com"))
askForExit() askForExit()
except: except Exception as e:
print((code_error + "Unable to reach tempophone.com API. Skipping.")) print((code_error + "Unable to reach tempophone.com API. Skipping."))
osintDisposableNumScan() osintDisposableNumScan()
@ -590,7 +527,7 @@ def osintScan():
code_info + "Would you like to rerun OSINT scan ? (e.g to use a different format) (y/N) ") code_info + "Would you like to rerun OSINT scan ? (e.g to use a different format) (y/N) ")
if retry_input.lower() == 'y' or retry_input.lower() == 'yes': if retry_input.lower() == 'y' or retry_input.lower() == 'yes':
osintScan() osintScan(True)
else: else:
return -1 return -1
@ -634,19 +571,83 @@ def scanNumber(InputNumber):
print('\n') print('\n')
try: def download_file(url, target_path):
if args.no_ansi or args.output: response = requests.get(url, stream=True)
code_info = '[*] ' handle = open(target_path, "wb")
code_warning = '(!) ' for chunk in response.iter_content(chunk_size=512):
code_result = '[+] ' if chunk: # filter out keep-alive new chunks
code_error = '[!] ' handle.write(chunk)
code_title = ''
else:
code_info = Fore.RESET + Style.BRIGHT + '[*] ' def updateTool():
code_warning = Fore.YELLOW + Style.BRIGHT + '(!) ' print('Updating PhoneInfoga...')
code_result = Fore.GREEN + Style.BRIGHT + '[+] ' print('Actual version: {}'.format(__version__))
code_error = Fore.RED + Style.BRIGHT + '[!] '
code_title = Fore.YELLOW + Style.BRIGHT # Fetching last github tag
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'
]
try:
print('[*] Updating OSINT files')
for file in osintFiles:
url = 'https://raw.githubusercontent.com/sundowndev/PhoneInfoga/master/osint/{}'.format(
file)
output_directory = 'osint/{}'.format(file)
download_file(url, output_directory)
print('[*] Updating python script')
url = 'https://raw.githubusercontent.com/sundowndev/PhoneInfoga/master/phoneinfoga.py'
output_directory = 'phoneinfoga.py'
download_file(url, output_directory)
except Exception as e:
print('Update failed. Try using git pull.')
sys.exit()
print('The tool was successfully updated.')
sys.exit()
def main():
scanners = ['any', 'all', 'numverify', 'ovh']
banner()
if sys.version_info[0] < 3:
print(
"\033[1m\033[93m(!) Please run the tool using Python 3" + Style.RESET_ALL)
sys.exit()
# Reset text color at exit
atexit.register(resetColors)
# If any param is passed, execute help command
if not len(sys.argv) > 1:
parser.print_help()
sys.exit()
elif args.version:
print("Version {}".format(__version__))
sys.exit()
requests.packages.urllib3.disable_warnings()
requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS += 'HIGH:!DH:!aNULL'
try:
requests.packages.urllib3.contrib.pyopenssl.DEFAULT_SSL_CIPHER_LIST += 'HIGH:!DH:!aNULL'
except AttributeError:
# no pyopenssl support used / needed / available
pass
if args.update:
updateTool()
if args.output: if args.output:
if args.osint: if args.osint:
@ -655,7 +656,7 @@ try:
sys.exit() sys.exit()
sys.stdout = args.output sys.stdout = args.output
banner() banner() # Output banner again in the file
# Verify scanner option # Verify scanner option
if not args.scanner in scanners: if not args.scanner in scanners:
@ -667,9 +668,19 @@ try:
elif args.input: elif args.input:
for line in args.input.readlines(): for line in args.input.readlines():
scanNumber(line) scanNumber(line)
else:
parser.print_help()
sys.exit()
if args.output: if args.output:
args.output.close() args.output.close()
except KeyboardInterrupt:
print(("\n" + code_error + "Scan interrupted. Good bye!"))
def signal_handler(signal, frame):
print('\n[-] You pressed Ctrl+C! Exiting.')
sys.exit() sys.exit()
if __name__ == '__main__':
signal.signal(signal.SIGINT, signal_handler)
main()