diff --git a/README.md b/README.md deleted file mode 100644 index 969742d..0000000 --- a/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# AURIGA — Toolbox - -One-page network toolbox: https://auriga.thetempleofdoom.com - -- **Whats-My-IP MAX** — geo, ASN, ISP, VPN/proxy/hosting flags, rDNS, headers. API: `GET /api/ip` -- **Card Check** — Luhn + BIN (brand/issuer/country/prepaid flags). Nothing stored or charged. `POST /card` -- **SMS Rental** — disposable numbers, 30-min windows, cancel = refund (SMSPool). `POST /api/sms/rent|check|cancel` -- **Proxy Lab** — test Pleiades gateway `user:pass` (same keys fleet-wide), see egress IP/geo. `POST /api/proxy/test` -- **Free Tools** — DNS (DoH), HTTP header inspector, JWT decoder, hasher, UUID/password gen. `GET /api/hash`, `GET /api/hdr` - -CT 768 @ 10.30.20.216, Flask :5000 behind nginx. Stack: single-file Flask + SQLite. diff --git a/app.py b/app.py index 99f98f6..591e4b9 100644 --- a/app.py +++ b/app.py @@ -31,6 +31,14 @@ def _migrate(con): cols = [r[1] for r in con.execute("PRAGMA table_info(sms_rentals)")] if "user_id" not in cols: con.execute("ALTER TABLE sms_rentals ADD COLUMN user_id INTEGER DEFAULT 0") + cols = [r[1] for r in con.execute("PRAGMA table_info(canary_hits)")] + if cols and "lang" not in cols: + con.execute("ALTER TABLE canary_hits ADD COLUMN lang TEXT DEFAULT ''") + con.execute("ALTER TABLE canary_hits ADD COLUMN ref TEXT DEFAULT ''") + cols = [r[1] for r in con.execute("PRAGMA table_info(canaries)")] + if cols and "kind" not in cols: + con.execute("ALTER TABLE canaries ADD COLUMN kind TEXT DEFAULT 'link'") + con.execute("ALTER TABLE canaries ADD COLUMN rearm INTEGER DEFAULT 0") def db(): con = sqlite3.connect(DB_PATH); con.row_factory = sqlite3.Row @@ -105,13 +113,15 @@ def get_balance(uid): return con.execute("SELECT cents FROM balances WHERE user_id=?", (uid,)).fetchone()["cents"] def charge(uid, cents, reason): - """Deduct from balance; return False if insufficient.""" + """Deduct from balance; return False if insufficient. + FREE MODE (Oct 2026): every tool on dark0rbits is free — the lab absorbs all costs. + Charges become zero-cost ledger entries and always succeed.""" if cents <= 0: return True - if get_balance(uid) < cents: return False - con = db() - con.execute("UPDATE balances SET cents = cents - ? WHERE user_id=?", (cents, uid)) - con.execute("INSERT INTO ledger(user_id,delta_cents,reason,ts) VALUES(?,?,?,?)", (uid, -cents, reason, int(time.time()))) - con.commit() + if uid: + con = db() + con.execute("INSERT INTO ledger(user_id,delta_cents,reason,ts) VALUES(?,?,?,?)", + (uid, 0, f"FREE (was {cents}¢) {reason}", int(time.time()))) + con.commit() return True def key_user(): @@ -248,7 +258,7 @@ header{position:sticky;top:0;z-index:40;background:rgba(7,10,19,.86);backdrop-fi :focus-visible{outline:2px solid var(--acc2);outline-offset:2px;border-radius:4px} .skip{position:absolute;left:-9999px;top:0;z-index:100;background:var(--acc);color:#0d0722;padding:.5rem 1rem;border-radius:0 0 8px 0;font-weight:800} .skip:focus{left:0} -table{display:block;overflow-x:auto;max-width:100%;-webkit-overflow-scrolling:touch} +/* tables: real tables, wrap in .tblwide for scroll on tiny screens */ @media(max-width:640px){.dnav a{padding:.45rem .7rem;font-size:.8rem}#dev{display:none}} @media(prefers-reduced-motion:reduce){ #space{display:none}.gridlines{display:none}#lbar{transition:none}.type,.typed-cursor,.crt{display:none}.logo::before,.logo::after{animation:none}.card{transition:none}} .drawer{position:fixed;inset:0;z-index:60;background:rgba(7,10,19,.96);backdrop-filter:blur(6px);display:none;flex-direction:column;padding:1.2rem;overflow-y:auto} @@ -265,10 +275,12 @@ h1 span{color:var(--acc)} .sub{color:var(--dim);margin:.25rem 0 1.7rem;font-size:1.03rem;line-height:1.65;max-width:62ch} .card{background:var(--card);border:1px solid var(--line);border-radius:16px;padding:1.4rem 1.5rem;margin:1.35rem 0;backdrop-filter:blur(4px)} .card.glow{box-shadow:0 0 34px -16px var(--acc)} -.kv{display:grid;grid-template-columns:1fr;gap:.45rem .9rem;text-align:left} -.kv div:nth-child(odd){color:var(--dim);font-size:.82rem;letter-spacing:.05em;text-transform:uppercase;padding-top:.5rem;font-weight:700} -.kv div:nth-child(even){background:rgba(255,255,255,.03);border-radius:8px;padding:.35rem .6rem} -@media(min-width:640px){.kv{grid-template-columns:180px 1fr}.kv div:nth-child(odd){padding-top:.35rem}} +.kv{display:grid;grid-template-columns:200px minmax(0,1fr);gap:0;border:1px solid var(--line);border-radius:12px;overflow:hidden;text-align:left} +.kv div{padding:.6rem .9rem;border-bottom:1px solid var(--line);min-width:0;overflow-wrap:anywhere} +.kv div:nth-child(odd){color:var(--dim);font-size:.78rem;letter-spacing:.06em;text-transform:uppercase;font-weight:700;background:rgba(255,255,255,.02)} +.kv div:nth-child(even){background:transparent} +.kv div:nth-child(even){background:transparent} +.kv div:nth-last-child(2),.kv div:last-child{border-bottom:0} input,select,button,textarea{font:inherit;background:rgba(10,15,30,.9);color:var(--fg);border:1px solid #2c3860;border-radius:10px;padding:.72rem .9rem;max-width:100%;text-align:left} .card label{display:block;text-align:left;color:var(--dim);font-size:.88rem;margin:.6rem 0 .2rem} .card input,.card select,.card textarea{width:100%} @@ -305,8 +317,13 @@ button.big{font-size:1.02rem;padding:.75rem 1.4rem;margin:.25rem;color:#0d0722} @media(min-width:700px){.grid2{grid-template-columns:1fr 1fr}} .tag{display:inline-block;padding:.14rem .6rem;border-radius:999px;font-size:.74rem;border:1px solid;margin:.15rem} .tag.ok{color:var(--ok);border-color:var(--ok)}.tag.bad{color:var(--bad);border-color:var(--bad)}.tag.warn{color:var(--acc);border-color:var(--acc)} -table{width:100%;border-collapse:collapse;font-size:.93rem} -td,th{padding:.55rem .5rem;border-bottom:1px solid var(--line);text-align:left} +table{width:100%;border-collapse:collapse;font-size:.9rem;table-layout:auto} +.tblwide{overflow-x:auto;-webkit-overflow-scrolling:touch} +@media(max-width:520px){.tblwide table{table-layout:auto}} +td,th{padding:.6rem .8rem;border-bottom:1px solid var(--line);text-align:left;vertical-align:top;overflow-wrap:anywhere} +tr:last-child td{border-bottom:0} +th{white-space:nowrap} +td code{font-size:.82em} th{color:var(--dim);text-transform:uppercase;font-size:.75rem;letter-spacing:.06em} footer{color:var(--dim);padding:2.4rem 1rem 5rem;font-size:.88rem;position:relative;z-index:2;text-align:center;line-height:1.7} footer a{color:var(--acc)} @@ -322,7 +339,14 @@ pre{text-align:left;white-space:pre-wrap;overflow-x:auto} #dev{position:fixed;bottom:14px;right:14px;z-index:45;background:rgba(19,25,44,.92);border:1px solid var(--acc);color:var(--acc);border-radius:999px;padding:.5rem .9rem;font-size:.8rem;text-decoration:none;box-shadow:0 0 18px -6px var(--acc)} #dev:hover{background:var(--acc);color:#161000} img{max-width:100%;border-radius:10px} -li{text-align:left;margin:.2rem 0} +ul,ol{text-align:left;margin:.6rem 0;padding-left:1.4rem} +li{text-align:left;margin:.45rem 0;line-height:1.65} +li::marker{color:var(--acc)} +.steps{counter-reset:step;list-style:none;padding-left:0;margin:.8rem 0 0} +.steps li{counter-increment:step;position:relative;padding:.55rem 0 .55rem 2.6rem;margin:.35rem 0;color:var(--fg);line-height:1.6} +.steps li::before{content:counter(step);position:absolute;left:0;top:.5rem;width:1.7rem;height:1.7rem;border-radius:50%;border:1px solid var(--acc);color:var(--acc);font-size:.8rem;font-weight:800;display:flex;align-items:center;justify-content:center;background:rgba(167,139,250,.08)} +.steps li b{color:var(--acc)} +.flowrole{display:inline-block;font-size:.68rem;letter-spacing:.18em;text-transform:uppercase;color:var(--acc2);border:1px solid var(--line);border-radius:999px;padding:.1rem .55rem;margin-right:.4rem;vertical-align:middle} .gridlines{position:fixed;inset:0;z-index:1;pointer-events:none;background:repeating-linear-gradient(0deg,rgba(255,255,255,.012) 0 1px,transparent 1px 3px),linear-gradient(rgba(111,214,255,.03) 1px,transparent 1px),linear-gradient(90deg,rgba(111,214,255,.03) 1px,transparent 1px);background-size:auto,80px 80px,80px 80px;mask-image:linear-gradient(rgba(0,0,0,.7),rgba(0,0,0,.25))} #acct{display:flex;align-items:center;gap:.4rem;white-space:nowrap} .abtn{display:inline-flex;align-items:center;font-size:.78rem;letter-spacing:.08em;text-decoration:none;border-radius:999px;padding:.42rem .95rem;border:1px solid var(--line);color:var(--dim);transition:.15s;cursor:pointer} @@ -342,6 +366,8 @@ li{text-align:left;margin:.2rem 0} SMSPROXY STEGOTRACK MAIL-FORENSICSIMG-FORENSICS +PHONEUSER-SLEUTH +DOMAIN CANARYDEAD-DROPBURNER-MAIL SHOTFRAUD-SCORE INBOXPASSPORT @@ -355,8 +381,11 @@ li{text-align:left;margin:.2rem 0} ◈ IP INTEL geo, ASN, ISP, VPN flags — any target ◈ CARD CHECK luhn + BIN issuer intelligence ◈ MAG-LAB browser magstripe studio — ISO 7811 encode, read, batch issue (closed-loop only) -◈ MAIL FORENSICS origin + SPF/DKIM/DMARC + spoof flags +◈ MAIL FORENSICS true origin, relay delays, spoof flags, .eml import ◈ IMAGE FORENSICS EXIF, GPS, ELA, edit detection +◈ PHONE LOOKUP carrier, line type, region, timezone — any number +◈ USERNAME SLEUTH find one handle across 12+ platforms +◈ DOMAIN RECON RDAP whois, DNS, nameservers, subdomains

Operate

◈ SMS RENTAL 30-min numbers, refundable ◈ PROXY LAB residential egress, geo builder @@ -364,16 +393,19 @@ li{text-align:left;margin:.2rem 0} ◈ BURNER MAIL receive-only mailboxes, countdown

Hunt

◈ TRACK FILE opens report back: IP, city, ISP -◈ CANARY TRAPS tripwires with instant alerts +◈ CANARY TRAPS links, pixels & honeytokens — instant alerts ◈ DEAD-DROP burn-after-read encrypted notes ◈ SCREENSHOT page capture or rendered-text fallback ◈ FRAUD-SCORE composite IP + email + BIN risk 0-100 ◈ FREE TOOLS DNS, headers, JWT, hasher +◈ PHONE LOOKUP osint: carrier + line type + region +◈ USERNAME SLEUTH osint: handle across platforms +◈ DOMAIN RECON osint: RDAP + DNS + subdomains

Account

◈ INBOX no-KYC messaging ◈ SIGN UP username + password, 10 seconds, no KYC ◈ API KEYS account, balance, metered keys -◈ PASS $10/mo all-access +◈ PASS everything's free now — no pass needed ◈ AGENT PASSPORT machine-readable badge
{{body}}
@@ -507,11 +539,11 @@ var PAL=[ ['/card','card BIN + Luhn check'], ['/sms','rent a burner number, 30 min'], ['/proxy','proxy lab — test Pleiades egress'], -['/steg','hide / extract text in images'], +['/steg','hide / extract secret text in pictures'], ['/track','trackable files — opens report back'], -['/eh','email header forensics'], +['/eh','email forensics — origin, spoof flags, .eml import'], ['/forensics','image forensics — EXIF + ELA'], -['/canary','canary tripwires'], +['/canary','canary traps — links, pixels, honeytokens'], ['/deaddrop','burn-after-read encrypted notes'], ['/mail','burner mailbox'], ['/shot','screenshot / page capture'], @@ -620,19 +652,28 @@ def Redirect(u): def agent_card(endpoint, example, notes): """Interactive-for-LLMs card: exact curl + auth + link to openapi.""" - return ('
FOR AGENTS ' - '?
' + return ('
FOR AGENTS ' + '?
' '' + esc(endpoint) + '
' - '' + esc(example) + '
' + esc(notes) + + '' + esc(example) + '' + '' + esc(notes) + ' · spec: /openapi.json · catalog: /llms.txt
') + def gloss(terms): - chips = " ".join('' + esc(t) + '' for t, d in terms) - return '
JARGON — hover any term: ' + chips + '
' + chips = " ".join('' + esc(t) + '' for t, d in terms) + return '
JARGON — hover any chip:
' + chips + '
' + def how(steps): lis = "".join(f"
  • {esc(s)}
  • " for s in steps) - return f'
    HOW IT WORKS
      {lis}
    ' + return f'
    HOW IT WORKS
      {lis}
    ' + +def flow(title, steps): + """Concrete example flow: numbered scene-by-scene walkthrough with role chips.""" + lis = "".join(f"
  • {s}
  • " for s in steps) # steps carry their own / markup + return f'
    EXAMPLE FLOW — {esc(title)}
      {lis}
    ' + # ---------- AGENT DISCOVERY ---------- LLMS_SETTINGS = """ @@ -648,10 +689,14 @@ API_INDEX = { "endpoints": [ {"method": "GET", "path": "/signup", "desc": "No-KYC signup page (humans): username + password, 4+ chars, ~10 seconds. Agents: POST /inbox form act=register&u=NAME&p=PASS -> session cookie dark0rbits_tok (30 days) + $1 free trial credit."}, {"method": "GET/POST", "path": "/api/settings", "desc": "Per-account UI tunables (bg, warp, parallax, density, speed, twinkle, hue, grid, scan, toast, type). Agents can theme their own client. GET returns current; POST form key=val applies (validated + clamped)."}, - {"method": "GET", "path": "/deaddrop", "desc": "Burn-after-read encrypted notes. POST /api/deaddrop/create (body, burn_after 1-10, ttl_hours 1-72, password optional) -> token. 5c, free with PASS."}, - {"method": "GET", "path": "/shot", "desc": "Page capture: POST /api/shot/create {url} then GET /api/shot/status/. SSRF-guarded. 25c, free with PASS."}, - {"method": "GET", "path": "/score", "desc": "Composite fraud score: IP 45% + disposable-email 25% + BIN 30%. 2c, free with PASS."}, + {"method": "GET", "path": "/deaddrop", "desc": "Burn-after-read encrypted notes. POST /api/deaddrop/create (body, burn_after 1-10, ttl_hours 1-72, password optional) -> token. FREE."}, + {"method": "GET", "path": "/shot", "desc": "Page capture: POST /api/shot/create {url} then GET /api/shot/status/. SSRF-guarded. FREE."}, + {"method": "GET", "path": "/score", "desc": "Composite fraud score: IP 45% + disposable-email 25% + BIN 30%. FREE."}, {"method": "GET", "path": "/api/ip?target=", "desc": "Caller IP intel (auto) or any IP you pass: geo, ASN, ISP, VPN/hosting flags, rDNS."}, + {"method": "GET", "path": "/api/phone?num=", "desc": "Phone OSINT: validity, country, region, carrier, line type (mobile/landline/voip), timezones, risk flags + free deep-dive lead links. Any format."}, + {"method": "GET", "path": "/api/user?u=", "desc": "Username OSINT: probes 16 platforms in parallel (GitHub, Reddit, Telegram, Steam…) → per-site found/not-found/unknown + lead links."}, + {"method": "GET", "path": "/api/domain?d=", "desc": "Domain OSINT: RDAP registration (registrar/dates/status), full DNS (A/AAAA/MX/NS/TXT/CNAME via DoH), certificate-transparency subdomains. Passive."}, + {"method": "POST", "path": "/api/forensics", "files": ["image"], "desc": "Deep image forensics: all EXIF IFDs, decoded GPS + map links, XMP, embedded thumbnail, hashes, editor flags, ELA verdict."}, {"method": "POST", "path": "/api/card", "params": {"num": "card number"}, "desc": "Luhn + BIN intel. Nothing stored/charged."}, {"method": "POST", "path": "/api/sms/rent", "params": {"service": "id/keyword", "country": "id"}, "desc": "Rent disposable number, 30 min, refundable."}, {"method": "GET", "path": "/api/sms/check?pid=", "desc": "Poll SMS code."}, @@ -660,17 +705,21 @@ API_INDEX = { {"method": "POST", "path": "/api/proxy/test", "params": {"user": "Pleiades user", "pass": "password"}, "desc": "Tunnel CONNECT via Pleiades gateway, return egress IP/geo."}, {"method": "POST", "path": "/api/steg/hide", "params": {"image": "png file", "text": "secret", "password": "optional", "bits": "1-3", "spread": "sequential|random"}, "desc": "LSB steganography → PNG download."}, {"method": "POST", "path": "/api/steg/extract", "params": {"image": "png file", "password": "optional"}, "desc": "Extract hidden text."}, - {"method": "POST", "path": "/api/track/create", "params": {"filename": "name"}, "desc": "Create $1 BTCPay invoice for a trackable file. Returns checkoutLink."}, + {"method": "POST", "path": "/api/track/create", "params": {"filename": "name"}, "desc": "Create free trackable file. Returns upload_url + token. Login required (POST /inbox act=register)."}, {"method": "GET", "path": "/api/track/events?token=", "desc": "Open events for a trackable (auth via account)."}, {"method": "GET", "path": "/api/hash?s=", "desc": "md5/sha1/sha256/sha512."}, {"method": "GET", "path": "/api/hdr?url=", "desc": "Fetch URL, return status + headers."}, - {"method": "POST", "path": "/api/deaddrop/create", "params": {"body": "note text (max 8000 chars)", "burn_after_reads": "1-10", "ttl_hours": "1-72", "password": "optional"}, "desc": "AES-GCM encrypted burn-after-read note. Returns /drop/ URL. Free with PASS, else 5c from balance. Reads decrement; note self-destructs at 0 or at TTL."}, + {"method": "POST", "path": "/api/deaddrop/create", "params": {"body": "note text (max 8000 chars)", "burn_after_reads": "1-10", "ttl_hours": "1-72", "password": "optional"}, "desc": "AES-GCM encrypted burn-after-read note. Returns /drop/ URL. FREE. Reads decrement; note self-destructs at 0 or at TTL."}, {"method": "GET", "path": "/drop/", "desc": "Read a dead-drop (password-protected if set). Each view burns one read."}, - {"method": "POST", "path": "/api/shot/create", "params": {"url": "http(s):// target"}, "desc": "Screenshot queue. Headless Chromium PNG if available, else rendered-text capture (status=text_fallback). 25c/shot, free with PASS. Poll /api/shot/status/."}, + {"method": "POST", "path": "/api/shot/create", "params": {"url": "http(s):// target"}, "desc": "Screenshot queue. Headless Chromium PNG if available, else rendered-text capture (status=text_fallback). FREE. Poll /api/shot/status/."}, {"method": "GET", "path": "/api/shot/status/", "desc": "Shot result: base64 PNG (png_b64) or text preview + page intel."}, - {"method": "GET", "path": "/api/score?ip=&email=&bin=", "desc": "Composite fraud score 0-100 + weighted breakdown: IP intel (VPN/hosting/abuse geo), disposable-email domain, BIN country/type risk. 2c/call, free with PASS."}, + {"method": "GET", "path": "/api/score?ip=&email=&bin=", "desc": "Composite fraud score 0-100 + weighted breakdown: IP intel (VPN/hosting/abuse geo), disposable-email domain, BIN country/type risk. FREE."}, + {"method": "POST", "path": "/canary", "desc": "Create canary trap. Form: tag, kind (link|pixel|cred|file), rearm (0|1). Login required. Link = /c/, pixel = /c/.png, honeyfile = /c//download, credential returned by /api/canary/list."}, + {"method": "GET", "path": "/api/canary/list", "desc": "Your traps with hit counts, links, generated honeytoken credentials. Login required."}, + {"method": "GET", "path": "/api/canary/hits?token=", "desc": "Full hit log for a trap: ts, ip, ua, lang, ref + geolocated city/ISP/VPN flags per hit. Login required."}, + {"method": "POST", "path": "/api/eh", "desc": "Email header forensics v2: origin IP (+source), origin_geo, hop chain, per-hop relay delays (delays), SPF/DKIM/DMARC verdicts, spoof flags. Handles pasted headers or .eml content. FREE 20/min."}, ], - "payment": "BTCPay BTC only (no Stripe). SMS meters to house account; trackables $1 each.", + "payment": "EVERYTHING IS FREE — the lab absorbs all costs (SMS rentals, mail, trackables, screenshots). No top-ups needed.", } @app.route("/api/settings", methods=["GET", "POST"]) @@ -700,7 +749,7 @@ INDEXNOW = "a8f3d4rk0rbits9e2b1c7x5k8m2v4q6t8" @app.route("/sitemap.xml") def sitemap(): S = "https://dark0rbits.thetempleofdoom.com" - pages = ["", "ip", "card", "sms", "proxy", "steg", "track", "eh", "forensics", "canary", "deaddrop", "shot", "score", "mail", "inbox", "passport", "pass", "keys", "maglab", "tools", "signup"] + pages = ["", "ip", "card", "sms", "proxy", "steg", "track", "eh", "forensics", "phone", "user", "domain", "canary", "deaddrop", "shot", "score", "mail", "inbox", "passport", "pass", "keys", "maglab", "tools", "signup"] xml = '' + "".join(f"{S}/{p}weekly" for p in pages) + "" return xml, 200, {"Content-Type": "application/xml"} @@ -729,6 +778,10 @@ def openapi(): item["requestBody"] = {"content": {"application/x-www-form-urlencoded": {"schema": {"type": "object", "properties": {k: {"type": "string"} for k in params}}}}} ps["paths"][path] = ps["paths"].get(path, {}) | {method: {"responses": {"200": {"description": "ok"}}, **item}} add("/api/ip", "get", "IP intel (caller or ?target=)", {"target": "optional IP"}) + add("/api/phone", "get", "Phone OSINT: carrier, line type, region, timezones, leads", {"num": "phone number, any format"}, req=True) + add("/api/user", "get", "Username OSINT probe across 16 platforms", {"u": "username"}, req=True) + add("/api/domain", "get", "Domain recon: RDAP + DNS + CT subdomains", {"d": "domain"}, req=True) + add("/api/forensics", "post", "Deep image forensics: EXIF IFDs, GPS decoded, XMP, thumbnail, ELA", files=["image"]) add("/api/card", "post", "Luhn + BIN validation", {"num": "card number"}, req=True) add("/api/sms/rent", "post", "Rent number 30 min", {"service": "id", "country": "id"}, req=True) add("/api/sms/check", "get", "Poll SMS code", {"pid": "orderid"}, req=True) @@ -746,6 +799,10 @@ def openapi(): add("/api/shot/create", "post", "Queue page capture", {"url": "target url"}, req=True) add("/api/shot/status/{id}", "get", "Shot result (png_b64 or text_fallback)") add("/api/score", "get", "Composite fraud score 0-100", {"ip": "opt", "email": "opt", "bin": "opt"}) + add("/canary", "post", "Create canary trap (tag, kind, rearm)", {"tag": "label", "kind": "link|pixel|cred|file", "rearm": "0|1"}, req=True) + add("/api/canary/list", "get", "Your traps + hit counts + honeytoken creds") + add("/api/canary/hits", "get", "Full hit log with geo per hit", {"token": "trap token"}, req=True) + add("/api/eh", "post", "Email header forensics v2 (origin, delays, verdicts, flags)", {"raw": "full headers or .eml content"}, req=True) add("/signup", "get", "No-KYC signup page (username + password only)") return jsonify(ps) @@ -845,6 +902,250 @@ def bin_lookup(bin8): "type": str(h.get("Type", "")).lower() or None, "prepaid": "prepaid" in str(h.get("Type","")).lower() or None, "scheme": h.get("Scheme")} return bl +# ---------- 2b. PHONE LOOKUP (OSINT, offline metadata + free lead links) ---------- +def phone_report(raw): + out = {"ok": False} + try: + import phonenumbers as pn + from phonenumbers import carrier as pncarrier, timezone as pntz, geocoder as pngeo + n = pn.parse(raw.strip(), None) + except Exception as e: + out["error"] = f"cannot parse number: {e}"[:200] + return out + out["ok"] = True + out["e164"] = pn.format_number(n, pn.PhoneNumberFormat.E164) + out["national"] = pn.format_number(n, pn.PhoneNumberFormat.NATIONAL) + out["international"] = pn.format_number(n, pn.PhoneNumberFormat.INTERNATIONAL) + out["valid"] = pn.is_valid_number(n) + out["possible"] = pn.is_possible_number(n) + out["country"] = pn.region_code_for_country_code(n.country_code or 0) + try: out["country_calling_code"] = f"+{n.country_code}" + except Exception: pass + try: + out["region_desc"] = pngeo.description_for_number(n, "en") or "" + except Exception: out["region_desc"] = "" + try: + out["carrier"] = pncarrier.name_for_number(n, "en") or "" + except Exception: out["carrier"] = "" + try: + out["timezones"] = list(pntz.time_zones_for_number(n)) + except Exception: out["timezones"] = [] + tmap = {0:"fixed_line",1:"mobile",2:"fixed_or_mobile",3:"freephone",4:"premium_rate",5:"shared_cost",6:"voip",7:"personal_number",8:"pager",9:"uan",10:"voicemail"} + try: + t = pn.number_type(n) + out["line_type"] = tmap.get(t, "unknown") + out["line_type_risk"] = ("voip/uan numbers are often disposable or bulk-registered" if t in (6, 9) else "") + except Exception: out["line_type"] = "unknown" + q = out["e164"] + out["leads"] = { + "google": "https://www.google.com/search?q=%22" + urllib.parse.quote(q) + "%22", + "duckduckgo": "https://duckduckgo.com/?q=" + urllib.parse.quote(q), + "truecaller": "https://www.truecaller.com/search/" + (out["country"] or "us").lower() + "/" + q.lstrip("+"), + } + if out["line_type"] == "voip": out.setdefault("flags", []).append("voip — high disposable/spoof potential") + if not out["valid"]: out.setdefault("flags", []).append("not a valid number — fake or mistyped") + return out + +@app.route("/phone", methods=["GET", "POST"]) +def phone_tool(): + res = "" + if request.method == "POST": + raw = param("num") or "" + if raw.strip(): + d = phone_report(raw) + if d.get("ok"): + res = kv([ + ("Number", f'{esc(d["e164"])} ({esc(d["national"])})'), + ("Valid", 'VALID' if d["valid"] else 'NOT VALID'), + ("Country", esc(d["country"]) + " " + esc(d["country_calling_code"])), + ("Region", esc(d["region_desc"]) or "—"), + ("Carrier", esc(d["carrier"]) or "—"), + ("Line type", esc(d["line_type"])), + ("Timezones", esc(", ".join(d["timezones"])) or "—"), + ]) + if d.get("flags"): + res += '
    Flags
    ' + "
    ".join('' + esc(f) + "" for f in d["flags"]) + "
    " + l = d["leads"] + res += f'''
    Deep-dive leads (free public sources)
    +Google the exact number → · +DuckDuckGo → · +TrueCaller web search →
    ''' + else: + res = f'
    PARSE FAILED
    {esc(d.get("error"))}
    ' + body = f""" +

    PHONE LOOKUP

    Parse + intel on any number worldwide: validity, country, region, carrier, line type (mobile/landline/VOIP), timezones — plus free deep-dive lead links. No KYC, no logs.

    +
    +{res} +
    API: GET /api/phone?num=%2B14255550100 → JSON: valid, country, region, carrier, line_type, timezones, flags, lead links.
    """ + how(["Type the number in any format — country code, spaces, dashes, all handled.", +"Metadata comes from offline libphonenumber data — instant and private, nothing phoned home.", +"Line type matters: VOIP/UAN numbers are the disposable, bulk-registered kind.", +"Follow the lead links for the human layer: public mentions, directory listings, name lookups.", +"Pair it with SMS RENTAL — know the number type before you verify with it."]) + body += gloss([("E164","the international standard format: + and country code, no spaces"),("line type","mobile vs landline vs VOIP — carriers publish the ranges"),("VOIP","internet-based number — cheap, disposable, often spoofed")]) + body += agent_card('GET /api/phone?num=%2B14255550100', 'curl "https://dark0rbits.thetempleofdoom.com/api/phone?num=%2B14255550100"', 'valid, country, region, carrier, line_type, timezones, flags + free lead links.') + return page("phone", body) + +@app.route("/api/phone", methods=["GET", "POST"]) +def api_phone(): + r = rate_limit("phone", 30, 60) + if r: return r + raw = (param("num") or "").strip() + if not raw: return jsonify({"ok": False, "error": "num required (any format, country code encouraged)"}), 400 + return jsonify(phone_report(raw)) + +# ---------- 2c. USERNAME SLEUTH (OSINT profile probe) ---------- +USER_SITES = [ + ("GitHub", "https://github.com/{u}"), + ("GitLab", "https://gitlab.com/{u}"), + ("Reddit", "https://www.reddit.com/user/{u}/"), + ("Telegram", "https://t.me/{u}"), + ("Medium", "https://medium.com/@{u}"), + ("Pastebin", "https://pastebin.com/u/{u}"), + ("Keybase", "https://keybase.io/{u}"), + ("About.me", "https://about.me/{u}"), + ("SoundCloud", "https://soundcloud.com/{u}"), + ("Vimeo", "https://vimeo.com/{u}"), + ("Steam", "https://steamcommunity.com/id/{u}"), + ("Last.fm", "https://www.last.fm/user/{u}"), + ("Dribbble", "https://dribbble.com/{u}"), + ("Imgur", "https://imgur.com/user/{u}"), + ("Chess.com", "https://www.chess.com/member/{u}"), + ("Twitch", "https://www.twitch.tv/{u}"), +] +def _probe_site(name, url): + st, b = http(url, timeout=10) + if st == 200: + return {"site": name, "url": url, "status": "found", "http": st} + if st == 404: + return {"site": name, "url": url, "status": "not found", "http": st} + return {"site": name, "url": url, "status": "unknown", "http": st, "note": "site blocked or rate-limited the probe — check manually"} + +def user_probe(u): + from concurrent.futures import ThreadPoolExecutor + with ThreadPoolExecutor(max_workers=8) as ex: + results = list(ex.map(lambda s: _probe_site(s[0], s[1].format(u=urllib.parse.quote(u))), USER_SITES)) + found = [r for r in results if r["status"] == "found"] + return {"ok": True, "username": u, "found": found, "results": results, + "hits": len(found), "leads": { + "google": "https://www.google.com/search?q=%22" + urllib.parse.quote(u) + "%22", + "instantusername": "https://instantusername.com/#/" + urllib.parse.quote(u)}} + +@app.route("/user", methods=["GET", "POST"]) +def user_tool(): + res = "" + if request.method == "POST": + u = (param("u") or "").strip() + if u and 2 <= len(u) <= 60 and all(c not in "<>\"'" for c in u): + d = user_probe(u) + rows = "".join(f'{esc(r["site"])}{esc(r["status"])}{esc(r["url"])}{r.get("http")}' for r in d["results"]) + res = kv([("Username", esc(u)), ("Profiles found", f'{d["hits"]} of {len(USER_SITES)} platforms')]) + res += f'
    Probe results{rows}
    SiteStatusURLHTTP
    ' + res += f'' + body = f""" +

    USERNAME SLEUTH

    Give it a handle — it probes {len(USER_SITES)} major platforms in parallel and reports where that username lives. Classic OSINT footwork, automated.

    +
    +{res} +
    API: GET /api/user?u=NAME → JSON with per-site found/not-found/unknown.
    """ + how(["Type the handle — no @, no https, just the name.", +"Sixteen sites get probed at once — GitHub, Reddit, Telegram, Steam and more.", +"FOUND = a live profile answered on that exact URL. Unknown = the site blocked the probe (check manually).", +"Follow the Google/InstantUsername leads for the long tail of smaller platforms.", +"Same handle on multiple sites = the same human. That's the whole point."]) + body += gloss([("probe","an HTTP GET that never logs in or scrapes private data"),("handle","the username part of a profile URL"),("correlation","linking profiles across sites by shared handle")]) + body += agent_card('GET /api/user?u=somehandle', 'curl "https://dark0rbits.thetempleofdoom.com/api/user?u=somehandle"', 'Per-site found/not-found/unknown + lead links. ~8s, all probes in parallel.') + return page("user", body) + +@app.route("/api/user", methods=["GET", "POST"]) +def api_user(): + r = rate_limit("user", 10, 60) + if r: return r + u = (param("u") or "").strip() + if not u or len(u) > 60 or any(c in "<>\"'" for c in u): return jsonify({"ok": False, "error": "u required (max 60 chars, no html)"}), 400 + return jsonify(user_probe(u)) + +# ---------- 2d. DOMAIN RECON (RDAP + DNS + subdomains) ---------- +def domain_report(d): + d = d.strip().lower().replace("https://", "").replace("http://", "").split("/")[0] + out = {"ok": True, "domain": d} + st, b = http("https://rdap.org/" + urllib.parse.quote(d), timeout=15) + rd = jf(b) + if rd: + out["rdap"] = {k: rd.get(k) for k in ("handle", "ldhName", "status", "events", "entities", "nameservers") if rd.get(k)} + evs = {} + for e in rd.get("events") or []: + evs[e.get("eventAction", "?")] = e.get("eventDate") + out["events"] = evs + ents = [] + for e in rd.get("entities") or []: + roles = e.get("roles") or [] + fn = "" + try: + v = e.get("vcardArray") or [] + for item in (v[1] if len(v) > 1 else []): + if item and item[0] == "fn": fn = item[3] + except Exception: pass + if "registrar" in roles or "registrant" in roles: ents.append({"roles": roles, "name": fn}) + out["entities"] = ents + else: + out["rdap_error"] = f"rdap.org returned {st}" + doh = "https://dns.google/resolve?name=" + urllib.parse.quote(d) + "&type=" + recs = {} + for rt in ("A", "AAAA", "MX", "NS", "TXT", "CNAME"): + st, b = http(doh + rt, timeout=10) + j = jf(b) + if j and j.get("Answer"): + recs[rt] = [a.get("data") for a in j["Answer"]] + out["dns"] = recs + st, b = http("https://crt.sh/?q=%25." + urllib.parse.quote(d) + "&output=json", timeout=25) + subs = set() + j = jf(b) + if isinstance(j, list): + for row in j: + for nm in str(row.get("name_value", "")).split("\n"): + nm = nm.strip().lower().lstrip("*.") + if nm.endswith("." + d) and nm != d: subs.add(nm) + out["subdomains"] = sorted(subs)[:100] + out["subdomain_count"] = len(subs) + return out + +@app.route("/domain", methods=["GET", "POST"]) +def domain_tool(): + res = "" + if request.method == "POST": + d = (param("d") or "").strip() + if d and len(d) <= 100: + try: + rep = domain_report(d) + evs = rep.get("events") or {} + ent = "; ".join(f'{"/".join(e["roles"])}: {e["name"]}' for e in (rep.get("entities") or [])) or "—" + ns = ", ".join(str(x.get("ldhName") or x) for x in (rep.get("nameservers") or rep.get("rdap", {}).get("nameservers") or [])) or (rep.get("dns", {}).get("NS") and ", ".join(rep["dns"]["NS"])) or "—" + dns_rows = "".join(f"{esc(k)}{esc('
    '.join(v))}" for k, v in (rep.get("dns") or {}).items()) + subs = rep.get("subdomains") or [] + res = kv([("Registrar info", esc(ent)), ("Registered", esc(evs.get("registration", "—"))), ("Expires", esc(evs.get("expiration", "—"))), ("Last changed", esc(evs.get("last changed", "—"))), ("Status", esc(", ".join(rep.get("rdap", {}).get("status") or []) or "—")), ("Nameservers", esc(ns))]) + res += f'
    DNS{dns_rows or ""}
    none resolved
    ' + res += f'
    Certificate-transparency subdomains ({rep.get("subdomain_count",0)} found)
    ' + (esc(" · ".join(subs[:60])) + (" …" if len(subs) > 60 else "") or "—") + "
    " + except Exception as e: + res = f'
    LOOKUP FAILED
    {esc(str(e)[:300])}
    ' + body = f""" +

    DOMAIN RECON

    Full passive recon on any domain: RDAP registration data (registrar, dates, status), live DNS records, and certificate-transparency subdomain discovery. Free, no keys.

    +
    +{res} +
    API: GET /api/domain?d=example.com → JSON: rdap, events, entities, dns, subdomains.
    """ + how(["Type the bare domain — no scheme, no path.", +"RDAP answers who runs it, when it was registered and when it expires.", +"DNS shows A/AAAA/MX/NS/TXT/CNAME — where it lives and what mail it accepts.", +"Certificate logs expose hostnames even when DNS tries to hide them — great for finding staging/hidden subdomains.", +"All sources are public registries — passive, no packets touch the target."]) + body += gloss([("RDAP","modern successor to WHOIS — structured registration data"),("CT log","certificate-transparency log: every TLS cert ever issued, public"),("TXT","DNS records used for SPF/verification claims")]) + body += agent_card('GET /api/domain?d=example.com', 'curl "https://dark0rbits.thetempleofdoom.com/api/domain?d=example.com"', 'RDAP registration, DNS records, CT-log subdomains. Passive OSINT, free.') + return page("domain", body) + +@app.route("/api/domain", methods=["GET", "POST"]) +def api_domain(): + r = rate_limit("domain", 10, 60) + if r: return r + d = (param("d") or "").strip() + if not d or len(d) > 100: return jsonify({"ok": False, "error": "d required"}), 400 + return jsonify(domain_report(d)) + @app.route("/card", methods=["GET", "POST"]) def card(): result = "" @@ -1024,7 +1325,7 @@ if(sr.headings&&sr.headings.length)h+='
    ';body.innerHTML=h;return}} if(sr.status==='error'){{body.innerHTML=''+_esc(sr.error)+'';return}} body.textContent='rendering… (poll '+i+'/20)'}}}}catch(e){{body.textContent='error: '+e}}}} -""" + SHOT_API + how(["Paste a URL — the job queues with a 25¢ charge (free with PASS).", +""" + SHOT_API + how(["Paste a URL — the job queues instantly (free).", "With a headless browser on the host you get a real PNG back as base64.", "No browser installed? You get text_fallback: title, description, headings, first 400 words — honestly labeled.", "Agents: POST /api/shot/create then poll /api/shot/status/ until status != queued.", @@ -1139,7 +1440,7 @@ def sms(): hist = con.execute("SELECT * FROM sms_rentals WHERE user_id=? ORDER BY id DESC LIMIT 8", (uid,)).fetchall() hist_rows = "".join(f"+{h['phone']} copy{h['service']}{h['status']}#{h['purchase_id']}…" for h in hist) body = f""" -

    SMS RENTAL

    Disposable numbers, 30-minute windows. Cancel before a code = full refund.

    +

    SMS RENTAL

    Disposable numbers, 30-minute windows, free — the lab picks up the tab. Cancel before a code = instant burn.

    Rent a number
    @@ -1408,26 +1709,30 @@ def steg_extract(img_bytes, password="", bits=None, spread=None): @app.route("/steg", methods=["GET"]) def steg(): body = f""" -

    STEGO LAB

    Hide words inside pictures — LSB steganography with real settings. PNG in, PNG out, looks untouched.

    -
    -
    Hide text +

    STEGO LAB

    Hide secret text inside an ordinary PNG so completely that the picture looks untouched — no metadata, no visible change, nothing to see. Only someone who knows it's there (and has the password) can read it back.

    +
    +
    Hide text in a picture -
    📤 drop a PNG here or click
    +
    📤 drop a PNG here or click — bigger pictures hide more
    - - -
    - - -
    -
    -
    Extract text + + + +
    + +
    + +
    The download is a normal PNG. Post it, email it, host it — the secret rides along.
    +
    Read hidden text back
    -
    📥 drop the carrier PNG
    +
    📥 drop the carrier PNG — anyone can try, only the password works
    - -
    -
    + +
    + +
    -
    API: POST /api/steg/hide (image, text, password?, bits 1-3, spread) → PNG · POST /api/steg/extract (image, password?, bits?, spread?) → JSON
    """ + how(["Drop a PNG — your words are written into the least-significant bits of its pixels.","Depth 1 = invisible and robust; depth 2-3 fits more text but is easier to detect.","Spread=randomized scatters bits across the image instead of top-down.","A password encrypts the payload AND derives the scatter pattern — wrong password = noise.","Extract reads the embedded metadata automatically — just drop the file and the words come back."]) - body += gloss([("LSB","least significant bit — pixel bits that carry hidden data"),("depth","how many bit planes carry the payload"),("spread","payload dispersed across the image to survive edits")]) - body += agent_card('POST /api/steg/hide image= text=hi [password= bits= spread=]', 'curl -X POST https://dark0rbits.thetempleofdoom.com/api/steg/hide -F image=@x.png -F text=hi -F password=hunter2', 'Extract: POST /api/steg/extract. Free with PASS.') +
    API: POST /api/steg/hide (image, text, password?, bits 1-3, spread) → PNG · POST /api/steg/extract (image, password?, bits?, spread?) → JSON
    +""" + flow("smuggle a passphrase through a photo wall", [ +"you drop in a vacation photo — the meter says 1920×1080 holds ~777,600 hidden characters. Plenty.", +"you type the wifi password hunter2-sunset-2026, add password peanut, spread randomized, hit Hide.", +"the site flips the least-significant bits of random pixels — the downloaded PNG looks pixel-for-pixel identical to the original.", +"you post the photo publicly. It passes through phones, compressors, screenshots — it's just a picture.", +"ally saves it, opens STEGO LAB, drops the file, types peanut → the words come back.", +"stranger drops the same file with no password → noise. Without the key, it's a photo of a beach."]) + how([ +"Every pixel's color is three numbers. Change the last binary digit of each — changes of ±1 in brightness — and no eye can tell.", +"Depth 1 hides ~1 character per 2–3 pixels: invisible and robust. Depth 2–3 packs more but survives re-compression worse.", +"Randomized spread scatters your bits across the whole image instead of the top rows — a cropped picture can still give the text back.", +"A password encrypts the payload AND seeds the scatter pattern: wrong password yields pure noise, not garbage text.", +"Extraction auto-reads the embedded settings — the file knows its own depth and spread. Just drop and go.", +"Warning: posting to platforms that re-compress (Instagram, WhatsApp) can damage depth-1 edges — send the file itself, unmodified."]) + body += gloss([("LSB","least significant bit — the final binary digit of a color value; changing it is invisible"),("depth","how many bit-planes carry the payload — more depth, more text, more detectable"),("spread","where the bits live: top-down or scattered across the image"),("carrier","the innocent-looking picture that transports your hidden text")]) + body += agent_card('POST /api/steg/hide image= text=hi [password= bits= spread=]', 'curl -X POST https://dark0rbits.thetempleofdoom.com/api/steg/hide -F image=@beach.png -F text="wifi is hunter2" -F password=peanut', 'Extract: POST /api/steg/extract (image, password?). Free, 20/min.') return page("steg", body) @app.route("/api/steg/hide", methods=["POST"]) @@ -1485,22 +1815,40 @@ def track(): mine = "" if uid: con = db() - rows = con.execute("SELECT * FROM trackables WHERE user_id=? ORDER BY id DESC LIMIT 10", (uid,)).fetchall() + rows = con.execute("SELECT * FROM trackables WHERE user_id=? ORDER BY id DESC LIMIT 15", (uid,)).fetchall() if rows: - trs = "".join(f"{esc(t['filename'])}{'events' if t['paid'] else '—'}{'paid ✓' if t['paid'] else 'unpaid'}" for t in rows) - mine = f'
    Your trackables{trs}
    FileEventsStatus
    ' + trs = "".join( + f"{esc(t['filename'])}
    {t['kind'] or 'file'}" + f"{SITE}/t/{t['token']}" + f"{'view events' if t['paid'] else '—'}" + f"{'live' if t['paid'] else 'awaiting upload'}" + for t in rows) + mine = ('
    Your trackables
    ' + + trs + '
    FileTracked linkEventsStatus
    ') body = f""" -

    TRACK FILE

    Pay $1 BTC → upload a file or picture → get a tracked link + an email-ready version. Every open pings back into your INBOX.

    +

    TRACK FILE

    Upload any file or picture and get a tracked link for it. The moment anyone opens that link — or views the email version — their IP, city, ISP, device and language fire back into your INBOX. The image-IP trick, weaponized and clean.

    -1 · Pay $1
    -
    -
    BTCPay BTC only. After payment the upload opens automatically.
    +1 · Name your bait
    + +
    {mine} -
    How it works: your file gets a secret link — every open is logged (time, IP, device) and lands in your inbox. You also get an HTML copy with an embedded tracking pixel: email THAT and every view fires too. Login (no KYC) to see events.
    -
    API: POST /api/track/create (filename) → invoice · POST /api/track/upload?token= (file) → link · GET /api/track/events?token=
    """ + how(["Pay $1 in BTC — the invoice settles and unlocks the upload instantly.","Upload your file or picture: you get a secret tracked link plus an email-ready HTML copy.","Email the HTML copy or share the link — every open fires back.","Each open reports: exact time, real IP, city/country, ISP, timezone, VPN flag, device, language, referrer.","Alerts land in your INBOX the second it happens."]) +
    How it works: your file gets a secret link — every open is logged (time, IP, device) and lands in your inbox with geo. You also get an HTML copy with an embedded tracking pixel: email THAT and every view fires too. Login (no KYC) to see events.
    +
    API: POST /api/track/create (filename) → upload_url · POST /api/track/upload?token= (file) → tracked_link + pixel + email_html · GET /api/track/events?token=
    """ + flow("learn who opens your 'photo'", [ +"you create a trackable named sunset.jpg — free, instant, and the upload page opens.", +"you upload the actual photo. You get back: a tracked link, a pixel URL, and an email-ready HTML copy.", +"you send the link — 'hey check out this pic'. That's the whole trick.", +"them taps it. The image renders normally in their browser — but the page quietly pings home first.", +"you INBOX lights up: sunset.jpg opened — IP 203.0.113.7 · Rotterdam NL · KPN · Android Chrome · timezone Europe/Amsterdam.", +"the HTML copy works over email too — every preview pane that loads images fires the pixel, no click needed."]) + how([ +"Free now — click create and the upload opens instantly, no payment.", +"Upload your file or picture: you get a secret tracked link plus an email-ready HTML copy.", +"Email the HTML copy or share the link — every open fires back.", +"Each open reports: exact time, real IP, city/country, ISP, timezone, VPN flag, device, language, referrer.", +"Alerts land in your INBOX the second it happens; full event log via the API."]) return page("track", body) + BTCPAY_PUBLIC = "https://btcpay.thetempleofdoom.com" def public_checkout(link): """LAN invoices must be payable from the open internet — swap host on checkout links.""" @@ -1677,11 +2025,11 @@ def mail(): body = f"""

    BURNER MAIL

    Receive-only disposable mailboxes @thetempleofdoom.com. Counting down in real time. Anything you sign up for — codes, confirmations, one-off handouts — lands right here, no other identity attached.

    -Pick a package (BTC) +Pick a package (free) {''.join(f'
    ' for d,n,_,_ in MAIL_PACKS)} -
    Type your desired mailbox name, pick a length, pay the invoice — the mailbox activates the moment the payment settles.
    +
    Pick your mailbox and length — it activates instantly. Free now, no invoice.
    {mine} -
    API: POST /api/mail/create (local, days) → invoice · GET /api/mail/inbox?addr= (needs login) — inbound via Cloudflare Email Routing → worker relay.
    """ + how(["Pick a name and a package — 7, 30 or 90 days, BTC priced.","Pay the invoice; the mailbox activates the second it settles.","The address is receive-only: verification codes, confirmations, one-off handouts.","The countdown runs in real time; when it hits zero the mailbox retires itself.","All mail shows on the site inbox — nothing touches any other identity."]) +
    API: POST /api/mail/create (local, days) → activates instantly (free) · GET /api/mail/inbox?addr= (needs login) — inbound via Cloudflare Email Routing → worker relay.
    """ + how(["Pick a name and a package — 7, 30 or 90 days, all free now.","Pay the invoice; the mailbox activates the second it settles.","The address is receive-only: verification codes, confirmations, one-off handouts.","The countdown runs in real time; when it hits zero the mailbox retires itself.","All mail shows on the site inbox — nothing touches any other identity."]) return page("mail", body) @app.route("/api/mail/create", methods=["POST"]) @@ -1780,7 +2128,7 @@ def pass_page(): left = r["expires"] - int(time.time()) mine = f'
    PASS ACTIVE {left//86400} days {left%86400//3600}h left — all tools unlimited (proxy rentals still metered at the storefront), trackables free, burner mail discounts.
    ' body = f""" -

    PASS — ALL ACCESS

    One BTC payment. Near-unlimited everything on this site: unlimited SMS rentals (house caps still apply for sanity), free trackables, burner mail included, no per-tool payments.

    +

    PASS — EVERYTHING FREE

    The meters are gone: unlimited SMS rentals, free trackables, burner mail, screenshots — every tool costs nothing. No PASS needed anymore.

    {''.join(f'
    ' for d,n,_,_ in PASS_PACKS)}
    Proxy rentals stay separate (they burn real upstream bandwidth — buy those at the storefront).
    @@ -1862,7 +2210,7 @@ def keys(): keys_block = ('
    Keys'+keys_html+'
    KeyLabelCreated
    ') if rows else '' body = f"""

    API KEYS — balance: ${bal/100:.2f}

    -

    Metered access for agents and humans. Every paid call deducts from your balance. $1 free trial credit on signup. No KYC, BTC top-ups only.

    +

    Metered access is over — every tool is free for humans and agents. No top-ups, no meters, no KYC. Your API keys still work everywhere.

    New API key
    {newkey_block} @@ -1910,8 +2258,23 @@ def parse_headers(raw): hops = [] for h in msg.get_all("Received", []) or []: hop = h.strip().replace("\n", " ") - hops.append(hop[:300]) + hops.append(hop[:400]) out["hops"] = list(reversed(hops)) # first-hop origin first + # timestamps per hop → relay delays + times = [] + for h in hops: + m = re.search(r";\s*(.+)$", h) + if m: + try: + import email.utils as eu + t = eu.parsedate_to_datetime(m.group(1).strip()) + if t: times.append(t) + except Exception: pass + delays = [] + if len(times) >= 2: + for a, b in zip(times, times[1:]): + delays.append(round((b - a).total_seconds(), 1)) + out["delays"] = delays auth = msg.get_all("Authentication-Results", []) or [] out["auth_results"] = [a.strip()[:300] for a in auth] out["dkim"] = [d.strip()[:200] for d in (msg.get_all("DKIM-Signature", []) or [])][:3] @@ -1928,16 +2291,23 @@ def parse_headers(raw): addr_rt = ((m_rt.group(1) if m_rt else out["reply_to"]).strip()).lower() if addr_rt.split("@")[-1] != addr_from.split("@")[-1]: flags.append(f"Reply-To ({addr_rt}) differs from From — possible reply-hijack") - # origin IP = the bottom-most Received header (original sender); in reversed list it's index 0 + # origin IP: prefer X-Originator-IP, then the bottom-most (oldest) Received origin_ip = None - for h in hops: # reversed order → origin first - m = re.search(r"\[(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\]", h) or re.search(r"\b(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\b", h) - if m: - origin_ip = m.group(1); break + origin_src = None + xoi = msg.get("X-Originator-IP") or msg.get("X-Originating-IP") or "" + m = re.search(r"(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})", xoi) + if m: + origin_ip, origin_src = m.group(1), "X-Originator-IP header" + if not origin_ip: + for h in hops: + m = re.search(r"\[(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\]", h) or re.search(r"\b(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\b", h) + if m: + origin_ip, origin_src = m.group(1), "oldest Received hop" + break out["origin_ip"] = origin_ip + out["origin_source"] = origin_src if origin_ip: out["origin_geo"] = enrich_ip(origin_ip) out["flags"] = flags - # dmarc/spf/dkim verdict parse from Authentication-Results verdicts = {} blob = " ".join(out["auth_results"]).lower() for k in ("spf","dkim","dmarc"): @@ -1949,27 +2319,69 @@ def parse_headers(raw): @app.route("/eh") def eh(): body = f""" -

    EMAIL FORENSICS

    Paste full raw email headers (View source → copy all) — get the real origin, SPF/DKIM/DMARC verdicts, and spoof flags.

    -
    +

    MAIL FORENSICS

    Paste raw email headers — or drop the whole .eml file — and get the true origin IP + location, the full relay chain with per-hop delays, SPF/DKIM/DMARC verdicts, and automatic spoof detection.

    +
    Analyze an email + + + + +
    📄 drop a .eml file here or click
    +
    -
    API: POST /api/eh (raw=…) → JSON: origin IP+geo, hop chain, verdicts, spoof flags.
    """ + how(["Open the suspicious email → View source → copy ALL headers.","Paste them here — the parser walks the full Received chain.","The real origin IP is pulled from the bottom-most relay hop and geolocated.","SPF/DKIM/DMARC verdicts are extracted and color-coded.","Spoof markers are flagged automatically: envelope≠From domain, Reply-To hijacks."]) - body += gloss([("SPF","a domain's list of servers allowed to send its mail"),("DKIM","cryptographic signature on real mail from the domain"),("DMARC","policy for what receivers do when SPF/DKIM fail"),("envelope-from","actual SMTP sender — can differ from the visible From")]) - body += agent_card('POST /api/eh raw=', 'curl -X POST https://dark0rbits.thetempleofdoom.com/api/eh --data-urlencode raw@headers.txt', 'Returns origin IP, hop chain, SPF/DKIM/DMARC verdicts, spoof flags.') + +
    API: POST /api/eh (raw=…) → JSON: origin IP + geo + source, hop chain, per-hop delays, verdicts, spoof flags. Free.
    """ + flow("was this 'bank email' really sent by the bank?", [ +"you get a scary email from security@yourbank-support.com — open it, ⋮ → Show original, copy everything.", +"you paste the headers here (or drop the .eml) and hit Analyze.", +"site walks the Received chain bottom-up: the oldest hop is where the mail actually entered the internet.", +"origin IP found: 185.234.72.19 — a bulletproof host in Sofia, Bulgaria · datacenter ⚠ — not your bank's infrastructure.", +"verdicts come back: SPF fail · DKIM none · DMARC fail — three red tags.", +"spoof flags light up: envelope-from ≠ From domain — the display name is wearing a costume.", +"relay delays show the 4-second stall at a server that has no business handling bank mail.", +"you verdict: phishing. Delete, report, done — and you have the origin evidence to show for it."]) + how([ +"An email's headers are its postal history — every server that touched it adds a Received line, and liars can't forge the chain reliably.", +"We read the chain from the bottom (oldest) up: that first hop is the true origin, and we geolocate its IP.", +"SPF/DKIM/DMARC are the domain's own authentication verdicts — fails here mean the mail didn't come from where it claims.", +"Spoof markers are checked automatically: envelope sender vs display From, Reply-To hijacks, mismatched domains.", +"Per-hop relay delays expose weird pit stops — legit bank mail doesn't detour through random countries.", +"Everything works from pasted headers OR a dropped .eml file — the parser handles both."]) + body += gloss([("Received chain","the list of every server an email passed through, newest first"),("SPF","a domain's list of servers allowed to send its mail"),("DKIM","cryptographic signature on real mail from the domain"),("DMARC","policy for what receivers do when SPF/DKIM fail"),("envelope-from","actual SMTP sender — can differ from the visible From"),(".eml","the raw email file itself — headers + body, openable from any mail app")]) + body += agent_card('POST /api/eh raw=', 'curl -X POST https://dark0rbits.thetempleofdoom.com/api/eh --data-urlencode raw@headers.txt', 'Returns origin_ip, origin_geo, hops, delays, verdicts, flags. No auth needed for 20/min.') return page("eh", body) @app.route("/eh_result", methods=["POST"]) def eh_result(): - d = parse_headers(request.form.get("raw") or "") - hops = "".join(f"
    hop {i+1}
    {esc(h)}
    " for i, h in enumerate(d["hops"])) + raw = request.form.get("raw") or "" + f = request.files.get("eml") + if f and not raw.strip(): + raw = f.read().decode("utf-8", "replace") + d = parse_headers(raw) + hops_html = "" + for i, h in enumerate(d["hops"]): + delay = f'+{d["delays"][i-1]}s to next hop' if i >= 1 and i-1 < len(d["delays"]) else "" + hops_html += f'
    hop {i+1}{delay}
    {esc(h)}
    ' verdicts = " ".join(f'{k.upper()}: {v}' for k, v in d["verdicts"].items()) - flags = "".join(f"
    {esc(f)}

    " for f in d["flags"]) or 'no spoof markers found' + flags = "".join(f'
    ⚠ {esc(f)}
    ' for f in d["flags"]) or '✓ no spoof markers found' og = d.get("origin_geo") or {} - origin = f"{esc(d.get('origin_ip'))}" + (f" — {esc(og.get('city'))}, {esc(og.get('country'))} · {esc(og.get('isp'))}" if og else "") - return page("eh", f""" -

    VERDICT {esc(d.get('subject') or '(no subject)')}

    -{kv([("From", esc(d.get('from'))), ("Envelope-from", esc(d.get('return_path'))), ("Reply-To", esc(d.get('reply_to') or '—')), ("Origin IP", origin)])} -
    Authentication
    {verdicts}

    Spoof flags
    {flags}
    -
    Relay chain (origin first){hops or 'no Received headers'}
    """) + orows = [("Origin IP", f"{esc(d.get('origin_ip') or 'not found')}")] + if d.get("origin_source"): orows.append(("Found via", esc(d["origin_source"]))) + if og: orows += [("Location", f"{esc(og.get('city'))}, {esc(og.get('regionName'))} {esc(og.get('countryCode'))}"), ("ISP", f"{esc(og.get('isp'))}{' · datacenter ⚠' if og.get('hosting') else ''}{' · VPN/proxy ⚠' if og.get('proxy') else ''}")] + body = f""" +

    VERDICT — {esc(d.get('subject') or '(no subject)')[:80]}

    +{kv(orows + [("From", esc(d.get('from'))), ("Envelope-from", esc(d.get('return_path') or '—')), ("Reply-To", esc(d.get('reply_to') or '—')), ("Date", esc(d.get('date') or '—'))])} +
    Authentication
    {verdicts}
    Spoof flags
    {flags}
    +
    Relay chain — origin first{hops_html or 'no Received headers'}
    +""" + return page("eh", body) @app.route("/api/eh", methods=["POST"]) def api_eh(): @@ -1977,19 +2389,27 @@ def api_eh(): if r: return r return jsonify(parse_headers(param("raw") or "")) + # ---------- 6e. IMAGE FORENSICS ---------- @app.route("/forensics") def forensics(): body = f""" -

    IMAGE FORENSICS

    EXIF dump, GPS extraction, date/software flags, error-level analysis (ELA) — spot edits, and sniff out OTHER people's stego.

    +

    IMAGE FORENSICS

    Deep forensics: full EXIF across all IFDs, GPS decoded to a map pin, XMP editor trails, embedded thumbnails, hashes, error-level analysis — expose doctored photos and find where they were taken.

    🖼 drop an image
    -
    API: POST /api/forensics (image) → JSON: exif, gps, flags, ELA score.
    """ + how(["Drop any image — EXIF and GPS get dumped instantly.","Error-level analysis (ELA) re-compresses and diffs: edited regions glow in the amplified view.","Edit-tool tags (Photoshop/GIMP) are flagged automatically.","EXIF-stripped images get flagged too — usually means scrubbed or generated.","If the image carries a DARK0RBITS stego payload, this tool sees it."]) +
    API: POST /api/forensics (image) → JSON: exif (all IFDs), gps_decoded (lat/lon + map links), xmp, thumbnail_b64, hashes, flags, ela_max_diff, verdict.
    """ + how(["Drop any image — every EXIF tag across IFD0, the EXIF sub-IFD and GPS gets dumped.", +"GPS is decoded to decimal degrees with one-click Google Maps / OpenStreetMap links — that's where the photo was taken.", +"XMP packets are parsed from the raw file: Adobe, Apple and Android editors leave trails there even after EXIF 'scrubbing'.", +"The embedded JPEG thumbnail is extracted — it can survive scrubbing and hold unstripped detail.", +"Error-level analysis (ELA) re-compresses and diffs: edited regions glow in the amplified view.", +"More than a dozen editors (Photoshop, GIMP, Canva, Snapseed, Lightroom…) are flagged automatically.", +"File hashes + format + dimensions come back too — match images across posts or leaks.", +"If the image carries a DARK0RBITS stego payload, this tool sees it."]) body += gloss([("ELA","error level analysis — regions re-saved after editing light up"),("EXIF","camera/software metadata embedded in the file"),("quantization","JPEG compression-table fingerprints")]) - body += agent_card('POST /api/forensics image=', 'curl -X POST https://dark0rbits.thetempleofdoom.com/api/forensics -F image=@img.jpg', 'EXIF dump, GPS, ELA score, editor flags.') + body += agent_card('POST /api/forensics image=', 'curl -X POST https://dark0rbits.thetempleofdoom.com/api/forensics -F image=@img.jpg', 'Deep: EXIF all IFDs, gps_decoded with map links, xmp, thumbnail_b64, hashes, ELA verdict.') return page("forensics", body) def _ela_score(img_bytes): @@ -2003,51 +2423,118 @@ def _ela_score(img_bytes): out = io.BytesIO(); enh.save(out, "PNG") return out.getvalue(), maxdiff -@app.route("/forensics_result", methods=["POST"]) -def forensics_result(): - f = request.files.get("image") - if not f: return page("steg", "no image") - data = f.read() +def _deep_forensics(data): + """Deep image analysis: full EXIF (all IFDs), decoded GPS, XMP, thumbnail, + hashes, file info, editor flags, ELA. Shared by web + API.""" from PIL import Image + from PIL.ExifTags import TAGS, GPSTAGS + import hashlib, re as _re im = Image.open(io.BytesIO(data)) + out = {"file": {}, "exif": {}, "exif_exif": {}, "gps": {}, "gps_decoded": None, + "xmp": {}, "flags": [], "stego_payload": ("auriga_meta" in im.info or "dark0rbits_meta" in im.info)} + fmt = im.format or "?" + out["file"] = {"format": fmt, "mode": im.mode, "size": list(im.size), "bytes": len(data), + "sha256": hashlib.sha256(data).hexdigest()[:32], "md5": hashlib.md5(data).hexdigest()[:24]} exif = im.getexif() - rows = [] - gps = {} - try: - from PIL.ExifTags import TAGS, GPSTAGS - except Exception: - TAGS, GPSTAGS = {}, {} + def _s(v): + return str(v.decode("utf-8", "replace") if isinstance(v, bytes) else v)[:200] for k, v in exif.items(): - name = TAGS.get(k, k) if isinstance(k, int) else k - try: rows.append((str(name), str(v)[:120])) + try: out["exif"][str(TAGS.get(k, k) if isinstance(k, int) else k)] = _s(v) except Exception: pass - # GPS + # EXIF sub-IFD (camera settings, lenses, serials…) + try: + sub = exif.get_ifd(0x8769) + for k, v in sub.items(): + try: out["exif_exif"][str(TAGS.get(k, k))] = _s(v) + except Exception: pass + except Exception: pass + # GPS sub-IFD, raw + decoded to decimal degrees + map links try: gifd = exif.get_ifd(0x8825) if gifd: for k, v in gifd.items(): - gps[GPSTAGS.get(k, k)] = str(v)[:60] + try: out["gps"][str(GPSTAGS.get(k, k))] = _s(v)[:80] + except Exception: pass + def _dms(t): + return float(t[0]) + float(t[1]) / 60.0 + float(t[2]) / 3600.0 + if gifd.get(2) and gifd.get(3): + try: + la, lo = _dms(gifd[2]), _dms(gifd[3]) + if str(gifd.get(1, "")).upper() in ("S", "SOUTH"): la = -la + if str(gifd.get(4, "")).upper() in ("W", "WEST"): lo = -lo + out["gps_decoded"] = {"lat": round(la, 6), "lon": round(lo, 6), + "maps": f"https://www.google.com/maps?q={la:.6f},{lo:.6f}", + "osm": f"https://www.openstreetmap.org/?mlat={la:.6f}&mlon={lo:.6f}#map=16/{la:.6f}/{lo:.6f}"} + except Exception: pass except Exception: pass - flags = [] - if not rows: flags.append("EXIF stripped/absent — edited or privacy-scrubbed") - else: - for k, v in rows: - if "software" in k.lower(): flags.append(f"software: {v}") - if "Photoshop" in v or "GIMP" in v: flags.append(f"⚠ EDITED IN {v}") - stego = ("auriga_meta" in im.info or "dark0rbits_meta" in im.info) + # XMP packet from raw bytes (Adobe/phone editing trails) + try: + m = _re.search(rb"", data, _re.S) + if not m: m = _re.search(rb"", data, _re.S) + if m: + x = m.group(0).decode("utf-8", "replace") + for attr in _re.findall(r'(?:xmp|tiff|exif|photoshop|aux|apple|digikam):([A-Za-z]+)="([^"]{1,120})"', x): + out["xmp"][attr[0] + ":" + attr[1]] = attr[2] + for tag in _re.findall(r"<(?:xmp|tiff|exif|photoshop|aux|apple):([A-Za-z]+)>([^<]{1,120})= 0: + tif_end = data.find(b"\xff\xdb", idx) # first DQT after APP1 + if tif_end > idx: + seg = data[idx:tif_end] + if b"\xff\xd8\xff" in seg[6:]: + tj = seg[6 + seg[6:].find(b"\xff\xd8\xff"):] + end = tj.find(b"\xff\xd9") + if end > 0: + tb = tj[:end + 2] + thumb_b64 = base64.b64encode(tb).decode()[:200000] + out["flags"].append(f"embedded thumbnail present ({len(tb)} bytes) — may hold unscrubbed detail") + except Exception: pass + if thumb_b64: out["thumbnail_b64"] = thumb_b64 ela_png, maxdiff = _ela_score(data) - fn = (f.filename or "image")[:60] - verdict = "CLEAN-ISH" if maxdiff < 12 and not flags else "SUSPECT — check ELA" - rows_html = "".join(f"{esc(k)}{esc(v)}" for k, v in rows) - gps_html = " ".join(f"
    {esc(k)}: {esc(v)}
    " for k, v in gps.items()) or "—" import base64 as b64mod - ela_b64 = b64mod.b64encode(ela_png).decode() + out["ela_png_b64"] = b64mod.b64encode(ela_png).decode() + out["ela_max_diff"] = maxdiff + verdict = "CLEAN-ISH" if maxdiff < 12 and not out["flags"] else "SUSPECT — check ELA + flags" + out["verdict"] = verdict + return out + +@app.route("/forensics_result", methods=["POST"]) +def forensics_result(): + f = request.files.get("image") + if not f: return page("steg", "no image") + d = _deep_forensics(f.read()) + fn = (f.filename or "image")[:60] + rows_html = "".join(f"{esc(k)}{esc(v)}" for k, v in {**d["exif"], **d["exif_exif"], **d["xmp"]}.items()) + gps_html = " ".join(f"
    {esc(k)}: {esc(v)}
    " for k, v in d["gps"].items()) or "—" + if d.get("gps_decoded"): + g = d["gps_decoded"] + gps_html += f'
    DECODED: {g["lat"]}, {g["lon"]} — Google Maps → OSM →
    ' + f_rows = "".join(f"{esc(k)}{esc(v)}" for k, v in d["file"].items()) return page("steg", f"""

    FORENSICS {esc(fn)}

    -{kv([("Verdict", f'{verdict}'), ("ELA max diff", f"{maxdiff} (low=uniform=re-saved clean)"), ("EXIF", f"{len(rows)} tags"), ("Stego", "DARK0RBITS payload present ✓" if stego else "none detected")])} -
    Flags
    {'
    '.join(esc(x) for x in flags) or 'none'}
    -
    ELA (amplified 15×)
    full PNG
    -
    EXIF table{rows_html or ''}
    no EXIF
    +{kv([("Verdict", f'{d["verdict"]}'), ("ELA max diff", f'{d["ela_max_diff"]} (low=uniform=re-saved clean)'), ("EXIF tags", f'{len(d["exif"]) + len(d["exif_exif"])} + {len(d["xmp"])} XMP'), ("Stego", "DARK0RBITS payload present ✓" if d["stego_payload"] else "none detected")])} +
    File{f_rows}
    +
    Flags
    {'
    '.join(esc(x) for x in d["flags"]) or 'none'}
    +
    ELA (amplified 15×)
    +{f'
    Embedded thumbnail
    ' if d.get("thumbnail_b64") else ''} +
    EXIF table (all IFDs + XMP){rows_html or ''}
    no EXIF
    GPS{gps_html}
    """) @app.route("/api/forensics", methods=["POST"]) @@ -2056,74 +2543,161 @@ def api_forensics(): if r: return r f = request.files.get("image") if not f: return jsonify({"ok": False, "error": "image required"}), 400 - data = f.read() - from PIL import Image - im = Image.open(io.BytesIO(data)) - exif = im.getexif() - ex = {} - try: - from PIL.ExifTags import TAGS - except Exception: - TAGS = {} - for k, v in exif.items(): - try: ex[str(TAGS.get(k, k) if isinstance(k, int) else k)] = str(v)[:200] - except Exception: pass - _, maxdiff = _ela_score(data) - return jsonify({"ok": True, "exif": ex, "gps_present": bool(exif.get_ifd(0x8825)) if hasattr(exif, "get_ifd") else False, - "stego_payload": ("auriga_meta" in im.info or "dark0rbits_meta" in im.info), "ela_max_diff": maxdiff, - "flags": (["exif-stripped"] if not ex else [])}) + d = _deep_forensics(f.read()) + d.pop("ela_png_b64", None) + d["filename"] = (f.filename or "image")[:60] + return jsonify({"ok": True, **d}) + +# ---------- 6f. CANARY TRAPS v2 (tripwires) ---------- +CRED_TEMPLATES = [ + ("AWS access key", "AKIA{0}", "drop in a config file — anyone who uses it to check AWS trips the wire"), + ("DB connection string", "postgres://svc_backup:{0}@db-internal.prod:5432/users", "classic honeytoken for dumped configs"), + ("API bearer token", "sk_live_{0}", "looks like a payment API key — screams 'valuable' to an attacker"), +] + +def _cred_line(token): + import random as _r + _r.seed(token) + body = "".join(_r.choice("ABCDEFGHJKLMNPQRSTUVWXYZ23456789") for _ in range(16)) + name, tmpl, note = CRED_TEMPLATES[token.__hash__() % len(CRED_TEMPLATES)] if False else CRED_TEMPLATES[_r.randrange(len(CRED_TEMPLATES))] + return name, tmpl.format(body), note + +def canary_hit_row(cid): + con = db() + ip = request.headers.get("X-Real-IP") or request.remote_addr or "?" + ua = request.headers.get("User-Agent", "") + lang = request.headers.get("Accept-Language", "") + ref = request.headers.get("Referer", "") + con.execute("INSERT INTO canary_hits(canary_id,ts,ip,ua,lang,ref) VALUES(?,?,?,?,?,?)", + (cid, int(time.time()), ip, ua[:200], lang[:60], ref[:160])) + con.commit() # commit BEFORE notify opens another connection (db-locked race) + return ip, ua + +def canary_notify(c, ip, ua): + geo = enrich_ip(ip) + where = f" — {geo.get('city','')}, {geo.get('regionName','')} {geo.get('countryCode','')} · {geo.get('isp','')}" if geo else "" + if geo.get("proxy"): where += " · VPN/proxy ⚠" + if geo.get("hosting"): where += " · datacenter ⚠" + kind = c["kind"] or "link" + con = db() + con.execute("INSERT INTO messages(user_id,sender,body,created) VALUES(?,?,?,?)", + (c["user_id"], "operator-bot", + f"🚨 CANARY FIRED: '{c['tag']}' ({kind}) — IP {esc(ip)}{esc(where)}
    device: {esc(ua[:100])}", int(time.time()))) + con.commit() -# ---------- 6f. CANARY TRAPS ---------- @app.route("/canary") def canary(): uid = current_user_id() body = f""" -

    CANARY TRAPS

    Plant tripwires. Anyone who touches one — clicks the link, loads the pixel — fires an instant alert into your inbox. Tag each trap with who it belongs to.

    -
    New trap
    - -
    -
    You get: a link (paste anywhere), a pixel URL (embed in docs/pages), and a fake credential line to drop in files.
    +

    CANARY TRAPS

    Tripwires for your files, folders, docs and links. When ANYONE touches one — opens the link, loads the pixel, pastes the credential into a checker — you get an instant alert with their IP, city, ISP and device. Nobody trips a canary by accident: that's the point.

    +
    New trap +
    + + + + +
    {canary_list()} -
    API: POST /canary (tag) · GET /api/canary/list (login) · hits log like trackables.
    """ + how(["Create a trap and tag it with who/where it belongs.","Plant the link anywhere — or embed the pixel URL, or drop the fake credential line.","The moment ANYONE touches it: IP, geo, ISP, device fire into your inbox.","Each trap shows its hit count and armed/triggered status.","One trap per place — re-plant after it fires."]) +
    API: POST /canary (tag, kind, rearm) · GET /api/canary/list (login) · GET /api/canary/hits?token= (login) — full hit log with geo.
    """ + flow("catch someone opening your stolen files", [ +"you create a trap tagged laptop-backups, type stealth link.", +"you save the link as RESTORE_THIS.txt inside your backup folder.", +"months later a thief copies the folder and opens the file out of curiosity.", +"them the link opens — a blank 404, nothing suspicious — but the tripwire fires.", +"you your INBOX lights up: laptop-backups hit from 203.0.113.7 — Rotterdam, NL · KPN · Windows Chrome · their timezone.", +"open /canary → the trap row shows hit count + view hits → full log: time, IP, geo, device, language."]) + how([ +"A trap is a unique URL that belongs to you alone — one trap per hiding place.", +"Stealth link returns a plain 404 page so the opener suspects nothing; the pixel is a 1×1 image that loads invisibly inside docs and emails.", +"The credential type gives you a realistic-looking fake AWS key or DB password — attackers who find it run it through a checker, and the check itself is the tripwire.", +"Every hit logs IP, city/region/country, ISP, device, language, referrer — and pings your site INBOX instantly.", +"Leave rearm OFF for one-shot traps (the trap flips to TRIGGERED), ON when you want to keep counting hits silently."]) + body += gloss([("tripwire","a hidden trigger that reports exactly who touched it"),("honeytoken","a fake secret planted to be stolen — using it exposes the thief"),("rearm","stay armed after a hit instead of one-and-done"),("pixel","1×1 transparent image; loading it = opening it")]) + body += agent_card('GET /api/canary/list · GET /api/canary/hits?token=', 'curl "https://dark0rbits.thetempleofdoom.com/api/canary/hits?token=AbC123" -H "Cookie: dark0rbits_tok=…"', 'Hits include ts, ip, ua, lang, ref. Create traps with POST /canary (form: tag, kind, rearm).') return page("canary", body) def canary_list(): uid = current_user_id() - if not uid: return "" + if not uid: return '
    Log in (no KYC) to see your traps.
    ' con = db() - rows = con.execute("SELECT * FROM canaries WHERE user_id=? ORDER BY id DESC LIMIT 20", (uid,)).fetchall() + rows = con.execute("SELECT * FROM canaries WHERE user_id=? ORDER BY id DESC LIMIT 30", (uid,)).fetchall() trs = "" for c in rows: - hits = con.execute("SELECT COUNT(*) c FROM canary_hits WHERE canary_id=?", (c["id"],)).fetchone()["c"] - trs += f"{esc(c['tag'])}{SITE}/c/{c['token']} copy{SITE}/c/{c['token']}.png{hits}{'armed' if c['armed'] else 'triggered ⚠'}" - return f'
    Your traps{trs or ""}
    TagLinkPixelHitsStatus
    none yet
    ' + hits = con.execute("SELECT COUNT(*) c, MAX(ts) last FROM canary_hits WHERE canary_id=?", (c["id"],)).fetchone() + url = f"{SITE}/c/{c['token']}" + kind = c["kind"] or "link" + extra = "" + if kind == "cred": + _, line, _note = _cred_line(c["token"]) + extra = ('
    credential: ' + esc(line) + ' copy') + if kind == "file": + extra = f'
    honeyfile: {url}/download (downloads a plausible secrets.txt)' + last = time.strftime("%b %d %H:%M", time.localtime(hits["last"])) if hits["last"] else "—" + status = ('armed' + (" ⟳" if c["rearm"] else "") + '') if c["armed"] else 'triggered ⚠' + trs += (f"{esc(c['tag'])}
    {kind}" + f"{url}
    copy link · pixel{extra}" + f"{hits['c']}
    last {last}" + f"{status}" + f"view hits") + return ('
    Your traps
    ' + + (trs or '') + '
    TagTrap URLHitsStatusLog
    none yet — create one above
    ') @app.route("/canary", methods=["POST"]) def canary_create(): uid = current_user_id() - if not uid: return page("canary", "
    login required
    ") + if not uid: return page("canary", "
    login required — free, no KYC
    ") tag = (param("tag") or "untagged")[:80] + kind = param("kind") if param("kind") in ("link", "pixel", "cred", "file") else "link" + rearm = 1 if param("rearm") else 0 con = db() token = secrets.token_urlsafe(12) - con.execute("INSERT INTO canaries(user_id,token,tag,created,armed) VALUES(?,?,?,?,1)", (uid, token, esc(tag), int(time.time()))) + con.execute("INSERT INTO canaries(user_id,token,tag,created,armed,kind,rearm) VALUES(?,?,?,?,1,?,?)", (uid, token, esc(tag), int(time.time()), kind, rearm)) con.commit() resp = Response(status=302); resp.headers["Location"] = "/canary" return resp +@app.route("/canary/events") +def canary_events(): + uid = current_user_id() + token = param("token") or "" + if not uid: return page("canary", "
    login required
    ") + con = db() + c = con.execute("SELECT * FROM canaries WHERE token=? AND user_id=?", (token, uid)).fetchone() + if not c: return page("canary", "
    unknown trap
    ") + hits = con.execute("SELECT * FROM canary_hits WHERE canary_id=? ORDER BY id DESC LIMIT 100", (c["id"],)).fetchall() + trs = "" + for h in hits: + geo = {} + ip = (h["ip"] or "").strip() + if ip and not ip.startswith(("10.", "127.", "172.")): + g = enrich_ip(ip) + geo = g or {} + where = f"{geo.get('city','—')}, {geo.get('countryCode','')}" if geo else "—" + isp = geo.get("isp", "—") if geo else "—" + trs += (f"{time.strftime('%b %d %H:%M:%S', time.localtime(h['ts']))}{esc(ip)}" + f"{esc(where)}{esc(isp)}{esc((h['ua'] or '')[:90])}" + f"{esc(h['lang'] or '—')}") + empty = "no hits yet - quiet" + return page("canary", f""" +

    TRAP HITS

    Every touch on trap {esc(c['tag'])} ({c['kind'] or 'link'}).

    + +
    {trs or empty}
    WhenIPWhereISPDeviceLang
    """) + @app.route("/c/") def canary_hit(token): con = db() c = con.execute("SELECT * FROM canaries WHERE token=?", (token,)).fetchone() - if not c: return "not found", 404 - con.execute("INSERT INTO canary_hits(canary_id,ts,ip,ua) VALUES(?,?,?,?)", - (c["id"], int(time.time()), request.headers.get("X-Real-IP") or request.remote_addr, request.headers.get("User-Agent",""))) - con.execute("UPDATE canaries SET armed=0 WHERE id=?", (c["id"],)) + if not c: return "Not Found", 404 + kind = c["kind"] or "link" + ip, ua = canary_hit_row(c["id"]) + if not c["rearm"]: + con.execute("UPDATE canaries SET armed=0 WHERE id=?", (c["id"],)) + con.commit() # end this connection's txn BEFORE notify writes (db-locked race) if c["user_id"]: - ip = request.headers.get("X-Real-IP") or request.remote_addr - geo = enrich_ip(ip) - where = f" — {geo.get('city','')}, {geo.get('countryCode','')} · {geo.get('isp','')}" if geo else "" - con.execute("INSERT INTO messages(user_id,sender,body,created) VALUES(?,?,?,?)", - (c["user_id"], "operator-bot", f"🚨 CANARY TRIGGERED: '{c['tag']}' — IP {esc(ip)}{esc(where)} · device {esc(request.headers.get('User-Agent','')[:80])}", int(time.time()))) + canary_notify(c, ip, ua) con.commit() return "Not Found", 404 @@ -2133,13 +2707,49 @@ def canary_pixel(token): px = base64.b64decode("R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7") return Response(px, mimetype="image/gif", headers={"Cache-Control": "no-store"}) +@app.route("/c//download") +def canary_file(token): + canary_hit(token) + bait = ("# internal — do not share\n" + "aws_access_key_id = AKIA" + re.sub(r"[^A-Z0-9]", "", token.upper())[:16].ljust(16, "X") + "\n" + "aws_secret_access_key = " + secrets.token_urlsafe(40) + "\n" + "db_master = postgres://svc_restore:" + secrets.token_urlsafe(16) + "@db-internal.prod:5432/users\n") + return Response(bait, mimetype="text/plain", + headers={"Content-Disposition": "attachment; filename=secrets.txt", "Cache-Control": "no-store"}) + @app.route("/api/canary/list") def api_canary_list(): uid = current_user_id() - if not uid: return jsonify({"ok": False, "error": "login required — free no-KYC account at /inbox"}) + if not uid: return jsonify({"ok": False, "error": "login required — free no-KYC account at /inbox"}), 401 con = db() - rows = [dict(r) | {"hits": con.execute("SELECT COUNT(*) c FROM canary_hits WHERE canary_id=?", (r["id"],)).fetchone()["c"]} for r in con.execute("SELECT * FROM canaries WHERE user_id=? ORDER BY id DESC LIMIT 50", (uid,))] - return jsonify(rows) + rows = [] + for r in con.execute("SELECT * FROM canaries WHERE user_id=? ORDER BY id DESC LIMIT 50", (uid,)).fetchall(): + d = dict(r) + d["hits"] = con.execute("SELECT COUNT(*) c FROM canary_hits WHERE canary_id=?", (r["id"],)).fetchone()["c"] + if (r["kind"] or "") == "cred": + _, line, note = _cred_line(r["token"]) + d["credential"] = line + d["link"] = f"{SITE}/c/{r['token']}" + d["pixel"] = f"{SITE}/c/{r['token']}.png" + rows.append(d) + return jsonify({"ok": True, "traps": rows}) + +@app.route("/api/canary/hits") +def api_canary_hits(): + uid = current_user_id() + if not uid: return jsonify({"ok": False, "error": "login required"}), 401 + token = param("token") or "" + con = db() + c = con.execute("SELECT * FROM canaries WHERE token=? AND user_id=?", (token, uid)).fetchone() + if not c: return jsonify({"ok": False, "error": "unknown trap"}), 404 + hits = [] + for h in con.execute("SELECT * FROM canary_hits WHERE canary_id=? ORDER BY id DESC LIMIT 200", (c["id"],)).fetchall(): + d = dict(h) + g = enrich_ip(d.get("ip", "")) or {} + if g: + d["geo"] = {k: g.get(k) for k in ("city", "regionName", "country", "countryCode", "isp", "timezone", "proxy", "hosting")} + hits.append(d) + return jsonify({"ok": True, "trap": {"tag": c["tag"], "kind": c["kind"], "armed": c["armed"], "rearm": c["rearm"]}, "hits": hits}) # ---------- 6g. AGENT PASSPORT ---------- @app.route("/passport") @@ -2684,15 +3294,18 @@ def index(): tools = [ ("ip","IP INTEL","Geo, ASN, ISP, VPN/hosting flags, rDNS — your IP auto-detected, any target on demand.","◈","INTEL"), ("card","CARD CHECK","Luhn + BIN: issuer bank, brand, type, country, prepaid risk flags. Nothing stored, nothing charged.","◈","INTEL"), - ("eh","MAIL FORENSICS","Paste raw headers → real origin IP + geo, SPF/DKIM/DMARC verdicts, spoof flags.","◈","INTEL"), - ("forensics","IMAGE FORENSICS","EXIF, GPS, edit-tool detection, error-level analysis — expose doctored photos.","◈","INTEL"), + ("eh","MAIL FORENSICS","Paste headers or drop a .eml → true origin IP + geo, relay delays, SPF/DKIM/DMARC verdicts, spoof flags.","◈","INTEL"), + ("phone","PHONE LOOKUP","OSINT on any number: carrier, line type, region, timezones + free deep-dive leads. VOIP/fake detection.","◈","INTEL"), + ("user","USERNAME SLEUTH","One handle → probed across 16 platforms in parallel. Find where the human lives online.","◈","INTEL"), + ("domain","DOMAIN RECON","RDAP registration, full DNS, certificate-log subdomain discovery. Passive recon, free.","◈","INTEL"), + ("forensics","IMAGE FORENSICS","Deep EXIF (all IFDs), decoded GPS + map links, XMP trails, embedded thumbnails, ELA — expose doctored photos.","◈","INTEL"), ("sms","SMS RENTAL","Disposable numbers, 30-min windows, instant refund on cancel.","◈","ACQUIRE"), ("mail","BURNER MAIL","Receive-only mailboxes, 7–90 days, live countdown. Codes & confirmations without an identity.","◈","ACQUIRE"), ("proxy","PROXY LAB","Residential egress testing on the Pleiades rail — same gateway keys fleet-wide.","◈","ACQUIRE"), ("deaddrop","DEAD-DROP","AES-GCM encrypted notes that burn after N reads or TTL. Optional password. No trace left.","◈","ACQUIRE"), - ("steg","STEGO LAB","Hide words inside pictures. LSB depth, randomized spread, password-encrypted payloads.","◈","OPERATE"), - ("track","TRACK FILE","$1 → tracked link + email pixel. Every open reports back: IP, location, ISP, device.","◈","HUNT"), - ("canary","CANARY TRAPS","Tripwire links and pixels — instant alert the moment anyone touches one.","◈","HUNT"), + ("steg","STEGO LAB","Hide secret text inside a normal PNG — invisible, password-encrypted, scattered. Live capacity meter.","◈","OPERATE"), + ("track","TRACK FILE","Send an image or file, learn who opened it: IP, city, ISP, device, language — instantly in your inbox.","◈","HUNT"), + ("canary","CANARY TRAPS","Tripwires: stealth links, pixels, fake-credential honeytokens, honeyfile baits — instant alerts with IP + geo when touched.","◈","HUNT"), ("shot","SCREENSHOT","Headless-Chromium PNG capture of any page. Agents: poll the status API.","◈","HUNT"), ("score","FRAUD-SCORE","Composite 0-100 risk: IP intel + disposable-email + BIN heuristics, with full breakdown.","◈","HUNT"), ("tools","FREE TOOLS","DNS resolver, HTTP header inspector, JWT decoder, hasher, generators.","◈","UTILITY"), @@ -2710,7 +3323,7 @@ def index():
    $ ./dark0rbits --intro ▊

    The toolbox that treats you like an operator, not a product.

    -

    No KYC. No email. No Stripe — BTC only. Every tool has a JSON API, metered per call, so scripts and agents are first-class customers.

    +

    No KYC. No email. No meters — every tool is FREE. Every tool has a JSON API, so scripts and agents are first-class customers.

    {stat_line}
    {cta}
    {tcards}
    -NO KYC BTC ONLY AGENT-FIRST APIs {n_sms} SMS RENTALS SERVED {n_px} PROXY CHECKS
    +NO KYC ALL FREE AGENT-FIRST APIs {n_sms} SMS RENTALS SERVED {n_px} PROXY CHECKS
    For agents: machine catalog at /llms.txt, OpenAPI at /openapi.json, metered keys at /keys. For humans: click a card. That's it.
    """ @@ -2758,12 +3371,12 @@ def og_img(): except Exception: f = f2 = None dr.text((600, 290), "DARK0RBITS", fill=(255, 201, 77), anchor="mm", font=f) - dr.text((600, 390), "no-KYC network toolbox · BTC only · agents welcome", fill=(147, 160, 194), anchor="mm", font=f2) + dr.text((600, 390), "no-KYC network toolbox · everything free · agents welcome", fill=(147, 160, 194), anchor="mm", font=f2) buf = io.BytesIO(); im.save(buf, "PNG") return Response(buf.getvalue(), mimetype="image/png") @app.route("/health") -def health(): return jsonify({"ok": True, "service": "dark0rbits", "version": "2.0"}) +def health(): return jsonify({"ok": True, "service": "dark0rbits", "version": "3.0"}) # REDIRECT legacy auriga hostname → dark0rbits