diff --git a/README.md b/README.md
index 7a01c0589..1d84188e9 100644
--- a/README.md
+++ b/README.md
@@ -1,15 +1,35 @@
-# PhoneInfoga
-
-[![Build Status](https://travis-ci.org/sundowndev/PhoneInfoga.svg?branch=master)](https://travis-ci.org/sundowndev/PhoneInfoga)
-![](https://img.shields.io/badge/python-3.6-blue.svg)
-![](https://img.shields.io/github/tag/SundownDEV/PhoneInfoga.svg)
-![](https://img.shields.io/badge/license-MIT-blue.svg)
-
-Information gathering & OSINT reconnaissance tool for phone numbers.
-
-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.
-
-### [OSINT Tutorial: Building an OSINT Reconnaissance Tool from Scratch](https://medium.com/@SundownDEV/phone-number-scanning-osint-recon-tool-6ad8f0cac27b)
+
PhoneInfoga
+
+
+
+Information gathering & OSINT reconnaissance tool for phone numbers
+
+
+
For the love of open source investigations. Built with ❤︎ by
+ @sundowndev
+
+
+
+
+## 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
diff --git a/data/CountryCodes.json b/data/CountryCodes.json
deleted file mode 100644
index 1c2b97243..000000000
--- a/data/CountryCodes.json
+++ /dev/null
@@ -1 +0,0 @@
-[{"name":"Israel","dial_code":"+972","code":"IL"},{"name":"Afghanistan","dial_code":"+93","code":"AF"},{"name":"Albania","dial_code":"+355","code":"AL"},{"name":"Algeria","dial_code":"+213","code":"DZ"},{"name":"AmericanSamoa","dial_code":"+1 684","code":"AS"},{"name":"Andorra","dial_code":"+376","code":"AD"},{"name":"Angola","dial_code":"+244","code":"AO"},{"name":"Anguilla","dial_code":"+1 264","code":"AI"},{"name":"Antigua and Barbuda","dial_code":"+1268","code":"AG"},{"name":"Argentina","dial_code":"+54","code":"AR"},{"name":"Armenia","dial_code":"+374","code":"AM"},{"name":"Aruba","dial_code":"+297","code":"AW"},{"name":"Australia","dial_code":"+61","code":"AU"},{"name":"Austria","dial_code":"+43","code":"AT"},{"name":"Azerbaijan","dial_code":"+994","code":"AZ"},{"name":"Bahamas","dial_code":"+1 242","code":"BS"},{"name":"Bahrain","dial_code":"+973","code":"BH"},{"name":"Bangladesh","dial_code":"+880","code":"BD"},{"name":"Barbados","dial_code":"+1 246","code":"BB"},{"name":"Belarus","dial_code":"+375","code":"BY"},{"name":"Belgium","dial_code":"+32","code":"BE"},{"name":"Belize","dial_code":"+501","code":"BZ"},{"name":"Benin","dial_code":"+229","code":"BJ"},{"name":"Bermuda","dial_code":"+1 441","code":"BM"},{"name":"Bhutan","dial_code":"+975","code":"BT"},{"name":"Bosnia and Herzegovina","dial_code":"+387","code":"BA"},{"name":"Botswana","dial_code":"+267","code":"BW"},{"name":"Brazil","dial_code":"+55","code":"BR"},{"name":"British Indian Ocean Territory","dial_code":"+246","code":"IO"},{"name":"Bulgaria","dial_code":"+359","code":"BG"},{"name":"Burkina Faso","dial_code":"+226","code":"BF"},{"name":"Burundi","dial_code":"+257","code":"BI"},{"name":"Cambodia","dial_code":"+855","code":"KH"},{"name":"Cameroon","dial_code":"+237","code":"CM"},{"name":"Canada","dial_code":"+1","code":"CA"},{"name":"Cape Verde","dial_code":"+238","code":"CV"},{"name":"Cayman Islands","dial_code":"+ 345","code":"KY"},{"name":"Central African Republic","dial_code":"+236","code":"CF"},{"name":"Chad","dial_code":"+235","code":"TD"},{"name":"Chile","dial_code":"+56","code":"CL"},{"name":"China","dial_code":"+86","code":"CN"},{"name":"Christmas Island","dial_code":"+61","code":"CX"},{"name":"Colombia","dial_code":"+57","code":"CO"},{"name":"Comoros","dial_code":"+269","code":"KM"},{"name":"Congo","dial_code":"+242","code":"CG"},{"name":"Cook Islands","dial_code":"+682","code":"CK"},{"name":"Costa Rica","dial_code":"+506","code":"CR"},{"name":"Croatia","dial_code":"+385","code":"HR"},{"name":"Cuba","dial_code":"+53","code":"CU"},{"name":"Cyprus","dial_code":"+537","code":"CY"},{"name":"Czech Republic","dial_code":"+420","code":"CZ"},{"name":"Denmark","dial_code":"+45","code":"DK"},{"name":"Djibouti","dial_code":"+253","code":"DJ"},{"name":"Dominica","dial_code":"+1 767","code":"DM"},{"name":"Dominican Republic","dial_code":"+1 849","code":"DO"},{"name":"Ecuador","dial_code":"+593","code":"EC"},{"name":"Egypt","dial_code":"+20","code":"EG"},{"name":"El Salvador","dial_code":"+503","code":"SV"},{"name":"Equatorial Guinea","dial_code":"+240","code":"GQ"},{"name":"Eritrea","dial_code":"+291","code":"ER"},{"name":"Estonia","dial_code":"+372","code":"EE"},{"name":"Ethiopia","dial_code":"+251","code":"ET"},{"name":"Faroe Islands","dial_code":"+298","code":"FO"},{"name":"Fiji","dial_code":"+679","code":"FJ"},{"name":"Finland","dial_code":"+358","code":"FI"},{"name":"France","dial_code":"+33","code":"FR"},{"name":"French Guiana","dial_code":"+594","code":"GF"},{"name":"French Polynesia","dial_code":"+689","code":"PF"},{"name":"Gabon","dial_code":"+241","code":"GA"},{"name":"Gambia","dial_code":"+220","code":"GM"},{"name":"Georgia","dial_code":"+995","code":"GE"},{"name":"Germany","dial_code":"+49","code":"DE"},{"name":"Ghana","dial_code":"+233","code":"GH"},{"name":"Gibraltar","dial_code":"+350","code":"GI"},{"name":"Greece","dial_code":"+30","code":"GR"},{"name":"Greenland","dial_code":"+299","code":"GL"},{"name":"Grenada","dial_code":"+1 473","code":"GD"},{"name":"Guadeloupe","dial_code":"+590","code":"GP"},{"name":"Guam","dial_code":"+1 671","code":"GU"},{"name":"Guatemala","dial_code":"+502","code":"GT"},{"name":"Guinea","dial_code":"+224","code":"GN"},{"name":"Guinea-Bissau","dial_code":"+245","code":"GW"},{"name":"Guyana","dial_code":"+595","code":"GY"},{"name":"Haiti","dial_code":"+509","code":"HT"},{"name":"Honduras","dial_code":"+504","code":"HN"},{"name":"Hungary","dial_code":"+36","code":"HU"},{"name":"Iceland","dial_code":"+354","code":"IS"},{"name":"India","dial_code":"+91","code":"IN"},{"name":"Indonesia","dial_code":"+62","code":"ID"},{"name":"Iraq","dial_code":"+964","code":"IQ"},{"name":"Ireland","dial_code":"+353","code":"IE"},{"name":"Israel","dial_code":"+972","code":"IL"},{"name":"Italy","dial_code":"+39","code":"IT"},{"name":"Jamaica","dial_code":"+1 876","code":"JM"},{"name":"Japan","dial_code":"+81","code":"JP"},{"name":"Jordan","dial_code":"+962","code":"JO"},{"name":"Kazakhstan","dial_code":"+7 7","code":"KZ"},{"name":"Kenya","dial_code":"+254","code":"KE"},{"name":"Kiribati","dial_code":"+686","code":"KI"},{"name":"Kuwait","dial_code":"+965","code":"KW"},{"name":"Kyrgyzstan","dial_code":"+996","code":"KG"},{"name":"Latvia","dial_code":"+371","code":"LV"},{"name":"Lebanon","dial_code":"+961","code":"LB"},{"name":"Lesotho","dial_code":"+266","code":"LS"},{"name":"Liberia","dial_code":"+231","code":"LR"},{"name":"Liechtenstein","dial_code":"+423","code":"LI"},{"name":"Lithuania","dial_code":"+370","code":"LT"},{"name":"Luxembourg","dial_code":"+352","code":"LU"},{"name":"Madagascar","dial_code":"+261","code":"MG"},{"name":"Malawi","dial_code":"+265","code":"MW"},{"name":"Malaysia","dial_code":"+60","code":"MY"},{"name":"Maldives","dial_code":"+960","code":"MV"},{"name":"Mali","dial_code":"+223","code":"ML"},{"name":"Malta","dial_code":"+356","code":"MT"},{"name":"Marshall Islands","dial_code":"+692","code":"MH"},{"name":"Martinique","dial_code":"+596","code":"MQ"},{"name":"Mauritania","dial_code":"+222","code":"MR"},{"name":"Mauritius","dial_code":"+230","code":"MU"},{"name":"Mayotte","dial_code":"+262","code":"YT"},{"name":"Mexico","dial_code":"+52","code":"MX"},{"name":"Monaco","dial_code":"+377","code":"MC"},{"name":"Mongolia","dial_code":"+976","code":"MN"},{"name":"Montenegro","dial_code":"+382","code":"ME"},{"name":"Montserrat","dial_code":"+1664","code":"MS"},{"name":"Morocco","dial_code":"+212","code":"MA"},{"name":"Myanmar","dial_code":"+95","code":"MM"},{"name":"Namibia","dial_code":"+264","code":"NA"},{"name":"Nauru","dial_code":"+674","code":"NR"},{"name":"Nepal","dial_code":"+977","code":"NP"},{"name":"Netherlands","dial_code":"+31","code":"NL"},{"name":"Netherlands Antilles","dial_code":"+599","code":"AN"},{"name":"New Caledonia","dial_code":"+687","code":"NC"},{"name":"New Zealand","dial_code":"+64","code":"NZ"},{"name":"Nicaragua","dial_code":"+505","code":"NI"},{"name":"Niger","dial_code":"+227","code":"NE"},{"name":"Nigeria","dial_code":"+234","code":"NG"},{"name":"Niue","dial_code":"+683","code":"NU"},{"name":"Norfolk Island","dial_code":"+672","code":"NF"},{"name":"Northern Mariana Islands","dial_code":"+1 670","code":"MP"},{"name":"Norway","dial_code":"+47","code":"NO"},{"name":"Oman","dial_code":"+968","code":"OM"},{"name":"Pakistan","dial_code":"+92","code":"PK"},{"name":"Palau","dial_code":"+680","code":"PW"},{"name":"Panama","dial_code":"+507","code":"PA"},{"name":"Papua New Guinea","dial_code":"+675","code":"PG"},{"name":"Paraguay","dial_code":"+595","code":"PY"},{"name":"Peru","dial_code":"+51","code":"PE"},{"name":"Philippines","dial_code":"+63","code":"PH"},{"name":"Poland","dial_code":"+48","code":"PL"},{"name":"Portugal","dial_code":"+351","code":"PT"},{"name":"Puerto Rico","dial_code":"+1 939","code":"PR"},{"name":"Qatar","dial_code":"+974","code":"QA"},{"name":"Romania","dial_code":"+40","code":"RO"},{"name":"Rwanda","dial_code":"+250","code":"RW"},{"name":"Samoa","dial_code":"+685","code":"WS"},{"name":"San Marino","dial_code":"+378","code":"SM"},{"name":"Saudi Arabia","dial_code":"+966","code":"SA"},{"name":"Senegal","dial_code":"+221","code":"SN"},{"name":"Serbia","dial_code":"+381","code":"RS"},{"name":"Seychelles","dial_code":"+248","code":"SC"},{"name":"Sierra Leone","dial_code":"+232","code":"SL"},{"name":"Singapore","dial_code":"+65","code":"SG"},{"name":"Slovakia","dial_code":"+421","code":"SK"},{"name":"Slovenia","dial_code":"+386","code":"SI"},{"name":"Solomon Islands","dial_code":"+677","code":"SB"},{"name":"South Africa","dial_code":"+27","code":"ZA"},{"name":"South Georgia and the South Sandwich Islands","dial_code":"+500","code":"GS"},{"name":"Spain","dial_code":"+34","code":"ES"},{"name":"Sri Lanka","dial_code":"+94","code":"LK"},{"name":"Sudan","dial_code":"+249","code":"SD"},{"name":"Suriname","dial_code":"+597","code":"SR"},{"name":"Swaziland","dial_code":"+268","code":"SZ"},{"name":"Sweden","dial_code":"+46","code":"SE"},{"name":"Switzerland","dial_code":"+41","code":"CH"},{"name":"Tajikistan","dial_code":"+992","code":"TJ"},{"name":"Thailand","dial_code":"+66","code":"TH"},{"name":"Togo","dial_code":"+228","code":"TG"},{"name":"Tokelau","dial_code":"+690","code":"TK"},{"name":"Tonga","dial_code":"+676","code":"TO"},{"name":"Trinidad and Tobago","dial_code":"+1 868","code":"TT"},{"name":"Tunisia","dial_code":"+216","code":"TN"},{"name":"Turkey","dial_code":"+90","code":"TR"},{"name":"Turkmenistan","dial_code":"+993","code":"TM"},{"name":"Turks and Caicos Islands","dial_code":"+1 649","code":"TC"},{"name":"Tuvalu","dial_code":"+688","code":"TV"},{"name":"Uganda","dial_code":"+256","code":"UG"},{"name":"Ukraine","dial_code":"+380","code":"UA"},{"name":"United Arab Emirates","dial_code":"+971","code":"AE"},{"name":"United Kingdom","dial_code":"+44","code":"GB"},{"name":"United States","dial_code":"+1","code":"US"},{"name":"Uruguay","dial_code":"+598","code":"UY"},{"name":"Uzbekistan","dial_code":"+998","code":"UZ"},{"name":"Vanuatu","dial_code":"+678","code":"VU"},{"name":"Wallis and Futuna","dial_code":"+681","code":"WF"},{"name":"Yemen","dial_code":"+967","code":"YE"},{"name":"Zambia","dial_code":"+260","code":"ZM"},{"name":"Zimbabwe","dial_code":"+263","code":"ZW"},{"name":"land Islands","dial_code":"","code":"AX"},{"name":"Antarctica","dial_code":null,"code":"AQ"},{"name":"Bolivia, Plurinational State of","dial_code":"+591","code":"BO"},{"name":"Brunei Darussalam","dial_code":"+673","code":"BN"},{"name":"Cocos (Keeling) Islands","dial_code":"+61","code":"CC"},{"name":"Congo, The Democratic Republic of the","dial_code":"+243","code":"CD"},{"name":"Cote d'Ivoire","dial_code":"+225","code":"CI"},{"name":"Falkland Islands (Malvinas)","dial_code":"+500","code":"FK"},{"name":"Guernsey","dial_code":"+44","code":"GG"},{"name":"Holy See (Vatican City State)","dial_code":"+379","code":"VA"},{"name":"Hong Kong","dial_code":"+852","code":"HK"},{"name":"Iran, Islamic Republic of","dial_code":"+98","code":"IR"},{"name":"Isle of Man","dial_code":"+44","code":"IM"},{"name":"Jersey","dial_code":"+44","code":"JE"},{"name":"Korea, Democratic People's Republic of","dial_code":"+850","code":"KP"},{"name":"Korea, Republic of","dial_code":"+82","code":"KR"},{"name":"Lao People's Democratic Republic","dial_code":"+856","code":"LA"},{"name":"Libyan Arab Jamahiriya","dial_code":"+218","code":"LY"},{"name":"Macao","dial_code":"+853","code":"MO"},{"name":"Macedonia, The Former Yugoslav Republic of","dial_code":"+389","code":"MK"},{"name":"Micronesia, Federated States of","dial_code":"+691","code":"FM"},{"name":"Moldova, Republic of","dial_code":"+373","code":"MD"},{"name":"Mozambique","dial_code":"+258","code":"MZ"},{"name":"Palestinian Territory, Occupied","dial_code":"+970","code":"PS"},{"name":"Pitcairn","dial_code":"+872","code":"PN"},{"name":"Réunion","dial_code":"+262","code":"RE"},{"name":"Russia","dial_code":"+7","code":"RU"},{"name":"Saint Barthélemy","dial_code":"+590","code":"BL"},{"name":"Saint Helena, Ascension and Tristan Da Cunha","dial_code":"+290","code":"SH"},{"name":"Saint Kitts and Nevis","dial_code":"+1 869","code":"KN"},{"name":"Saint Lucia","dial_code":"+1 758","code":"LC"},{"name":"Saint Martin","dial_code":"+590","code":"MF"},{"name":"Saint Pierre and Miquelon","dial_code":"+508","code":"PM"},{"name":"Saint Vincent and the Grenadines","dial_code":"+1 784","code":"VC"},{"name":"Sao Tome and Principe","dial_code":"+239","code":"ST"},{"name":"Somalia","dial_code":"+252","code":"SO"},{"name":"Svalbard and Jan Mayen","dial_code":"+47","code":"SJ"},{"name":"Syrian Arab Republic","dial_code":"+963","code":"SY"},{"name":"Taiwan, Province of China","dial_code":"+886","code":"TW"},{"name":"Tanzania, United Republic of","dial_code":"+255","code":"TZ"},{"name":"Timor-Leste","dial_code":"+670","code":"TL"},{"name":"Venezuela, Bolivarian Republic of","dial_code":"+58","code":"VE"},{"name":"Viet Nam","dial_code":"+84","code":"VN"},{"name":"Virgin Islands, British","dial_code":"+1 284","code":"VG"},{"name":"Virgin Islands, U.S.","dial_code":"+1 340","code":"VI"}]
\ No newline at end of file
diff --git a/examples/generate.sh b/examples/generate.sh
index 5c80ca267..3ff767f3d 100755
--- a/examples/generate.sh
+++ b/examples/generate.sh
@@ -2,6 +2,12 @@
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 -n "+86 591 2284 8571" -s all -o $scriptDir/output_single.txt
+
+echo "Test script executed."
\ No newline at end of file
diff --git a/examples/output_from_input.txt b/examples/output_from_input.txt
index 0977fa31c..80ebc144b 100644
--- a/examples/output_from_input.txt
+++ b/examples/output_from_input.txt
@@ -4,90 +4,84 @@
/ ___/| | | | (_) | | | | __/\/ /_ | | | | _| (_) | (_| | (_| |
\/ |_| |_|\___/|_| |_|\___\____/ |_| |_|_| \___/ \__, |\__,_|
|___/
- PhoneInfoga Ver. v1.1.0-rc1
+ PhoneInfoga Ver. v1.0.0
Coded by Sundowndev
[!] ---- Fetching informations for 8562099453217 ---- [!]
-[*] Running local scan...
+[-] Running local scan...
[+] International format: +856 20 99 453 217
[+] Local format: 02099453217
-[+] Country code: +856
-[+] Location: Laos
+[+] Country found: Laos (+856)
+[+] City/Area: Laos
[+] Carrier: Unitel
-[+] Area: Laos
[+] Timezone: Asia/Vientiane
-[*] The number is valid and possible.
-[*] Scan finished.
+[-] The number is valid and possible.
+[-] Scan finished.
[!] ---- Fetching informations for 59172768361 ---- [!]
-[*] Running local scan...
+[-] Running local scan...
[+] International format: +591 72768361
[+] Local format: 072768361
-[+] Country code: +591
-[+] Location: Bolivia
+[+] Country found: Bolivia (+591)
+[+] City/Area: Bolivia
[+] Carrier: Entel
-[+] Area: Bolivia
[+] Timezone: America/La_Paz
-[*] The number is valid and possible.
-[*] Scan finished.
+[-] The number is valid and possible.
+[-] Scan finished.
[!] ---- Fetching informations for 32474123456 ---- [!]
-[*] Running local scan...
+[-] Running local scan...
[+] International format: +32 474 12 34 56
[+] Local format: 0474123456
-[+] Country code: +32
-[+] Location: Belgium
+[+] Country found: Belgium (+32)
+[+] City/Area: Belgium
[+] Carrier: Proximus
-[+] Area: Belgium
[+] Timezone: Europe/Brussels
-[*] The number is valid and possible.
-[*] Scan finished.
+[-] The number is valid and possible.
+[-] Scan finished.
[!] ---- Fetching informations for 15417543010 ---- [!]
-[*] Running local scan...
+[-] Running local scan...
[+] International format: +1 541-754-3010
[+] Local format: 05417543010
-[+] Country code: +1
-[+] Location: Corvallis, OR
+[+] Country found: United States (+1)
+[+] City/Area: Corvallis, OR
[+] Carrier:
-[+] Area: Corvallis, OR
[+] Timezone: America/Los_Angeles
-[*] The number is valid and possible.
-[*] Scan finished.
+[-] The number is valid and possible.
+[-] Scan finished.
[!] ---- Fetching informations for 8659122848571 ---- [!]
-[*] Running local scan...
+[-] Running local scan...
[+] International format: +86 591 2284 8571
[+] Local format: 059122848571
-[+] Country code: +86
-[+] Location: Fuzhou, Fujian
+[+] Country found: China (+86)
+[+] City/Area: Fuzhou, Fujian
[+] Carrier:
-[+] Area: Fuzhou, Fujian
[+] Timezone: Asia/Shanghai
-[*] The number is valid and possible.
-[*] Scan finished.
+[-] The number is valid and possible.
+[-] Scan finished.
[!] ---- Fetching informations for 74964819375 ---- [!]
-[*] Running local scan...
+[-] Running local scan...
[+] International format: +7 496 481-93-75
[+] Local format: 04964819375
-[+] Country code: +7
-[+] Location: Moscow
+[+] Country found: Russia (+7)
+[+] City/Area: Moscow
[+] Carrier:
-[+] Area: Moscow
[+] Timezone: Europe/Moscow
-[*] The number is valid and possible.
-[*] Scan finished.
+[-] The number is valid and possible.
+[-] Scan finished.
[!] ---- Fetching informations for 39172768361 ---- [!]
-[*] Running local scan...
-[*] Scan finished.
+[-] Running local scan...
+[-] Scan finished.
diff --git a/examples/output_single.txt b/examples/output_single.txt
index fc711f8a9..13df83789 100644
--- a/examples/output_single.txt
+++ b/examples/output_single.txt
@@ -4,28 +4,27 @@
/ ___/| | | | (_) | | | | __/\/ /_ | | | | _| (_) | (_| | (_| |
\/ |_| |_|\___/|_| |_|\___\____/ |_| |_|_| \___/ \__, |\__,_|
|___/
- PhoneInfoga Ver. v1.1.0-rc1
+ PhoneInfoga Ver. v1.0.0
Coded by Sundowndev
[!] ---- Fetching informations for 8659122848571 ---- [!]
-[*] Running local scan...
+[-] Running local scan...
[+] International format: +86 591 2284 8571
[+] Local format: 059122848571
-[+] Country code: +86
-[+] Location: Fuzhou, Fujian
+[+] Country found: China (+86)
+[+] City/Area: Fuzhou, Fujian
[+] Carrier:
-[+] Area: Fuzhou, Fujian
[+] Timezone: Asia/Shanghai
-[*] The number is valid and possible.
-[*] Running Numverify.com scan...
+[-] The number is valid and possible.
+[-] Running Numverify.com scan...
[+] Number: (+86) 059122848571
[+] Country: China (People's Republic of) (CN)
[+] Location: Fuzhou
[+] Carrier:
[+] Line type: landline
(!) This is most likely a landline, but it can still be a fixed VoIP number.
-[*] Running OVH scan...
-[*] Scan finished.
+[-] Running OVH scan...
+[-] Scan finished.
diff --git a/phoneinfoga.py b/phoneinfoga.py
index c5205088e..bd5309c0f 100644
--- a/phoneinfoga.py
+++ b/phoneinfoga.py
@@ -4,36 +4,28 @@
try:
import sys
+ import signal
from colorama import Fore, Style
import atexit
import argparse
import random
-except KeyboardInterrupt:
- print('[!] Exiting.')
- sys.exit()
-except:
+ 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 Exception as e:
print('[!] Missing requirements. Try running python3 -m pip install -r requirements.txt')
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__),
usage='%(prog)s -n [options]')
@@ -58,106 +50,22 @@ def banner():
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)
-
-# 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')
+parser.add_argument('-v', '--version', action='store_true',
+ help='Show tool version')
- 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']
+args = parser.parse_args()
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(
"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 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(
@@ -174,6 +82,36 @@ def download_file(url, target_path):
googleAbuseToken = ''
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):
global googleAbuseToken
@@ -229,10 +167,11 @@ def search(req, stop):
if re.match(r"^(?:\/search\?q\=)", url) is not None:
url = 'https://google.com' + url
- links.append(url)
-
- return links
- except:
+ if links is not None:
+ return links
+ else:
+ return []
+ except Exception as e:
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:
PhoneNumberObject = phonenumbers.parse(FormattedPhoneNumber, None)
- except:
+ except Exception as e:
return False
else:
if not phonenumbers.is_valid_number(PhoneNumberObject):
@@ -264,18 +203,6 @@ def localScan(InputNumber):
numberCountryCode = phonenumbers.format_number(
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(
PhoneNumberObject, phonenumbers.PhoneNumberFormat.E164).replace(numberCountryCode, '')
internationalNumber = phonenumbers.format_number(
@@ -283,11 +210,12 @@ def localScan(InputNumber):
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 + 'Country found: {} ({})'.format(
+ geocoder.country_name_for_number(PhoneNumberObject, "en"), numberCountryCode))
+ print(code_result + 'City/Area: {}'.format(
+ geocoder.description_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))
@@ -305,9 +233,14 @@ def numverifyScan():
print(code_info + 'Running Numverify.com scan...')
- requestSecret = ''
- resp = requests.get('https://numverify.com/')
- soup = BeautifulSoup(resp.text, "html5lib")
+ try:
+ requestSecret = ''
+ 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"):
if tag['name'] == "scl_request_secret":
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)
data = json.loads(response.content.decode('utf-8'))
- except:
- print(code_error + 'Numverify is not available')
+ except Exception as e:
+ print(code_error + 'Numverify.com is not available')
return -1
if response.content == "Unauthorized" or response.status_code != 200:
@@ -383,7 +316,7 @@ def ovhScan():
response = requests.request(
"GET", "https://api.ovh.com/1.0/telephony/number/detailedZones", data="", headers=headers, params=querystring)
data = json.loads(response.content.decode('utf-8'))
- except:
+ except Exception as e:
print(code_error + 'OVH API is unreachable. Maybe retry later.')
return -1
@@ -431,6 +364,7 @@ def osintIndividualScan():
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))
@@ -474,6 +408,7 @@ def osintSocialMediaScan():
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))
@@ -489,6 +424,7 @@ def osintDisposableNumScan():
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'])))
@@ -496,7 +432,7 @@ def osintDisposableNumScan():
askForExit()
-def osintScan():
+def osintScan(rerun=False):
global number
global localNumber
global internationalNumber
@@ -508,15 +444,16 @@ def osintScan():
print(code_info + 'Running OSINT footprint reconnaissance...')
- # Whitepages
- print((code_info + "Generating scan URL on 411.com..."))
- print(code_result + "Scan URL: https://www.411.com/phone/{}".format(
- internationalNumber.replace('+', '').replace(' ', '-')))
+ if not rerun:
+ # Whitepages
+ print((code_info + "Generating scan URL on 411.com..."))
+ 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':
+ if rerun or askingCustomPayload == 'y' or askingCustomPayload == 'yes':
customFormatting = input(code_info + 'Custom format: ')
print((code_info + '---- Web pages footprints ----'))
@@ -568,7 +505,7 @@ def osintScan():
print(
(code_result + "Found a temporary number provider: tempophone.com"))
askForExit()
- except:
+ except Exception as e:
print((code_error + "Unable to reach tempophone.com API. Skipping."))
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) ")
if retry_input.lower() == 'y' or retry_input.lower() == 'yes':
- osintScan()
+ osintScan(True)
else:
return -1
@@ -634,19 +571,83 @@ def scanNumber(InputNumber):
print('\n')
-try:
- 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 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)
+
+
+def updateTool():
+ 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 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.osint:
@@ -655,7 +656,7 @@ def scanNumber(InputNumber):
sys.exit()
sys.stdout = args.output
- banner()
+ banner() # Output banner again in the file
# Verify scanner option
if not args.scanner in scanners:
@@ -667,9 +668,19 @@ def scanNumber(InputNumber):
elif args.input:
for line in args.input.readlines():
scanNumber(line)
+ else:
+ parser.print_help()
+ sys.exit()
if args.output:
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()
+
+
+if __name__ == '__main__':
+ signal.signal(signal.SIGINT, signal_handler)
+ main()