#!/usr/bin/env python3 """ Spacetime Traceroute v1.0 "IP addresses can't hide when physics is watching" Author: You & Grok, 2025 WARNING: For educational/research use only. Respect laws & ToS. """ import asyncio import struct import time import socket import statistics from collections import defaultdict import maxminddb # pip install maxminddb import requests import math from scapy.all import * # pip install scapy # ========================= CONFIG ========================= TARGET = "1.1.1.1" # Change this to whatever you're tracing MAX_HOPS = 30 PINGS_PER_HOP = 8 TIMEOUT = 2 GEOIP_DB = "GeoLite2-City.mmdb" # Download free from MaxMind SUBMARINE_CABLES = "submarine_cables.json" # We'll include a tiny one below # Tiny built-in cable database (landing points in km from equator/prime meridian) CABLES = { "SEA-ME-WE 4": [ (1.3521, 103.8198), (19.0760, 72.8777) ], # SG -> Mumbai "FASTER": [ (35.6762, 139.6503), (45.5231, -122.6765) ], # Tokyo -> Portland "MAE-WEST": [ (37.4419, -122.1430), (37.7749, -122.4194) ], # Palo Alto -> SF # Add more if you want - or load full 2025 cable map } # ========================= PHYSICS HELPERS ========================= def haversine(lat1, lon1, lat2, lon2): R = 6371 # km dlat = math.radians(lat2 - lat1) dlon = math.radians(lon2 - lon1) a = math.sin(dlat/2)**2 + math.cos(math.radians(lat1)) * math.cos(math.radians(lat2)) * math.sin(dlon/2)**2 return 2 * R * math.atan2(math.sqrt(a), math.sqrt(1-a)) def min_fiber_delay_km(distance_km): # Light in fiber ≈ 200,000 km/s (refractive index ~1.5) return (distance_km / 200000) * 1000 # in milliseconds # ========================= GEOIP LOADER ========================= try: geo_reader = maxminddb.open_database(GEOIP_DB) except: print("[-] GeoLite2-City.mmdb not found → download from https://dev.maxmind.com/geoip/geolite2-free-geolocation-data") exit(1) # ========================= CORE TRACEROUTE ========================= async def icmp_ping(dest_addr, ttl): icmp = socket.getprotobyname('icmp') sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, icmp) sock.setsockopt(socket.IPPROTO_IP, socket.IP_TTL, struct.pack('I', ttl)) sock.settimeout(TIMEOUT) checksum = 0 header = struct.pack("bbHHh", 8, 0, checksum, 12345, 1) packet = header + b"spacetime_traceroute_rocks" checksum = 0 # simple ICMP checksum for i in range(0, len(packet), 2): if i != 2: checksum += (packet[i] << 8) + packet[i+1] checksum = (checksum >> 16) + (checksum & 0xffff) checksum += checksum >> 16 header = struct.pack("bbHHh", 8, 0, socket.htons(~checksum & 0xffff), 12345, 1) packet = header + b"spacetime_traceroute_rocks" start = time.perf_counter() sock.sendto(packet, (dest_addr, 0)) try: data, addr = sock.recvfrom(1024) rtt = (time.perf_counter() - start) * 1000 return addr[0], rtt except socket.timeout: return "*", None finally: sock.close() async def trace_route(target): print(f"\nSpacetime Traceroute to {target} (physics mode activated)\n") dest_ip = socket.gethostbyname(target) print(f"Resolved: {target} → {dest_ip}\n{'Hop':<4} {'IP':<25} {'ASN':<12} {'City (GeoIP)':<20} {'RTT (ms)':<12} {'Physics Clue'}") print("-" * 100) prev_rtt = 0 path = [] for ttl in range(1, MAX_HOPS + 1): rtts = [] ips = [] for _ in range(PINGS_PER_HOP): ip, rtt = await icmp_ping(dest_ip, ttl) if rtt: rtts.append(rtt) ips.append(ip) if not rtts: print(f"{ttl:<4} *") continue ip = max(set(ips), key=ips.count) # most common reply median_rtt = statistics.median(rtts) delta = median_rtt - prev_rtt # GeoIP + ASN try: resp = geo_reader.get(ip) city = resp['city']['names']['en'] if resp and 'city' in resp else "?" country = resp['country']['iso_code'] if resp and 'country' in resp else "??" asn = resp['traits']['autonomous_system_number'] if resp and 'traits' in resp else None except: city, country, asn = "?", "??", None # BGP ASN org (quick lookup) try: org = requests.get(f"http://ipinfo.io/{ip}/org", timeout=3).text.split(" ", 1)[1] except: org = "" # Physics clue clue = "" if delta > 0.5: expected_min = 999999 real_loc = None for cable_name, points in CABLES.items(): d = haversine(points[0][0], points[0][1], points[1][0], points[1][1]) min_ms = min_fiber_delay_km(d) if abs(delta - min_ms) < abs(delta - expected_min): expected_min = min_ms real_loc = cable_name if real_loc and abs(delta - expected_min) < 15: clue = f"→ crosses {real_loc} cable!" print(f"{ttl:<4} {ip:<25} AS{asn or '?':<11} {city}, {country:<20} {median_rtt:6.2f} Δ{delta:5.2f} {clue}") path.append({ 'hop': ttl, 'ip': ip, 'rtt': median_rtt, 'delta': delta, 'city': city, 'country': country, 'asn': asn }) prev_rtt = median_rtt if ip == dest_ip: print("\nReached target!") break # Final spacetime verdict print("\n" + "="*60) print("SPACETIME VERDICT") print("="*60) if "Cloudflare" in org or "Amazon" in org or "Akamai" in org or "ExpressVPN" in org: print("Endpoint is behind a major VPN/commercial proxy") print("But look at the hop deltas — physics still leaks truth:") for p in path[-5:]: if p['delta'] > 20: print(f" Huge ΔRTT {p['delta']:.1f}ms at hop {p['hop']} → likely real exit near {p['city']}, {p['country']}") else: print("No obvious VPN detected — this is probably the real location") return path # ========================= MAIN ========================= if __name__ == "__main__": print(""" ____ __ _ / __ \\____ ___ ____ / /_____(_)_ ______ ___ / /_/ / __ \\/ _ \\/ __ \\/ __/ __/ / / / / __ `__ \\ / ____/ /_/ / __/ / / / /_/ /_/ / / /_/ / / / / / / /_/ \\____/\\___/_/ /_/\\__/\\__/(_)\\__,_/_/ /_/ /_/ When IP lies, physics tells the truth. """) TARGET = input("Enter target hostname or IP (or press Enter for 1.1.1.1): ").strip() if not TARGET: TARGET = "1.1.1.1" asyncio.run(trace_route(TARGET))