bhp-pro 1.3.0__py3-none-any.whl → 1.3.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bhp_pro
3
- Version: 1.3.0
3
+ Version: 1.3.2
4
4
  Summary: Web Enumeration Tool
5
5
  Author: ssskingsss12
6
6
  Author-email: smalls3000i@gmail.com
@@ -0,0 +1,6 @@
1
+ bhp_pro.py,sha256=i5J-aBNaC14n76DYyym6cs2BBkHF7kT_cLImMl1zb38,777565
2
+ bhp_pro-1.3.2.dist-info/METADATA,sha256=p5i7atVTfveV5iPPzgiUMtczuAsgD6xN-sDAzPCGT_E,600
3
+ bhp_pro-1.3.2.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
4
+ bhp_pro-1.3.2.dist-info/entry_points.txt,sha256=Yn3HpraGX3lXX4FPq3Gm-lHh3SwQA-5rtgPWNWMFXkw,41
5
+ bhp_pro-1.3.2.dist-info/top_level.txt,sha256=1xjbIaVM77UJz9Tsi1JjILgE0YDG7iLhY6KSMNEi9zM,8
6
+ bhp_pro-1.3.2.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
bhp_pro.py CHANGED
@@ -16875,89 +16875,696 @@ def menu3():
16875
16875
  #===SUBDOmain TAKEOVER===#
16876
16876
  def access_control():
16877
16877
 
16878
- generate_ascii_banner("ACCESS", "CONTROL")
16879
- THREAD_COUNT = 100
16880
-
16881
- LOCK = threading.Lock()
16882
- user_input = input("Enter a domain or .txt file: ").strip()
16883
- OUTPUT_FILE = input("Enter output file name (default is x_requested_with_results.txt): ").strip() or "x_requested_with_results.txt"
16884
- def check_domain(domain, progress):
16885
- preflight_headers = {
16886
- 'Origin': 'https://yahoo.com/',
16887
- 'Access-Control-Request-Method': 'GET',
16888
- 'Access-Control-Request-Headers': 'X-Requested-With, X-Online-Host, X-Forwarded-For',
16889
- 'User-Agent': 'Mozilla/5.0'
16890
- }
16891
-
16892
- for protocol in ['http://', 'https://']:
16893
- url = protocol + domain
16894
- try:
16895
- response = requests.options(url, headers=preflight_headers, timeout=5)
16896
- status = response.status_code
16897
- allowed_headers = response.headers.get('Access-Control-Allow-Headers', '').lower()
16898
-
16899
- allowed = []
16900
- if 'x-requested-with' in allowed_headers:
16901
- allowed.append('X-Requested-With')
16902
- if 'x-online-host' in allowed_headers:
16903
- allowed.append('X-Online-Host')
16904
- if 'x-forwarded-for' in allowed_headers:
16905
- allowed.append('X-Forwarded-For')
16906
-
16907
- if allowed:
16908
- server = response.headers.get('Server', 'Unknown')
16909
- print(f"✅ {url} - ALLOWS: {', '.join(allowed)} | Status: {status}")
16910
- with LOCK:
16911
- with open(OUTPUT_FILE, "a") as f:
16912
- f.write(f"{url} | Status: {status} | Server: {server} | Allowed Headers: {', '.join(allowed)}\n")
16913
- else:
16914
- print(f"⚠️ {url} - None of the desired X-* headers allowed.")
16915
-
16916
- except requests.exceptions.RequestException as e:
16917
- print(f"❌ {url} - Request failed: {e}")
16918
- finally:
16919
- with LOCK:
16920
- progress.update(1)
16921
-
16922
-
16923
- def worker(domain_queue, progress):
16924
- while not domain_queue.empty():
16925
- domain = domain_queue.get()
16926
- check_domain(domain, progress)
16927
- domain_queue.task_done()
16878
+ import os
16879
+ import re
16880
+ import socket
16881
+ import time
16882
+ import threading
16883
+ import ipaddress
16884
+ from queue import Queue
16885
+ from tqdm import tqdm
16928
16886
 
16929
- def access_main():
16887
+ FREE_SERVERS = {
16888
+ 'google': 'www.google.com',
16889
+ 'cloudflare': '1.1.1.1',
16890
+ 'open_dns': '208.67.222.222',
16891
+ 'quad9': '9.9.9.9',
16892
+ 'example': 'example.com',
16893
+ 'test_server': 'test.server.com'
16894
+ }
16930
16895
 
16896
+ XHTTP_PAYLOADS = {
16897
+ "1": {
16898
+ "name": "Standard HTTP/1.1",
16899
+ "payload": "GET / HTTP/1.1\r\nHost: [HOST]\r\nUser-Agent: [UA]\r\nAccept: */*\r\nConnection: keep-alive\r\n\r\n",
16900
+ "type": "XHTTP"
16901
+ },
16902
+ "2": {
16903
+ "name": "HTTP/1.1 Keep-Alive",
16904
+ "payload": "GET / HTTP/1.1\r\nHost: [HOST]\r\nUser-Agent: [UA]\r\nConnection: Keep-Alive\r\nKeep-Alive: timeout=30\r\n\r\n",
16905
+ "type": "XHTTP"
16906
+ },
16907
+ "3": {
16908
+ "name": "Chrome User-Agent",
16909
+ "payload": "GET / HTTP/1.1\r\nHost: [HOST]\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nAccept-Language: en-US,en;q=0.9\r\nAccept-Encoding: gzip, deflate\r\nConnection: keep-alive\r\n\r\n",
16910
+ "type": "XHTTP"
16911
+ },
16912
+ "4": {
16913
+ "name": "CONNECT Method",
16914
+ "payload": "CONNECT [HOST]:443 HTTP/1.1\r\nHost: [HOST]:443\r\nUser-Agent: [UA]\r\nProxy-Connection: Keep-Alive\r\n\r\n",
16915
+ "type": "XHTTP"
16916
+ },
16917
+ "5": {
16918
+ "name": "X-Online-Host Injection",
16919
+ "payload": f"GET / HTTP/1.1\r\nHost: [HOST]\r\nX-Online-Host: {FREE_SERVERS['google']}\r\nUser-Agent: [UA]\r\n\r\n",
16920
+ "type": "XHTTP"
16921
+ },
16922
+ "6": {
16923
+ "name": "X-Forwarded-Host Injection",
16924
+ "payload": f"GET / HTTP/1.1\r\nHost: [HOST]\r\nX-Forwarded-Host: {FREE_SERVERS['example']}\r\nUser-Agent: [UA]\r\n\r\n",
16925
+ "type": "XHTTP"
16926
+ },
16927
+ "7": {
16928
+ "name": "Simple POST Request",
16929
+ "payload": "POST / HTTP/1.1\r\nHost: [HOST]\r\nUser-Agent: [UA]\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: 0\r\n\r\n",
16930
+ "type": "XHTTP"
16931
+ },
16932
+ "8": {
16933
+ "name": "HTTP/2 Preface",
16934
+ "payload": "GET / HTTP/1.1\r\nHost: [HOST]\r\nUser-Agent: [UA]\r\nUpgrade: h2c\r\nHTTP2-Settings: AAEAAEAAAAIAAAABAAMAAABkAAQBAAAAAAUAAEAA\r\nConnection: Upgrade, HTTP2-Settings\r\n\r\n",
16935
+ "type": "XHTTP"
16936
+ },
16937
+ "9": {
16938
+ "name": "Mobile Safari UA",
16939
+ "payload": "GET / HTTP/1.1\r\nHost: [HOST]\r\nUser-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nAccept-Language: en-US,en;q=0.9\r\n\r\n",
16940
+ "type": "XHTTP"
16941
+ },
16942
+ "10": {
16943
+ "name": "No Cache Headers",
16944
+ "payload": "GET / HTTP/1.1\r\nHost: [HOST]\r\nUser-Agent: [UA]\r\nCache-Control: no-cache, no-store, must-revalidate\r\nPragma: no-cache\r\nExpires: 0\r\n\r\n",
16945
+ "type": "XHTTP"
16946
+ },
16947
+ "11": {
16948
+ "name": "Double Host Header",
16949
+ "payload": f"GET / HTTP/1.1\r\nHost: [HOST]\r\nHost: {FREE_SERVERS['example']}\r\nUser-Agent: [UA]\r\n\r\n",
16950
+ "type": "XHTTP"
16951
+ },
16952
+ "12": {
16953
+ "name": "WebSocket Upgrade",
16954
+ "payload": "GET / HTTP/1.1\r\nHost: [HOST]\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Key: [KEY]\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Extensions: permessage-deflate; client_max_window_bits\r\n\r\n",
16955
+ "type": "WS"
16956
+ },
16957
+ "13": {
16958
+ "name": "Google Bot UA",
16959
+ "payload": "GET / HTTP/1.1\r\nHost: [HOST]\r\nUser-Agent: Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; Googlebot/2.1; +http://www.google.com/bot.html) Chrome/120.0.0.0 Safari/537.36\r\n\r\n",
16960
+ "type": "XHTTP"
16961
+ },
16962
+ "14": {
16963
+ "name": "Forwarded Headers",
16964
+ "payload": f"GET / HTTP/1.1\r\nHost: [HOST]\r\nUser-Agent: [UA]\r\nForwarded: for=192.168.1.1;proto=http;host={FREE_SERVERS['test_server']}\r\nX-Forwarded-For: 192.168.1.1\r\nX-Real-IP: 192.168.1.1\r\n\r\n",
16965
+ "type": "XHTTP"
16966
+ },
16967
+ "15": {
16968
+ "name": "Pipelined Request",
16969
+ "payload": "GET / HTTP/1.1\r\nHost: [HOST]\r\n\r\nGET /favicon.ico HTTP/1.1\r\nHost: [HOST]\r\n\r\n",
16970
+ "type": "XHTTP"
16971
+ }
16972
+ }
16931
16973
 
16932
- if os.path.isfile(user_input) and user_input.endswith('.txt'):
16933
- with open(user_input, 'r') as file:
16934
- domains = [line.strip() for line in file if line.strip()]
16935
- else:
16936
- domains = [user_input]
16974
+ class Config:
16975
+ def __init__(self):
16976
+ self.payloads = []
16977
+ self.targets = []
16978
+ self.proxies = []
16979
+ self.output_file = "working_configs.txt"
16980
+ self.timeout = 3
16981
+ self.threads = 50
16982
+
16983
+ class PayloadManager:
16984
+ @staticmethod
16985
+ def generate_websocket_key():
16986
+ import base64, os
16987
+ return base64.b64encode(os.urandom(16)).decode()
16988
+
16989
+ @staticmethod
16990
+ def prepare_payload(payload_template, target_domain):
16991
+ replacements = {
16992
+ '[HOST]': target_domain,
16993
+ '[UA]': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
16994
+ '[KEY]': PayloadManager.generate_websocket_key()
16995
+ }
16996
+ payload = payload_template
16997
+ for placeholder, value in replacements.items():
16998
+ payload = payload.replace(placeholder, value)
16999
+ return payload
17000
+
17001
+ @staticmethod
17002
+ def format_config(result):
17003
+ escaped_payload = result['sent_payload'].replace('\r\n', '[crlf]')
17004
+ return f"""# ====================================================
17005
+ # CONFIG #{result['config_id']}
17006
+ # ====================================================
17007
+ [CONFIG]
17008
+ Name={result['payload_name']} | {result['status_code']} | {result['proxy_host']}:{result['proxy_port']}
17009
+ Server={result['proxy_host']}
17010
+ Port={result['proxy_port']}
17011
+ Protocol=XHTTP
17012
+ SNI={result['target']}
17013
+ ProxyType=HTTP
17014
+
17015
+ [PAYLOAD]
17016
+ {escaped_payload}
17017
+
17018
+ [HEADERS]
17019
+ User-Agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36
17020
+ Accept=*/*
17021
+ Accept-Language=en-US,en;q=0.9
17022
+ Accept-Encoding=gzip, deflate
17023
+ Connection=keep-alive
17024
+
17025
+ [SETTINGS]
17026
+ ForwardHost=true
17027
+ UseSNI=true
17028
+
17029
+ [TEST_INFO]
17030
+ Date={time.strftime("%Y-%m-%d %H:%M:%S")}
17031
+ Target={result['target']}
17032
+ Status=HTTP {result['status_code']}
17033
+ Response_Time={result['response_time']:.2f}s
17034
+ Server={result['server']}
17035
+ Bypass_Indicators={','.join(result['bypass_indicators'])}
17036
+ # ====================================================
16937
17037
 
16938
- if os.path.exists(OUTPUT_FILE):
16939
- os.remove(OUTPUT_FILE)
17038
+ """
17039
+
17040
+ @staticmethod
17041
+ def save_results(results, filename, status_filter='All'):
17042
+ if not results:
17043
+ return 0
17044
+
17045
+ with open(filename, 'w', encoding='utf-8') as f:
17046
+ f.write(f"""# HTTP Injector Configurations
17047
+ # Generated: {time.strftime('%Y-%m-%d %H:%M:%S')}
17048
+ # Total Configs: {len(results)}
17049
+ # Status Filter: {status_filter}
17050
+ #
17051
+ # HOW TO USE:
17052
+ # 1. Copy each [CONFIG] section
17053
+ # 2. Create new config in HTTP Injector
17054
+ # 3. Paste the settings
17055
+ # ====================================================
16940
17056
 
16941
- domain_queue = Queue()
16942
- for domain in domains:
16943
- domain_queue.put(domain)
17057
+ """)
17058
+ f.write("[SUMMARY]\n")
17059
+ f.write(f"Total_Configs={len(results)}\n")
17060
+ f.write(f"Status_Filter={status_filter}\n")
17061
+
17062
+ status_stats = {}
17063
+ for result in results:
17064
+ status = result['status_code']
17065
+ status_category = f"{status//100}xx"
17066
+ status_stats[status_category] = status_stats.get(status_category, 0) + 1
17067
+
17068
+ f.write("\n[STATUS_DISTRIBUTION]\n")
17069
+ for status, count in sorted(status_stats.items()):
17070
+ f.write(f"{status}={count}\n")
17071
+
17072
+ f.write(f"\n#{'='*50}\n# WORKING CONFIGURATIONS\n#{'='*50}\n\n")
17073
+
17074
+ for i, result in enumerate(results, 1):
17075
+ result['config_id'] = i
17076
+ f.write(PayloadManager.format_config(result))
17077
+
17078
+ return len(results)
16944
17079
 
16945
- progress = tqdm(total=len(domains) * 2, desc="Checking", ncols=80)
17080
+ class ProxyManager:
17081
+ @staticmethod
17082
+ def parse_proxy_input(proxy_input, ports):
17083
+ proxies = []
17084
+
17085
+ if ':' in proxy_input:
17086
+ ip_part, port = proxy_input.split(':', 1)
17087
+ port = int(port)
17088
+
17089
+ if '/' in ip_part:
17090
+ try:
17091
+ network = ipaddress.ip_network(ip_part, strict=False)
17092
+ for ip in network.hosts():
17093
+ proxies.append((str(ip), port))
17094
+ except:
17095
+ pass
17096
+ else:
17097
+ proxies.append((ip_part, port))
17098
+ return proxies
17099
+
17100
+ if '/' in proxy_input:
17101
+ try:
17102
+ network = ipaddress.ip_network(proxy_input, strict=False)
17103
+ for ip in network.hosts():
17104
+ for port in ports:
17105
+ proxies.append((str(ip), port))
17106
+ except:
17107
+ pass
17108
+ return proxies
17109
+
17110
+ if '-' in proxy_input:
17111
+ parts = proxy_input.split('-')
17112
+ if len(parts) == 2:
17113
+ base_ip = parts[0].rsplit('.', 1)[0]
17114
+ start = int(parts[0].rsplit('.', 1)[1])
17115
+ end = int(parts[1])
17116
+
17117
+ for i in range(start, end + 1):
17118
+ ip = f"{base_ip}.{i}"
17119
+ for port in ports:
17120
+ proxies.append((ip, port))
17121
+ return proxies
17122
+
17123
+ for port in ports:
17124
+ proxies.append((proxy_input.strip(), port))
17125
+
17126
+ return proxies
16946
17127
 
16947
- threads = []
16948
- for _ in range(THREAD_COUNT):
16949
- t = threading.Thread(target=worker, args=(domain_queue, progress))
16950
- t.start()
16951
- threads.append(t)
17128
+ class NetworkTester:
17129
+ def __init__(self, config):
17130
+ self.config = config
17131
+ self.working_configs = []
17132
+ self.lock = threading.Lock()
17133
+ self.queue = Queue()
17134
+ self.tested = 0
17135
+ self.successful = 0
17136
+ self.failed = 0
17137
+
17138
+ def detect_provider(self, response_text, target):
17139
+ provider_indicators = {
17140
+ 'Google': ['Google', 'gws', 'GSE', 'YouTube'],
17141
+ 'Microsoft': ['Microsoft', 'IIS', 'Azure', 'Office'],
17142
+ 'Facebook': ['Facebook', 'fb', 'Instagram'],
17143
+ 'Cloudflare': ['Cloudflare', 'CF-RAY', 'cf-cache-status'],
17144
+ 'Akamai': ['Akamai', 'Akamai-Ghost'],
17145
+ 'Amazon': ['Amazon', 'AWS', 'CloudFront', 'S3'],
17146
+ 'Alibaba': ['Alibaba', 'Aliyun', 'EMAS', 'AlibabaCloud'],
17147
+ 'Tencent': ['Tencent', 'QCloud', 'TCB'],
17148
+ 'Baidu': ['Baidu', 'baidu.com'],
17149
+ 'Fastly': ['Fastly', 'Fastly error'],
17150
+ 'CDN77': ['CDN77', 'NetDNA'],
17151
+ 'Cloudflare': ['Cloudflare', 'CF-RAY'],
17152
+ 'Nginx': ['nginx'],
17153
+ 'Apache': ['Apache', 'httpd'],
17154
+ 'LiteSpeed': ['LiteSpeed', 'LSWS'],
17155
+ 'Varnish': ['Varnish'],
17156
+ 'Sucuri': ['Sucuri'],
17157
+ 'Imperva': ['Imperva', 'Imperva Incapsula']
17158
+ }
17159
+
17160
+ for provider, indicators in provider_indicators.items():
17161
+ for indicator in indicators:
17162
+ if indicator.lower() in response_text.lower():
17163
+ return provider
17164
+
17165
+ return 'Unknown'
17166
+
17167
+ def test_connection(self, payload_info, target, proxy_host, proxy_port):
17168
+ try:
17169
+ sent_payload = PayloadManager.prepare_payload(payload_info['payload'], target)
17170
+
17171
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
17172
+ sock.settimeout(self.config.timeout)
17173
+
17174
+ start_time = time.time()
17175
+ sock.connect((proxy_host, proxy_port))
17176
+ sock.send(sent_payload.encode())
17177
+
17178
+ response = b""
17179
+ try:
17180
+ sock.settimeout(self.config.timeout)
17181
+ while True:
17182
+ chunk = sock.recv(1024)
17183
+ if not chunk:
17184
+ break
17185
+ response += chunk
17186
+ if len(response) > 8192:
17187
+ break
17188
+ except socket.timeout:
17189
+ pass
17190
+
17191
+ sock.close()
17192
+ response_time = time.time() - start_time
17193
+
17194
+ response_text = response.decode('utf-8', errors='ignore')
17195
+
17196
+ status_match = re.search(r'HTTP/\d\.\d\s+(\d{3})', response_text)
17197
+ status_code = int(status_match.group(1)) if status_match else 0
17198
+
17199
+ if status_code == 0:
17200
+ return {'success': False, 'error': 'No HTTP response'}
17201
+
17202
+ server_match = re.search(r'Server:\s*([^\r\n]+)', response_text, re.IGNORECASE)
17203
+ server_info = server_match.group(1) if server_match else "Unknown"
17204
+
17205
+ bypass_indicators = self._check_bypass_indicators(response_text)
17206
+ provider = self.detect_provider(response_text, target)
17207
+
17208
+ return {
17209
+ 'payload_name': payload_info['name'],
17210
+ 'payload_template': payload_info['payload'],
17211
+ 'sent_payload': sent_payload,
17212
+ 'target': target,
17213
+ 'proxy_host': proxy_host,
17214
+ 'proxy_port': proxy_port,
17215
+ 'status_code': status_code,
17216
+ 'response_time': response_time,
17217
+ 'server': server_info,
17218
+ 'bypass_indicators': bypass_indicators,
17219
+ 'provider': provider,
17220
+ 'success': True
17221
+ }
17222
+
17223
+ except socket.timeout:
17224
+ return {'success': False, 'error': 'Connection timeout'}
17225
+ except ConnectionRefusedError:
17226
+ return {'success': False, 'error': 'Connection refused'}
17227
+ except Exception as e:
17228
+ return {'success': False, 'error': str(e)}
17229
+
17230
+ def _check_bypass_indicators(self, response_text):
17231
+ indicators = []
17232
+ checks = [
17233
+ (r'CF-RAY', 'Cloudflare Proxy'),
17234
+ (r'X-Cache', 'Caching Proxy'),
17235
+ (r'Connection established', 'CONNECT Successful'),
17236
+ (r'101 Switching Protocols', 'WebSocket Upgrade'),
17237
+ (r'HTTP/1.1 200.*HTTP/1.1', 'Request Smuggling'),
17238
+ (r'Upgrade:', 'Protocol Upgrade'),
17239
+ (r'Keep-Alive', 'Connection Persistence'),
17240
+ (r'X-Forwarded-For', 'Forwarded Request'),
17241
+ (r'X-Real-IP', 'Real IP Header'),
17242
+ (r'X-Forwarded-Host', 'Host Bypass'),
17243
+ (r'X-Original-Host', 'Original Host'),
17244
+ (r'Via:', 'Proxy Chain'),
17245
+ (r'Proxy-Connection', 'Proxy Support'),
17246
+ (r'Transfer-Encoding: chunked', 'Chunked Encoding'),
17247
+ (r'Content-Encoding: gzip', 'Compression Support'),
17248
+ (r'Server:.*nginx', 'Nginx Server'),
17249
+ (r'Server:.*Apache', 'Apache Server'),
17250
+ (r'Set-Cookie', 'Session Cookie'),
17251
+ (r'Vary:', 'Cache Variation'),
17252
+ (r'Age:', 'Cache Age')
17253
+ ]
17254
+
17255
+ for pattern, meaning in checks:
17256
+ if re.search(pattern, response_text, re.IGNORECASE | re.DOTALL):
17257
+ indicators.append(meaning)
17258
+
17259
+ return indicators
17260
+
17261
+ def worker(self, progress_bar):
17262
+ while True:
17263
+ try:
17264
+ task = self.queue.get_nowait()
17265
+ except:
17266
+ break
17267
+
17268
+ try:
17269
+ payload_info, target, proxy_host, proxy_port = task
17270
+ result = self.test_connection(payload_info, target, proxy_host, proxy_port)
17271
+
17272
+ with self.lock:
17273
+ self.tested += 1
17274
+
17275
+ if result['success']:
17276
+ self.successful += 1
17277
+ self.working_configs.append(result)
17278
+
17279
+ icon = "✅" if 200 <= result['status_code'] < 300 else \
17280
+ "↪️" if 300 <= result['status_code'] < 400 else \
17281
+ "⚠️" if 400 <= result['status_code'] < 500 else "❌"
17282
+
17283
+ if result['bypass_indicators']:
17284
+ icon += "🚀"
17285
+
17286
+ provider_icon = {
17287
+ 'Google': '🔍',
17288
+ 'Microsoft': '🪟',
17289
+ 'Facebook': '👥',
17290
+ 'YouTube': '📺',
17291
+ 'Amazon': '📦',
17292
+ 'Cloudflare': '🛡️'
17293
+ }.get(result['provider'], '🌐')
17294
+
17295
+ print(f"\r{icon}{provider_icon} {result['payload_name'][:20]:20} → "
17296
+ f"{target[:15]:15} HTTP {result['status_code']:3} via {proxy_host}:{proxy_port}")
17297
+ else:
17298
+ self.failed += 1
17299
+
17300
+ progress_bar.update(1)
17301
+ self.queue.task_done()
17302
+
17303
+ except Exception as e:
17304
+ with self.lock:
17305
+ self.tested += 1
17306
+ self.failed += 1
17307
+ progress_bar.update(1)
17308
+ self.queue.task_done()
17309
+
17310
+ def run_tests(self):
17311
+ tasks = []
17312
+ for payload_info in self.config.payloads:
17313
+ for target in self.config.targets:
17314
+ if self.config.proxies:
17315
+ for proxy_host, proxy_port in self.config.proxies:
17316
+ tasks.append((payload_info, target, proxy_host, proxy_port))
17317
+ else:
17318
+ tasks.append((payload_info, target, target, 80))
17319
+
17320
+ for task in tasks:
17321
+ self.queue.put(task)
17322
+
17323
+ total_tests = len(tasks)
17324
+
17325
+ print(f"\n{'='*60}")
17326
+ print(f"🧪 TESTING CONFIGURATION")
17327
+ print(f"{'='*60}")
17328
+ print(f"Payloads: {len(self.config.payloads)}")
17329
+ print(f"Targets: {len(self.config.targets)}")
17330
+ print(f"Proxies: {len(self.config.proxies) if self.config.proxies else 'Direct'}")
17331
+ print(f"Total Tests: {total_tests}")
17332
+ print(f"Threads: {min(self.config.threads, total_tests)}")
17333
+ print(f"{'='*60}")
17334
+
17335
+ print("\n📡 TESTING IN PROGRESS...\n")
17336
+
17337
+ thread_count = min(self.config.threads, total_tests, 100)
17338
+
17339
+ self.working_configs = []
17340
+ self.tested = 0
17341
+ self.successful = 0
17342
+ self.failed = 0
17343
+
17344
+ with tqdm(total=total_tests, desc="Testing", unit="test", ncols=80) as progress_bar:
17345
+ threads = []
17346
+ for _ in range(thread_count):
17347
+ t = threading.Thread(target=self.worker, args=(progress_bar,))
17348
+ t.daemon = True
17349
+ t.start()
17350
+ threads.append(t)
17351
+
17352
+ for t in threads:
17353
+ t.join()
17354
+
17355
+ print("\r" + " " * 80 + "\r", end="")
17356
+
17357
+ print(f"\n{'='*60}")
17358
+ print(f"✅ TESTING COMPLETE")
17359
+ print(f"{'='*60}")
17360
+ print(f"Tests Completed: {self.tested}")
17361
+ print(f"Successful: {self.successful}")
17362
+ print(f"Failed: {self.failed}")
17363
+ print(f"Configs Found: {len(self.working_configs)}")
17364
+
17365
+ return self.working_configs
16952
17366
 
16953
- for t in threads:
16954
- t.join()
17367
+ def get_user_input():
17368
+ config = Config()
17369
+
17370
+ print("\n📋 AVAILABLE PAYLOADS:")
17371
+ for key, info in XHTTP_PAYLOADS.items():
17372
+ print(f"{key:>2}. {info['name']:25} [{info['type']:6}]")
17373
+
17374
+ selection = input("\nSelect payloads (comma-separated, or 'all'): ").strip()
17375
+
17376
+ if selection.lower() == 'all':
17377
+ selected_keys = list(XHTTP_PAYLOADS.keys())
17378
+ else:
17379
+ selected_keys = [s.strip() for s in selection.split(',') if s.strip() in XHTTP_PAYLOADS]
17380
+
17381
+ if not selected_keys:
17382
+ print("❌ No payloads selected!")
17383
+ return None
17384
+
17385
+ for key in selected_keys:
17386
+ config.payloads.append(XHTTP_PAYLOADS[key])
17387
+
17388
+ print(f"\n✅ Selected {len(config.payloads)} payloads")
17389
+
17390
+ targets_input = input("\nEnter target domain(s) (comma-separated or file): ").strip()
17391
+
17392
+ if os.path.isfile(targets_input):
17393
+ with open(targets_input, 'r') as f:
17394
+ config.targets = [line.strip() for line in f if line.strip()]
17395
+ else:
17396
+ config.targets = [t.strip() for t in targets_input.split(',') if t.strip()]
17397
+
17398
+ if not config.targets:
17399
+ print("❌ No targets specified!")
17400
+ return None
17401
+
17402
+ print("\n🔄 PROXY SETTINGS")
17403
+ print("1. Use proxies")
17404
+ print("2. Direct connection")
17405
+
17406
+ proxy_choice = input("\nSelect option (1-2): ").strip()
17407
+
17408
+ if proxy_choice == '1':
17409
+ proxy_input = input("Enter proxy (IP, IP:PORT, CIDR, or IP range): ").strip()
17410
+
17411
+ ports_input = input("Ports (default=80,443,8080,8443): ").strip()
17412
+ ports = [int(p.strip()) for p in ports_input.split(',') if p.strip().isdigit()] if ports_input else [80, 443, 8080, 8443]
17413
+
17414
+ config.proxies = ProxyManager.parse_proxy_input(proxy_input, ports)
17415
+
17416
+ if not config.proxies:
17417
+ print("❌ Invalid proxy input!")
17418
+ return None
17419
+
17420
+ print(f"✅ Loaded {len(config.proxies)} proxies")
17421
+
17422
+ return config
16955
17423
 
16956
- progress.close()
16957
- print(f"\n✅ Finished checking. Results saved to {OUTPUT_FILE}")
17424
+ def show_status_distribution(working_configs):
17425
+ status_details = {}
17426
+ for config in working_configs:
17427
+ status = config['status_code']
17428
+ status_details[status] = status_details.get(status, 0) + 1
17429
+
17430
+ print(f"\n{'='*60}")
17431
+ print("📊 STATUS CODE DISTRIBUTION")
17432
+ print(f"{'='*60}")
17433
+
17434
+ for status, count in sorted(status_details.items()):
17435
+ print(f" HTTP {status}: {count} configs")
17436
+
17437
+ print(f"\n{'='*60}")
17438
+ print("💾 SAVE RESULTS")
17439
+ print(f"{'='*60}")
17440
+ print("Which status codes to save?")
17441
+ print("1. All status codes")
17442
+ print("2. Only 2xx (Success)")
17443
+ print("3. Only 3xx (Redirection)")
17444
+ print("4. Only 4xx (Client Error)")
17445
+ print("5. Only 5xx (Server Error)")
17446
+ print("6. Success (2xx and 3xx)")
17447
+
17448
+ while True:
17449
+ choice = input("\nSelect option (1-6): ").strip()
17450
+
17451
+ if choice in ['1', '2', '3', '4', '5', '6']:
17452
+ status_filter_map = {
17453
+ '1': 'all',
17454
+ '2': '2xx',
17455
+ '3': '3xx',
17456
+ '4': '4xx',
17457
+ '5': '5xx',
17458
+ '6': 'success'
17459
+ }
17460
+ status_filter = status_filter_map[choice]
17461
+
17462
+ if choice == '2' and not any(200 <= s < 300 for s in status_details.keys()):
17463
+ print("⚠️ No 2xx responses found!")
17464
+ continue
17465
+ elif choice == '3' and not any(300 <= s < 400 for s in status_details.keys()):
17466
+ print("⚠️ No 3xx responses found!")
17467
+ continue
17468
+ elif choice == '4' and not any(400 <= s < 500 for s in status_details.keys()):
17469
+ print("⚠️ No 4xx responses found!")
17470
+ continue
17471
+ elif choice == '5' and not any(500 <= s < 600 for s in status_details.keys()):
17472
+ print("⚠️ No 5xx responses found!")
17473
+ continue
17474
+ elif choice == '6' and not any(200 <= s < 400 for s in status_details.keys()):
17475
+ print("⚠️ No success responses found!")
17476
+ continue
17477
+ elif choice == '':
17478
+ print("⚠️ Back to main menu.")
17479
+ continue
17480
+
17481
+ return status_filter
17482
+ else:
17483
+ print("❌ Invalid option!")
17484
+
17485
+ def save_with_filter(results, filename, status_filter):
17486
+ if not results:
17487
+ return 0
17488
+
17489
+ if status_filter == 'all':
17490
+ filtered_results = results
17491
+ elif status_filter == '2xx':
17492
+ filtered_results = [r for r in results if 200 <= r['status_code'] < 300]
17493
+ elif status_filter == '3xx':
17494
+ filtered_results = [r for r in results if 300 <= r['status_code'] < 400]
17495
+ elif status_filter == '4xx':
17496
+ filtered_results = [r for r in results if 400 <= r['status_code'] < 500]
17497
+ elif status_filter == '5xx':
17498
+ filtered_results = [r for r in results if 500 <= r['status_code'] < 600]
17499
+ elif status_filter == 'success':
17500
+ filtered_results = [r for r in results if 200 <= r['status_code'] < 400]
17501
+ else:
17502
+ filtered_results = results
17503
+
17504
+ if not filtered_results:
17505
+ print(f"❌ No results matching filter: {status_filter}")
17506
+ return 0
17507
+
17508
+ return PayloadManager.save_results(filtered_results, filename, status_filter)
16958
17509
 
17510
+ def xhttp_payload_validator():
17511
+ os.system('clear' if os.name == 'posix' else 'cls')
17512
+
17513
+ banner = """
17514
+ ╔══════════════════════════════════════════════════════════╗
17515
+ ║ XHTTP TUNNEL PAYLOAD TESTER ║
17516
+ ║ Generate HTTP Injector Configs from Live Tests ║
17517
+ ╚══════════════════════════════════════════════════════════╝
17518
+ """
17519
+ print(banner)
17520
+
17521
+ config = get_user_input()
17522
+ if not config:
17523
+ return
17524
+
17525
+ estimated_tests = len(config.payloads) * len(config.targets) * max(len(config.proxies), 1)
17526
+
17527
+ print(f"\n{'='*60}")
17528
+ print("READY TO TEST")
17529
+ print(f"{'='*60}")
17530
+ print(f"Payloads: {len(config.payloads)}")
17531
+ print(f"Targets: {len(config.targets)}")
17532
+ print(f"Proxies: {len(config.proxies) if config.proxies else 'Direct'}")
17533
+ print(f"Estimated Tests: {estimated_tests}")
17534
+ print(f"{'='*60}")
17535
+
17536
+ if input("\nStart testing? (y/n): ").strip().lower() != 'y':
17537
+ print("❌ Cancelled")
17538
+ return
17539
+
17540
+ start_time = time.time()
17541
+ tester = NetworkTester(config)
17542
+ working_configs = tester.run_tests()
17543
+
17544
+ if working_configs:
17545
+ status_filter = show_status_distribution(working_configs)
17546
+
17547
+ output_file = input("\n💾 Output file (default=working_configs.txt): ").strip()
17548
+ if output_file:
17549
+ if not output_file.endswith('.txt'):
17550
+ output_file += '.txt'
17551
+ config.output_file = output_file
17552
+
17553
+ saved_count = save_with_filter(working_configs, config.output_file, status_filter)
17554
+ elapsed = time.time() - start_time
17555
+
17556
+ if saved_count > 0:
17557
+ print(f"\n{'='*60}")
17558
+ print("📦 RESULTS SAVED")
17559
+ print(f"{'='*60}")
17560
+ print(f"✅ Generated {saved_count} configs")
17561
+ print(f"📁 Output: {config.output_file}")
17562
+ print(f"⏱️ Time: {elapsed:.1f}s")
17563
+ print(f"{'='*60}")
17564
+ else:
17565
+ print("\n❌ No working configurations found!")
16959
17566
 
16960
- access_main()
17567
+ xhttp_payload_validator()
16961
17568
 
16962
17569
 
16963
17570
  def x_menu():
@@ -17058,7 +17665,7 @@ def banner():
17058
17665
  MAGENTA + "██╔═══╝ ██╔══██╗██║ ██║" + LIME + "user should understand that useage of this script may be" + ENDC,
17059
17666
  MAGENTA + "██║ ██║ ██║╚██████╔╝" + LIME + "concidered an attack on a data network, and may violate terms" + ENDC,
17060
17667
  MAGENTA + "╚═╝ ╚═╝ ╚═╝ ╚═════╝" + LIME + "of service, use on your own network or get permission first" + ENDC,
17061
- PURPLE + "script_version@ 1.3.0 ®" + ENDC,
17668
+ PURPLE + "script_version@ 1.3.2 ®" + ENDC,
17062
17669
  ORANGE + "All rights reserved 2022-2026 ♛: ®" + ENDC,
17063
17670
  MAGENTA + "In Collaboration whit Ayan Rajpoot ® " + ENDC,
17064
17671
  BLUE + "Support: https://t.me/BugScanX 💬" + ENDC,
@@ -1,6 +0,0 @@
1
- bhp_pro.py,sha256=WJ2J94cH1-qKf3AynRr8Q4t0GhzNxs2VunaQip0T7zA,748620
2
- bhp_pro-1.3.0.dist-info/METADATA,sha256=t7JildGhotdLKQG8WAcZWV-rFl9R6FhukOP2UhCNEMs,600
3
- bhp_pro-1.3.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
4
- bhp_pro-1.3.0.dist-info/entry_points.txt,sha256=Yn3HpraGX3lXX4FPq3Gm-lHh3SwQA-5rtgPWNWMFXkw,41
5
- bhp_pro-1.3.0.dist-info/top_level.txt,sha256=1xjbIaVM77UJz9Tsi1JjILgE0YDG7iLhY6KSMNEi9zM,8
6
- bhp_pro-1.3.0.dist-info/RECORD,,