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
This commit is contained in:
@@ -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']:
|
||||
|
||||
@@ -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']))
|
||||
|
||||
Reference in New Issue
Block a user