Merge pull request #9 from sundowndev/develop
Update feature & migration to Python 3
This commit is contained in:
commit
692480457f
11
README.md
11
README.md
|
|
@ -1,11 +1,12 @@
|
||||||
# PhoneInfoga
|
# PhoneInfoga
|
||||||
|
|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
Information gathering & OSINT reconnaissance tool for phone numbers.
|
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.
|
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.
|
||||||
|
|
||||||
**This tool requires python 2.x**
|
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- Check if phone number exists and is possible
|
- Check if phone number exists and is possible
|
||||||
|
|
@ -38,7 +39,7 @@ Use `any` to disable this feature. Default value: `all`
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/sundowndev/PhoneInfoga
|
git clone https://github.com/sundowndev/PhoneInfoga
|
||||||
cd ./PhoneInfoga
|
cd ./PhoneInfoga
|
||||||
pip install -r requirements.txt
|
pip3 install -r requirements.txt
|
||||||
```
|
```
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
@ -129,6 +130,8 @@ PhoneInfo use a workaround to handle Google bot detection. When running OSINT sc
|
||||||
- Go to **Storage**, then **Cookies**
|
- Go to **Storage**, then **Cookies**
|
||||||
- Copy the value of the *GOOGLE_ABUSE_EXEMPTION* cookie and paste it in the CLI
|
- Copy the value of the *GOOGLE_ABUSE_EXEMPTION* cookie and paste it in the CLI
|
||||||
|
|
||||||
|
**Note: sometimes you'll need to refresh the page to get the cookie.**
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Custom formatting
|
## Custom formatting
|
||||||
|
|
@ -138,3 +141,5 @@ Sometimes the phone number has footprints but is used with a different formattin
|
||||||
## License
|
## License
|
||||||
|
|
||||||
This tool is licensed under the GNU General Public License v3.0.
|
This tool is licensed under the GNU General Public License v3.0.
|
||||||
|
|
||||||
|
[](https://app.fossa.io/projects/git%2Bgithub.com%2Fsundowndev%2FPhoneInfoga?ref=badge_large)
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"site": "numinfo.net",
|
"site": "numinfo.net",
|
||||||
"request": "site:\"numinfo.net\" intext:\"$n\" | $i",
|
"request": "site:\"numinfo.net\" intext:\"$n\" | intext:\"$i\"",
|
||||||
"dialCode": null,
|
"dialCode": null,
|
||||||
"stop": 2
|
"stop": 2
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"site": "sync.me",
|
"site": "sync.me",
|
||||||
"request": "site:\"sync.me\" intext:\"$n\" | $i",
|
"request": "site:\"sync.me\" intext:\"$n\" | intext:\"$i\"",
|
||||||
"dialCode": null,
|
"dialCode": null,
|
||||||
"stop": 1
|
"stop": 1
|
||||||
},
|
},
|
||||||
|
|
@ -16,5 +16,17 @@
|
||||||
"request": "site:\"whocallsyou.de\" intext:\"0$n\"",
|
"request": "site:\"whocallsyou.de\" intext:\"0$n\"",
|
||||||
"dialCode": null,
|
"dialCode": null,
|
||||||
"stop": 1
|
"stop": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"site": "pastebin.com",
|
||||||
|
"request": "site:\"pastebin.com\" intext:\"$n\" | intext:\"$i\"",
|
||||||
|
"dialCode": null,
|
||||||
|
"stop": 5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"site": "whycall.me",
|
||||||
|
"request": "site:\"whycall.me\" intext:\"$n\" | intext:\"$l\"",
|
||||||
|
"dialCode": null,
|
||||||
|
"stop": 1
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "phone fraud footprints",
|
"title": "phone fraud footprints",
|
||||||
"request": "intitle:\"Phone Fraud\" intext:\"$n\" | \"$n\"",
|
"request": "intitle:\"Phone Fraud\" intext:\"$n\" | intext:\"$i\"",
|
||||||
"stop": 5
|
"stop": 5
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
||||||
231
phoneinfoga.py
231
phoneinfoga.py
|
|
@ -1,27 +1,31 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
__version__ = '0.9-dev'
|
__version__ = '0.10-dev'
|
||||||
|
|
||||||
def banner():
|
def banner():
|
||||||
print " ___ _ _____ __ "
|
print(" ___ _ _____ __ ")
|
||||||
print " / _ \ |__ ___ _ __ ___ \_ \_ __ / _| ___ __ _ __ _ "
|
print(" / _ \ |__ ___ _ __ ___ \_ \_ __ / _| ___ __ _ __ _ ")
|
||||||
print " / /_)/ '_ \ / _ \| '_ \ / _ \ / /\/ '_ \| |_ / _ \ / _` |/ _` |"
|
print(" / /_)/ '_ \ / _ \| '_ \ / _ \ / /\/ '_ \| |_ / _ \ / _` |/ _` |")
|
||||||
print " / ___/| | | | (_) | | | | __/\/ /_ | | | | _| (_) | (_| | (_| |"
|
print(" / ___/| | | | (_) | | | | __/\/ /_ | | | | _| (_) | (_| | (_| |")
|
||||||
print " \/ |_| |_|\___/|_| |_|\___\____/ |_| |_|_| \___/ \__, |\__,_|"
|
print(" \/ |_| |_|\___/|_| |_|\___\____/ |_| |_|_| \___/ \__, |\__,_|")
|
||||||
print " |___/ "
|
print(" |___/ ")
|
||||||
print " PhoneInfoga Ver. %s " % __version__
|
print(" PhoneInfoga Ver. {}".format(__version__))
|
||||||
print " Coded by Sundowndev "
|
print(" Coded by Sundowndev")
|
||||||
print "\n"
|
print("\n")
|
||||||
|
|
||||||
print "\n \033[92m"
|
print("\n \033[92m")
|
||||||
banner()
|
banner()
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import argparse
|
import argparse
|
||||||
import random
|
import random
|
||||||
|
|
||||||
|
if sys.version_info[0] < 3:
|
||||||
|
print("\033[1m\033[93m(!) Please run the tool using Python 3")
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(description=
|
parser = argparse.ArgumentParser(description=
|
||||||
"Advanced information gathering tool for phone numbers (https://github.com/sundowndev/PhoneInfoga) version %s" % __version__,
|
"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]')
|
||||||
|
|
||||||
parser.add_argument('-n', '--number', metavar='number', type=str,
|
parser.add_argument('-n', '--number', metavar='number', type=str,
|
||||||
|
|
@ -47,10 +51,10 @@ args = parser.parse_args()
|
||||||
# If any param is passed, execute help command
|
# If any param is passed, execute help command
|
||||||
if not len(sys.argv) > 1:
|
if not len(sys.argv) > 1:
|
||||||
parser.print_help()
|
parser.print_help()
|
||||||
sys.exit();
|
sys.exit()
|
||||||
|
|
||||||
if args.update:
|
if args.update:
|
||||||
print 'update'
|
print('update')
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
@ -66,15 +70,15 @@ try:
|
||||||
from phonenumbers import geocoder
|
from phonenumbers import geocoder
|
||||||
from phonenumbers import timezone
|
from phonenumbers import timezone
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
print '\033[91m[!] Exiting.'
|
print('\033[91m[!] Exiting.')
|
||||||
sys.exit()
|
sys.exit()
|
||||||
except:
|
except:
|
||||||
print '\033[91m[!] Missing requirements. Try running pip install -r requirements.txt'
|
print('\033[91m[!] Missing requirements. Try running pip install -r requirements.txt')
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
scanners = ['any', 'all', 'numverify', 'ovh']
|
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("Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:26.0) Gecko/20100101 Firefox/26.0")
|
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 (X11; U; Linux x86_64; en-US; rv:1.9.1.3) Gecko/20090913 Firefox/3.5.3")
|
||||||
|
|
@ -112,21 +116,21 @@ def search(req, stop):
|
||||||
}
|
}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
URL = 'https://www.google.com/search?tbs=li:1&q=%s&gws_rd=ssl' % (req)
|
URL = 'https://www.google.com/search?tbs=li:1&q={}&gws_rd=ssl'.format(req)
|
||||||
r = s.get(URL + googleAbuseToken, headers=headers)
|
r = s.get(URL + googleAbuseToken, headers=headers)
|
||||||
|
|
||||||
while r.status_code == 503:
|
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 : %s' % URL
|
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 = raw_input('\nGOOGLE_ABUSE_EXEMPTION=')
|
token = input('\nGOOGLE_ABUSE_EXEMPTION=')
|
||||||
googleAbuseToken = '&google_abuse=' + token
|
googleAbuseToken = '&google_abuse=' + token
|
||||||
r = s.get(URL + googleAbuseToken, headers=headers)
|
r = s.get(URL + googleAbuseToken, headers=headers)
|
||||||
|
|
||||||
soup = BeautifulSoup(r.content, 'html.parser')
|
soup = BeautifulSoup(r.content, 'html.parser')
|
||||||
results = soup.find("div", id="search").find_all("div", class_="g")
|
results = soup.find("div", id="search").find_all("div", class_="g")
|
||||||
|
|
||||||
links=[]
|
links = []
|
||||||
counter=0
|
counter = 0
|
||||||
|
|
||||||
for result in results:
|
for result in results:
|
||||||
counter += 1
|
counter += 1
|
||||||
|
|
@ -140,14 +144,14 @@ def search(req, stop):
|
||||||
url = re.sub(r'(?:\&sa\=)(?:.*)', '', url)
|
url = re.sub(r'(?:\&sa\=)(?:.*)', '', url)
|
||||||
url = re.sub(r'(?:\&rct\=)(?:.*)', '', url)
|
url = re.sub(r'(?:\&rct\=)(?:.*)', '', url)
|
||||||
|
|
||||||
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)
|
links.append(url)
|
||||||
|
|
||||||
return links
|
return links
|
||||||
except:
|
except:
|
||||||
print code_error + 'Request failed. Please retry or open an issue on GitHub.'
|
print(code_error + 'Request failed. Please retry or open an issue on GitHub.')
|
||||||
|
|
||||||
def formatNumber(InputNumber):
|
def formatNumber(InputNumber):
|
||||||
return re.sub("(?:\+)?(?:[^[0-9]*)", "", InputNumber)
|
return re.sub("(?:\+)?(?:[^[0-9]*)", "", InputNumber)
|
||||||
|
|
@ -159,7 +163,7 @@ def localScan(InputNumber):
|
||||||
global numberCountryCode
|
global numberCountryCode
|
||||||
global numberCountry
|
global numberCountry
|
||||||
|
|
||||||
print code_info + 'Running local scan...'
|
print(code_info + 'Running local scan...')
|
||||||
|
|
||||||
FormattedPhoneNumber = "+" + formatNumber(InputNumber)
|
FormattedPhoneNumber = "+" + formatNumber(InputNumber)
|
||||||
|
|
||||||
|
|
@ -174,25 +178,25 @@ def localScan(InputNumber):
|
||||||
number = phonenumbers.format_number(PhoneNumberObject, phonenumbers.PhoneNumberFormat.E164).replace('+', '')
|
number = phonenumbers.format_number(PhoneNumberObject, phonenumbers.PhoneNumberFormat.E164).replace('+', '')
|
||||||
numberCountryCode = phonenumbers.format_number(PhoneNumberObject, phonenumbers.PhoneNumberFormat.INTERNATIONAL).split(' ')[0]
|
numberCountryCode = phonenumbers.format_number(PhoneNumberObject, phonenumbers.PhoneNumberFormat.INTERNATIONAL).split(' ')[0]
|
||||||
|
|
||||||
countryRequest = json.loads(requests.request('GET', 'https://restcountries.eu/rest/v2/callingcode/%s' % numberCountryCode.replace('+', '')).content)
|
countryRequest = json.loads(requests.request('GET', 'https://restcountries.eu/rest/v2/callingcode/{}'.format(numberCountryCode.replace('+', ''))).content)
|
||||||
numberCountry = countryRequest[0]['alpha2Code']
|
numberCountry = countryRequest[0]['alpha2Code']
|
||||||
|
|
||||||
localNumber = phonenumbers.format_number(PhoneNumberObject, phonenumbers.PhoneNumberFormat.E164).replace(numberCountryCode, '')
|
localNumber = phonenumbers.format_number(PhoneNumberObject, phonenumbers.PhoneNumberFormat.E164).replace(numberCountryCode, '')
|
||||||
internationalNumber = phonenumbers.format_number(PhoneNumberObject, phonenumbers.PhoneNumberFormat.INTERNATIONAL)
|
internationalNumber = phonenumbers.format_number(PhoneNumberObject, phonenumbers.PhoneNumberFormat.INTERNATIONAL)
|
||||||
|
|
||||||
print code_result + 'International format: %s' % internationalNumber
|
print(code_result + 'International format: {}'.format(internationalNumber))
|
||||||
print code_result + 'Local format: 0%s' % localNumber
|
print(code_result + 'Local format: 0{}'.format(localNumber))
|
||||||
print code_result + 'Country code: %s' % numberCountryCode
|
print(code_result + 'Country code: {}'.format(numberCountryCode))
|
||||||
print code_result + 'Location: %s' % geocoder.description_for_number(PhoneNumberObject, "en")
|
print(code_result + 'Location: {}'.format(geocoder.description_for_number(PhoneNumberObject, "en")))
|
||||||
print code_result + 'Carrier: %s' % carrier.name_for_number(PhoneNumberObject, 'en')
|
print(code_result + 'Carrier: {}'.format(carrier.name_for_number(PhoneNumberObject, 'en')))
|
||||||
print code_result + 'Area: %s' % geocoder.description_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: %s' % (timezoneResult)
|
print(code_result + 'Timezone: {}'.format(timezoneResult))
|
||||||
|
|
||||||
if phonenumbers.is_possible_number(PhoneNumberObject):
|
if phonenumbers.is_possible_number(PhoneNumberObject):
|
||||||
print code_info + 'The number is valid and possible.'
|
print(code_info + 'The number is valid and possible.')
|
||||||
else:
|
else:
|
||||||
print code_warning + 'The number is valid but might not be possible.'
|
print(code_warning + 'The number is valid but might not be possible.')
|
||||||
|
|
||||||
def numverifyScan():
|
def numverifyScan():
|
||||||
global number
|
global number
|
||||||
|
|
@ -200,7 +204,7 @@ def numverifyScan():
|
||||||
if not args.scanner == 'numverify' and not args.scanner == 'all':
|
if not args.scanner == 'numverify' and not args.scanner == 'all':
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
print code_info + 'Running Numverify.com scan...'
|
print(code_info + 'Running Numverify.com scan...')
|
||||||
|
|
||||||
requestSecret = ''
|
requestSecret = ''
|
||||||
resp = requests.get('https://numverify.com/')
|
resp = requests.get('https://numverify.com/')
|
||||||
|
|
@ -208,11 +212,9 @@ def numverifyScan():
|
||||||
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']
|
||||||
break;
|
break
|
||||||
|
|
||||||
apiKey = hashlib.md5()
|
apiKey = hashlib.md5((number + requestSecret).encode('utf-8')).hexdigest()
|
||||||
apiKey.update(number + requestSecret)
|
|
||||||
apiKey = apiKey.hexdigest()
|
|
||||||
|
|
||||||
headers = {
|
headers = {
|
||||||
'host': "numverify.com",
|
'host': "numverify.com",
|
||||||
|
|
@ -229,30 +231,30 @@ def numverifyScan():
|
||||||
'cache-control': "no-cache"
|
'cache-control': "no-cache"
|
||||||
}
|
}
|
||||||
|
|
||||||
response = requests.request("GET", "https://numverify.com/php_helper_scripts/phone_api.php?secret_key=" + apiKey + "&number=" + 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:
|
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).")
|
print((code_error + "An error occured while calling the API (bad request or wrong api key)."))
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
data = json.loads(response.content)
|
data = json.loads(response.content)
|
||||||
|
|
||||||
if data["valid"] == False:
|
if data["valid"] == False:
|
||||||
print(code_error + "Error: Please specify a valid phone number. Example: +6464806649")
|
print((code_error + "Error: Please specify a valid phone number. Example: +6464806649"))
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
InternationalNumber = '('+data["country_prefix"]+')' + data["local_format"]
|
InternationalNumber = '({}){}'.format(data["country_prefix"], data["local_format"])
|
||||||
|
|
||||||
print(code_result + "Number: (%s) %s") % (data["country_prefix"],data["local_format"])
|
print((code_result + "Number: ({}) {}").format(data["country_prefix"],data["local_format"]))
|
||||||
print(code_result + "Country: %s (%s)") % (data["country_name"],data["country_code"])
|
print((code_result + "Country: {} ({})").format(data["country_name"],data["country_code"]))
|
||||||
print(code_result + "Location: %s") % data["location"]
|
print((code_result + "Location: {}").format(data["location"]))
|
||||||
print(code_result + "Carrier: %s") % data["carrier"]
|
print((code_result + "Carrier: {}").format(data["carrier"]))
|
||||||
print(code_result + "Line type: %s") % data["line_type"]
|
print((code_result + "Line type: {}").format(data["line_type"]))
|
||||||
|
|
||||||
if data["line_type"] == 'landline':
|
if data["line_type"] == 'landline':
|
||||||
print(code_warning + "This is most likely a land line, but it can still be a fixed VoIP.")
|
print((code_warning + "This is most likely a landline, but it can still be a fixed VoIP number."))
|
||||||
elif data["line_type"] == 'mobile':
|
elif data["line_type"] == 'mobile':
|
||||||
print(code_warning + "This is most likely a mobile, but it can still be a VoIP.")
|
print((code_warning + "This is most likely a mobile number, but it can still be a VoIP number."))
|
||||||
|
|
||||||
def ovhScan():
|
def ovhScan():
|
||||||
global localNumber
|
global localNumber
|
||||||
|
|
@ -261,7 +263,7 @@ def ovhScan():
|
||||||
if not args.scanner == 'ovh' and not args.scanner == 'all':
|
if not args.scanner == 'ovh' and not args.scanner == 'all':
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
print code_info + 'Running OVH scan...'
|
print(code_info + 'Running OVH scan...')
|
||||||
|
|
||||||
querystring = { "country": numberCountry.lower() }
|
querystring = { "country": numberCountry.lower() }
|
||||||
|
|
||||||
|
|
@ -279,12 +281,23 @@ def ovhScan():
|
||||||
|
|
||||||
for voip_number in data:
|
for voip_number in data:
|
||||||
if voip_number['number'] == askedNumber:
|
if voip_number['number'] == askedNumber:
|
||||||
print(code_info + "1 result found in OVH database")
|
print((code_info + "1 result found in OVH database"))
|
||||||
print(code_result + "Number range: " + voip_number['number'])
|
print((code_result + "Number range: {}".format(voip_number['number'])))
|
||||||
print(code_result + "City: " + voip_number['city'])
|
print((code_result + "City: {}".format(voip_number['city'])))
|
||||||
print(code_result + "Zip code: " + 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()
|
askForExit()
|
||||||
|
|
||||||
|
def replaceVariables(string):
|
||||||
|
global number
|
||||||
|
global internationalNumber
|
||||||
|
global localNumber
|
||||||
|
|
||||||
|
string = string.replace('$n', number)
|
||||||
|
string = string.replace('$i', internationalNumber)
|
||||||
|
string = string.replace('$l', localNumber)
|
||||||
|
|
||||||
|
return string
|
||||||
|
|
||||||
def osintIndividualScan():
|
def osintIndividualScan():
|
||||||
global number
|
global number
|
||||||
global internationalNumber
|
global internationalNumber
|
||||||
|
|
@ -296,14 +309,14 @@ def osintIndividualScan():
|
||||||
for dork in dorks:
|
for dork in dorks:
|
||||||
if dork['dialCode'] is None or dork['dialCode'] == numberCountryCode:
|
if dork['dialCode'] is None or dork['dialCode'] == numberCountryCode:
|
||||||
if customFormatting:
|
if customFormatting:
|
||||||
dorkRequest = dork['request'].replace('$n', number).replace('$i', internationalNumber) + ' | intext:"%s"' % (customFormatting)
|
dorkRequest = replaceVariables(dork['request']) + ' | intext:"{}"'.format(customFormatting)
|
||||||
else:
|
else:
|
||||||
dorkRequest = dork['request'].replace('$n', number).replace('$i', internationalNumber)
|
dorkRequest = replaceVariables(dork['request'])
|
||||||
|
|
||||||
print(code_info + "Searching for footprints on %s..." % dork['site'])
|
print((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))
|
||||||
else:
|
else:
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
|
|
@ -316,14 +329,14 @@ def osintReputationScan():
|
||||||
|
|
||||||
for dork in dorks:
|
for dork in dorks:
|
||||||
if customFormatting:
|
if customFormatting:
|
||||||
dorkRequest = dork['request'].replace('$n', number).replace('$i', internationalNumber) + ' | intext:"%s"' % (customFormatting)
|
dorkRequest = replaceVariables(dork['request']) + ' | intext:"{}"'.format(customFormatting)
|
||||||
else:
|
else:
|
||||||
dorkRequest = dork['request'].replace('$n', number).replace('$i', internationalNumber)
|
dorkRequest = replaceVariables(dork['request'])
|
||||||
|
|
||||||
print(code_info + "Searching for %s..." % dork['title'])
|
print((code_info + "Searching for {}...".format(dork['title'])))
|
||||||
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))
|
||||||
|
|
||||||
def osintSocialMediaScan():
|
def osintSocialMediaScan():
|
||||||
global number
|
global number
|
||||||
|
|
@ -334,14 +347,14 @@ def osintSocialMediaScan():
|
||||||
|
|
||||||
for dork in dorks:
|
for dork in dorks:
|
||||||
if customFormatting:
|
if customFormatting:
|
||||||
dorkRequest = dork['request'].replace('$n', number).replace('$i', internationalNumber) + ' | intext:"%s"' % (customFormatting)
|
dorkRequest = replaceVariables(dork['request']) + ' | intext:"{}"'.format(customFormatting)
|
||||||
else:
|
else:
|
||||||
dorkRequest = dork['request'].replace('$n', number).replace('$i', internationalNumber)
|
dorkRequest = replaceVariables(dork['request'])
|
||||||
|
|
||||||
print(code_info + "Searching for footprints on %s..." % dork['site'])
|
print((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))
|
||||||
|
|
||||||
def osintDisposableNumScan():
|
def osintDisposableNumScan():
|
||||||
global number
|
global number
|
||||||
|
|
@ -349,13 +362,13 @@ def osintDisposableNumScan():
|
||||||
dorks = json.load(open('osint/disposable_num_providers.json'))
|
dorks = json.load(open('osint/disposable_num_providers.json'))
|
||||||
|
|
||||||
for dork in dorks:
|
for dork in dorks:
|
||||||
dorkRequest = dork['request'].replace('$n', number)
|
dorkRequest = replaceVariables(dork['request'])
|
||||||
|
|
||||||
print(code_info + "Searching for footprints on %s..." % dork['site'])
|
print((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: %s" % dork['site'])
|
print((code_result + "Result found: {}".format(dork['site'])))
|
||||||
print(code_result + "URL: " + result)
|
print((code_result + "URL: " + result))
|
||||||
askForExit()
|
askForExit()
|
||||||
|
|
||||||
def osintScan():
|
def osintScan():
|
||||||
|
|
@ -369,84 +382,84 @@ def osintScan():
|
||||||
if not args.osint:
|
if not args.osint:
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
print code_info + 'Running OSINT footprint reconnaissance...'
|
print(code_info + 'Running OSINT footprint reconnaissance...')
|
||||||
|
|
||||||
# Whitepages
|
# Whitepages
|
||||||
print(code_info + "Generating scan URL on 411.com...")
|
print((code_info + "Generating scan URL on 411.com..."))
|
||||||
print code_result + "Scan URL: https://www.411.com/phone/%s" % internationalNumber.replace('+', '').replace(' ', '-')
|
print(code_result + "Scan URL: https://www.411.com/phone/{}".format(internationalNumber.replace('+', '').replace(' ', '-')))
|
||||||
|
|
||||||
askingCustomPayload = raw_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 askingCustomPayload == 'y' or askingCustomPayload == 'yes':
|
||||||
customFormatting = raw_input(code_info + 'Custom format: ')
|
customFormatting = input(code_info + 'Custom format: ')
|
||||||
|
|
||||||
print(code_info + '---- Web pages footprints ----')
|
print((code_info + '---- Web pages footprints ----'))
|
||||||
|
|
||||||
print(code_info + "Searching for footprints on web pages... (limit=5)")
|
print((code_info + "Searching for footprints on web pages... (limit=5)"))
|
||||||
if customFormatting:
|
if customFormatting:
|
||||||
req = '%s | intext:"%s" | intext:"%s" | intext:"%s"' % (number,number,internationalNumber,customFormatting)
|
req = '{} | intext:"{}" | intext:"{}" | intext:"{}"'.format(number,number,internationalNumber,customFormatting)
|
||||||
else:
|
else:
|
||||||
req = '%s | intext:"%s" | intext:"%s"' % (number,number,internationalNumber)
|
req = '{} | intext:"{}" | intext:"{}"'.format(number,number,internationalNumber)
|
||||||
for result in search(req, stop=5):
|
for result in search(req, stop=5):
|
||||||
if result:
|
if result:
|
||||||
print(code_result + "Result found: " + result)
|
print((code_result + "Result found: " + result))
|
||||||
|
|
||||||
# Documents
|
# Documents
|
||||||
print(code_info + "Searching for documents... (limit=10)")
|
print((code_info + "Searching for documents... (limit=10)"))
|
||||||
if customFormatting:
|
if customFormatting:
|
||||||
req = 'intext:"%s" | intext:"%s" | intext:"%s" ext:doc | ext:docx | ext:odt | ext:pdf | ext:rtf | ext:sxw | ext:psw | ext:ppt | ext:pptx | ext:pps | ext:csv | ext:txt' % (number,internationalNumber,customFormatting)
|
req = 'intext:"{}" | intext:"{}" | intext:"{}" ext:doc | ext:docx | ext:odt | ext:pdf | ext:rtf | ext:sxw | ext:psw | ext:ppt | ext:pptx | ext:pps | ext:csv | ext:txt'.format(number,internationalNumber,customFormatting)
|
||||||
else:
|
else:
|
||||||
req = 'intext:"%s" | intext:"%s" ext:doc | ext:docx | ext:odt | ext:pdf | ext:rtf | ext:sxw | ext:psw | ext:ppt | ext:pptx | ext:pps | ext:csv | ext:txt' % (number,internationalNumber)
|
req = 'intext:"{}" | intext:"{}" ext:doc | ext:docx | ext:odt | ext:pdf | ext:rtf | ext:sxw | ext:psw | ext:ppt | ext:pptx | ext:pps | ext:csv | ext:txt'.format(number,internationalNumber)
|
||||||
for result in search('intext:"%s" | intext:"%s" ext:doc | ext:docx | ext:odt | ext:pdf | ext:rtf | ext:sxw | ext:psw | ext:ppt | ext:pptx | ext:pps | ext:csv | ext:txt' % (number,internationalNumber), stop=10):
|
for result in search('intext:"{}" | intext:"{}" ext:doc | ext:docx | ext:odt | ext:pdf | ext:rtf | ext:sxw | ext:psw | ext:ppt | ext:pptx | ext:pps | ext:csv | ext:txt'.format(number,internationalNumber), stop=10):
|
||||||
if result:
|
if result:
|
||||||
print(code_result + "Result found: " + result)
|
print((code_result + "Result found: " + result))
|
||||||
|
|
||||||
print(code_info + '---- Reputation footprints ----')
|
print((code_info + '---- Reputation footprints ----'))
|
||||||
|
|
||||||
osintReputationScan()
|
osintReputationScan()
|
||||||
|
|
||||||
print(code_info + "Generating URL on scamcallfighters.com...")
|
print((code_info + "Generating URL on scamcallfighters.com..."))
|
||||||
print code_result + 'http://www.scamcallfighters.com/search-phone-%s.html' % number
|
print(code_result + 'http://www.scamcallfighters.com/search-phone-{}.html'.format(number))
|
||||||
|
|
||||||
tmpNumAsk = raw_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':
|
if tmpNumAsk.lower() != 'n' and tmpNumAsk.lower() != 'no':
|
||||||
print(code_info + '---- Temporary number providers footprints ----')
|
print((code_info + '---- Temporary number providers footprints ----'))
|
||||||
|
|
||||||
print(code_info + "Searching for phone number on tempophone.com...")
|
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)
|
data = json.loads(response.content)
|
||||||
for voip_number in data['objects']:
|
for voip_number in data['objects']:
|
||||||
if voip_number['phone'] == formatNumber(number):
|
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()
|
askForExit()
|
||||||
|
|
||||||
osintDisposableNumScan()
|
osintDisposableNumScan()
|
||||||
|
|
||||||
print(code_info + '---- Social media footprints ----')
|
print((code_info + '---- Social media footprints ----'))
|
||||||
|
|
||||||
osintSocialMediaScan()
|
osintSocialMediaScan()
|
||||||
|
|
||||||
print(code_info + '---- Phone books footprints ----')
|
print((code_info + '---- Phone books footprints ----'))
|
||||||
|
|
||||||
if numberCountryCode == '+1':
|
if numberCountryCode == '+1':
|
||||||
print(code_info + "Generating URL on True People... ")
|
print((code_info + "Generating URL on True People... "))
|
||||||
print code_result + 'https://www.truepeoplesearch.com/results?phoneno=%s' % internationalNumber.replace(' ', '')
|
print(code_result + 'https://www.truepeoplesearch.com/results?phoneno={}'.format(internationalNumber.replace(' ', '')))
|
||||||
|
|
||||||
osintIndividualScan()
|
osintIndividualScan()
|
||||||
|
|
||||||
def askForExit():
|
def askForExit():
|
||||||
if not args.output:
|
if not args.output:
|
||||||
user_input = raw_input(code_info + "Continue scanning ? (y/N) ")
|
user_input = input(code_info + "Continue scanning ? (y/N) ")
|
||||||
|
|
||||||
if user_input.lower() == 'y' or user_input.lower() == 'yes':
|
if user_input.lower() == 'y' or user_input.lower() == 'yes':
|
||||||
return -1
|
return -1
|
||||||
else:
|
else:
|
||||||
print code_info + "Good bye!"
|
print(code_info + "Good bye!")
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
def scanNumber(InputNumber):
|
def scanNumber(InputNumber):
|
||||||
print code_title + "[!] ---- Fetching informations for %s ---- [!]" % formatNumber(InputNumber)
|
print(code_title + "[!] ---- Fetching informations for {} ---- [!]".format(formatNumber(InputNumber)))
|
||||||
|
|
||||||
localScan(InputNumber)
|
localScan(InputNumber)
|
||||||
|
|
||||||
|
|
@ -457,16 +470,16 @@ def scanNumber(InputNumber):
|
||||||
global numberCountry
|
global numberCountry
|
||||||
|
|
||||||
if not number:
|
if not number:
|
||||||
print(code_error + "Error: number " + formatNumber(InputNumber) + " is not valid. Skipping.")
|
print((code_error + "Error: number {} is not valid. Skipping.".format(formatNumber(InputNumber))))
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
numverifyScan()
|
numverifyScan()
|
||||||
ovhScan()
|
ovhScan()
|
||||||
osintScan()
|
osintScan()
|
||||||
|
|
||||||
print code_info + "Scan finished."
|
print(code_info + "Scan finished.")
|
||||||
|
|
||||||
print '\n'
|
print('\n')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if args.output:
|
if args.output:
|
||||||
|
|
@ -477,7 +490,7 @@ try:
|
||||||
code_title = ''
|
code_title = ''
|
||||||
|
|
||||||
if args.osint:
|
if args.osint:
|
||||||
print '\033[91m[!] OSINT scanner is not available using output option (sorry).'
|
print('\033[91m[!] OSINT scanner is not available using output option (sorry).')
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
sys.stdout = args.output
|
sys.stdout = args.output
|
||||||
|
|
@ -491,7 +504,7 @@ try:
|
||||||
|
|
||||||
# Verify scanner option
|
# Verify scanner option
|
||||||
if not args.scanner in scanners:
|
if not args.scanner in scanners:
|
||||||
print(code_error + "Error: scanner doesn't exists.")
|
print((code_error + "Error: scanner doesn't exists."))
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
if args.number:
|
if args.number:
|
||||||
|
|
@ -503,5 +516,5 @@ try:
|
||||||
if args.output:
|
if args.output:
|
||||||
args.output.close()
|
args.output.close()
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
print(code_error + "Scan interrupted. Good bye!")
|
print(("\n" + code_error + "Scan interrupted. Good bye!"))
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
|
||||||
|
|
@ -2,3 +2,4 @@ requests
|
||||||
bs4
|
bs4
|
||||||
html5lib
|
html5lib
|
||||||
phonenumbers
|
phonenumbers
|
||||||
|
argparse
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue