-
-
Notifications
You must be signed in to change notification settings - Fork 53
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding ipsourcebypass.py version 1.1
- Loading branch information
1 parent
4f1ad64
commit b468b07
Showing
5 changed files
with
206 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# These are supported funding model platforms | ||
|
||
github: p0dalirius | ||
patreon: Podalirius |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,52 @@ | ||
# ipsourcebypass | ||
# ipsourcebypass | ||
|
||
This Python script can be used to bypass IP source restrictions using HTTP headers. | ||
|
||
![](./.github/four_results.png) | ||
|
||
## Features | ||
|
||
- [x] 17 HTTP headers. | ||
- [x] Multithreading. | ||
- [x] JSON export with `--json outputfile.json`. | ||
- [x] Autodetecting most successfull bypasses. | ||
|
||
## Usage | ||
|
||
``` | ||
$ ./ipsourcebypass.py -h | ||
[~] IP source bypass using HTTP headers, v1.1 | ||
usage: ipsourcebypass.py [-h] [-v] -i IP [-t THREADS] [-x PROXY] [-k] [-L] [-j JSONFILE] url | ||
This Python script can be used to test for IP source bypass using HTTP headers | ||
positional arguments: | ||
url e.g. https://example.com:port/path | ||
optional arguments: | ||
-h, --help show this help message and exit | ||
-v, --verbose arg1 help message | ||
-i IP, --ip IP IP to spoof. | ||
-t THREADS, --threads THREADS | ||
Number of threads (default: 5) | ||
-x PROXY, --proxy PROXY | ||
Specify a proxy to use for requests (e.g., http://localhost:8080) | ||
-k, --insecure Allow insecure server connections when using SSL (default: False) | ||
-L, --location Follow redirects (default: False) | ||
-j JSONFILE, --jsonfile JSONFILE | ||
Save results to specified JSON file. | ||
``` | ||
|
||
## Autodetecting most probable results | ||
|
||
Results are sorted by uncommon length, meaning the results with unique response length will be on top, and lots of results with the same content length, at the bottom: | ||
|
||
| Two different result lengths | Four different result lengths | | ||
|------------------------------|--------------------------------| | ||
| ![](./.github/two_results.png) | ![](./.github/four_results.png) | | ||
|
||
|
||
## Contributing | ||
|
||
Pull requests are welcome. Feel free to open an issue if you want to add other features. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
#!/usr/bin/env python3 | ||
# -*- coding: utf-8 -*- | ||
# File name : ipsourcebypass.py | ||
# Author : Podalirius (@podalirius_) | ||
# Date created : 10 Oct 2021 | ||
|
||
import argparse | ||
import sys | ||
from concurrent.futures import ThreadPoolExecutor | ||
import requests | ||
from rich.console import Console | ||
from rich import box | ||
from rich.table import Table | ||
import json | ||
from http.cookies import SimpleCookie | ||
|
||
banner = "[~] IP source bypass using HTTP headers, v1.1\n" | ||
|
||
BYPASS_HEADERS = [ | ||
'Access-Control-Allow-Origin', 'Client-IP', 'Forwarded', 'Forwarded-For', 'Forwarded-For-IP', 'Origin', | ||
'X-Client-IP', 'X-Custom-IP-Authorization', 'X-Forwarded', 'X-Forwarded-By', 'X-Forwarded-For', | ||
'X-Forwarded-For-Original', 'X-Forwarded-Host', 'X-Forwarder-For', 'X-Originating-IP', 'X-Remote-Addr', | ||
'X-Remote-IP' | ||
] | ||
|
||
|
||
def test_bypass(options, proxies, results, header_name, header_value): | ||
try: | ||
r = requests.get( | ||
url=options.url, | ||
verify=options.verify, # this is to set the client to accept insecure servers | ||
proxies=proxies, | ||
allow_redirects=options.redirect, | ||
stream=True, # this is to prevent the download of huge files, focus on the request, not on the data, | ||
headers={header_name: header_value} | ||
) | ||
except requests.exceptions.ProxyError: | ||
print("[!] Invalid proxy specified") | ||
raise SystemExit | ||
if options.verbose == True: | ||
print("[!] Obtained results: [%d] length : %d bytes" %(r.status_code, len(r.content))) | ||
|
||
results[header_name] = {"status_code": r.status_code, "length": len(r.text), "header": "%s: %s" % (header_name, header_value)} | ||
|
||
def print_results(console, results): | ||
if options.verbose == True: | ||
print("[>] Parsing & printing results") | ||
table = Table(show_header=True, header_style="bold blue", border_style="blue", box=box.SIMPLE) | ||
table.add_column("Length") | ||
table.add_column("Status code") | ||
table.add_column("Header") | ||
|
||
# Choose colors for uncommon lengths | ||
lengths = [result[1]["length"] for result in results.items()] | ||
lengths = [(len([1 for result in results.items() if result[1]["length"]==l]), l) for l in list(set(lengths))] | ||
|
||
if len(lengths) == 2: | ||
for result in results.items(): | ||
if result[1]["length"] == min(lengths)[1]: | ||
style = "green" | ||
elif result[1]["length"] == max(lengths)[1]: | ||
style = "red" | ||
table.add_row(str(result[1]["length"]), str(result[1]["status_code"]), result[1]["header"], style=style) | ||
elif len(lengths) <= 4: | ||
scale = ["red", "orange3", "yellow3", "green"] | ||
colors = {str(sorted(lengths, reverse=True)[k][1]):scale[k] for k in range(len(lengths))} | ||
for result in results.items(): | ||
style = colors[str(result[1]["length"])] | ||
table.add_row(str(result[1]["length"]), str(result[1]["status_code"]), result[1]["header"], style=style) | ||
else: | ||
for result in results.items(): | ||
style = "orange3" | ||
table.add_row(str(result[1]["length"]), str(result[1]["status_code"]), result[1]["header"], style=style) | ||
console.print(table) | ||
|
||
|
||
def parseArgs(): | ||
description = "This Python script can be used to test for IP source bypass using HTTP headers" | ||
parser = argparse.ArgumentParser( | ||
description=description, | ||
formatter_class=argparse.RawTextHelpFormatter, | ||
) | ||
parser.add_argument( | ||
"url", | ||
help="e.g. https://example.com:port/path" | ||
) | ||
parser.add_argument("-v", "--verbose", default=None, action="store_true", help='arg1 help message') | ||
parser.add_argument("-i", "--ip", dest="ip", required=True, help="IP to spoof.") | ||
parser.add_argument("-t", "--threads", dest="threads", action="store", type=int, default=5, required=False, help="Number of threads (default: 5)") | ||
parser.add_argument('-x', '--proxy', action="store", default=None, dest='proxy', help="Specify a proxy to use for requests (e.g., http://localhost:8080)") | ||
parser.add_argument("-k", "--insecure", dest="verify", action="store_false", default=True, required=False, help="Allow insecure server connections when using SSL (default: False)") | ||
parser.add_argument("-L", "--location", dest="redirect", action="store_true", default=False, required=False, help="Follow redirects (default: False)") | ||
parser.add_argument("-j", "--jsonfile", dest="jsonfile", default=None, required=False, help="Save results to specified JSON file.") | ||
return parser.parse_args() | ||
|
||
|
||
if __name__ == '__main__': | ||
print(banner) | ||
|
||
options = parseArgs() | ||
try: | ||
console = Console() | ||
# Verifying the proxy option | ||
if options.proxy: | ||
try: | ||
proxies = { | ||
"http": "http://" + options.proxy.split('//')[1], | ||
"https": "http://" + options.proxy.split('//')[1] | ||
} | ||
if options.verbose == True: | ||
print("[debug] Setting proxies to %s" % str(proxies)) | ||
except (IndexError, ValueError): | ||
print("[!] Invalid proxy specified.") | ||
sys.exit(1) | ||
else: | ||
if options.verbose == True: | ||
print("[debug] Setting proxies to 'None'") | ||
proxies = None | ||
|
||
if not options.verify: | ||
# Disable warings of insecure connection for invalid cerificates | ||
requests.packages.urllib3.disable_warnings() | ||
# Allow use of deprecated and weak cipher methods | ||
requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS += ':HIGH:!DH:!aNULL' | ||
try: | ||
requests.packages.urllib3.contrib.pyopenssl.util.ssl_.DEFAULT_CIPHERS += ':HIGH:!DH:!aNULL' | ||
except AttributeError: | ||
pass | ||
|
||
results = {} | ||
# Waits for all the threads to be completed | ||
with ThreadPoolExecutor(max_workers=min(options.threads, len(BYPASS_HEADERS))) as tp: | ||
for bph in BYPASS_HEADERS: | ||
tp.submit(test_bypass, options, proxies, results, bph, options.ip) | ||
|
||
# Sorting the results by method name | ||
results = {key: results[key] for key in sorted(results, key=lambda key:results[key]["length"])} | ||
|
||
# Parsing and print results | ||
print_results(console, results) | ||
|
||
# Export to JSON if specified | ||
if options.jsonfile is not None: | ||
f = open(options.jsonfile, "w") | ||
f.write(json.dumps(results, indent=4) + "\n") | ||
f.close() | ||
|
||
except KeyboardInterrupt: | ||
print("[+] Terminating script...") | ||
raise SystemExit |