From 23aabaf520990c1377167e479c8a2bf5fd18aa95 Mon Sep 17 00:00:00 2001 From: n0mad1k Date: Thu, 30 Apr 2026 16:59:24 -0400 Subject: [PATCH] Move Tor prompt before cost estimate and factor Tor latency into estimate table - Tor choice now appears before the estimate table so the displayed time/cost is accurate - build_estimate_table accepts use_tor; applies 0.2x rate multiplier for nmap/probe modes - masscan-only excluded from multiplier (masscan bypasses proxychains via raw sockets) - Added per-mode warnings explaining which traffic actually routes through Tor --- modules/webrunner/deploy_webrunner.py | 28 ++++++++++++++++----------- utils/provider_rates.py | 8 ++++++++ 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/modules/webrunner/deploy_webrunner.py b/modules/webrunner/deploy_webrunner.py index 50f9a42..20ff699 100644 --- a/modules/webrunner/deploy_webrunner.py +++ b/modules/webrunner/deploy_webrunner.py @@ -157,8 +157,8 @@ def _get_targets_info(scan_mode: str) -> tuple[str, list[int]]: return "", sorted(set(ports_list)) or [80, 443, 22] -def _show_estimate_table(total_ips: int, n_ports: int, providers: list[str], scan_mode: str): - rows = build_estimate_table(total_ips, n_ports, providers, scan_mode) +def _show_estimate_table(total_ips: int, n_ports: int, providers: list[str], scan_mode: str, use_tor: bool = False): + rows = build_estimate_table(total_ips, n_ports, providers, scan_mode, use_tor=use_tor) C = COLORS['CYAN'] W = COLORS['WHITE'] @@ -166,10 +166,11 @@ def _show_estimate_table(total_ips: int, n_ports: int, providers: list[str], sca G = COLORS['GREEN'] R = COLORS['RESET'] + tor_note = " [Tor: estimates reflect nmap/probe latency]" if use_tor else "" print(f"\n{C}{'─' * 70}{R}") print(f"{C} WEBRUNNER — Cost & Time Estimate{R}") print(f"{W} Total: {fmt_ip_count(total_ips)} IPs {n_ports} ports Mode: {scan_mode}{R}") - print(f"{W} Providers: {', '.join(PROVIDER_LABELS[p] for p in providers)}{R}") + print(f"{W} Providers: {', '.join(PROVIDER_LABELS[p] for p in providers)}{Y}{tor_note}{R}") print(f"{C}{'─' * 70}{R}") print(f" {'Preset':<14} {'Nodes':>6} {'IPs/Node':>10} {'Time/Node':>12} {'Total $':>10}") print(f" {'─' * 56}") @@ -266,8 +267,19 @@ def gather_webrunner_parameters() -> dict | None: print(f"{COLORS['GREEN']}Total: {fmt_ip_count(total_ips)} IPs across {len(country_codes)} countries{COLORS['RESET']}") config['total_ips'] = total_ips - # Cost / time estimate - _show_estimate_table(total_ips, len(ports), providers, scan_mode) + # Tor routing — ask before estimate so table reflects the slowdown + tor_raw = input(f"\nRoute scans through Tor? [y/N]: ").strip().lower() + config['use_tor'] = tor_raw in ['y', 'yes'] + if config['use_tor']: + if scan_mode == 'masscan-only': + print(f"{COLORS['YELLOW']} Warning: masscan uses raw sockets and bypasses proxychains — Tor has no effect in masscan-only mode.{COLORS['RESET']}") + elif scan_mode in ('geo-scout', 'masscan+nmap'): + print(f"{COLORS['YELLOW']} Note: masscan phase bypasses Tor (raw sockets); nmap and probe phases will use Tor.{COLORS['RESET']}") + else: + print(f"{COLORS['YELLOW']} Tor routing enabled — all nmap traffic will use proxychains → SOCKS5 9050.{COLORS['RESET']}") + + # Cost / time estimate — reflects Tor throughput impact + _show_estimate_table(total_ips, len(ports), providers, scan_mode, use_tor=config['use_tor']) # Preset selection print(f"{COLORS['BLUE']}Select deployment preset:{COLORS['RESET']}") @@ -322,12 +334,6 @@ def gather_webrunner_parameters() -> dict | None: config['node_chunks'] = node_chunks print(f"{COLORS['GREEN']}Nodes: {len(node_chunks)} ({preset_key}, {fmt_ip_count(chunk_size)}/node){COLORS['RESET']}") - # Tor routing - tor_raw = input(f"\nRoute scans through Tor? [y/N]: ").strip().lower() - config['use_tor'] = tor_raw in ['y', 'yes'] - if config['use_tor']: - print(f"{COLORS['YELLOW']} Tor routing enabled — masscan/nmap will use proxychains{COLORS['RESET']}") - # Operator IP config['operator_ip'] = get_public_ip() if config['operator_ip']: diff --git a/utils/provider_rates.py b/utils/provider_rates.py index 090fd54..2f4de88 100644 --- a/utils/provider_rates.py +++ b/utils/provider_rates.py @@ -73,13 +73,21 @@ def fmt_ip_count(n: int) -> str: return str(n) +# Tor adds ~5x latency overhead for TCP probes; masscan bypasses proxychains (raw sockets) +# so only nmap/probe phases are affected — modes that include masscan see partial impact +TOR_RATE_MULTIPLIER = 0.2 + + def build_estimate_table( total_ips: int, n_ports: int, providers: list[str], scan_mode: str, + use_tor: bool = False, ) -> list[dict]: mode_rate = SCAN_MODES.get(scan_mode, {'rate': 3000})['rate'] + if use_tor and scan_mode != 'masscan-only': + mode_rate = int(mode_rate * TOR_RATE_MULTIPLIER) rows = [] for preset_key, preset in PRESETS.items(): n_chunks = max(1, math.ceil(total_ips / preset['chunk_size']))