Full Code of AbirHasan2005/OPRecon for AI

master da8c95230fdd cached
21 files
78.0 KB
20.5k tokens
78 symbols
1 requests
Download .txt
Repository: AbirHasan2005/OPRecon
Branch: master
Commit: da8c95230fdd
Files: 21
Total size: 78.0 KB

Directory structure:
gitextract_p879nsh0/

├── README.md
├── files/
│   ├── RESOURCES.md
│   ├── core/
│   │   ├── FileExporter.py
│   │   ├── IpGeoLocation.py
│   │   ├── IpGeoLocationLib.py
│   │   ├── Logger.py
│   │   ├── Menu.py
│   │   ├── MyExceptions.py
│   │   ├── Utils.py
│   │   └── __init__.py
│   ├── examples/
│   │   └── input.txt
│   ├── ipgeolocation.py
│   ├── osint/
│   │   ├── disposable_num_providers.json
│   │   ├── individuals.json
│   │   ├── reputation.json
│   │   └── social_medias.json
│   ├── phoneinfoga.py
│   └── tracker.py
├── requirements.txt
├── run.sh
└── update.sh

================================================
FILE CONTENTS
================================================

================================================
FILE: README.md
================================================
# OPRecon v1.8-BETA
Using this you can find informations via PhoneInFoga(In-Built), Find location via IP Address & website link via IPGeoLocation(In-Built) and Phone Number Tracker(Made by @AbirHasan2005). Phone Number Tracker will give you IP Address using phone number. For more information join my Telegram Group.

## Telegram Group: http://t.me/linux_repo
Join Telegram Group for help and Feedback.

## Social Sites:
- Twitter: https://twitter.com/AbirHasan2005 [Only Follow]
- Instagram: https://instagram.com/AbirHasan2005 [Only Follow]
- Facebook: https://facebook.com/AbirHasan2005 [Only Follow]
- GitHub: https://github.com/AbirHasan2005 
- Telegram Group: http://t.me/linux_repo [Chat]

![Screenshot](https://github.com/AbirHasan2005/OPRecon/blob/master/capture.png)

## How to use:
- Compatible with:
	- Linux(Desktop)
	- Termux(Android)
- Requirements:
	- Python3
	- pip3
	- Git
- pip packages:
	- termcolor
	- colorama
	- requests
	- bs4
	- html5lib
	- phonenumbers
	- argparse
	- urllib3
- Commands:
```
git clone https://github.com/AbirHasan2005/OPRecon
cd OPRecon
python3 -m pip install -r requirements.txt
chmod +x *
bash run.sh
```

[![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://paypal.me/AbirHasan2005)

================================================
FILE: files/RESOURCES.md
================================================
### Inderstanding phone numbers

    http://whitepages.fr/phonesystem/
    https://support.twilio.com/hc/en-us/articles/223183008-Formatting-International-Phone-Numbers
    https://en.wikipedia.org/wiki/National_conventions_for_writing_telephone_numbers

### Open data

    https://api.ovh.com/console/#/telephony
    https://countrycode.org/
    http://www.countryareacode.net/en/
    http://directory.didww.com/area-prefixes
    http://hs3x.com/
    http://www.numinfo.net/

# Data sources

Both free and premium resources are included. Be careful, the listing of a data source here does not mean it has been verified or is used in the tool. Data might be false. Use it as an OSINT framework.

### Reputation / fraud

    scamcallfighters.com
    signal-arnaques.com
    
### Disposable numbers

    receive-sms-online.com
    receive-sms-now.com
    hs3x.com
    twilio.com
    freesmsverification.com
    freeonlinephone.org
    sms-receive.net
    smsreceivefree.com
    receive-a-sms.com
    receivefreesms.com
    freephonenum.com
    receive-smss.com
    receivetxt.com
    temp-mails.com
    receive-sms.com
    receivesmsonline.net
    receivefreesms.com
    sms-receive.net
    pinger.com (=> textnow.com)
    receive-a-sms.com
    k7.net
    kall8.com
    faxaway.com
    receivesmsonline.com
    receive-sms-online.info
    sellaite.com
    getfreesmsnumber.com
    smsreceiving.com
    smstibo.com
    catchsms.com
    freesmscode.com
    smsreceiveonline.com
    smslisten.com
    sms.sellaite.com
    
### Individuals

    Facebook
    True People
    Fast People
    Background Check
    Pipl
    Spytox
    Makelia
    IvyCall
    PhoneSearch
    411
    USPhone
    WP Plus
    Thats Them
    True Caller
    Sync.me
    WhoCallsMe
    ZabaSearch
    DexKnows
    WeLeakInfo
    OK Caller
    SearchBug
    numinfo.net
    
### Google dork examples

    `insubject:"+XXXXXXXXX" | insubject:"+XXXXX" | insubject:"XXXXX XXX XXX`
    `insubject:"XXXXXXXXX" | intitle:"XXXXXXXXX"`
    `intext:"XXXXXXXXX" ext:doc | ext:docx | ext:odt | ext:pdf | ext:rtf | ext:sxw | ext:psw | ext:ppt | ext:pptx | ext:pps | ext:csv | ext:txt | ext:html`
    `site:"hs3x.com" intext:"+XXXXXXXXX"`
    `site:signal-arnaques.com intext:"XXXXXXXXX" intitle:" | Phone Fraud"`


================================================
FILE: files/core/FileExporter.py
================================================
#!/usr/bin/env python3
# encoding: UTF-8

"""
    This file is part of IPGeoLocation tool.
    Copyright (C) 2015-2016 @maldevel
    https://github.com/maldevel/IPGeoLocation
    
    IPGeoLocation - Retrieve IP Geolocation information 
    Powered by http://ip-api.com
    
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
    
    For more see the file 'LICENSE' for copying permission.
"""

__author__ = 'maldevel'

import csv
from xml.etree import ElementTree as etree
from collections import OrderedDict

class FileExporter:
    
    def __init__(self):
        pass
    
    def ExportListToCSV(self, ipGeoLocObjs, filename):
        return self.__ExportToCSV(ipGeoLocObjs, filename)
        
    def ExportToCSV(self, ipGeoLocObj, filename):
        return self.__ExportToCSV([ipGeoLocObj], filename)
    
    def ExportListToXML(self, ipGeoLocObjs, filename):
        return self.__ExportToXML(ipGeoLocObjs, filename)
    
    def ExportToXML(self, ipGeoLocObj, filename):
        return self.__ExportToXML([ipGeoLocObj], filename)

    def ExportListToTXT(self, ipGeoLocObjs, filename):
        return self.__ExportToTXT(ipGeoLocObjs, filename)
        
    def ExportToTXT(self, ipGeoLocObj, filename):
        return self.__ExportToTXT([ipGeoLocObj], filename)
    
    def __ExportToTXT(self, ipGeoLocObjs, filename):
        try:
            with open(filename, 'w') as txtfile:
                txtfile.write('Results IPGeolocation\n')
                for ipGeoLocObj in ipGeoLocObjs:
                    if ipGeoLocObj:
                        txtfile.write('Target: {}\n'.format(ipGeoLocObj.Query))
                        txtfile.write('IP: {}\n'.format(ipGeoLocObj.IP))
                        txtfile.write('ASN: {}\n'.format(ipGeoLocObj.ASN))
                        txtfile.write('City: {}\n'.format(ipGeoLocObj.City))
                        txtfile.write('Country: {}\n'.format(ipGeoLocObj.Country))
                        txtfile.write('Country Code: {}\n'.format(ipGeoLocObj.CountryCode))
                        txtfile.write('ISP: {}\n'.format(ipGeoLocObj.ISP))
                        txtfile.write('Latitude: {}\n'.format(ipGeoLocObj.Latitude))
                        txtfile.write('Longtitude: {}\n'.format(ipGeoLocObj.Longtitude))
                        txtfile.write('Organization: {}\n'.format(ipGeoLocObj.Organization))
                        txtfile.write('Region: {}\n'.format(ipGeoLocObj.Region))
                        txtfile.write('Region Name: {}\n'.format(ipGeoLocObj.RegionName))
                        txtfile.write('Timezone: {}\n'.format(ipGeoLocObj.Timezone))
                        txtfile.write('Zip: {}\n'.format(ipGeoLocObj.Zip))
                        txtfile.write('Google Maps: {}\n'.format(ipGeoLocObj.GoogleMapsLink))
                        txtfile.write('\n')
            return True
        except:
            return False
        
        
    def __ExportToXML(self, ipGeoLocObjs, filename):
        try:
            root = etree.Element('Results')
            
            for ipGeoLocObj in ipGeoLocObjs:
                if ipGeoLocObj:
                    orderedData = OrderedDict(sorted(ipGeoLocObj.ToDict().items()))
                    self.__add_items(etree.SubElement(root, 'IPGeolocation'),
                      ((key.replace(' ', ''), value) for key, value in orderedData.items()))
        
                    tree = etree.ElementTree(root)

            tree.write(filename, xml_declaration=True, encoding='utf-8')
                        
            return True
        except:
            return False
        
        
    def __ExportToCSV(self, ipGeoLocObjs, filename):
        try:
            with open(filename, 'w', newline='') as csvfile:
                writer = csv.writer(csvfile, delimiter=';', quoting=csv.QUOTE_MINIMAL)
                writer.writerow(['Results', 'IPGeolocation'])
                for ipGeoLocObj in ipGeoLocObjs:
                    if ipGeoLocObj:
                        writer.writerow(['Target', ipGeoLocObj.Query])
                        writer.writerow(['IP', ipGeoLocObj.IP])
                        writer.writerow(['ASN', ipGeoLocObj.ASN])
                        writer.writerow(['City', ipGeoLocObj.City])
                        writer.writerow(['Country', ipGeoLocObj.Country])
                        writer.writerow(['Country Code', ipGeoLocObj.CountryCode])
                        writer.writerow(['ISP', ipGeoLocObj.ISP])
                        writer.writerow(['Latitude', ipGeoLocObj.Latitude])
                        writer.writerow(['Longtitude', ipGeoLocObj.Longtitude])
                        writer.writerow(['Organization', ipGeoLocObj.Organization])
                        writer.writerow(['Region', ipGeoLocObj.Region])
                        writer.writerow(['Region Name', ipGeoLocObj.RegionName])
                        writer.writerow(['Timezone', ipGeoLocObj.Timezone])
                        writer.writerow(['Zip', ipGeoLocObj.Zip])
                        writer.writerow(['Google Maps', ipGeoLocObj.GoogleMapsLink])
                        writer.writerow([])
            return True
        except:
            return False
        
    
    def __add_items(self, root, items):
        for name, text in items:
            elem = etree.SubElement(root, name)
            elem.text = text



================================================
FILE: files/core/IpGeoLocation.py
================================================
#!/usr/bin/env python3
# encoding: UTF-8

"""
    This file is part of IPGeoLocation tool.
    Copyright (C) 2015-2016 @maldevel
    https://github.com/maldevel/IPGeoLocation
    
    IPGeoLocation - Retrieve IP Geolocation information 
    Powered by http://ip-api.com
    
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
    
    For more see the file 'LICENSE' for copying permission.
"""

__author__ = 'maldevel'


class IpGeoLocation:
    """Represents an IP Geolocation information object"""
    
    def __init__(self, query, jsonData = None):
        self.Query = query
        self.ASN = '-'
        self.City = '-'
        self.Country = '-'
        self.CountryCode = '-'
        self.ISP = '-'
        self.Latitude = 0.0
        self.Longtitude = 0.0
        self.Organization = '-'
        self.IP = '0.0.0.0'
        self.Region = '-'
        self.RegionName = '-'
        self.Status = '-'
        self.Timezone = '-'
        self.Zip = '-'
        self.GoogleMapsLink = ''
        
        if jsonData != None:
            if type(jsonData) is dict:
                if 'as' in jsonData: 
                    self.ASN = jsonData['as']
                
                if 'city' in jsonData:
                    self.City = jsonData['city']
                 
                if 'country' in jsonData:
                    self.Country = jsonData['country']
                   
                if 'countryCode' in jsonData:
                    self.CountryCode = jsonData['countryCode']
                   
                if 'isp' in jsonData:
                    self.ISP = jsonData['isp']
                   
                if 'lat' in jsonData:
                    self.Latitude = jsonData['lat']
                  
                if 'lon' in jsonData:
                    self.Longtitude = jsonData['lon']
                  
                if 'org' in jsonData:
                    self.Organization = jsonData['org']
                   
                if 'query' in jsonData:
                    self.IP = jsonData['query']
                  
                if 'region' in jsonData:
                    self.Region = jsonData['region']
                  
                if 'regionName' in jsonData:
                    self.RegionName = jsonData['regionName']
                  
                if 'status' in jsonData:
                    self.Status = jsonData['status']
                   
                if 'timezone' in jsonData:
                    self.Timezone = jsonData['timezone']
                   
                if 'zip' in jsonData:
                    self.Zip = jsonData['zip']
                
                if type(self.Latitude) == float and type(self.Longtitude) == float: 
                    self.GoogleMapsLink = 'http://www.google.com/maps/place/{0},{1}/@{0},{1},16z'.format(self.Latitude, self.Longtitude)
                    
                    
    def ToDict(self):
        #self.__dict__.
        return {'Target':self.Query, 'IP':self.IP, 'ASN':self.ASN, 'City':self.City, 
                    'Country':self.Country, 'Country Code':self.CountryCode, 'ISP':self.ISP, 
                    'Latitude':str(self.Latitude), 'Longtitude':str(self.Longtitude), 
                    'Organization':self.Organization, 'Region':self.Region, 
                    'Region Name':self.RegionName, 'Timezone':self.Timezone, 
                    'Zip':self.Zip, 'Google Maps':self.GoogleMapsLink
                } 

================================================
FILE: files/core/IpGeoLocationLib.py
================================================
#!/usr/bin/env python3
# encoding: UTF-8

"""
    This file is part of IPGeoLocation tool.
    Copyright (C) 2015-2016 @maldevel
    https://github.com/maldevel/IPGeoLocation
    
    IPGeoLocation - Retrieve IP Geolocation information 
    Powered by http://ip-api.com
    
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
    
    For more see the file 'LICENSE' for copying permission.
"""

__author__ = 'maldevel'

from core.Utils import Utils
import json, random, os
from core.MyExceptions import *
from core.IpGeoLocation import IpGeoLocation
from time import sleep
from core.FileExporter import FileExporter
from urllib.parse import urlparse
from urllib import request 

class IpGeoLocationLib:
    """Retrieve IP Geolocation information from http://ip-api.com"""
    
    def __init__(self, target, logger, noprint=False, nolog=False, verbose=False):    
        self.URL = 'http://ip-api.com'
        self.RequestURL = self.URL + '/json/{}'
        self.BOLD = '\033[1m'
        self.Proxy = None
        self.UserAgentFile = None
        self.UserAgents = None
        self.Proxies = None
        self.TargetsFile = None
        self.ProxiesFile = None
        self.Targets = None
        self.NoPrint = noprint
        self.Target = target
        self.Logger = logger
        self.Utils = Utils(nolog, verbose)
        
    def GetInfo(self, userAgent, targetsFile=None, 
                userAgentFile=None, proxy=False, proxiesFile=None, 
                exportToCSVFile=None, exportToXMLFile=None, 
                exportToTXTFile=None, googleMaps=False):
        """Retrieve information"""
        
        self.UserAgent = userAgent
        
        try:
            
            #check proxies file and load it
            if proxiesFile and os.path.isfile(proxiesFile) and os.access(proxiesFile, os.R_OK):
                self.ProxiesFile = proxiesFile
                self.Logger.Print('Loading Proxies from file {}..'.format(self.ProxiesFile))
                self.__loadProxies()
            
            #check user-agent strings file and load it
            if userAgentFile and os.path.isfile(userAgentFile) and os.access(userAgentFile, os.R_OK):
                self.UserAgentFile = userAgentFile
                self.Logger.Print('Loading User-Agent strings from file {}..'.format(self.UserAgentFile))
                self.__loadUserAgents()
            
            #check targets file and load it
            if targetsFile and os.path.isfile(targetsFile) and os.access(targetsFile, os.R_OK):
                self.TargetsFile = targetsFile
                self.Logger.Print('Loading targets from file {}..'.format(self.TargetsFile))
                self.__loadTargets()

            #check if proxy valid and configure connection
            if proxy:
                self.__configureProxy(proxy)
            
            
            #retrieve information
            results = None
            if self.TargetsFile:
                results = self.__retrieveGeolocations()
            
            else:
                results = self.__retrieveGeolocation(self.Target)
            
            #export information
            if exportToCSVFile and not os.path.exists(exportToCSVFile) and os.access(os.path.dirname(exportToCSVFile), os.W_OK):
                self.__exportResultsToCSV(results, exportToCSVFile)
                
            if exportToXMLFile and not os.path.exists(exportToXMLFile) and os.access(os.path.dirname(exportToXMLFile), os.W_OK):
                self.__exportResultsToXML(results, exportToXMLFile)
                
            if exportToTXTFile and not os.path.exists(exportToTXTFile) and os.access(os.path.dirname(exportToTXTFile), os.W_OK):
                self.__exportResultsToTXT(results, exportToTXTFile)
            
            #open location in Google Maps with default browser
            if googleMaps and type(results) is IpGeoLocation:
                self.Utils.openLocationInGoogleMaps(results)
                
            return True
        
        except UserAgentFileEmptyError:
            self.Logger.PrintError("User-Agent strings file is empty!")
        except InvalidTargetError:
            self.Logger.PrintError('Please provide a valid Domain or IP address!')
        except TargetsFileEmptyError:
            self.Logger.PrintError('Targets file is empty!')
        except UserAgentFileNotSpecifiedError:
            self.Logger.PrintError('User-Agent strings file has not been provided!')
        except TargetsFileNotSpecifiedError:
            self.Logger.PrintError('Targets file has not been provided!')
        except ProxyServerNotReachableError:
            self.Logger.PrintError('Proxy server not reachable!')
        except ProxiesFileNotSpecifiedError:
            self.Logger.PrintError('Proxies file has not been provided!')
        except ProxiesFileEmptyError:
            self.Logger.PrintError('Proxies file is empty!')
        except InvalidProxyUrlError:
            self.Logger.PrintError('Proxy URL is not valid!')
        except Exception as error:
            self.Logger.PrintError('An unexpected error occurred {}!'.format(error))
        
        return False
    
    def __checkProxyUrl(self, url):
        """Check if proxy url is valid"""
        url_checked = urlparse(url)
        if (url_checked.scheme not in ('http', 'https')) | (url_checked.netloc == ''):
            return False
        return url_checked
    
    
    def __configureProxy(self, proxy):
        #proxy = self.__checkProxyUrl(proxy)
        #if not proxy:
        #    raise MyExceptions.InvalidProxyUrlError()
        
        self.Utils.checkProxyConn(self.URL, proxy.netloc)
        self.Proxy = proxy
        proxyHandler = request.ProxyHandler({'http':proxy.scheme + '://' + proxy.netloc})
        opener = request.build_opener(proxyHandler)
        request.install_opener(opener)
        self.Logger.Print('Proxy ({}) has been configured.'.format(proxy.scheme + '://' + proxy.netloc))
                
                
    def __exportResultsToCSV(self, objToExport, csvFile):
        """Export results to csv file"""
        fileExporter = FileExporter()
        self.Logger.Print('Saving results to {} CSV file.'.format(csvFile))
        success = False
        
        if type(objToExport) is IpGeoLocation:
            success = fileExporter.ExportToCSV(objToExport, csvFile)
        elif type(objToExport) is list:
            success = fileExporter.ExportListToCSV(objToExport, csvFile)
        
        if not success:
            self.Logger.PrintError('Saving results to {} CSV file failed.'.format(csvFile))
            
    
    def __exportResultsToXML(self, objToExport, xmlFile):
        """Export results to xml file"""
        fileExporter = FileExporter()
        self.Logger.Print('Saving results to {} XML file.'.format(xmlFile))
        success = False
        
        if type(objToExport) is IpGeoLocation:
            success = fileExporter.ExportToXML(objToExport, xmlFile)
        elif type(objToExport) is list:
            success = fileExporter.ExportListToXML(objToExport, xmlFile)
        
        if not success:
            self.Logger.PrintError('Saving results to {} XML file failed.'.format(xmlFile))
            
            
    def __exportResultsToTXT(self, objToExport, txtFile):
        """Export results to text file"""
        fileExporter = FileExporter()
        self.Logger.Print('Saving results to {} text file.'.format(txtFile))
        success = False
        
        if type(objToExport) is IpGeoLocation:
            success = fileExporter.ExportToTXT(objToExport, txtFile)
        elif type(objToExport) is list:
            success = fileExporter.ExportListToTXT(objToExport, txtFile)
        
        if not success:
            self.Logger.PrintError('Saving results to {} text file failed.'.format(txtFile))
            
        
    def __retrieveGeolocations (self):
        """Retrieve IP Geolocation for each target in the list"""
        IpGeoLocObjs = []
                    
        for target in self.Targets:
            IpGeoLocObjs.append(self.__retrieveGeolocation(target))
            if len(self.Targets)>=150:
                sleep(.500) #1/2 sec - ip-api will automatically ban any IP address doing over 150 requests per minute
                
        return IpGeoLocObjs
        
        
    def __retrieveGeolocation(self, target):
        """Retrieve IP Geolocation for single target"""
        
        if not target:
            query = 'My IP'
            target=''
            
        elif self.Utils.isValidIPAddress(target):
            query = target
            
        else:
            ip = self.Utils.hostnameToIP(target)#domain?
            if not ip:
                raise InvalidTargetError()
            
            query = target
            target = ip
        
        
        #pick random user-agent string
        if self.UserAgentFile:
            self.__pickRandomUserAgent()
            
            
        #pick random proxy connection
        if self.ProxiesFile:
            self.__pickRandomProxy()
            
        
        self.Logger.Print('Retrieving {} Geolocation..'.format(query))
        
        req = request.Request(self.RequestURL.format(target), data=None, headers={
          'User-Agent':self.UserAgent
        })
        
        response = request.urlopen(req)
        
        if response.code == 200:
            
            self.Logger.Print('User-Agent used: {}'.format(self.UserAgent))
            
            encoding = response.headers.get_content_charset()
            ipGeoLocObj = IpGeoLocation(query, json.loads(response.read().decode(encoding)))
            
            self.Logger.Print('Geolocation information has been retrieved for {}({}).'.format(query, ipGeoLocObj.IP))
            
            if not self.NoPrint:
                self.Logger.PrintIPGeoLocation(ipGeoLocObj)
                
            return ipGeoLocObj

        return False
    
    
    def __loadProxies(self):
        """Load proxies from file"""
        if not self.ProxiesFile:
            raise ProxiesFileNotSpecifiedError()
        
        self.Proxies = [line.strip() for line in open(self.ProxiesFile, 'r') if line.strip()]
        self.Logger.Print('{} Proxies loaded.'.format(len(self.Proxies)))
                
        if len(self.Proxies) == 0:
            raise ProxiesFileEmptyError()
        
        
    def __loadUserAgents(self):
        """Load user-agent strings from file"""
        if not self.UserAgentFile:
            raise UserAgentFileNotSpecifiedError()
        
        self.UserAgents = [line.strip() for line in open(self.UserAgentFile, 'r') if line.strip()]
        self.Logger.Print('{} User-Agent strings loaded.'.format(len(self.UserAgents)))

        if len(self.UserAgents) == 0:
            raise UserAgentFileEmptyError()
        
        
    def __loadTargets(self):
        """Load targets from file"""
        if not self.TargetsFile:
            raise TargetsFileNotSpecifiedError()
        
        self.Targets = [line.strip() for line in open(self.TargetsFile, 'r') if line.strip()]
        self.Logger.Print('{} Targets loaded.'.format(len(self.Targets)))
            
        if len(self.Targets) == 0:
            raise TargetsFileEmptyError()


    def __pickRandomProxy(self):
        """Pick randomly a proxy from the list"""
        if not self.Proxies or len(self.Proxies) == 0:
            raise ProxiesFileEmptyError()
        
        self.__configureProxy(random.choice(self.Proxies))
 
 
    def __pickRandomUserAgent(self):
        """Pick randomly a user-agent string from the list"""
        if not self.UserAgents or len(self.UserAgents) == 0:
            raise UserAgentFileEmptyError()
        
        self.UserAgent = random.choice(self.UserAgents)
        


================================================
FILE: files/core/Logger.py
================================================
#!/usr/bin/env python3
# encoding: UTF-8

"""
    This file is part of IPGeoLocation tool.
    Copyright (C) 2015-2016 @maldevel
    https://github.com/maldevel/IPGeoLocation
    
    IPGeoLocation - Retrieve IP Geolocation information 
    Powered by http://ip-api.com
    
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
    
    For more see the file 'LICENSE' for copying permission.
"""

__author__ = 'maldevel'

from datetime import datetime
import os
from termcolor import colored
from sys import platform as _platform


if _platform == 'win32':
    import colorama
    colorama.init()

def Red(value):
        return colored(value, 'red', attrs=['bold'])
    
def Green(value):
    return colored(value, 'green', attrs=['bold'])
    
          
class Logger:
    
    def __init__(self, nolog=False, verbose=False):
        self.NoLog = nolog
        self.Verbose = verbose
        
        
    def WriteLog(self, messagetype, message):
        filename = '{}.log'.format(datetime.strftime(datetime.now(), "%Y%m%d"))
        path = os.path.join('.', 'logs', filename)
        with open(path, 'a') as logFile:
            logFile.write('[{}] {} - {}\n'.format(messagetype, datetime.strftime(datetime.now(), "%Y-%m-%d %H:%M:%S"), message))
              
              
    def PrintError(self, message):
        """Print/Log error message"""
        if not self.NoLog:
            self.WriteLog('ERROR', message)
        
        print('[{}] {}'.format(Red('ERROR'), message))
    
    
    def PrintResult(self, title, value):
        """print result to terminal"""
        print('{}: {}'.format(title, Green(value)))
    
    
    def Print(self, message):
        """print/log info message"""
        if not self.NoLog:
            self.WriteLog('INFO', message)
            
        if self.Verbose:
            print('[{}] {}'.format(Green('**'), message))
    
    
    def PrintIPGeoLocation(self, ipGeoLocation):
        """print IP Geolocation information to terminal"""
        self.PrintResult('\nTarget', ipGeoLocation.Query)
        self.PrintResult('IP', ipGeoLocation.IP)
        self.PrintResult('ASN', ipGeoLocation.ASN)
        self.PrintResult('City', ipGeoLocation.City)
        self.PrintResult('Country', ipGeoLocation.Country)
        self.PrintResult('Country Code', ipGeoLocation.CountryCode)
        self.PrintResult('ISP', ipGeoLocation.ISP)
        self.PrintResult('Latitude', str(ipGeoLocation.Latitude))
        self.PrintResult('Longtitude', str(ipGeoLocation.Longtitude))
        self.PrintResult('Organization', ipGeoLocation.Organization)
        self.PrintResult('Region Code', ipGeoLocation.Region)
        self.PrintResult('Region Name', ipGeoLocation.RegionName)
        self.PrintResult('Timezone', ipGeoLocation.Timezone)
        self.PrintResult('Zip Code', ipGeoLocation.Zip)
        self.PrintResult('Google Maps', ipGeoLocation.GoogleMapsLink)
        print()
        #.encode('cp737', errors='replace').decode('cp737')
    

================================================
FILE: files/core/Menu.py
================================================
#!/usr/bin/env python3
# encoding: UTF-8

"""
    This file is part of IPGeoLocation tool.
    Copyright (C) 2015-2016 @maldevel
    https://github.com/maldevel/IPGeoLocation
    
    IPGeoLocation - Retrieve IP Geolocation information 
    Powered by http://ip-api.com
    
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
    
    For more see the file 'LICENSE' for copying permission.
"""

__author__   = 'maldevel'
__twitter__  = '@maldevel'
__version__  = '2.0.4'
__year__     = '2015-2016'


from argparse import RawTextHelpFormatter
import argparse, os
from urllib.parse import urlparse
from core.Logger import Red


banner = """
{0} 

{1} Retrieve IP Geolocation information from ip-api.com
{1} Copyright (c) {2} {3} ({4})
{1} ip-api.com service will automatically ban any IP addresses doing over 150 requests per minute.

""".format(Red('IPGeolocation ' + __version__), Red('--['), __year__, __author__, __twitter__)


def checkFileRead(filename):
    """Check if file exists and we have access to read it"""
    if os.path.isfile(filename) and os.access(filename, os.R_OK):
        return filename
    else:
        raise argparse.ArgumentTypeError("Invalid {} file (File does not exist, insufficient permissions or it's not a file).".format(filename))


def checkFileWrite(filename):
    """Check if we can write to file"""
    if os.path.isfile(filename):
        raise argparse.ArgumentTypeError("File {} already exists.".format(filename))
    elif os.path.isdir(filename):
        raise argparse.ArgumentTypeError("Folder provided. Please provide a file.")
    elif os.access(os.path.dirname(filename), os.W_OK):
        return filename
    else:
        raise argparse.ArgumentTypeError("Unable to write to {} file (Insufficient permissions).".format(filename))
    
    
def checkProxyUrl(url):
    """Check if proxy url is valid"""
    url_checked = urlparse(url)
    if (url_checked.scheme not in ('http', 'https')) | (url_checked.netloc == ''):
        raise argparse.ArgumentTypeError('Invalid {} Proxy URL (example: http://127.0.0.1:8080).'.format(url))
    return url_checked


parser = argparse.ArgumentParser(description=banner, formatter_class=RawTextHelpFormatter)
    
#pick target/s
parser.add_argument('-m', '--my-ip',  
                    dest='myip',
                    action='store_true', 
                    help='Get Geolocation info for my IP address.')

parser.add_argument('-t', '--target',  
                    help='IP Address or Domain to be analyzed.')

parser.add_argument('-T', '--tlist', 
                    metavar='file',
                    type=checkFileRead, 
                    help='A list of IPs/Domains targets, each target in new line.')


#user-agent configuration
parser.add_argument('-u', '--user-agent', 
                    metavar='User-Agent', 
                    dest='uagent',
                    default='IP2GeoLocation {}'.format(__version__), 
                    help='Set the User-Agent request header (default: IP2GeoLocation {}).'.format(__version__))

parser.add_argument('-U', '--ulist', 
                    metavar='file', 
                    type=checkFileRead, 
                    help='A list of User-Agent strings, each string in new line.')


#misc options
parser.add_argument('-g', 
                    action='store_true', 
                    help='Open IP location in Google maps with default browser.')

parser.add_argument('--noprint', 
                    action='store_true', 
                    help='IPGeolocation will print IP Geolocation info to terminal. It is possible to tell IPGeolocation not to print results to terminal with this option.')

parser.add_argument('-v', '--verbose', 
                    action='store_true', 
                    help='Enable verbose output.')

parser.add_argument('--nolog', 
                    action='store_true', 
                    help='IPGeolocation will save a .log file. It is possible to tell IPGeolocation not to save those log files with this option.')


#anonymity options
parser.add_argument('-x', '--proxy', 
                    type=checkProxyUrl, 
                    help='Setup proxy server (example: http://127.0.0.1:8080)')

parser.add_argument('-X', '--xlist', 
                    metavar='file', 
                    type=checkFileRead, 
                    help='A list of proxies, each proxy url in new line.')


#export options
parser.add_argument('-e', '--txt', 
                    metavar='file', 
                    type=checkFileWrite, 
                    help='Export results.')

parser.add_argument('-ec', '--csv', 
                    metavar='file', 
                    type=checkFileWrite, 
                    help='Export results in CSV format.')

parser.add_argument('-ex', '--xml', 
                    metavar='file', 
                    type=checkFileWrite, 
                    help='Export results in XML format.')


args = parser.parse_args()

================================================
FILE: files/core/MyExceptions.py
================================================
#!/usr/bin/env python3
# encoding: UTF-8

"""
    This file is part of IPGeoLocation tool.
    Copyright (C) 2015-2016 @maldevel
    https://github.com/maldevel/IPGeoLocation
    
    IPGeoLocation - Retrieve IP Geolocation information 
    Powered by http://ip-api.com
    
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
    
    For more see the file 'LICENSE' for copying permission.
"""

__author__ = 'maldevel'


class UserAgentFileEmptyError(Exception):
    pass

class InvalidTargetError(Exception):
    pass

class TargetsFileEmptyError(Exception):
    pass

class TargetsFileNotSpecifiedError(Exception):
    pass

class UserAgentFileNotSpecifiedError(Exception):
    pass

class ProxyServerNotReachableError(Exception):
    pass

class ProxiesFileNotSpecifiedError(Exception):
    pass

class ProxiesFileEmptyError(Exception):
    pass

class InvalidProxyUrlError(Exception):
    pass

================================================
FILE: files/core/Utils.py
================================================
#!/usr/bin/env python3
# encoding: UTF-8

"""
    This file is part of IPGeoLocation tool.
    Copyright (C) 2015-2016 @maldevel
    https://github.com/maldevel/IPGeoLocation
    
    IPGeoLocation - Retrieve IP Geolocation information 
    Powered by http://ip-api.com
    
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
    
    For more see the file 'LICENSE' for copying permission.
"""

__author__ = 'maldevel'

import webbrowser, ipaddress, socket
from sys import platform as _platform
from subprocess import call
from urllib import request
from core import MyExceptions 
from core.Logger import Logger

class Utils:
    
    def __init__(self, nolog=False, verbose=False):    
        self.Logger = Logger(nolog, verbose)
        
        
    def openLocationInGoogleMaps(self, ipGeolObj):
        """Open IP Geolocation in Google Maps with default browser"""
        if type(ipGeolObj.Longtitude) == float and type(ipGeolObj.Latitude) == float:
            self.Logger.Print('Opening Geolocation in browser..')
            
            if _platform == 'cygwin':
                call(['cygstart', ipGeolObj.GoogleMapsLink])
                
            elif _platform == 'win32' or _platform == 'linux' or _platform == 'linux2':
                webbrowser.open(ipGeolObj.GoogleMapsLink)
            
            else:
                self.Logger.PrintError('-g option is not available on your platform.')
                
                
    def hostnameToIP(self, hostname):
        """Resolve hostname to IP address"""
        try:
            return socket.gethostbyname(hostname)
        except:
            return False
    
    
    def isValidIPAddress(self, ip):
        """Check if ip is a valid IPv4/IPv6 address"""
        try:
            ipaddress.ip_address(ip)
            return True
        except:
            return False
    
            
    def checkProxyConn(self, url, proxy):
        """check proxy connectivity"""
        check = True
        self.Logger.Print('Testing proxy {} connectivity..'.format(proxy))
    
        try:
            req = request.Request(url)
            req.set_proxy(proxy, 'http')
            request.urlopen(req)
        except:
            check = False
        
        if check == True:
            self.Logger.Print('Proxy server is reachable.')
        else:
            raise MyExceptions.ProxyServerNotReachableError()
            
            

================================================
FILE: files/core/__init__.py
================================================
"""
    This file is part of IPGeoLocation tool.
    Copyright (C) 2015-2016 @maldevel
    https://github.com/maldevel/IPGeoLocation
    
    IPGeoLocation - Retrieve IP Geolocation information 
    Powered by http://ip-api.com
    
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
    
    For more see the file 'LICENSE' for copying permission.
"""

__author__ = 'maldevel'

================================================
FILE: files/examples/input.txt
================================================
+856 20 99 453 217
+59172768361
+32474123456
+1 (541) 754-3010
+86 591 2284 8571
+7 496 4819375
39172768361


================================================
FILE: files/ipgeolocation.py
================================================
#!/usr/bin/env python3
# encoding: UTF-8

"""
    This file is part of IPGeoLocation tool.
    Copyright (C) 2015-2016 @maldevel
    https://github.com/maldevel/IPGeoLocation
    
    IPGeoLocation - Retrieve IP Geolocation information 
    Powered by http://ip-api.com
    
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
    
    For more see the file 'LICENSE' for copying permission.
"""

__author__  = 'maldevel'


import sys, os
from core.IpGeoLocationLib import IpGeoLocationLib
from core.Logger import Logger
from core.Menu import parser,args,banner
    
def main():

    # no args provided
    if len(sys.argv) == 1:
        parser.print_help()
        sys.exit(1)
    
    logsDir = os.path.join(os.getcwd(), 'logs')
    #resultsDir = os.path.join(os.getcwd(), 'results')
    if not os.path.exists(logsDir):
        os.mkdir(logsDir)
    #if not os.path.exists(resultsDir):
    #    os.mkdir(resultsDir)
        
    logger = Logger(args.nolog, args.verbose)
    
    #single target or multiple targets 
    if(args.target and args.tlist):
        logger.PrintError("You can request Geolocation information either for a single target(-t) or a list of targets(-T). Not both!", args.nolog)
        sys.exit(2)
        
    #my ip address or single target
    if(args.target and args.myip):
        logger.PrintError("You can request Geolocation information either for a single target(-t) or your own IP address. Not both!", args.nolog)
        sys.exit(3)
        
    #multiple targets or my ip address
    if(args.tlist and args.myip):
        logger.PrintError("You can request Geolocation information either for a list of targets(-T) or your own IP address. Not both!", args.nolog)
        sys.exit(4)
    
    #single target and google maps only allowed
    if(args.tlist and args.g):
        logger.PrintError("Google maps location is working only with single targets.", args.nolog)
        sys.exit(5)
    
    #specify user-agent or random
    if(args.uagent and args.ulist):
        logger.PrintError("You can either specify a user-agent string or let IPGeolocation pick random user-agent strings for you from a file.", args.nolog)
        sys.exit(6)
        
    #specify proxy or random
    if(args.proxy and args.xlist):
        logger.PrintError("You can either specify a proxy or let IPGeolocation pick random proxy connections for you from a file.", args.nolog)
        sys.exit(7)
        
        
    #init lib
    ipGeoLocRequest = IpGeoLocationLib(args.target, logger, args.noprint)
    
    print(banner)
    
    #retrieve information
    if not ipGeoLocRequest.GetInfo(args.uagent, args.tlist, 
                                     args.ulist, args.proxy, args.xlist,
                                     args.csv, args.xml, args.txt, args.g):
        logger.PrintError("Retrieving IP Geolocation information failed.")
        sys.exit(8)


if __name__ == '__main__':
    main()
    

================================================
FILE: files/osint/disposable_num_providers.json
================================================
[
  {
    "site": "hs3x.com",
    "request": "site:\"hs3x.com\" intext:\"+$n\"",
    "stop": 1
  },
  {
    "site": "receive-sms-now.com",
    "request": "site:\"receive-sms-now.com\" intext:\"$n\"",
    "stop": 1
  },
  {
    "site": "smslisten.com",
    "request": "site:\"smslisten.com\" intext:\"$n\"",
    "stop": 1
  },
  {
    "site": "smsnumbersonline.com",
    "request": "site:\"smsnumbersonline.com\" intext:\"+$n\"",
    "stop": 1
  },
  {
    "site": "freesmscode.com",
    "request": "site:\"freesmscode.com\" intext:\"+$n\"",
    "stop": 1
  },
  {
    "site": "catchsms.com",
    "request": "site:\"catchsms.com\" intext:\"+$n\"",
    "stop": 1
  },
  {
    "site": "smstibo.com",
    "request": "site:\"smstibo.com\" intext:\"+$n\"",
    "stop": 1
  },
  {
    "site": "smsreceiving.com",
    "request": "site:\"smsreceiving.com\" intext:\"+$n\"",
    "stop": 1
  },
  {
    "site": "getfreesmsnumber.com",
    "request": "site:\"getfreesmsnumber.com\" intext:\"+$n\"",
    "stop": 1
  },
  {
    "site": "sellaite.com",
    "request": "site:\"sellaite.com\" intext:\"+$n\"",
    "stop": 1
  },
  {
    "site": "receive-sms-online.info",
    "request": "site:\"receive-sms-online.info\" intext:\"+$n\"",
    "stop": 1
  },
  {
    "site": "receivesmsonline.com",
    "request": "site:\"receivesmsonline.com\" intext:\"+$n\"",
    "stop": 1
  },
  {
    "site": "receive-a-sms.com",
    "request": "site:\"receive-a-sms.com\" intext:\"+$n\"",
    "stop": 1
  },
  {
    "site": "sms-receive.net",
    "request": "site:\"sms-receive.net\" intext:\"+$n\"",
    "stop": 1
  },
  {
    "site": "receivefreesms.com",
    "request": "site:\"receivefreesms.com\" intext:\"+$n\"",
    "stop": 1
  },
  {
    "site": "receive-sms.com",
    "request": "site:\"receive-sms.com\" intext:\"+$n\"",
    "stop": 1
  },
  {
    "site": "receivetxt.com",
    "request": "site:\"receivetxt.com\" $n",
    "stop": 1
  },
  {
    "site": "freephonenum.com",
    "request": "site:\"freephonenum.com\" intext:\"$n\"",
    "stop": 1
  },
  {
    "site": "freesmsverification.com",
    "request": "site:\"freesmsverification.com\" $n",
    "stop": 1
  },
  {
    "site": "receive-sms-online.com",
    "request": "site:\"receive-sms-online.com\" intext:\"$n\"",
    "stop": 1
  },
  {
    "site": "smslive.co",
    "request": "site:\"smslive.co\" intext:\"$n\"",
    "stop": 1
  }
]


================================================
FILE: files/osint/individuals.json
================================================
[
  {
    "site": "numinfo.net",
    "request": "site:\"numinfo.net\" intext:\"$n\" | intext:\"$i\"",
    "dialCode": null,
    "stop": 2
  },
  {
    "site": "sync.me",
    "request": "site:\"sync.me\" intext:\"$n\" | intext:\"$i\"",
    "dialCode": null,
    "stop": 1
  },
  {
    "site": "whocallsyou.de",
    "request": "site:\"whocallsyou.de\" intext:\"0$n\"",
    "dialCode": null,
    "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
  }
]


================================================
FILE: files/osint/reputation.json
================================================
[
  {
    "title": "reputation report on whosenumber.info",
    "request": "site:\"whosenumber.info\" intext:\"$n\" intitle:\"who called\"",
    "stop": 1
  },
  {
    "title": "phone fraud footprints",
    "request": "intitle:\"Phone Fraud\" intext:\"$n\" | intext:\"$i\"",
    "stop": 5
  }
]


================================================
FILE: files/osint/social_medias.json
================================================
[
  {
    "site": "facebook.com",
    "request": "site:\"facebook.com\" intext:\"$i\" | intext:\"$n\"",
    "stop": 5
  },
  {
    "site": "twitter.com",
    "request": "site:\"twitter.com\" intext:\"$i\" | intext:\"$n\"",
    "stop": 5
  },
  {
    "site": "linkedin.com",
    "request": "site:\"linkedin.com\" intext:\"$i\" | intext:\"$n\"",
    "stop": 5
  },
  {
    "site": "instagram.com",
    "request": "site:\"instagram.com\" intext:\"$i\" | intext:\"$n\"",
    "stop": 5
  }
]


================================================
FILE: files/phoneinfoga.py
================================================
#!/usr/bin/env python3

__version__ = 'v2.3.8-BETA'

try:
    import sys
    from colorama import Fore, Style
    import atexit
    import argparse
    import random
except KeyboardInterrupt:
    print('[!] Exiting.')
    sys.exit()
except:
    print('\033[91m[!] Missing requirements.\033[92m')
    sys.exit()

def banner():
    print("\033[92m    ___ _                       _____        __                   ")
    print("   / _ \ |__   ___  _ __   ___  \_   \_ __  / _| ___   __ _  __ _ ")
    print("  / /_)/ '_ \ / _ \| '_ \ / _ \  / /\/ '_ \| |_ / _ \ / _` |/ _` |")
    print(" / ___/| | | | (_) | | | |  __/\/ /_ | | | |  _| (_) | (_| | (_| |")
    print(" \/    |_| |_|\___/|_| |_|\___\____/ |_| |_|_|  \___/ \__, |\__,_|")
    print("                                                      |___/       ")
    print(" PhoneInfoga version {}".format(__version__))
    print(" Coded by Charon IV")
    print(" Modified by @AbirHasan2005")
    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 <number> [options]')

parser.add_argument('-n', '--number', metavar='number', type=str,
                    help='The phone number to scan (E164 or international format)')

parser.add_argument('-i', '--input', metavar="input_file", type=argparse.FileType('r'),
                    help='Phone number list to scan (one per line)')

parser.add_argument('-o', '--output', metavar="output_file", type=argparse.FileType('w'),
                    help='Output to save scan results')

parser.add_argument('-s', '--scanner', metavar="scanner", default="all", type=str,
                    help='The scanner to use')

parser.add_argument('--osint', action='store_true',
                    help='Use OSINT reconnaissance')

parser.add_argument('-u', '--update', action='store_true',
                    help='Update the project(Not Working)')

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
except KeyboardInterrupt:
    print('\033[91m[!] Exiting.')
    sys.exit()
except:
    print('\033[91m[!] Missing requirements.\033[92m')
    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.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; U; Windows NT 5.2; en-US; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729)")
uagent.append("Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.1) Gecko/20090718 Firefox/3.5.1")
uagent.append("Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:63.0) Gecko/20100101 Firefox/63.0")

number = '' # Full number format
localNumber = '' # Local number format
internationalNumber = '' # International numberformat
numberCountryCode = '' # Dial code; e.g:"+33"
numberCountry = '' # Country; e.g:France

googleAbuseToken = ''
customFormatting = ''

def search(req, stop):
    global googleAbuseToken
    global uagent

    chosenUserAgent = random.choice(uagent)

    s = requests.Session()
    headers = {
        'User-Agent': chosenUserAgent,
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
        'Accept-Language': 'en-us,en;q=0.5',
        'Accept-Encoding': 'gzip,deflate',
        'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.7',
        'Keep-Alive': '115',
        'Connection': 'keep-alive',
        'Cookie': 'Cookie: CGIC=Ij90ZXh0L2h0bWwsYXBwbGljYXRpb24veGh0bWwreG1sLGFwcGxpY2F0aW9uL3htbDtxPTAuOSwqLyo7cT0wLjg; CONSENT=YES+RE.fr+20150809-08-0; 1P_JAR=2018-11-28-14; NID=148=aSdSHJz71rufCokaUC93nH3H7lOb8E7BNezDWV-PyyiHTXqWK5Y5hsvj7IAzhZAK04-QNTXjYoLXVu_eiAJkiE46DlNn6JjjgCtY-7Fr0I4JaH-PZRb7WFgSTjiFqh0fw2cCWyN69DeP92dzMd572tQW2Z1gPwno3xuPrYC1T64wOud1DjZDhVAZkpk6UkBrU0PBcnLWL7YdL6IbEaCQlAI9BwaxoH_eywPVyS9V; SID=uAYeu3gT23GCz-ktdGInQuOSf-5SSzl3Plw11-CwsEYY0mqJLSiv7tFKeRpB_5iz8SH5lg.; HSID=AZmH_ctAfs0XbWOCJ; SSID=A0PcRJSylWIxJYTq_; APISID=HHB2bKfJ-2ZUL5-R/Ac0GK3qtM8EHkloNw; SAPISID=wQoxetHBpyo4pJKE/A2P6DUM9zGnStpIVt; SIDCC=ABtHo-EhFAa2AJrJIUgRGtRooWyVK0bAwiQ4UgDmKamfe88xOYBXM47FoL5oZaTxR3H-eOp7-rE; OTZ=4671861_52_52_123900_48_436380; OGPC=873035776-8:; OGP=-873035776:;'
    }

    try:
        URL = 'https://www.google.com/search?tbs=li:1&q={}&amp;gws_rd=ssl'.format(req)
        r = s.get(URL + googleAbuseToken, headers=headers)

        while r.status_code == 503:
            print(code_warning + 'You are temporary blacklisted from Google search. Complete the captcha at the following URL and copy/paste the content of GOOGLE_ABUSE_EXEMPTION cookie : {}'.format(URL))
            print('\n' + code_info + 'Need help ? Read https://github.com/sundowndev/PhoneInfoga#dealing-with-google-captcha')
            token = input('\nGOOGLE_ABUSE_EXEMPTION=')
            googleAbuseToken = '&google_abuse=' + token
            r = s.get(URL + googleAbuseToken, headers=headers)

        soup = BeautifulSoup(r.content, 'html.parser')
        results = soup.find("div", id="search").find_all("div", class_="g")

        links = []
        counter = 0

        for result in results:
            counter += 1

            if int(counter) > int(stop):
                break

            url = result.find("a").get('href')
            url = re.sub(r'(?:\/url\?q\=)', '', url)
            url = re.sub(r'(?:\/url\?url\=)', '', url)
            url = re.sub(r'(?:\&sa\=)(?:.*)', '', url)
            url = re.sub(r'(?:\&rct\=)(?:.*)', '', url)

            if re.match(r"^(?:\/search\?q\=)", url) is not None:
                url = 'https://google.com' + url

            links.append(url)

        return links
    except:
        print(code_error + 'Request failed. Please retry or open an issue on GitHub.')

def formatNumber(InputNumber):
    return re.sub("(?:\+)?(?:[^[0-9]*)", "", InputNumber)

def localScan(InputNumber):
    global number
    global localNumber
    global internationalNumber
    global numberCountryCode
    global numberCountry

    print(code_info + 'Running local scan ...')

    FormattedPhoneNumber = "+" + formatNumber(InputNumber)

    try:
        PhoneNumberObject = phonenumbers.parse(FormattedPhoneNumber, None)
    except:
        return False
    else:
        if not phonenumbers.is_valid_number(PhoneNumberObject):
            return False

        number = phonenumbers.format_number(PhoneNumberObject, phonenumbers.PhoneNumberFormat.E164).replace('+', '')
        numberCountryCode = phonenumbers.format_number(PhoneNumberObject, phonenumbers.PhoneNumberFormat.INTERNATIONAL).split(' ')[0]

        countryRequest = json.loads(requests.request('GET', 'https://restcountries.eu/rest/v2/callingcode/{}'.format(numberCountryCode.replace('+', ''))).content)
        numberCountry = countryRequest[0]['alpha2Code']

        localNumber = phonenumbers.format_number(PhoneNumberObject, phonenumbers.PhoneNumberFormat.E164).replace(numberCountryCode, '')
        internationalNumber = phonenumbers.format_number(PhoneNumberObject, phonenumbers.PhoneNumberFormat.INTERNATIONAL)

        print(code_result + 'International format: {}'.format(internationalNumber))
        print(code_result + 'Local format: 0{}'.format(localNumber))
        print(code_result + 'Country code: {}'.format(numberCountryCode))
        print(code_result + 'Location: {}'.format(geocoder.description_for_number(PhoneNumberObject, "en")))
        print(code_result + 'Carrier: {}'.format(carrier.name_for_number(PhoneNumberObject, 'en')))
        print(code_result + 'Area: {}'.format(geocoder.description_for_number(PhoneNumberObject, 'en')))
        for timezoneResult in timezone.time_zones_for_number(PhoneNumberObject):
            print(code_result + 'Timezone: {}'.format(timezoneResult))

        if phonenumbers.is_possible_number(PhoneNumberObject):
            print(code_info + 'The number is valid and possible.')
        else:
            print(code_warning + 'The number is valid but might not be possible.')

def numverifyScan():
    global number

    if not args.scanner == 'numverify' and not args.scanner == 'all':
        return -1

    print(code_info + 'Running Numverify.com scan ...')

    requestSecret = ''
    resp = requests.get('https://numverify.com/')
    soup = BeautifulSoup(resp.text, "html5lib")
    for tag in soup.find_all("input", type="hidden"):
        if tag['name'] == "scl_request_secret":
            requestSecret = tag['value']
            break

    apiKey = hashlib.md5((number + requestSecret).encode('utf-8')).hexdigest()

    headers = {
        'host': "numverify.com",
        'connection': "keep-alive",
        'content-length': "49",
        'accept': "application/json",
        'origin': "https://numverify.com",
        'x-requested-with': "XMLHttpRequest",
        'user-agent': "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36",
        'content-type': "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW",
        'referer': "https://numverify.com/",
        'accept-encoding': "gzip, deflate, br",
        'accept-language': "en-US,en;q=0.9,fr;q=0.8,la;q=0.7,es;q=0.6,zh-CN;q=0.5,zh;q=0.4",
        'cache-control': "no-cache"
    }

    response = requests.request("GET", "https://numverify.com/php_helper_scripts/phone_api.php?secret_key={}&number={}".format(apiKey, number), data="", headers=headers)

    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)."))
        return -1

    data = json.loads(response.content)

    if data["valid"] == False:
        print((code_error + "Error: Please specify a valid phone number. Example: +6464806649"))
        sys.exit()

    InternationalNumber = '({}){}'.format(data["country_prefix"], data["local_format"])

    print((code_result + "Number: ({}) {}").format(data["country_prefix"],data["local_format"]))
    print((code_result + "Country: {} ({})").format(data["country_name"],data["country_code"]))
    print((code_result + "Location: {}").format(data["location"]))
    print((code_result + "Carrier: {}").format(data["carrier"]))
    print((code_result + "Line type: {}").format(data["line_type"]))

    if data["line_type"] == 'landline':
        print((code_warning + "This is most likely a landline, but it can still be a fixed VoIP number."))
    elif data["line_type"] == 'mobile':
        print((code_warning + "This is most likely a mobile number, but it can still be a VoIP number."))

def ovhScan():
    global localNumber
    global numberCountry

    if not args.scanner == 'ovh' and not args.scanner == 'all':
        return -1

    print(code_info + 'Running OVH scan...')

    querystring = { "country": numberCountry.lower() }

    headers = {
        'accept': "application/json",
        'cache-control': "no-cache"
    }

    response = requests.request("GET", "https://api.ovh.com/1.0/telephony/number/detailedZones", data="", headers=headers, params=querystring)

    data = json.loads(response.content)

    if isinstance(data, list):
        askedNumber = "0" + localNumber.replace(localNumber[-4:], 'xxxx')

        for voip_number in data:
            if voip_number['number'] == askedNumber:
                print((code_info + "1 result found in OVH database"))
                print((code_result + "Number range: {}".format(voip_number['number'])))
                print((code_result + "City: {}".format(voip_number['city'])))
                print((code_result + "Zip code: {}".format(voip_number['zipCode'] if voip_number['zipCode'] is not None else '')))
                askForExit()

def replaceVariables(string):
    global number
    global internationalNumber
    global localNumber

    string = string.replace('$n', number)
    string = string.replace('$i', internationalNumber)
    string = string.replace('$l', localNumber)

    return string

def osintIndividualScan():
    global number
    global internationalNumber
    global numberCountryCode
    global customFormatting

    dorks = json.load(open('osint/individuals.json'))

    for dork in dorks:
        if dork['dialCode'] is None or dork['dialCode'] == numberCountryCode:
            if customFormatting:
                dorkRequest = replaceVariables(dork['request']) + ' | intext:"{}"'.format(customFormatting)
            else:
                dorkRequest = replaceVariables(dork['request'])

            print((code_info + "Searching for footprints on {}...".format(dork['site'])))
            for result in search(dorkRequest, stop=dork['stop']):
                if result:
                    print((code_result + "URL: " + result))
        else:
            return -1

def osintReputationScan():
    global number
    global internationalNumber
    global customFormatting

    dorks = json.load(open('osint/reputation.json'))

    for dork in dorks:
        if customFormatting:
            dorkRequest = replaceVariables(dork['request']) + ' | intext:"{}"'.format(customFormatting)
        else:
            dorkRequest = replaceVariables(dork['request'])

        print((code_info + "Searching for {}...".format(dork['title'])))
        for result in search(dorkRequest, stop=dork['stop']):
            if result:
                print((code_result + "URL: " + result))

def osintSocialMediaScan():
    global number
    global internationalNumber
    global customFormatting

    dorks = json.load(open('osint/social_medias.json'))

    for dork in dorks:
        if customFormatting:
            dorkRequest = replaceVariables(dork['request']) + ' | intext:"{}"'.format(customFormatting)
        else:
            dorkRequest = replaceVariables(dork['request'])

        print((code_info + "Searching for footprints on {}...".format(dork['site'])))
        for result in search(dorkRequest, stop=dork['stop']):
            if result:
                print((code_result + "URL: " + result))

def osintDisposableNumScan():
    global number

    dorks = json.load(open('osint/disposable_num_providers.json'))

    for dork in dorks:
        dorkRequest = replaceVariables(dork['request'])

        print((code_info + "Searching for footprints on {}...".format(dork['site'])))
        for result in search(dorkRequest, stop=dork['stop']):
            if result:
                print((code_result + "Result found: {}".format(dork['site'])))
                print((code_result + "URL: " + result))
                askForExit()

def osintScan():
    global number
    global localNumber
    global internationalNumber
    global numberCountryCode
    global numberCountry
    global customFormatting

    if not args.osint:
        return -1

    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(' ', '-')))

    askingCustomPayload = input(code_info + 'Would you like to use an additional format for this number ? (y/N) ')

    if askingCustomPayload == 'y' or askingCustomPayload == 'yes':
        customFormatting = input(code_info + 'Custom format: ')

    print((code_info + '---- Web pages footprints ----'))

    print((code_info + "Searching for footprints on web pages ... (limit=5)"))
    if customFormatting:
        req = '{} | intext:"{}" | intext:"{}" | intext:"{}"'.format(number,number,internationalNumber,customFormatting)
    else:
        req = '{} | intext:"{}" | intext:"{}"'.format(number,number,internationalNumber)
    for result in search(req, stop=5):
        if result:
            print((code_result + "Result found: " + result))

    # Documents
    print((code_info + "Searching for documents ... (limit=10)"))
    if 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:
        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:"{}" | 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:
            print((code_result + "Result found: " + result))

    print((code_info + '---- Reputation footprints ----'))

    osintReputationScan()

    print((code_info + "Generating URL on scamcallfighters.com ..."))
    print(code_result + 'http://www.scamcallfighters.com/search-phone-{}.html'.format(number))

    tmpNumAsk = input(code_info + "Would you like to search for temporary number providers footprints ? (Y/n) ")

    if tmpNumAsk.lower() != 'n' and tmpNumAsk.lower() != 'no':
        print((code_info + '---- Temporary number providers footprints ----'))

        print((code_info + "Searching for phone number on tempophone.com..."))
        response = requests.request("GET", "https://tempophone.com/api/v1/phones")
        data = json.loads(response.content)
        for voip_number in data['objects']:
            if voip_number['phone'] == formatNumber(number):
                print((code_result + "Found a temporary number provider: tempophone.com"))
                askForExit()

        osintDisposableNumScan()

    print((code_info + '---- Social media footprints ----'))

    osintSocialMediaScan()

    print((code_info + '---- Phone books footprints ----'))

    if numberCountryCode == '+1':
        print((code_info + "Generating URL on True People ... "))
        print(code_result + 'https://www.truepeoplesearch.com/results?phoneno={}'.format(internationalNumber.replace(' ', '')))

    osintIndividualScan()

def askForExit():
    if not args.output:
        user_input = input(code_info + "Continue scanning ? (y/n) ")

        if user_input.lower() == 'y' or user_input.lower() == 'yes':
            return -1
        else:
            print(code_info + "Good bye!")
            sys.exit()

def scanNumber(InputNumber):
    print(code_title + "[!] ---- Fetching informations for {} ---- [!]".format(formatNumber(InputNumber)))

    localScan(InputNumber)

    global number
    global localNumber
    global internationalNumber
    global numberCountryCode
    global numberCountry

    if not number:
        print((code_error + "\033[91mError: number {} is not valid.\n\033[92mFor help join Telegram Group:\033[96m http://t.me/linux_repo\n\n\033[91mSkipping ...\033[92m".format(formatNumber(InputNumber))))
        sys.exit()

    numverifyScan()
    ovhScan()
    osintScan()

    print(code_info + "Scan finished!")

    print('\n' + Style.RESET_ALL)

try:
    if args.output:
        code_info = '[*] '
        code_warning = '(!) '
        code_result = '[+] '
        code_error = '[!] '
        code_title = ''

        if args.osint:
            print('\033[91m[!] OSINT scanner is not available using output option (sorry).\033[92m')
            sys.exit()

        sys.stdout = args.output
        banner()
    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

    # Verify scanner option
    if not args.scanner in scanners:
        print((code_error + "Error: scanner doesn't exists."))
        sys.exit()

    if args.number:
        scanNumber(args.number)
    elif args.input:
        for line in args.input.readlines():
            scanNumber(line)

    if args.output:
        args.output.close()
except KeyboardInterrupt:
    print(("\n" + code_error + "Scan interrupted. Good bye!"))
    sys.exit()


================================================
FILE: files/tracker.py
================================================
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
import requests
import json
import time
import urllib
import os

class color:
   PURPLE = '\033[95m'
   CYAN = '\033[96m'
   DARKCYAN = '\033[36m'
   BLUE = '\033[94m'
   GREEN = '\033[92m'
   YELLOW = '\033[93m'
   RED = '\033[91m'
   BOLD = '\033[1m'
   UNDERLINE = '\033[4m'
   END = '\033[0m'
   HEADER = '\033[95m'
   OKBLUE = '\033[94m'
   OKGREEN = '\033[92m'
   WARNING = '\033[93m'
   FAIL = '\033[91m'

class config:
	key = "2dfa8e4851add96619e675427cdb72f1" #go to https://numverify.com/ and sign up if if get error. This API token is mine so after 100 use of this token this tool will not work. So you have to wait for next update or ask at my Telegram Group: http://t.me/linux_repo

def banner():
	os.system('clear')
	print  (color.BLUE + """
████████╗██████╗  █████╗  ██████╗██╗  ██╗███████╗██████╗ 
╚══██╔══╝██╔══██╗██╔══██╗██╔════╝██║ ██╔╝██╔════╝██╔══██╗
   ██║   ██████╔╝███████║██║     █████╔╝ █████╗  ██████╔╝
   ██║   ██╔══██╗██╔══██║██║     ██╔═██╗ ██╔══╝  ██╔══██╗
   ██║   ██║  ██║██║  ██║╚██████╗██║  ██╗███████╗██║  ██║
   ╚═╝   ╚═╝  ╚═╝╚═╝  ╚═╝ ╚═════╝╚═╝  ╚═╝╚══════╝╚═╝  ╚═╝
	Version: 1.6-DEV by @AbirHasan2005                 
	""" + color.END)

def main():
	banner()
	if len(sys.argv) == 2:
		number = sys.argv[1]
		api = "http://apilayer.net/api/validate?access_key=" + config.key + "&number=" + number + "&country_code=&format=1"
		output = requests.get(api)
		content = output.text
		obj = json.loads(content)
		country_code = obj['country_code']
		country_name = obj['country_name']
		location = obj['location']
		carrier = obj['carrier']
		line_type = obj['line_type']

		print (color.BLUE + "[+] " + color.END + "Phone number information gathering")
		print ("--------------------------------------")
		time.sleep(0.2)

		if country_code == "":
			print (" - Getting Country		[ " + color.RED + "FAILED " + color.END + "] ")
		else:
			print (" - Getting Country		[ " + color.GREEN + "OK " + color.END + "]")

		time.sleep(0.2)
		if country_name == "":
			print (" - Getting Country Name		[ " + color.RED + "FAILED " + color.END + "]")
		else:
			print (" - Getting Country Name		[ " + color.GREEN + "OK " + color.END + "]")

		time.sleep(0.2)
		if location == "":
			print (" - Getting Location		[ " + color.RED + "FAILED " + color.END + "]")
		else:
			print (" - Getting Location		[ " + color.GREEN + "OK " + color.END + "]")

		time.sleep(0.2)
		if carrier == "":
			print (" - Getting Carrier		[ " + color.RED + "FAILED " + color.END + "]")
		else:
			print (" - Getting Carrier		[ " + color.GREEN + "OK " + color.END + "]")

		time.sleep(0.2)
		if line_type == None:
			print (" - Getting Device		[ " + color.RED + "FAILED " + color.END + "]")
		else:
			print (" - Getting Device		[ " + color.GREEN + "OK " + color.END + "]")

		print ("")
		print (color.BLUE + "[+] " + color.END + "Information Output")
		print ("--------------------------------------")
		print (" - Phone number: " +str(number))
		print (" - Country: " +str(country_code))
		print (" - Country Name: " +str(country_name))
		print (" - Location: " +str(location))
		print (" - Carrier: " +str(carrier))
		print (" - Device: " +str(line_type))
	else:
		print ("[TRACKER] Usage:")
		print ("./%s <phone-number>" % (sys.argv[0]))
		print ("./%s +13213707446" % (sys.argv[0]))

main()

================================================
FILE: requirements.txt
================================================
termcolor
colorama
requests
bs4
html5lib
phonenumbers
argparse
urllib3

================================================
FILE: run.sh
================================================
#!/bin/bash
# This script was coded by @AbirHasan2005
# Please give me credits if you us any codes from here.
# Telegram Group: http://t.me/linux_repo
# GitHub: https://github.com/AbirHasan2005
# If you find any problem in this script than please report to my Telegram Group.

clear

banner() {
printf "\n\e[1;92m"
printf "\n\e[1;92m░█▀█░█▀█░█▀▄░█▀▀░█▀▀░█▀█░█▀█"
printf "\n\e[1;92m░█░█░█▀▀░█▀▄░█▀▀░█░░░█░█░█░█"
printf "\n\e[1;92m░▀▀▀░▀░░░▀░▀░▀▀▀░▀▀▀░▀▀▀░▀░▀  \e[1;95mv1.8-BETA\n"
printf "\n\e[1;92m   Coded by \e[1;94m@AbirHasan2005\n\n\e[1;92m"
}
dependencies() {
command -v git > /dev/null 2>&1 || { echo >&2 "Package GIT is not installed ... Aborting ..."; exit 1; }
command -v python3 > /dev/null 2>&1 || { echo >&2 "Package Python3 is not installed ... Aborting ..."; exit 1; }
}
script() {
printf "\n\e[1;92m[\e[1;93m01\e[1;92m] Find information via phone number\n[\e[1;93m02\e[1;92m] Find location via IP Address/Website Link\n[\e[1;93m03\e[1;92m] Phone Number Tracker (Recommanded to find IP Address)\n[\e[1;93m04\e[1;92m] Exit"
read -p $'\n\n\e[1;92m[\e[0m\e[1;77m*\e[0m\e[1;92m]\e[1;93m Choose an option: \e[1;93m' option

if [[ $option == 1 || $option == 01 ]]; then
	printf "\n\nEnter your phone number in international format ...\n"
	read -p $'\n\n\e[1;92m[\e[0m\e[1;77m*\e[0m\e[1;92m]\e[1;93m Enter Number: \e[1;92m' optiona

	printf "\n\e[1;92m This process will take a few moments ...\n\n\e[1;92m"
	sleep 2.9
	python3 files/phoneinfoga.py -n $optiona
	printf "\n\n\e[1;92mNOTE: If you get any problem while using this tool than please report to\nTelegram Group: \e[1;96mhttp://t.me/linux_repo\e[1;92m\n"
	script

elif [[ $option == 2 || $option == 02 ]]; then
	printf "\n\n\e[1;92mEnter IP Address or website link to find location ...\nExample: 198.235.36.25\n         google.com   \e[1;91m[Don't enter \e[1;96mhttp://\e[1;91m]"
	read -p $'\n\n\e[1;92m[\e[0m\e[1;77m*\e[0m\e[1;92m]\e[1;93m Enter: \e[1;92m' optionb

	printf "\n\e[1;92m Please wait ...\n\n\e[1;92m"
	sleep 3
	python3 files/ipgeolocation.py -t $optionb
	printf "\n\n\e[1;92mNOTE: If you get any problem while using this tool than please report to\nTelegram Group: \e[1;96mhttp://t.me/linux_repo\e[1;92m\n"
	script

elif [[ $option == 3 || $option == 03 ]]; then
	printf "\n\nEnter your phone number in international format ...\n"
	read -p $'\n\n\e[1;92m[\e[0m\e[1;77m*\e[0m\e[1;92m]\e[1;93m Enter Number: \e[1;92m' optionc

	python3 files/tracker.py $optionc
	printf "\n\n\e[1;92mNOTE: If you get any problem while using this tool than please report to\nTelegram Group: \e[1;96mhttp://t.me/linux_repo\e[1;92m\n"
	script

elif [[ $option == 4 || $option == 04 ]]; then
	printf "\n\n\e[1;92m Join Telegram Group for feedback:\e[1;96m http://t.me/linux_repo\e[1;92m\n"
	exit 1

else
	printf "\n\n\e[1;91mCommand not found!\e[1;92m\n"
	printf "\n\n\e[1;92mNOTE: If you get any problem while using this tool than please report to\nTelegram Group: \e[1;96mhttp://t.me/linux_repo\e[1;92m\n"

fi
}

banner
dependencies
script

================================================
FILE: update.sh
================================================
#!/bin/bash
# Update Script for OPRecon v2.1-Stable
# Script created by @AbirHasan2005


dependencies() {

command -v git > /dev/null 2>&1 || { echo >&2 "Package GIT is not installed ... Unable to update ..."; exit 1; }

}

script() {

clear
printf "\n \e[1;92mUpdating \e[1;94mOPRecon\e[1;92m ...\n\n"
sleep 1.5
cd ..
rm -rf OPRecon
git clone https://github.com/AbirHasan2005/OPRecon
cd OPRecon
chmod +x run.sh
printf "\n\e[1;92mRestarting ...\n\e[0m"
bash run.sh
cd ..

}

dependencies
script

Download .txt
gitextract_p879nsh0/

├── README.md
├── files/
│   ├── RESOURCES.md
│   ├── core/
│   │   ├── FileExporter.py
│   │   ├── IpGeoLocation.py
│   │   ├── IpGeoLocationLib.py
│   │   ├── Logger.py
│   │   ├── Menu.py
│   │   ├── MyExceptions.py
│   │   ├── Utils.py
│   │   └── __init__.py
│   ├── examples/
│   │   └── input.txt
│   ├── ipgeolocation.py
│   ├── osint/
│   │   ├── disposable_num_providers.json
│   │   ├── individuals.json
│   │   ├── reputation.json
│   │   └── social_medias.json
│   ├── phoneinfoga.py
│   └── tracker.py
├── requirements.txt
├── run.sh
└── update.sh
Download .txt
SYMBOL INDEX (78 symbols across 10 files)

FILE: files/core/FileExporter.py
  class FileExporter (line 34) | class FileExporter:
    method __init__ (line 36) | def __init__(self):
    method ExportListToCSV (line 39) | def ExportListToCSV(self, ipGeoLocObjs, filename):
    method ExportToCSV (line 42) | def ExportToCSV(self, ipGeoLocObj, filename):
    method ExportListToXML (line 45) | def ExportListToXML(self, ipGeoLocObjs, filename):
    method ExportToXML (line 48) | def ExportToXML(self, ipGeoLocObj, filename):
    method ExportListToTXT (line 51) | def ExportListToTXT(self, ipGeoLocObjs, filename):
    method ExportToTXT (line 54) | def ExportToTXT(self, ipGeoLocObj, filename):
    method __ExportToTXT (line 57) | def __ExportToTXT(self, ipGeoLocObjs, filename):
    method __ExportToXML (line 84) | def __ExportToXML(self, ipGeoLocObjs, filename):
    method __ExportToCSV (line 103) | def __ExportToCSV(self, ipGeoLocObjs, filename):
    method __add_items (line 131) | def __add_items(self, root, items):

FILE: files/core/IpGeoLocation.py
  class IpGeoLocation (line 31) | class IpGeoLocation:
    method __init__ (line 34) | def __init__(self, query, jsonData = None):
    method ToDict (line 100) | def ToDict(self):

FILE: files/core/IpGeoLocationLib.py
  class IpGeoLocationLib (line 39) | class IpGeoLocationLib:
    method __init__ (line 42) | def __init__(self, target, logger, noprint=False, nolog=False, verbose...
    method GetInfo (line 58) | def GetInfo(self, userAgent, targetsFile=None,
    method __checkProxyUrl (line 138) | def __checkProxyUrl(self, url):
    method __configureProxy (line 146) | def __configureProxy(self, proxy):
    method __exportResultsToCSV (line 159) | def __exportResultsToCSV(self, objToExport, csvFile):
    method __exportResultsToXML (line 174) | def __exportResultsToXML(self, objToExport, xmlFile):
    method __exportResultsToTXT (line 189) | def __exportResultsToTXT(self, objToExport, txtFile):
    method __retrieveGeolocations (line 204) | def __retrieveGeolocations (self):
    method __retrieveGeolocation (line 216) | def __retrieveGeolocation(self, target):
    method __loadProxies (line 270) | def __loadProxies(self):
    method __loadUserAgents (line 282) | def __loadUserAgents(self):
    method __loadTargets (line 294) | def __loadTargets(self):
    method __pickRandomProxy (line 306) | def __pickRandomProxy(self):
    method __pickRandomUserAgent (line 314) | def __pickRandomUserAgent(self):

FILE: files/core/Logger.py
  function Red (line 40) | def Red(value):
  function Green (line 43) | def Green(value):
  class Logger (line 47) | class Logger:
    method __init__ (line 49) | def __init__(self, nolog=False, verbose=False):
    method WriteLog (line 54) | def WriteLog(self, messagetype, message):
    method PrintError (line 61) | def PrintError(self, message):
    method PrintResult (line 69) | def PrintResult(self, title, value):
    method Print (line 74) | def Print(self, message):
    method PrintIPGeoLocation (line 83) | def PrintIPGeoLocation(self, ipGeoLocation):

FILE: files/core/Menu.py
  function checkFileRead (line 50) | def checkFileRead(filename):
  function checkFileWrite (line 58) | def checkFileWrite(filename):
  function checkProxyUrl (line 70) | def checkProxyUrl(url):

FILE: files/core/MyExceptions.py
  class UserAgentFileEmptyError (line 31) | class UserAgentFileEmptyError(Exception):
  class InvalidTargetError (line 34) | class InvalidTargetError(Exception):
  class TargetsFileEmptyError (line 37) | class TargetsFileEmptyError(Exception):
  class TargetsFileNotSpecifiedError (line 40) | class TargetsFileNotSpecifiedError(Exception):
  class UserAgentFileNotSpecifiedError (line 43) | class UserAgentFileNotSpecifiedError(Exception):
  class ProxyServerNotReachableError (line 46) | class ProxyServerNotReachableError(Exception):
  class ProxiesFileNotSpecifiedError (line 49) | class ProxiesFileNotSpecifiedError(Exception):
  class ProxiesFileEmptyError (line 52) | class ProxiesFileEmptyError(Exception):
  class InvalidProxyUrlError (line 55) | class InvalidProxyUrlError(Exception):

FILE: files/core/Utils.py
  class Utils (line 37) | class Utils:
    method __init__ (line 39) | def __init__(self, nolog=False, verbose=False):
    method openLocationInGoogleMaps (line 43) | def openLocationInGoogleMaps(self, ipGeolObj):
    method hostnameToIP (line 58) | def hostnameToIP(self, hostname):
    method isValidIPAddress (line 66) | def isValidIPAddress(self, ip):
    method checkProxyConn (line 75) | def checkProxyConn(self, url, proxy):

FILE: files/ipgeolocation.py
  function main (line 36) | def main():

FILE: files/phoneinfoga.py
  function banner (line 18) | def banner():
  function resetColors (line 60) | def resetColors():
  function download_file (line 101) | def download_file(url, target_path):
  function search (line 158) | def search(req, stop):
  function formatNumber (line 214) | def formatNumber(InputNumber):
  function localScan (line 217) | def localScan(InputNumber):
  function numverifyScan (line 259) | def numverifyScan():
  function ovhScan (line 317) | def ovhScan():
  function replaceVariables (line 348) | def replaceVariables(string):
  function osintIndividualScan (line 359) | def osintIndividualScan():
  function osintReputationScan (line 381) | def osintReputationScan():
  function osintSocialMediaScan (line 399) | def osintSocialMediaScan():
  function osintDisposableNumScan (line 417) | def osintDisposableNumScan():
  function osintScan (line 432) | def osintScan():
  function askForExit (line 509) | def askForExit():
  function scanNumber (line 519) | def scanNumber(InputNumber):

FILE: files/tracker.py
  class color (line 10) | class color:
  class config (line 27) | class config:
  function banner (line 30) | def banner():
  function main (line 42) | def main():
Condensed preview — 21 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (88K chars).
[
  {
    "path": "README.md",
    "chars": 1299,
    "preview": "# OPRecon v1.8-BETA\r\nUsing this you can find informations via PhoneInFoga(In-Built), Find location via IP Address & webs"
  },
  {
    "path": "files/RESOURCES.md",
    "chars": 2362,
    "preview": "### Inderstanding phone numbers\r\n\r\n    http://whitepages.fr/phonesystem/\r\n    https://support.twilio.com/hc/en-us/articl"
  },
  {
    "path": "files/core/FileExporter.py",
    "chars": 6090,
    "preview": "#!/usr/bin/env python3\r\n# encoding: UTF-8\r\n\r\n\"\"\"\r\n    This file is part of IPGeoLocation tool.\r\n    Copyright (C) 2015-2"
  },
  {
    "path": "files/core/IpGeoLocation.py",
    "chars": 4171,
    "preview": "#!/usr/bin/env python3\r\n# encoding: UTF-8\r\n\r\n\"\"\"\r\n    This file is part of IPGeoLocation tool.\r\n    Copyright (C) 2015-2"
  },
  {
    "path": "files/core/IpGeoLocationLib.py",
    "chars": 12780,
    "preview": "#!/usr/bin/env python3\r\n# encoding: UTF-8\r\n\r\n\"\"\"\r\n    This file is part of IPGeoLocation tool.\r\n    Copyright (C) 2015-2"
  },
  {
    "path": "files/core/Logger.py",
    "chars": 3682,
    "preview": "#!/usr/bin/env python3\r\n# encoding: UTF-8\r\n\r\n\"\"\"\r\n    This file is part of IPGeoLocation tool.\r\n    Copyright (C) 2015-2"
  },
  {
    "path": "files/core/Menu.py",
    "chars": 5689,
    "preview": "#!/usr/bin/env python3\r\n# encoding: UTF-8\r\n\r\n\"\"\"\r\n    This file is part of IPGeoLocation tool.\r\n    Copyright (C) 2015-2"
  },
  {
    "path": "files/core/MyExceptions.py",
    "chars": 1554,
    "preview": "#!/usr/bin/env python3\r\n# encoding: UTF-8\r\n\r\n\"\"\"\r\n    This file is part of IPGeoLocation tool.\r\n    Copyright (C) 2015-2"
  },
  {
    "path": "files/core/Utils.py",
    "chars": 3110,
    "preview": "#!/usr/bin/env python3\r\n# encoding: UTF-8\r\n\r\n\"\"\"\r\n    This file is part of IPGeoLocation tool.\r\n    Copyright (C) 2015-2"
  },
  {
    "path": "files/core/__init__.py",
    "chars": 1002,
    "preview": "\"\"\"\r\n    This file is part of IPGeoLocation tool.\r\n    Copyright (C) 2015-2016 @maldevel\r\n    https://github.com/maldeve"
  },
  {
    "path": "files/examples/input.txt",
    "chars": 115,
    "preview": "+856 20 99 453 217\r\n+59172768361\r\n+32474123456\r\n+1 (541) 754-3010\r\n+86 591 2284 8571\r\n+7 496 4819375\r\n39172768361\r\n"
  },
  {
    "path": "files/ipgeolocation.py",
    "chars": 3616,
    "preview": "#!/usr/bin/env python3\r\n# encoding: UTF-8\r\n\r\n\"\"\"\r\n    This file is part of IPGeoLocation tool.\r\n    Copyright (C) 2015-2"
  },
  {
    "path": "files/osint/disposable_num_providers.json",
    "chars": 2481,
    "preview": "[\r\n  {\r\n    \"site\": \"hs3x.com\",\r\n    \"request\": \"site:\\\"hs3x.com\\\" intext:\\\"+$n\\\"\",\r\n    \"stop\": 1\r\n  },\r\n  {\r\n    \"site"
  },
  {
    "path": "files/osint/individuals.json",
    "chars": 723,
    "preview": "[\r\n  {\r\n    \"site\": \"numinfo.net\",\r\n    \"request\": \"site:\\\"numinfo.net\\\" intext:\\\"$n\\\" | intext:\\\"$i\\\"\",\r\n    \"dialCode\""
  },
  {
    "path": "files/osint/reputation.json",
    "chars": 307,
    "preview": "[\r\n  {\r\n    \"title\": \"reputation report on whosenumber.info\",\r\n    \"request\": \"site:\\\"whosenumber.info\\\" intext:\\\"$n\\\" i"
  },
  {
    "path": "files/osint/social_medias.json",
    "chars": 509,
    "preview": "[\r\n  {\r\n    \"site\": \"facebook.com\",\r\n    \"request\": \"site:\\\"facebook.com\\\" intext:\\\"$i\\\" | intext:\\\"$n\\\"\",\r\n    \"stop\": "
  },
  {
    "path": "files/phoneinfoga.py",
    "chars": 23409,
    "preview": "#!/usr/bin/env python3\r\n\r\n__version__ = 'v2.3.8-BETA'\r\n\r\ntry:\r\n    import sys\r\n    from colorama import Fore, Style\r\n   "
  },
  {
    "path": "files/tracker.py",
    "chars": 3447,
    "preview": "#!/usr/bin/python\r\n# -*- coding: utf-8 -*-\r\nimport sys\r\nimport requests\r\nimport json\r\nimport time\r\nimport urllib\r\nimport"
  },
  {
    "path": "requirements.txt",
    "chars": 77,
    "preview": "termcolor\r\ncolorama\r\nrequests\r\nbs4\r\nhtml5lib\r\nphonenumbers\r\nargparse\r\nurllib3"
  },
  {
    "path": "run.sh",
    "chars": 2998,
    "preview": "#!/bin/bash\n# This script was coded by @AbirHasan2005\n# Please give me credits if you us any codes from here.\n# Telegram"
  },
  {
    "path": "update.sh",
    "chars": 496,
    "preview": "#!/bin/bash\n# Update Script for OPRecon v2.1-Stable\n# Script created by @AbirHasan2005\n\n\ndependencies() {\n\ncommand -v gi"
  }
]

About this extraction

This page contains the full source code of the AbirHasan2005/OPRecon GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 21 files (78.0 KB), approximately 20.5k tokens, and a symbol index with 78 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!