Repository: Nitr4x/whichCDN Branch: master Commit: 5fc6dddb8bfe Files: 22 Total size: 12.6 KB Directory structure: gitextract_rshehg3n/ ├── .gitignore ├── DISCLAIMER.md ├── LICENCE.txt ├── README.md ├── plugins/ │ ├── DNSDetection/ │ │ ├── __init__.py │ │ └── behaviors.py │ ├── ErrorServerDetection/ │ │ ├── __init__.py │ │ └── behaviors.py │ ├── HTTPHeaderDetection/ │ │ ├── __init__.py │ │ └── behaviors.py │ ├── SubdomainDetection/ │ │ ├── __init__.py │ │ └── behaviors.py │ ├── WhoisDetection/ │ │ ├── __init__.py │ │ └── behaviors.py │ └── __init__.py ├── requirements.txt ├── setup.py ├── utils/ │ ├── CDNEngine.py │ ├── __init__.py │ ├── loader.py │ └── request.py └── whichCDN ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ .DS_Store *.pyc __pycache__/ ================================================ FILE: DISCLAIMER.md ================================================ # DISCLAIMER.MD This tool has been developed as part of my work at BSSI consulting and cybersecurity. For any further information, please contact us at contact@bssi.fr ================================================ FILE: LICENCE.txt ================================================ MIT License Copyright (c) 2017 Nitrax - nitrax@lokisec.fr Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # whichCDN WhichCDN allows to detect if a given website is protected by a Content Delivery Network ## Requirements Install the necessary python packages. ``` pip install -r requirements.txt ``` ## Usage To scan a website, run whichCDN followed by the target URL or its domain name ``` whichCDN http://www.example.com | example.com ``` ## CDN supported * Cloudflare * Incapsula * Cloudfront * Akamai * Airee * CacheFly * EdgeCast * MaxCDN * Beluga * Limelight * Fastly * Myracloud * Microsft Azure ## Todo * Azion * ArvanCloud * Beluga * DN77 * CDNetwork * CDNsun * CDNvideo * ChinaCache * ChinaNetCenter * Highwinds * KeyCDN * Level3 * NGENIX * Quantil * SkyparkCDN * Verizon Digital Media services * Turbobyte ## More docs Help is available by running ```whichCDN -help``` ## Contribution Pull requests for new features, bug fixes, and suggestions are welcome ! ================================================ FILE: plugins/DNSDetection/__init__.py ================================================ #!/usr/bin/env python """ DNSDetection plugin performs CDN detection through nslookup results. """ from plugins.DNSDetection.behaviors import detect ================================================ FILE: plugins/DNSDetection/behaviors.py ================================================ #!/usr/bin/env python from __future__ import print_function import sys import re from utils import CDNEngine if sys.version_info >= (3, 0): import subprocess as commands import urllib.parse as urlparse else: import commands import urlparse def detect(hostname): """ Performs CDN detection through the DNS, using the nslookup command. Parameters ---------- hostname : str Hostname to assess """ print('[+] DNS detection\n') hostname = urlparse.urlparse(hostname).netloc regexp = re.compile('\\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\\b') out = commands.getoutput("host " + hostname) addresses = regexp.finditer(out) for addr in addresses: CDNEngine.find(commands.getoutput('nslookup ' + addr.group())) ================================================ FILE: plugins/ErrorServerDetection/__init__.py ================================================ #!/usr/bin/env python """ ErrorServerDetection plugin performs CDN detection when attempts to access the web server via its IP address fail and disclose information about the CDN in place. """ from plugins.ErrorServerDetection.behaviors import detect ================================================ FILE: plugins/ErrorServerDetection/behaviors.py ================================================ #!/usr/bin/env python from __future__ import print_function import sys import re from utils import CDNEngine from utils import request if sys.version_info >= (3, 0): import subprocess as commands import urllib.parse as urlparse else: import commands import urlparse def detect(hostname): """ Performs CDN detection thanks to information disclosure from server error. Parameters ---------- hostname : str Hostname to assess """ print('[+] Error server detection\n') hostname = urlparse.urlparse(hostname).netloc regexp = re.compile('\\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\\b') out = commands.getoutput("host " + hostname) addresses = regexp.finditer(out) for addr in addresses: res = request.do('http://' + addr.group()) if res is not None and res.status_code == 500: CDNEngine.find(res.text.lower()) ================================================ FILE: plugins/HTTPHeaderDetection/__init__.py ================================================ #!/usr/bin/env python """ HTTPHeaderDetection plugin performs CDN detection by assessing HTTP headers. """ from plugins.HTTPHeaderDetection.behaviors import detect ================================================ FILE: plugins/HTTPHeaderDetection/behaviors.py ================================================ #!/usr/bin/env python from __future__ import print_function import sys from utils import CDNEngine from utils import request if sys.version_info >= (3, 0): import urllib.parse as urlparse else: import urlparse def detect(hostname): """ Performs CDN detection thanks to HTTP headers. Parameters ---------- hostname : str Hostname to assess """ print('[+] HTTP header detection\n') hostname = urlparse.urlparse(hostname).scheme + '://' + urlparse.urlparse(hostname).netloc fields = { 'Server': True, 'X-CDN': True, 'x-cache': True, 'X-CDN-Forward': True, 'Fastly-Debug-Digest': False } res = request.do(hostname) if res is None: return for field, state in fields.items(): value = res.headers.get(field) if state and value is not None: CDNEngine.find(value.lower()) elif not state and value is not None: CDNEngine.find(field.lower()) ================================================ FILE: plugins/SubdomainDetection/__init__.py ================================================ #!/usr/bin/env python """ CDN are, sometimes, deployed on a specific subdomain. SubdomainDetection plugin performs CDN detection by trying to access this specific subdomain and by analyzing its DNS. """ from plugins.SubdomainDetection.behaviors import detect ================================================ FILE: plugins/SubdomainDetection/behaviors.py ================================================ #!/usr/bin/env python from __future__ import print_function import sys from utils import CDNEngine if sys.version_info >= (3, 0): import subprocess as commands import urllib.parse as urlparse else: import commands import urlparse def detect(hostname): """ Performs CDN detection by trying to access the cdn subdomain of the specified hostname. Parameters ---------- hostname : str Hostname to assess """ print('[+] CDN subdomain detection\n') hostname = "cdn." + urlparse.urlparse(hostname).netloc out = commands.getoutput("host -a " + hostname) CDNEngine.find(out.lower()) ================================================ FILE: plugins/WhoisDetection/__init__.py ================================================ #!/usr/bin/env python """ Whois Detection plugin performs CDN detection by analyzing data returned by whois command's. """ from plugins.WhoisDetection.behaviors import detect ================================================ FILE: plugins/WhoisDetection/behaviors.py ================================================ #!/usr/bin/env python from __future__ import print_function import sys from utils import CDNEngine if sys.version_info >= (3, 0): import subprocess as commands import urllib.parse as urlparse else: import commands import urlparse def detect(hostname): """ Performs CDN detection through whois command's. Parameters ---------- hostname : str Hostname to assess """ print('[+] Whois detection\n') hostname = urlparse.urlparse(hostname).netloc out = commands.getoutput("whois " + hostname) CDNEngine.find(out.lower()) ================================================ FILE: plugins/__init__.py ================================================ #!/usr/bin/env python from . import * # import all plugins ================================================ FILE: requirements.txt ================================================ requests ================================================ FILE: setup.py ================================================ #!/usr/bin/env python import os from setuptools import setup, find_packages from setuptools.command.install import install setup( name='whichCDN', version='1.0', description='WhichCDN allows to detect if a given website is protected by a Content Delivery Network', author_email='nitrax@lokisec.fr', author='Nitrax', license='MIT', packages=find_packages(), url='https://github.com/Nitr4x/whichCDN', scripts=['whichCDN'], classifiers=[ 'Development Status :: 5 - Production/Stable', 'License :: MIT', 'Operating system :: Unix', 'Operating system :: Windows', 'Operating system :: MacOS', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3' ], install_requires=[ 'requests' ] ) ================================================ FILE: utils/CDNEngine.py ================================================ #!/usr/bin/env python from __future__ import print_function import sys CDN = { 'Cloudflare': 'Cloudflare - https://www.cloudflare.com', 'Incapsula': 'Incapsula - https://www.incapsula.com/', 'Cloudfront': 'Cloudfront - https://aws.amazon.com/cloudfront/', 'Akamai': 'Akamai - https://akamai.com', 'Airee': 'Airee - https://airee.international', 'CacheFly': 'CacheFly - https://www.cachefly.com/', 'EdgeCast': 'EdgeCast - https://verizondigitalmedia.com', 'MaxCDN': 'MaxCDN - https://www.maxcdn.com/', 'Beluga': 'BelugaCDN - https://belugacdn.com', 'Limelight': 'Limelight - https://www.limelight.com', 'Fastly': 'Fastly - https://www.fastly.com/', 'Myracloud': 'Myra - https://myracloud.com', 'msecnd.ne': 'Microsoft Azure - https://azure.microsoft.com/en-us/services/cdn/', 'Clever-cloud': 'Clever Cloud - https://www.clever-cloud.com/' } def find(data): """ Compares the provided data to the CDN supported. Parameters ---------- data : str Data to analyze """ for keyword, description in CDN.items(): if data.find(keyword.lower()) != -1: print('\033[1;32mCDN found: ' + description + '\033[1;m\n') sys.exit(0) ================================================ FILE: utils/__init__.py ================================================ #!/usr/bin/env python2 ================================================ FILE: utils/loader.py ================================================ #!/usr/bin/env python import imp import os PluginFolder = "./plugins" MainModule = "__init__" def getPlugins(): """ List the plugins located in the plugins folder. """ plugins = [] pluginList = os.listdir(PluginFolder) for pluginName in pluginList: location = os.path.join(PluginFolder, pluginName) if not os.path.isdir(location) or not MainModule + ".py" in os.listdir(location): continue info = imp.find_module(MainModule, [location]) plugins.append({"name": pluginName, "info": info}) return plugins def loadPlugin(plugin): """ Loads the specified plugin. Parameters ---------- plugin : Plugin Plugin to load Return ------ The plugin loaded """ return imp.load_module(MainModule, *plugin["info"]) ================================================ FILE: utils/request.py ================================================ #!/usr/bin/env python from __future__ import print_function import signal import requests class TimeoutException(Exception): """ Exception called on timeouts. """ pass def requestTimeout(signum, frame): """ Request timeout. """ raise TimeoutException() def do(hostname): """ Performs a GET request. Parameters ---------- hostname : str Target request Return ------ The request results """ try: return requests.get(hostname, timeout=10) except TimeoutException: print("\033[1;31mRequest timeout: test aborted\n\033[1;m") return None except requests.ConnectionError: print("\033[1;31mServer not found: test aborted\n\033[1;m") return None finally: signal.alarm(0) ================================================ FILE: whichCDN ================================================ #!/usr/bin/env python from __future__ import print_function import argparse import signal import sys from utils import loader from utils import request if sys.version_info >= (3, 0): import urllib.parse as urlparse else: import urlparse def gracefulExit(signal, frame): sys.exit(0) def parser(): """ Parse arguments. """ parser = argparse.ArgumentParser(description="""\ WhichCDN allows to detect if a given website is protected by a Content Delivery Network.\r Fell free to contact the maintainer for any further questions or improvement vectors.\r Maintained by Nitrax """) parser.add_argument('target', type=str, help='hostname to scan') parser.parse_args() def sanitizeURL(hostname): """ Sanitizes the hostname by adding the http protocol if it has not been provided. Parameters ---------- hostname : str Hostname to assess Return ------ The hostname sanitized """ components = urlparse.urlparse(hostname) hostname = "http://" + hostname if components.scheme == '' else hostname return hostname if __name__ == "__main__": print(""" __ __.__ .__ .__ _________ ________ _______ / \ / \ |__ |__| ____ | |__ \_ ___ \\\\______ \ \ \\ \ \/\/ / | \| |/ ___\| | \/ \ \/ | | \ / | \\ \ /| Y \ \ \___| Y \ \____| ` \/ | \\ \__/\ / |___| /__|\___ >___| /\______ /_______ /\____|__ / \/ \/ \/ \/ \/ \/ \/ """) parser() signal.signal(signal.SIGALRM, request.requestTimeout) signal.signal(signal.SIGINT, gracefulExit) signal.alarm(5) hostname = sanitizeURL(sys.argv[1]) for module in loader.getPlugins(): plugin = loader.loadPlugin(module) plugin.detect(hostname) print('\033[1;31mNo CDN found\033[1;m')