Files
dark0rbits/app.py

2662 lines
176 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""Dark0rbits v2 — toolbox: IP intel, card validator, SMS rentals, proxy lab, stego lab,
trackable files (BTCPay), no-KYC site-only messaging inbox. Single-file Flask + SQLite."""
import base64, binascii, hashlib, hmac, html, io, ipaddress, json, os, re, secrets, shutil, socket, sqlite3, struct, subprocess, time, uuid
import urllib.request, urllib.parse
from flask import Flask, request, jsonify, render_template_string, Response, send_file
from flask import redirect
import importlib.util as _ilu
_HAVE_AESGCM = _ilu.find_spec("cryptography") is not None
app = Flask(__name__)
DB_PATH = os.environ.get("DARK0RBITS_DB", "/opt/dark0rbits/dark0rbits.db")
UPLOAD_DIR = os.environ.get("DARK0RBITS_UPLOADS", "/opt/dark0rbits/uploads")
os.makedirs(UPLOAD_DIR, exist_ok=True)
SMSP_KEY = os.environ.get("SMSP_KEY", "")
PLEIADES_GW = os.environ.get("PLEIADES_GW", "10.30.20.178:8080")
PLEIADES_APP = os.environ.get("PLEIADES_APP", "https://pleiades.thetempleofdoom.com")
BTCPAY = "https://10.30.20.140/api/v1"
BTCPAY_KEY = os.environ.get("BTCPAY_KEY", "6026288e2e315984661c748baafd509e81a75f22")
BTCPAY_STORE = os.environ.get("BTCPAY_STORE", "7h79ndYyZX2yF6CPa12xt2uVGQ5Fd6nrSDG4Koy86x6u")
WEBCHECK = os.environ.get("WEBCHECK", "http://10.30.20.13:3000")
ADMIN_PW = os.environ.get("DARK0RBITS_ADMIN", "Czapiewski1!")
BTCPAY_WHSEC = os.environ.get("BTCPAY_WHSEC", "TgJhmoBcNf9ATK2SFCg1VS")
BMAC = "https://buymeacoffee.com/r26xrthzttg"
SITE = "https://dark0rbits.thetempleofdoom.com"
def _migrate(con):
cols = [r[1] for r in con.execute("PRAGMA table_info(settings)")]
if not cols:
con.execute("CREATE TABLE IF NOT EXISTS settings(user_id INTEGER, key TEXT, val TEXT, PRIMARY KEY(user_id,key))")
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")
def db():
con = sqlite3.connect(DB_PATH); con.row_factory = sqlite3.Row
con.executescript("""CREATE TABLE IF NOT EXISTS sms_rentals(id INTEGER PRIMARY KEY, phone TEXT, service TEXT, country TEXT, purchase_id TEXT, cost REAL, status TEXT, created INTEGER, expires INTEGER);
CREATE TABLE IF NOT EXISTS proxy_checks(id INTEGER PRIMARY KEY, user_key TEXT, egress_ip TEXT, geo TEXT, ok INTEGER, ts INTEGER);
CREATE TABLE IF NOT EXISTS users(id INTEGER PRIMARY KEY, username TEXT UNIQUE, passhash TEXT, created INTEGER);
CREATE TABLE IF NOT EXISTS sessions(id INTEGER PRIMARY KEY, token TEXT UNIQUE, user_id INTEGER, created INTEGER);
CREATE TABLE IF NOT EXISTS trackables(id INTEGER PRIMARY KEY, user_id INTEGER, token TEXT UNIQUE, filename TEXT, kind TEXT, invoice_id TEXT, paid INTEGER DEFAULT 0, created INTEGER);
CREATE TABLE IF NOT EXISTS track_events(id INTEGER PRIMARY KEY, trackable_id INTEGER, ts INTEGER, ip TEXT, ua TEXT);
CREATE TABLE IF NOT EXISTS messages(id INTEGER PRIMARY KEY, user_id INTEGER, sender TEXT, body TEXT, created INTEGER);
CREATE TABLE IF NOT EXISTS mailboxes(id INTEGER PRIMARY KEY, user_id INTEGER, address TEXT UNIQUE, invoice_id TEXT, paid INTEGER DEFAULT 0, expires INTEGER DEFAULT 0, created INTEGER, plan_days INTEGER DEFAULT 7, cnt INTEGER DEFAULT 0);
CREATE TABLE IF NOT EXISTS mails(id INTEGER PRIMARY KEY, mailbox_id INTEGER, sender TEXT, subject TEXT, body TEXT, ts INTEGER);
CREATE TABLE IF NOT EXISTS passes(id INTEGER PRIMARY KEY, user_id INTEGER, invoice_id TEXT, paid INTEGER DEFAULT 0, expires INTEGER DEFAULT 0, plan_days INTEGER DEFAULT 30);
CREATE TABLE IF NOT EXISTS canaries(id INTEGER PRIMARY KEY, user_id INTEGER, token TEXT UNIQUE, tag TEXT, created INTEGER, armed INTEGER DEFAULT 1);
CREATE TABLE IF NOT EXISTS canary_hits(id INTEGER PRIMARY KEY, canary_id INTEGER, ts INTEGER, ip TEXT, ua TEXT);
CREATE TABLE IF NOT EXISTS balances(user_id INTEGER PRIMARY KEY, cents INTEGER DEFAULT 0);
CREATE TABLE IF NOT EXISTS apikeys(id INTEGER PRIMARY KEY, user_id INTEGER, key TEXT UNIQUE, label TEXT, created INTEGER, revoked INTEGER DEFAULT 0);
CREATE TABLE IF NOT EXISTS ledger(id INTEGER PRIMARY KEY, user_id INTEGER, delta_cents INTEGER, reason TEXT, ts INTEGER);
CREATE TABLE IF NOT EXISTS wh_processed(invoice_id TEXT PRIMARY KEY, ts INTEGER);
CREATE TABLE IF NOT EXISTS rate_hits(bucket TEXT, ip TEXT, ts INTEGER);
CREATE TABLE IF NOT EXISTS deadrops(id INTEGER PRIMARY KEY, user_id INTEGER, token TEXT UNIQUE, body_enc TEXT, reads_left INTEGER, burn_after INTEGER, expires INTEGER, pw_hash TEXT, created INTEGER);
CREATE TABLE IF NOT EXISTS shots(id INTEGER PRIMARY KEY, user_id INTEGER, url TEXT, status TEXT, result TEXT, created INTEGER);""")
_migrate(con)
return con
# ---------- USER SETTINGS (visible tunables, agent-settable) ----------
DEFAULT_SETTINGS = {
"bg": "1", "warp": "1", "parallax": "1", "density": "1.0", "speed": "1.0", "twinkle": "1.0",
"hue": "0", "grid": "1", "scan": "1", "toast": "1", "type": "1",
}
BOOL_SETTINGS = {"bg", "warp", "parallax", "grid", "scan", "toast", "type"}
RANGE_SETTINGS = {"density": (0, 2.5), "speed": (0, 3), "twinkle": (0, 3), "hue": (-180, 180)}
def get_settings(uid):
out = dict(DEFAULT_SETTINGS)
if not uid:
return out
con = db()
try:
for r in con.execute("SELECT key,val FROM settings WHERE user_id=?", (uid,)):
if r["key"] in out:
out[r["key"]] = r["val"]
except Exception:
pass
return out
def set_setting(uid, key, val):
if key not in DEFAULT_SETTINGS:
return False
if key in BOOL_SETTINGS:
val = "1" if str(val) in ("1", "true", "on", "yes") else "0"
elif key in RANGE_SETTINGS:
try:
lo, hi = RANGE_SETTINGS[key]
val = str(max(lo, min(hi, float(val))))
except Exception:
return False
con = db()
con.execute("INSERT INTO settings(user_id,key,val) VALUES(?,?,?) ON CONFLICT(user_id,key) DO UPDATE SET val=excluded.val", (uid, key, str(val)))
con.commit()
return True
# ---------- BILLING CORE (per-call metering for outside users) ----------
def get_balance(uid):
con = db()
con.execute("INSERT OR IGNORE INTO balances(user_id, cents) VALUES(?, 100)", (uid,)) # $1 free trial credit
con.commit()
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."""
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()
return True
def key_user():
"""API-key auth: Authorization: Bearer dk_... → user_id or None."""
auth = request.headers.get("Authorization", "")
if not auth.startswith("Bearer dk_"): return None
con = db()
r = con.execute("SELECT user_id FROM apikeys WHERE key=? AND revoked=0", (auth[7:],)).fetchone()
return r["user_id"] if r else None
def require_paid_key(cents, reason):
"""For API calls: key or session auth; metered charge. Returns (uid, error_json)."""
uid = key_user() or current_user_id()
if not uid: return None, (jsonify({"ok": False, "error": "auth required: account session or Authorization: Bearer dk_… key"}), 401)
if has_pass(uid): return uid, None # PASS = unlimited tools (proxy excluded)
if not charge(uid, cents, reason):
return None, (jsonify({"ok": False, "error": "insufficient balance", "balance_cents": get_balance(uid), "topup": SITE + "/keys"}), 402)
return uid, None
# ---------- RATE LIMITING ----------
_RL = {}
def rate_limit(bucket, limit, window):
"""Sliding-window per-IP limiter. Returns None if ok, else a 429 response."""
key = request.headers.get("X-Real-IP") or request.remote_addr or "?"
now = time.time()
con = db()
con.execute("DELETE FROM rate_hits WHERE bucket=? AND ts < ?", (bucket, now-window))
n = con.execute("SELECT COUNT(*) c FROM rate_hits WHERE bucket=? AND ip=?", (bucket, key)).fetchone()["c"]
if n >= limit:
return jsonify({"ok": False, "error": "rate limited — slow down"}), 429
con.execute("INSERT INTO rate_hits(bucket,ip,ts) VALUES(?,?,?)", (bucket, key, now))
con.commit()
return None
import ssl as _ssl
_CTX = _ssl.create_default_context()
_CTX.check_hostname = False
_CTX.verify_mode = _ssl.CERT_NONE
def http(url, headers=None, data=None, method="GET", timeout=12):
h = {"User-Agent": "Mozilla/5.0 (Dark0rbits toolbox)"}
h.update(headers or {})
req = urllib.request.Request(url, headers=h, data=data, method=method)
try:
with urllib.request.urlopen(req, timeout=timeout, context=_CTX) as r:
return r.status, r.read().decode("utf-8", "replace")
except urllib.error.HTTPError as e:
return e.code, e.read().decode("utf-8", "replace")
except Exception as e:
return 0, str(e)
def jf(b):
try: return json.loads(b)
except Exception: return None
def param(name):
return request.form.get(name) or request.args.get(name)
def esc(s): return html.escape(str(s))
# ---------- DEAD-DROP CRYPTO (AES-GCM on CT768, XOR-HMAC stream fallback) ----------
def _dd_master_key():
return hashlib.sha256(("dark0rbits-deaddrop-v1:" + (os.environ.get("DARK0RBITS_SECRET", "ct768-fallback-secret"))).encode()).digest()
def dd_encrypt(plaintext):
"""AES-256-GCM when cryptography is present, else HMAC-verified XOR stream. Returns 'mode:vault' string."""
if _HAVE_AESGCM:
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
nonce = secrets.token_bytes(12)
vault = AESGCM(_dd_master_key()).encrypt(nonce, plaintext.encode(), None)
return "aesgcm:" + base64.urlsafe_b64encode(nonce + vault).decode()
key = secrets.token_bytes(32)
stream = bytes(a ^ b for a, b in zip(plaintext.encode(), hashlib.shake_256(key + str(len(plaintext)).encode()).digest(len(plaintext) + 64)))
mac = hmac.new(_dd_master_key(), stream, hashlib.sha256).hexdigest()
return "xor:" + base64.urlsafe_b64encode(key + stream).decode() + ":" + mac
def dd_decrypt(vault):
try:
if vault.startswith("aesgcm:"):
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
raw = base64.urlsafe_b64decode(vault[7:].encode())
return AESGCM(_dd_master_key()).decrypt(raw[:12], raw[12:], None).decode()
if vault.startswith("xor:"):
k64, mac = vault[4:].rsplit(":", 1)
raw = base64.urlsafe_b64decode(k64.encode())
if not hmac.compare_digest(hmac.new(_dd_master_key(), raw[32:], hashlib.sha256).hexdigest(), mac): return None
n = len(raw) - 32 - 64
stream = bytes(a ^ b for a, b in zip(raw[32:], hashlib.shake_256(raw[:32] + str(n).encode()).digest(n + 64)))
return stream.decode()
except Exception:
pass
return None
BASE = """<!doctype html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1">
<title>DARK0RBITS — No-KYC Network Toolbox: IP Intel, Stego, Burner Mail, SMS Rentals, Proxy Lab</title>
<meta name=description content="DARK0RBITS: a no-KYC toolbox for operators and AI agents. IP intelligence, card BIN validation, burner mail, SMS number rentals, steganography, trackable files, email & image forensics, canary traps, residential proxy testing. BTC only.">
<meta name=keywords content="dark0rbits, no kyc tools, ip lookup, bin check, burner email, sms rental, steganography, stego, email forensics, image forensics, canary trap, proxy, bitcoin only, agent api">
<meta property="og:title" content="DARK0RBITS — The Operator's Toolbox">
<meta property="og:description" content="No-KYC network toolbox for humans and AI agents. BTC only. 12 tools, every one with a JSON API.">
<meta property="og:type" content="website">
<meta property="og:image" content="https://dark0rbits.thetempleofdoom.com/og.png">
<link rel="icon" href="/favicon.svg">
<meta property="og:url" content="https://dark0rbits.thetempleofdoom.com">
<meta name=robots content="index,follow">
<meta name=theme-color content="#070a13">
<link rel=canonical href="https://dark0rbits.thetempleofdoom.com">
<style>
:root{--bg:#070a13;--card:rgba(19,25,44,.82);--line:#242e4d;--fg:#e9edf8;--dim:#93a0c2;--acc:#a78bfa;--acc2:#6fd6ff;--acc3:#6fd6ff;--ok:#42e8a4;--bad:#ff6161}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{margin:0;min-height:100vh;color:var(--fg);font:16px/1.6 ui-monospace,Menlo,Consolas,monospace;text-align:center;overflow-x:hidden;background:var(--bg)}
#space{position:fixed;inset:0;z-index:0;display:block}
.vignette{position:fixed;inset:0;z-index:1;pointer-events:none;background:radial-gradient(ellipse at 50% -10%,var(--neb1,rgba(120,85,255,.16)),transparent 55%),radial-gradient(ellipse at 80% 110%,var(--neb2,rgba(0,190,255,.10)),transparent 50%),radial-gradient(ellipse at 50% 50%,transparent 60%,rgba(0,0,5,.55) 100%)}
main{position:relative;z-index:2;max-width:920px;margin:0 auto;padding:1.6rem 1.1rem 4rem;text-align:center}
#lbar{position:fixed;top:0;left:0;height:3px;width:0;background:linear-gradient(90deg,var(--acc),var(--acc2));z-index:50;transition:width .3s;box-shadow:0 0 10px var(--acc)}
#lbar.done{width:100%;opacity:0;transition:opacity .5s}
header{position:sticky;top:0;z-index:40;background:rgba(7,10,19,.86);backdrop-filter:blur(10px);border-bottom:1px solid var(--line)}
.hbar{max-width:920px;margin:0 auto;display:flex;align-items:center;justify-content:space-between;padding:.55rem 1rem}
.logo{color:var(--acc);text-decoration:none;font-weight:800;letter-spacing:.28em;font-size:1rem;text-shadow:0 0 18px rgba(167,139,250,.4)}
.burger{background:none;border:1px solid var(--line);color:var(--fg);font-size:1.15rem;border-radius:8px;padding:.35rem .7rem;cursor:pointer}
.burger:hover{border-color:var(--acc);color:var(--acc)}
.dnav{display:flex;flex-wrap:wrap;gap:.35rem;justify-content:center}
.dnav a{color:var(--dim);text-decoration:none;font-size:.72rem;padding:.3rem .55rem;border:1px solid var(--line);border-radius:999px;white-space:nowrap;transition:.15s}
.dnav a.on,.dnav a:hover{color:var(--acc);border-color:var(--acc)}
.tchip{color:var(--fg);margin-right:.5rem;white-space:nowrap}
.srow{display:flex;align-items:center;gap:.5rem;margin:.45rem 0;font-size:.85rem;color:var(--fg)}
.srow input[type=range]{flex:1;accent-color:var(--acc)}
.srow input[type=checkbox]{accent-color:var(--acc);width:16px;height:16px}
#pinp{background:var(--card);border:1px solid var(--line);border-radius:8px;padding:.6rem;color:var(--fg)}
.pitem{display:block;padding:.5rem .6rem;border:1px solid transparent;border-radius:8px;color:var(--fg);text-decoration:none;cursor:pointer}
.pitem:hover,.pitem.sel{border-color:var(--acc);color:var(--acc)}
.pitem small{display:block;color:var(--dim)}
: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}
@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}
.drawer.open{display:flex}
.drawer .dhead{display:flex;justify-content:space-between;align-items:center;margin-bottom:.8rem}
.drawer h4{color:var(--dim);font-size:.75rem;letter-spacing:.25em;text-align:left;margin:1rem 0 .4rem;text-transform:uppercase}
.drawer a.dl{color:var(--fg);text-decoration:none;padding:.65rem .8rem;border:1px solid var(--line);border-radius:10px;margin:.25rem 0;text-align:left;font-size:.95rem}
.drawer a.dl:hover,.drawer a.dl.on{border-color:var(--acc);color:var(--acc)}
.drawer a.dl small{display:block;color:var(--dim);font-size:.72rem}
@media(min-width:860px){.burger{display:none}}
@media(max-width:859px){.dnav{display:none}}
h1{font-size:1.55rem;letter-spacing:.18em;margin:.8rem 0 .2rem}
h1 span{color:var(--acc)}
.sub{color:var(--dim);margin:.2rem 0 1.4rem;font-size:.95rem}
.card{background:var(--card);border:1px solid var(--line);border-radius:16px;padding:1.15rem 1.2rem;margin:.9rem 0;backdrop-filter:blur(4px)}
.card.glow{box-shadow:0 0 34px -16px var(--acc)}
.kv{display:grid;grid-template-columns:1fr;gap:.25rem;text-align:left}
.kv div:nth-child(odd){color:var(--dim);font-size:.78rem;letter-spacing:.12em;text-transform:uppercase;padding-top:.45rem}
.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}}
input,select,button,textarea{font:inherit;background:rgba(10,15,30,.9);color:var(--fg);border:1px solid #2c3860;border-radius:10px;padding:.6rem .8rem;max-width:100%}
button{background:linear-gradient(135deg,var(--acc),var(--acc2));color:#0d0722;border:0;font-weight:800;cursor:pointer;transition:.2s;letter-spacing:.05em}
button:hover{filter:brightness(1.15);box-shadow:0 0 20px -4px var(--acc)}
button.ghost{background:transparent;color:var(--acc);border:1px solid var(--acc)}
button.big{font-size:1.02rem;padding:.75rem 1.4rem;margin:.25rem;color:#0d0722}
.grid2{display:grid;grid-template-columns:1fr;gap:.9rem;text-align:center}
@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:.85rem}
td,th{padding:.4rem;border-bottom:1px solid var(--line);text-align:left}
th{color:var(--dim);text-transform:uppercase;font-size:.7rem;letter-spacing:.14em}
footer{color:var(--dim);padding:2.2rem 1rem 5rem;font-size:.8rem;position:relative;z-index:2;text-align:center}
footer a{color:var(--acc)}
code{background:rgba(10,15,30,.9);padding:.08rem .4rem;border-radius:5px;font-size:.86em;word-break:break-all}
a{color:var(--acc2)}
pre{text-align:left;white-space:pre-wrap;overflow-x:auto}
.drop{border:2px dashed #33406b;border-radius:14px;padding:1.8rem 1rem;cursor:pointer;transition:.2s}
.drop:hover,.drop.over{border-color:var(--acc);background:rgba(167,139,250,.06)}
.msg{background:rgba(10,15,30,.75);border-left:3px solid var(--acc);border-radius:0 10px 10px 0;padding:.6rem .9rem;margin:.55rem 0;text-align:left}
.msg.me{border-left-color:var(--acc2)}
.msg .who{color:var(--dim);font-size:.74rem}
.bar{height:7px;background:rgba(10,15,30,.9);border-radius:4px;overflow:hidden}.bar>i{display:block;height:100%;background:linear-gradient(90deg,var(--acc),var(--acc2));width:0;transition:width .5s}
#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}
.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))}
</style></head><body>
<div id="lbar"></div>
<a class=skip href="#main">skip to content</a>
<canvas id="space"></canvas><div class="gridlines"></div><div class="vignette" style="--neb1:{{n1}};--neb2:{{n2}}"></div>
<header><div class="hbar">
<a class=logo href=/ data-t="◈ DARK0RBITS">◈ DARK0RBITS</a>
<div class="dnav">
<a href=/ class={{o('home')}}>HOME</a><a href=/ip class={{o('ip')}}>IP</a><a href=/card class={{o('card')}}>CARD</a>
<a href=/sms class={{o('sms')}}>SMS</a><a href=/proxy class={{o('proxy')}}>PROXY</a>
<a href=/steg class={{o('steg')}}>STEGO</a><a href=/track class={{o('track')}}>TRACK</a>
<a href=/eh class={{o('eh')}}>MAIL-FORENSICS</a><a href=/forensics class={{o('forensics')}}>IMG-FORENSICS</a>
<a href=/canary class={{o('canary')}}>CANARY</a><a href=/deaddrop class={{o('deaddrop')}}>DEAD-DROP</a><a href=/mail class={{o('mail')}}>BURNER-MAIL</a>
<a href=/shot class={{o('shot')}}>SHOT</a><a href=/score class={{o('score')}}>FRAUD-SCORE</a>
<a href=/inbox class={{o('inbox')}}>INBOX</a><a href=/passport class={{o('passport')}}>PASSPORT</a>
<a href=/pass class={{o('pass')}}>PASS</a><a href=/keys class={{o('keys')}}>KEYS</a><a href=/tools class={{o('tools')}}>TOOLS</a>
</div>
<div id="acct">{{acct}}</div><button class=burger id=burger onclick="drw()">☰</button>
</div></header>
<div class=drawer id=drawer>
<div class=dhead><span class=logo style=font-size:.85rem>DARK0RBITS — MAP</span><button class=burger onclick="drw()">✕</button></div>
<h4>Intel</h4>
<a class="dl {{o('ip')}}" href=/ip>◈ IP INTEL <small>geo, ASN, ISP, VPN flags — any target</small></a>
<a class="dl {{o('card')}}" href=/card>◈ CARD CHECK <small>luhn + BIN issuer intelligence</small></a>
<a class="dl {{o('eh')}}" href=/eh>◈ MAIL FORENSICS <small>origin + SPF/DKIM/DMARC + spoof flags</small></a>
<a class="dl {{o('forensics')}}" href=/forensics>◈ IMAGE FORENSICS <small>EXIF, GPS, ELA, edit detection</small></a>
<h4>Operate</h4>
<a class="dl {{o('sms')}}" href=/sms>◈ SMS RENTAL <small>30-min numbers, refundable</small></a>
<a class="dl {{o('proxy')}}" href=/proxy>◈ PROXY LAB <small>residential egress, geo builder</small></a>
<a class="dl {{o('steg')}}" href=/steg>◈ STEGO LAB <small>hide words in pictures</small></a>
<a class="dl {{o('mail')}}" href=/mail>◈ BURNER MAIL <small>receive-only mailboxes, countdown</small></a>
<h4>Hunt</h4>
<a class="dl {{o('track')}}" href=/track>◈ TRACK FILE <small>opens report back: IP, city, ISP</small></a>
<a class="dl {{o('canary')}}" href=/canary>◈ CANARY TRAPS <small>tripwires with instant alerts</small></a>
<a class="dl {{o('deaddrop')}}" href=/deaddrop>◈ DEAD-DROP <small>burn-after-read encrypted notes</small></a>
<a class="dl {{o('shot')}}" href=/shot>◈ SCREENSHOT <small>page capture or rendered-text fallback</small></a>
<a class="dl {{o('score')}}" href=/score>◈ FRAUD-SCORE <small>composite IP + email + BIN risk 0-100</small></a>
<a class="dl {{o('tools')}}" href=/tools>◈ FREE TOOLS <small>DNS, headers, JWT, hasher</small></a>
<h4>Account</h4>
<a class="dl {{o('inbox')}}" href=/inbox>◈ INBOX <small>no-KYC messaging</small></a>
<a class="dl {{o('keys')}}" href=/keys>◈ API KEYS <small>metered access, balance</small></a>
<a class="dl {{o('pass')}}" href=/pass>◈ PASS <small>$10/mo all-access</small></a>
<a class="dl {{o('passport')}}" href=/passport>◈ AGENT PASSPORT <small>machine-readable badge</small></a>
</div>
<main id="main">{{body}}</main>
<footer>DARK0RBITS · built for agents &amp; humans · <a href="{{bmac}}" target=_blank rel=noopener>☕ fuel the lab</a></footer>
<a id=dev href="#" onclick="location.href='mailto:'+atob('bWFrZW1vbmV5czhAcHJvdG9uLm1l')+'?subject=Dark0rbits%20support';return false">✦ REACH THE DEV</a>
{{ CFG_JS }}
<div id=gearbtn onclick="spToggle()" title="settings — space, speed, density, hue" style="position:fixed;left:14px;bottom:14px;z-index:70;width:40px;height:40px;border-radius:50%;border:1px solid var(--line);background:rgba(7,10,19,.85);color:var(--acc);font-size:1.1rem;cursor:pointer;display:flex;align-items:center;justify-content:center" aria-label="settings">⚙</div>
<div id=spanel class="card" style="display:none;position:fixed;left:14px;bottom:62px;z-index:71;width:270px;max-height:76vh;overflow-y:auto;text-align:left" aria-label="site settings">
<b style=color:var(--acc)>TUNABLES</b> <span style="color:var(--dim);font-size:.75rem">(saved to your account — agents: POST /api/settings)</span>
<label class=srow><input type=checkbox id=sbg onchange="spSet('bg',this.checked)"> nebula + starfield</label>
<label class=srow><input type=checkbox id=swarp onchange="spSet('warp',this.checked)"> hyperdrive warp on click</label>
<label class=srow><input type=checkbox id=sparallax onchange="spSet('parallax',this.checked)"> mouse parallax</label>
<label class=srow><input type=checkbox id=sgrid onchange="spSet('grid',this.checked)"> grid overlay</label>
<label class=srow><input type=checkbox id=sscan onchange="spSet('scan',this.checked)"> scanlines</label>
<label class=srow><input type=checkbox id=stoast onchange="spSet('toast',this.checked)"> toasts</label>
<label class=srow><input type=checkbox id=stype onchange="spSet('type',this.checked)"> typed boot text</label>
<label class=srow>star density <input type=range id=sdensity min=0 max=2.5 step=0.1 onchange="spSet('density',this.value)"> <span id=sdensityv></span></label>
<label class=srow>drift speed <input type=range id=sspeed min=0 max=3 step=0.1 onchange="spSet('speed',this.value)"> <span id=sspeedv></span></label>
<label class=srow>twinkle <input type=range id=stwinkle min=0 max=3 step=0.1 onchange="spSet('twinkle',this.value)"> <span id=stwinklev></span></label>
<label class=srow>hue shift <input type=range id=shue min=-180 max=180 step=5 onchange="spSet('hue',this.value)"> <span id=shuev></span></label>
<button style="margin-top:.5rem" onclick="spReset()">reset defaults</button>
<div style="color:var(--dim);font-size:.72rem;margin-top:.4rem">⌘K / Ctrl+K — command palette</div>
</div>
<div id=palwin style="display:none;position:fixed;inset:0;z-index:80;background:rgba(4,6,12,.8);backdrop-filter:blur(4px)" onclick="if(event.target===this)palClose()">
<div class="card" style="max-width:520px;margin:12vh auto;text-align:left">
<input id=pinp placeholder="type a command… (ip, sms, steg, keys, dead-drop, settings…)" style="width:100%;font-size:1rem" oninput="palFilter()" onkeydown="palKey(event)">
<div id=plist style="margin-top:.6rem;max-height:50vh;overflow-y:auto"></div>
</div></div>
<iframe name=playout id=playout style="display:none" title="api playground output"></iframe>
<script defer src="https://analytics.thetempleofdoom.com/script.js" data-website-id="953c15df-ba4c-453a-a7c6-465fa9e3f202"></script>
<script>
function drw(){document.getElementById('drawer').classList.toggle('open')}
document.addEventListener('keydown',function(e){if(e.key==='Escape')document.getElementById('drawer').classList.remove('open')})
function cp(t){navigator.clipboard.writeText(t).then(function(){toast('Copied ✓')})}
function toast(m){var d=document.createElement('div');d.textContent=m;d.style.cssText='position:fixed;bottom:60px;left:50%;transform:translateX(-50%);background:var(--acc);color:#161000;padding:.55rem 1.1rem;border-radius:10px;font-weight:800;z-index:99';document.body.appendChild(d);setTimeout(function(){d.remove()},1800)}
var lb=document.getElementById('lbar');
function lbGo(){lb.classList.remove('done');lb.style.width='12%';var w=12;var t=setInterval(function(){w=Math.min(w+6,88);lb.style.width=w+'%'},250);window._lbt=t}
function lbDone(){if(window._lbt)clearInterval(window._lbt);lb.style.width='100%';setTimeout(function(){lb.style.width='0';lb.classList.remove('done')},600)}
document.addEventListener('submit',lbGo,true);
document.addEventListener('click',function(e){var a=e.target.closest('a[href]');if(a&&a.getAttribute('href')&&a.getAttribute('href').charAt(0)==='/'){lbGo();setTimeout(lbDone,1200)}},true);
window.addEventListener('load',lbDone);
(function(){
var DRB=window.DRB||{};
function drbN(v){v=parseFloat(v);return isNaN(v)?1:v}
var c=document.getElementById('space'),x=c.getContext('2d'),W,H,stars=[],dust=[],warpF=1,warpT=0;
function rs(){W=c.width=innerWidth;H=c.height=innerHeight;
stars=[];var n=Math.min(340,Math.floor(W*H/7000*drbN(DRB.density||1)));
for(var i=0;i<n;i++)stars.push({x:Math.random()*W,y:Math.random()*H,z:Math.random()+.3,tw:Math.random()*6.28});
dust=[];for(i=0;i<14;i++)dust.push({x:Math.random()*W,y:Math.random()*H,r:40+Math.random()*90,vx:(Math.random()-.5)*.035,vy:(Math.random()-.5)*.028,h:Math.random()<.5?120:265,a:.05+Math.random()*.05});}
rs();addEventListener('resize',rs);
var mx=0,my=0,tx=0,ty=0;
addEventListener('mousemove',function(e){tx=(e.clientX/W-.5);ty=(e.clientY/H-.5)});
addEventListener('touchmove',function(e){if(e.touches[0]){tx=(e.touches[0].clientX/W-.5);ty=(e.touches[0].clientY/H-.5)}},{passive:true});
function frame(){
x.clearRect(0,0,W,H);
if(DRB.bg==='0'){x.clearRect(0,0,W,H);requestAnimationFrame(frame);return;}
var spd=drbN(DRB.speed===undefined?1:DRB.speed),twk=drbN(DRB.twinkle===undefined?1:DRB.twinkle);
if(warpT>0){warpT-=.04;warpF=1+warpT*10}else warpF=1;
for(var i=0;i<dust.length;i++){var d=dust[i];d.x+=d.vx*spd*warpF;d.y+=d.vy*spd*warpF;
if(d.x<-100)d.x=W+80;if(d.x>W+100)d.x=-80;if(d.y<-100)d.y=H+80;if(d.y>H+100)d.y=-80;
var g=x.createRadialGradient(d.x,d.y,0,d.x,d.y,d.r);
g.addColorStop(0,'hsla('+d.h+',70%,60%,'+d.a+')');g.addColorStop(1,'transparent');
x.fillStyle=g;x.beginPath();x.arc(d.x,d.y,d.r,0,6.29);x.fill();}
mx+=(tx-mx)*.03;my+=(ty-my)*.03;
for(i=0;i<stars.length;i++){var s=stars[i];s.tw+=.011*twk;
var px=s.x+mx*s.z*40*warpF, py=s.y+my*s.z*40*warpF;
var a=(.28+.4*Math.abs(Math.sin(s.tw)))*(warpT>0?1.6:1);
x.fillStyle='rgba(220,228,255,'+(a*s.z)+')';
x.beginPath();x.arc(px,py,s.z*1.25,0,6.29);x.fill();}
requestAnimationFrame(frame);}
var _hue=drbN(DRB.hue||0);
if(_hue){c.style.filter='hue-rotate('+_hue+'deg)';}
frame();
})();
// ---------- live settings binding ----------
function spApply(){
var D=window.DRB||{};
if(!D.bg||D.bg==='0'){var cs=document.getElementById('space');if(cs)cs.style.display='none'}else{var cs2=document.getElementById('space');if(cs2)cs2.style.display='block'}
if(!D.bg||D.bg==='0'){document.querySelectorAll('.vignette,.gridlines').forEach(function(e){e.style.display='none'})}else{
document.querySelectorAll('.vignette').forEach(function(e){e.style.display='block'});
var g=document.querySelector('.gridlines');if(g)g.style.display=(D.grid==='0')?'none':'block';}
var hue=parseFloat(D.hue||0);
document.querySelectorAll('#space,.vignette').forEach(function(e){e.style.filter=hue?('hue-rotate('+hue+'deg)'):''});
}
function spToggle(){var p=document.getElementById('spanel');p.style.display=(p.style.display==='none')?'block':'none';if(p.style.display==='block')spSync()}
function spSync(){
var D=window.DRB||{};
var m={bg:'sbg',warp:'swarp',parallax:'sparallax',grid:'sgrid',scan:'sscan',toast:'stoast',type:'stype'};
Object.keys(m).forEach(function(k){var el=document.getElementById(m[k]);if(el)el.checked=(D[k]!=='0')});
[['density','sdensity'],['speed','sspeed'],['twinkle','stwinkle'],['hue','shue']].forEach(function(pr){
var el=document.getElementById(pr[1]);if(el){el.value=D[pr[0]]||1;var v=document.getElementById(pr[1]+'v');if(v)v.textContent=el.value}});
}
function spSet(k,v){
v=(v===true||v==='true')?'1':(v===false||v==='false')?'0':v;
window.DRB=window.DRB||{};window.DRB[k]=v;spApply();
if(k==='density'){window.DRB.density=v;location.reload();}
fetch('/api/settings',{method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded'},body:k+'='+encodeURIComponent(v)}).then(function(r){return r.json()}).then(function(d){if(d.ok)toast('✓ saved')}).catch(function(){});
}
function spReset(){
var def={bg:'1',warp:'1',parallax:'1',density:'1',speed:'1',twinkle:'1',hue:'0',grid:'1',scan:'1',toast:'1',type:'1'};
var body=Object.keys(def).map(function(k){return k+'='+def[k]}).join('&');
fetch('/api/settings',{method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded'},body:body}).then(function(){location.reload()});
}
// scanline toggle via body class
var _st=document.createElement('style');_st.textContent='.noscan .gridlines{display:none!important}';document.head.appendChild(_st);
new MutationObserver(function(){document.body.classList.toggle('noscan',window.DRB&&window.DRB.scan==='0')}).observe(document.documentElement,{attributes:true,childList:true,subtree:true});
setTimeout(function(){spApply()},0);
// ---------- hyperdrive warp on click ----------
document.addEventListener('click',function(e){
if(window.DRB&&window.DRB.warp==='0')return;
if(e.target.closest('a,button,input,select,textarea,label,.card,#spanel,#palwin,#gearbtn'))return;
warpT=.35;
});
// ---------- command palette (⌘K / Ctrl+K) ----------
var PAL=[
['/ip','IP intel — geo, ASN, VPN flags'],
['/card','card BIN + Luhn check'],
['/sms','rent a burner number, 30 min'],
['/proxy','proxy lab — test Pleiades egress'],
['/steg','hide / extract text in images'],
['/track','trackable files — opens report back'],
['/eh','email header forensics'],
['/forensics','image forensics — EXIF + ELA'],
['/canary','canary tripwires'],
['/deaddrop','burn-after-read encrypted notes'],
['/mail','burner mailbox'],
['/shot','screenshot / page capture'],
['/score','fraud score composite'],
['/inbox','no-KYC inbox + login'],
['/keys','API keys + balance'],
['/pass','all-access pass'],
['/passport','agent passport badge'],
['/tools','free tools'],
['/llms.txt','machine catalog for agents'],
['/openapi.json','OpenAPI spec'],
];
var palSel=0;
function palOpen(){var w=document.getElementById('palwin');w.style.display='block';var i=document.getElementById('pinp');i.value='';palRender('');i.focus()}
function palClose(){document.getElementById('palwin').style.display='none'}
function palRender(q){
q=(q||'').toLowerCase();
var el=document.getElementById('plist');el.innerHTML='';
PAL.filter(function(it){return !q||it[0].toLowerCase().indexOf(q)>=0||it[1].toLowerCase().indexOf(q)>=0}).forEach(function(it,idx){
var a=document.createElement('a');a.className='pitem'+(idx===palSel?' sel':'');a.href=it[0];a.innerHTML=it[0]+' <small>'+it[1]+'</small>';
a.onmouseenter=function(){var items=el.querySelectorAll('.pitem');items.forEach(function(x){x.classList.remove('sel')});a.classList.add('sel')};
el.appendChild(a);});
}
function palFilter(){palSel=0;palRender(document.getElementById('pinp').value)}
function palKey(e){
var el=document.getElementById('plist');
if(e.key==='Escape')palClose();
else if(e.key==='ArrowDown'){palSel=Math.min(palSel+1,el.querySelectorAll('.pitem').length-1);palRender(document.getElementById('pinp').value);e.preventDefault()}
else if(e.key==='ArrowUp'){palSel=Math.max(palSel-1,0);palRender(document.getElementById('pinp').value);e.preventDefault()}
else if(e.key==='Enter'){var a=el.querySelectorAll('.pitem')[palSel];if(a)location.href=a.href}
}
document.addEventListener('keydown',function(e){
if((e.metaKey||e.ctrlKey)&&e.key.toLowerCase()==='k'){e.preventDefault();var w=document.getElementById('palwin');(w.style.display==='block')?palClose():palOpen()}
});
// toasts toggle
var _origToast=toast;
toast=function(m){if(window.DRB&&window.DRB.toast==='0')return;_origToast(m)};
// typed boot toggle
if(window.DRB&&window.DRB.type==='0'){var t=document.querySelector('.type');if(t)t.dataset.lines='';}
})();
</script>
</body></html>
"""
NEBULAS = {
"home": ("rgba(120,85,255,.17)", "rgba(0,190,255,.10)"),
"ip": ("rgba(255,170,60,.13)", "rgba(120,85,255,.10)"),
"card": ("rgba(66,232,164,.10)", "rgba(0,190,255,.09)"),
"sms": ("rgba(0,190,255,.13)", "rgba(167,139,250,.10)"),
"proxy": ("rgba(167,139,250,.14)", "rgba(255,170,60,.08)"),
"steg": ("rgba(255,110,180,.11)", "rgba(120,85,255,.11)"),
"track": ("rgba(255,90,90,.11)", "rgba(255,170,60,.08)"),
"mail": ("rgba(66,232,164,.10)", "rgba(0,190,255,.08)"),
"forensics": ("rgba(0,210,255,.12)", "rgba(255,110,180,.07)"),
"canary": ("rgba(255,201,77,.12)", "rgba(255,90,90,.08)"),
"deaddrop": ("rgba(45,226,200,.13)", "rgba(160,225,255,.09)"),
"shot": ("rgba(111,214,255,.12)", "rgba(120,85,255,.10)"),
"score": ("rgba(255,110,180,.10)", "rgba(66,232,164,.10)"),
}
def kv(pairs):
rows = "".join(f"<div>{k}</div><div>{v}</div>" for k, v in pairs)
return '<div class="card glow"><div class="kv">' + rows + "</div></div>"
def page(sec, body):
n1, n2 = NEBULAS.get(sec, ("rgba(120,85,255,.16)", "rgba(0,190,255,.10)"))
uid = current_user_id()
acct = ""
if uid:
try:
con = db()
u = con.execute("SELECT username FROM users WHERE id=?", (uid,)).fetchone()
bal = get_balance(uid)
pas = has_pass(uid)
acct = ('<a href=/keys style="color:var(--acc2);text-decoration:none;font-size:.72rem">' +
("★ PASS · " if pas else "") + "$" + f"{bal/100:.2f}" + " · " + esc(u["username"]) + "</a>")
except Exception:
acct = ""
from markupsafe import Markup
st = get_settings(uid)
return render_template_string(BASE, body=Markup(body), bmac=BMAC, o=lambda s2: "on" if s2 == sec else "",
n1=n1, n2=n2, acct=acct,
CFG_JS="window.DRB=" + json.dumps(st) + ";")
def _checkout_or_json(payload):
"""If a browser form POSTed (no JSON accept / no X-Requested-With), redirect to
the BTCPay checkout page instead of showing raw JSON."""
wants_html = "text/html" in (request.headers.get("Accept") or "") and "application/json" not in (request.headers.get("Accept") or "")
link = payload.get("checkoutLink") if isinstance(payload, dict) else None
if wants_html and link:
return Redirect(link)
return jsonify(payload)
def Redirect(u):
from flask import redirect as _r
return _r(u)
def agent_card(endpoint, example, notes):
"""Interactive-for-LLMs card: exact curl + auth + link to openapi."""
return ('<div class=card style=color:var(--dim);font-size:.85rem><b>FOR AGENTS</b> '
'<span title="Every tool is callable over JSON. Auth: account session cookie, API key (Authorization: Bearer), or PASS.">?</span><br>'
'<code style=color:var(--ok)>' + esc(endpoint) + '</code><br>'
'<code style=white-space:pre-wrap>' + esc(example) + '</code><br>' + esc(notes) +
' · spec: <a href=/openapi.json style=color:var(--acc)>/openapi.json</a> · catalog: <a href=/llms.txt style=color:var(--acc)>/llms.txt</a></div>')
def gloss(terms):
chips = " ".join('<span class=tchip title="' + esc(d) + '" style="border-bottom:1px dotted var(--acc2);cursor:help">' + esc(t) + '</span>' for t, d in terms)
return '<div class=card style=color:var(--dim);font-size:.85rem><b>JARGON</b> — hover any term: ' + chips + '</div>'
def how(steps):
lis = "".join(f"<li>{esc(s)}</li>" for s in steps)
return f'<div class=card><b>HOW IT WORKS</b><ol style="color:var(--dim);margin:.4rem 0 0;padding-left:1.2rem">{lis}</ol></div>'
# ---------- AGENT DISCOVERY ----------
LLMS_SETTINGS = """
## ACCOUNT TUNABLES (machine-settable)
GET/POST /api/settings — keys: bg, warp, parallax, density (0-2.5), speed (0-3), twinkle (0-3), hue (-180-180), grid, scan, toast, type (1|0).
Agents driving browsers (or building clients) can persist a theme per API key: POST form-encoded key=value. Values validated server-side.
## KEYBOARD
Ctrl+K / Cmd+K — command palette on any page. Type tool name, Enter navigates.
"""
API_INDEX = {
"service": "dark0rbits",
"description": "IP intel, card BIN validation, 30-min SMS rentals, residential proxy lab, steganography, trackable files, no-KYC messaging, utilities.",
"endpoints": [
{"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/<id>. 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": "/api/ip?target=", "desc": "Caller IP intel (auto) or any IP you pass: geo, ASN, ISP, VPN/hosting flags, rDNS."},
{"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."},
{"method": "GET", "path": "/api/sms/cancel?pid=", "desc": "Cancel + refund."},
{"method": "GET", "path": "/api/sms/history", "desc": "Rental history."},
{"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": "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/<token> URL. Free with PASS, else 5c from balance. Reads decrement; note self-destructs at 0 or at TTL."},
{"method": "GET", "path": "/drop/<token>", "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/<id>."},
{"method": "GET", "path": "/api/shot/status/<id>", "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."},
],
"payment": "BTCPay BTC only (no Stripe). SMS meters to house account; trackables $1 each.",
}
@app.route("/api/settings", methods=["GET", "POST"])
def api_settings():
uid = key_user() or current_user_id()
if not uid:
return jsonify({"ok": False, "error": "auth required: account session or API key"}), 401
if request.method == "GET":
return jsonify({"ok": True, "settings": get_settings(uid)})
out = {}
for k in DEFAULT_SETTINGS:
if k in request.form:
out[k] = set_setting(uid, k, request.form[k])
return jsonify({"ok": True, "applied": out, "settings": get_settings(uid)})
@app.route("/api")
def api_index(): return jsonify(API_INDEX)
@app.route("/robots.txt")
def robots(): return "User-agent: *\nAllow: /\nSitemap: https://dark0rbits.thetempleofdoom.com/sitemap.xml\n", 200, {"Content-Type": "text/plain"}
@app.route("/a8f3dark0rbitskey.txt")
def indexnow_key(): return "a8f3d4rk0rbits9e2b1c7x5k8m2v4q6t8", 200, {"Content-Type": "text/plain"}
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", "tools"]
xml = '<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' + "".join(f"<url><loc>{S}/{p}</loc><changefreq>weekly</changefreq></url>" for p in pages) + "</urlset>"
return xml, 200, {"Content-Type": "application/xml"}
@app.route("/llms.txt")
def llms():
eps = "\n".join(f"- `{e['method']} {e['path']}` — {e['desc']}" for e in API_INDEX["endpoints"])
return f"# Dark0rbits\n\nBase: {SITE}\n\n## API\n{eps}\n{LLMS_SETTINGS}", 200, {"Content-Type": "text/plain"}
@app.route("/ai-plugin.json")
def aiplugin():
return jsonify({"name_for_model": "dark0rbits", "schema_version": "v1",
"description_for_model": "IP intelligence, card BIN validation, SMS number rentals, proxy egress testing, LSB steganography, trackable file links with open-notifications, no-KYC site messaging.",
"api": {"type": "openapi", "url": SITE + "/openapi.json"}, "auth": {"type": "none"}, "contact_email": "indianaholmes1@icloud.com"})
@app.route("/openapi.json")
def openapi():
ps = {"openapi": "3.0.0", "info": {"title": "DARK0RBITS", "version": "2.0.0"}, "paths": {}}
def add(path, method, desc, params=None, req=False, files=None):
item = {"summary": desc}
if files:
item["requestBody"] = {"content": {"multipart/form-data": {"schema": {"type": "object", "properties": {**{k: {"type": "string"} for k, v in (params or {}).items()}, **{f: {"type": "string", "format": "binary"} for f in files}}}}}}
elif params:
if method == "get":
item["parameters"] = [{"name": k, "in": "query", "required": req, "schema": {"type": "string"}} for k in params]
else:
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/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)
add("/api/sms/cancel", "get", "Cancel + refund", {"pid": "orderid"}, req=True)
add("/api/sms/history", "get", "Rental history")
add("/api/proxy/test", "post", "Test Pleiades gateway creds", {"user": "user", "pass": "pass"}, req=True)
add("/api/steg/hide", "post", "LSB-hide text in PNG", {"text": "secret", "password": "opt"}, req=True, files=["image"])
add("/api/steg/extract", "post", "Extract text from PNG", {"password": "opt"}, files=["image"])
add("/api/track/create", "post", "Create $1 invoice for trackable", {"filename": "name"}, req=True)
add("/api/track/events", "get", "Trackable open events", {"token": "token"}, req=True)
add("/api/hash", "get", "Hashes", {"s": "string"}, req=True)
add("/api/hdr", "get", "HTTP headers", {"url": "url"}, req=True)
add("/api/deaddrop/create", "post", "Encrypted burn-after-read note", {"body": "text", "burn_after_reads": "1-10", "ttl_hours": "1-72", "password": "optional"}, req=True)
add("/drop/{token}", "get", "Read a dead-drop (burns one read)")
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"})
return jsonify(ps)
# ---------- 1. IP INTEL (auto + manual target) ----------
def ip_report(ip):
st, b = http(f"http://ip-api.com/json/{ip}?fields=66846719")
d = jf(b) or {}
try: d["reverse"] = d.get("reverse") or socket.gethostbyaddr(ip)[0]
except Exception: pass
return d
@app.route("/ip", methods=["GET", "POST"])
def ip_page():
target = param("target") if request.method == "POST" else param("target")
if target and target.strip():
target = target.strip()
d = ip_report(target)
heading = f"INTEL FOR <span>{esc(target)}</span>"
mine = False
else:
ip = request.headers.get("X-Real-IP") or request.remote_addr or ""
d = ip_report(ip)
heading = "WHAT'S <span>MY IP</span>"
mine = True
if d.get("status") == "fail" or not d:
body = f"<h1>{heading}</h1><div class=card><span class=tag bad>lookup failed</span></div>{ip_form()}"
return page("ip", body)
rows = [
("IP", f"<b style='font-size:1.3rem;color:var(--acc)'>{esc(d.get('query'))}</b>"),
("Country", f"{esc(d.get('country'))} ({esc(d.get('countryCode'))})"),
("Region / City", f"{esc(d.get('regionName'))} / {esc(d.get('city'))} {esc(d.get('zip'))}"),
("Lat, Lon", f"{d.get('lat')}, {d.get('lon')} · TZ {esc(d.get('timezone'))}"),
("ISP", esc(d.get("isp"))), ("Organization", esc(d.get("org"))), ("AS", esc(d.get("as") or d.get("asname"))),
("Reverse DNS", esc(d.get("reverse") or "—")),
("Flags", f"mobile: {d.get('mobile')} · proxy/VPN: {d.get('proxy')} · hosting: {d.get('hosting')}"),
("Currency", esc(d.get("currency"))),
]
extra = ""
if mine:
hdrs = {k: v for k, v in request.headers.items() if k.lower() in ("user-agent","accept-language","x-forwarded-for","cf-connecting-ip","cf-ipcountry")}
extra = '<div class=card><b>Headers you sent</b><table>' + "".join(f"<tr><td>{esc(k)}</td><td>{esc(v)}</td></tr>" for k, v in hdrs.items()) + "</table></div>"
body = f"""
<h1>{heading}</h1><p class=sub>Auto-detects your IP and shows everything. Want intel on another IP? Type it below — full report, any target.</p>
{kv(rows)}
<div class=card><form method=post><input name=target placeholder="any IP or hostname" style="width:70%" value="{esc(param('target') or '')}"> <button>Look up</button></form></div>
{extra}
<div class=card style=color:var(--dim)>API: GET /api/ip (caller) · GET /api/ip?target=1.2.3.4 (any target)</div>""" + how(["Your IP is auto-detected the moment the page loads — no input needed.","Type any other IP or hostname into the field for the same full report.","Everything is one GET away for agents: /api/ip and /api/ip?target=.","VPN/proxy/hosting flags come from IP-quality heuristics — if it says proxy, you are looking at a relay."])
body += gloss([("ASN","Autonomous System Number — the network operator that owns this route"),("rDNS","reverse DNS — hostname pointer for an IP"),("hosting","datacenter/cloud IP, not a home connection"),("VPN/proxy","known tunnel or relay range")])
body += agent_card('GET /api/ip?target=1.2.3.4', 'curl "https://dark0rbits.thetempleofdoom.com/api/ip?target=1.2.3.4" -H "Authorization: Bearer drb_..."', 'Auto-detects caller IP if target omitted.')
return page("ip", body)
def ip_form():
return '<div class=card><form method=post><input name=target placeholder="IP or hostname"><button>Look up</button></form></div>'
@app.route("/api/ip")
def api_ip():
r = rate_limit("iptarget", 40, 60)
if r: return r
target = param("target")
if target and target.strip():
return jsonify(ip_report(target.strip()))
ip = request.headers.get("X-Real-IP") or request.remote_addr or ""
d = ip_report(ip)
d["headers_seen"] = dict(request.headers)
return jsonify(d)
# ---------- 2. CARD CHECK ----------
def luhn_ok(num):
digits = [int(c) for c in num]
s = sum(digits[-1::-2])
for d in digits[-2::-2]:
d *= 2
if d > 9: d -= 9
s += d
return s % 10 == 0
BRANDS = [("4","Visa"),("51","Mastercard"),("52","Mastercard"),("53","Mastercard"),("54","Mastercard"),("55","Mastercard"),
("22","Mastercard"),("23","Mastercard"),("24","Mastercard"),("25","Mastercard"),("26","Mastercard"),("27","Mastercard"),
("34","Amex"),("37","Amex"),("6011","Discover"),("65","Discover"),("644","Discover"),("645","Discover"),("646","Discover"),("647","Discover"),("648","Discover"),("649","Discover"),
("50","Maestro"),("56","Maestro"),("57","Maestro"),("58","Maestro"),("63","Maestro"),("67","Maestro"),
("30","Diners"),("36","Diners"),("38","Diners"),("39","Diners"),
("35","JCB"),("62","UnionPay"),("7","Mir")]
def brand_of(num):
for pfx, b in BRANDS:
if num.startswith(pfx): return b
return "Unknown"
def bin_lookup(bin8):
st, b = http(f"https://lookup.binlist.net/{bin8}", headers={"Accept-Version": "3"})
bl = jf(b) or {}
if not bl.get("bank") and not bl.get("type") and not bl.get("scheme"):
st, b = http(f"https://data.handyapi.com/bin/{bin8}")
h = jf(b) or {}
if h.get("Status") == "SUCCESS":
return {"bank": {"name": h.get("Issuer")}, "country": {"name": (h.get("Country") or {}).get("Name") if isinstance(h.get("Country"), dict) else h.get("Country")},
"type": str(h.get("Type", "")).lower() or None, "prepaid": "prepaid" in str(h.get("Type","")).lower() or None, "scheme": h.get("Scheme")}
return bl
@app.route("/card", methods=["GET", "POST"])
def card():
result = ""
num = re.sub(r"\D", "", param("num") or "")[:19]
if num:
ok = luhn_ok(num)
tags = ['<span class="tag ok">LUHN VALID</span>' if ok else '<span class="tag bad">LUHN INVALID — fake/dead number</span>']
brand = brand_of(num)
bl = bin_lookup(num[:8])
bank = (bl.get("bank") or {}).get("name", "—")
country = (bl.get("country") or {}).get("name", "—")
ctype = bl.get("type", "—")
prepaid = bl.get("prepaid", "—")
flags = []
if ctype == "prepaid" or prepaid is True: flags.append("PREPAID — commonly flagged by merchants")
rng = {"Visa":(13,16,19),"Mastercard":(16,),"Amex":(15,)}.get(brand,(13,15,16,19))
tags.append(f'<span class="tag ok">length {len(num)} valid for {brand}</span>' if len(num) in rng else f'<span class="tag bad">LENGTH {len(num)} WRONG for {brand}</span>')
result = f"""
{kv([("Brand",brand),("BIN",num[:8]),("Bank / Issuer",esc(bank)),("Country",esc(country)),("Type",str(ctype)),("Prepaid",str(prepaid))])}
<div class=card><b>Fraud &amp; structure flags</b><br>{' '.join(tags)}{'<br>⚠ ' + ' · '.join(flags) if flags else ''}</div>
<div class=card style=color:var(--dim)>Nothing stored. No charge, no auth — BIN + math validation only. Fraud "flagged" status lives at the issuer.</div>""" + how(["Paste the card number — it never leaves the request, nothing is stored.","Luhn checksum validates the digit structure instantly.","BIN (first 8 digits) reveals the issuer bank, brand, card type and country.","Prepaid BINs get flagged — merchants commonly reject them.","This CANNOT show balance or fraud-hold status; only the issuer knows that."])
body = f"""
<h1>CARD <span>CHECK</span></h1><p class=sub>Luhn + BIN intelligence: issuer, brand, type, country, prepaid risk flags.</p>
<div class=card><form method=post><input id=cardnum name=num placeholder="4539 1488 0343 6467" style="width:70%" value="{esc(' '.join(num[i:i+4] for i in range(0,len(num),4))) if num else ''}" autocomplete=off inputmode=numeric> <button>Check</button></form>
<div style=color:var(--dim);font-size:.85rem;margin-top:.4rem>Paste anything — auto-formats. Nothing stored.</div></div>
<script>
var cn=document.getElementById('cardnum');
cn.addEventListener('input',function(){{var v=this.value.replace(/\\D/g,'').slice(0,19);this.value=v.replace(/(.{{4}})/g,'$1 ').trim()}});
</script>
{result}"""
body += gloss([("BIN","first 6-8 digits of a card — identifies issuer, country, brand"),("Luhn","checksum test every real card number passes"),("prepaid","issued as prepaid — elevated fraud risk")])
body += agent_card('POST /api/card num=4539148803436467', 'curl -X POST https://dark0rbits.thetempleofdoom.com/api/card -d num=4539148803436467', 'Luhn + BIN intel. 2c/metered with API key, free with PASS.')
return page("card", body)
@app.route("/api/card", methods=["POST"])
def api_card():
r = rate_limit("card", 30, 60)
if r: return r
num = re.sub(r"\D", "", param("num") or "")[:19]
if not num: return jsonify({"ok": False, "error": "num required"})
ok = luhn_ok(num)
bl = bin_lookup(num[:8])
return jsonify({"ok": True, "luhn": ok, "brand": brand_of(num), "length_ok": len(num) in
{"Visa":(13,16,19),"Mastercard":(16,),"Amex":(15,)}.get(brand_of(num),(13,15,16,19)),
"bin": {"issuer": (bl.get("bank") or {}).get("name"), "country": (bl.get("country") or {}).get("name"),
"type": bl.get("type"), "prepaid": bl.get("prepaid")},
"flags": (["prepaid-risk"] if (bl.get("type")=="prepaid" or bl.get("prepaid") is True) else []) + (["luhn-invalid"] if not ok else [])})
# ---------- 7i. SCREENSHOT SERVICE (chromium if present, else rendered-text fallback) ----------
def shot_url_ok(u):
if not re.match(r"^https?://", u): return None, "url must start with http:// or https://"
try:
host = urllib.parse.urlsplit(u).hostname or ""
except Exception:
return None, "url parse error"
if not host: return None, "url has no host"
try:
candidate = ipaddress.ip_address(host)
except ValueError:
candidate = None
if candidate:
if candidate.is_private or candidate.is_loopback or candidate.is_link_local or candidate.is_reserved: return None, "private/reserved IPs blocked"
return u, None
try:
resolved = ipaddress.ip_address(socket.gethostbyname(host))
except Exception:
return u, None # cannot resolve here — let the fetcher report the failure
if resolved.is_private or resolved.is_loopback or resolved.is_link_local or resolved.is_reserved: return None, "private/reserved IPs blocked"
return u, None
def shot_find_browser():
for b in ("chromium", "chromium-browser", "google-chrome", "google-chrome-stable"):
if shutil.which(b): return b
return None
def _shot_html_harvest(url):
"""HTTP fetch + readability-ish text harvest + page intel. No browser, no fake PNG."""
status, html_text = http(url, timeout=15)
out = {"http_status": status}
try:
title = re.search(r"<title[^>]*>(.*?)</title>", html_text, re.I | re.S)
if title: out["title"] = html.unescape(title.group(1)).strip()[:300]
desc = re.search(r'<meta[^>]+name=["\']description["\'][^>]+content=["\'](.*?)["\']', html_text, re.I | re.S)
if desc: out["description"] = html.unescape(desc.group(1)).strip()[:400]
except Exception:
pass
intel = []
for m in re.finditer(r"<h([1-3])[^>]*>(.*?)</h\1>", html_text, re.I | re.S):
t = html.unescape(re.sub(r"<[^>]+>", "", m.group(2))).strip()
if t: intel.append("h" + m.group(1) + ": " + t[:120])
if len(intel) >= 15: break
t = re.sub(r"(?is)<(script|style|noscript|svg)[^>]*>.*?</\1>", " ", html_text)
t = re.sub(r"(?s)<!--.*?-->", " ", t)
t = re.sub(r"(?i)<(br|/p|/div|/li|/h[1-6]|/tr)[^>]*>", "\n", t)
t = re.sub(r"<[^>]+>", " ", t)
t = html.unescape(t)
t = re.sub(r"[ \t\r]+", " ", t)
t = re.sub(r"\n\s*\n+", "\n", t).strip()
words = t.split()
out["text_preview"] = " ".join(words[:400])
out["text_chars_total"] = len(words)
out["headings"] = intel
return out
def shot_run(sid):
con = db()
s = con.execute("SELECT * FROM shots WHERE id=?", (sid,)).fetchone()
if not s: return
url = s["url"]
browser = shot_find_browser()
if browser:
out = os.path.join(UPLOAD_DIR, f"shot_{sid}.png")
try:
cmd = [browser, "--headless=new", "--no-sandbox", "--disable-gpu", "--hide-scrollbars",
"--window-size=1280,1600", f"--screenshot={out}", "--virtual-time-budget=8000", url]
p = subprocess.run(cmd, capture_output=True, timeout=45)
if p.returncode == 0 and os.path.exists(out) and os.path.getsize(out) > 0:
with open(out, "rb") as f: png = f.read()
os.remove(out)
con.execute("UPDATE shots SET status=?, result=? WHERE id=?", ("done", base64.b64encode(png).decode(), sid))
con.commit(); return
err = (p.stderr or b"").decode(errors="replace")[:200]
result = {"error": "chromium render failed: " + (err or f"exit {p.returncode}")}
except subprocess.TimeoutExpired:
result = {"error": "chromium timed out after 45s"}
except Exception as e:
result = {"error": f"chromium error: {e}"}
else:
try:
result = _shot_html_harvest(url)
result["mode"] = "text_fallback"
except Exception as e:
result = {"error": f"fetch failed: {e}"}
con.execute("UPDATE shots SET status=?, result=? WHERE id=?", ("text_fallback" if "mode" in result else "error", json.dumps(result), sid))
con.commit()
SHOT_API = ("<div class=card><b>AGENT API</b><pre>POST " + SITE + """/api/shot/create
Content-Type: application/json (or form fields)
{"url":"https://example.com"}
-> {"ok":true,"id":42,"status":"queued","poll":"BASE/api/shot/status/42"}
GET /api/shot/status/42
-> {"ok":true,"id":42,"status":"done","png_b64":"iVBORw..."} (chromium present)
-> {"ok":true,"status":"text_fallback","title":"...","text_preview":"...","headings":[...]}
auth: session cookie or Authorization: Bearer dk_...
25c/shot, free with PASS - rate limit 6/min
NOTE: no headless browser on this host yet - expect text_fallback</pre></div>""").replace("BASE", SITE)
SHOT_EXPLAINER = """<div class=card><b>HOW CAPTURE WORKS</b><br><span style="color:var(--dim);font-size:.85rem">
&bull; With <span title="headless Chromium renders the page with JS + CSS and writes a real 1280x1600 PNG — nothing is faked">headless Chromium</span> installed, /shot returns a real browser render as base64 PNG.
&bull; No browser on the host? You get <span title="HTTP fetch + readability harvest: title, meta description, headings and first 400 words — honest output, never a fake image">text_fallback</span>: an honest fetch of the page with rendered-text preview + page intel. A status field always tells you which.
&bull; <span title="Requests to localhost, RFC1918 ranges, link-local and reserved ranges are rejected — the capture service can't be turned into an SSRF probe">SSRF guard</span>: private/reserved network targets are refused before any fetch.
&bull; 25&cent; per shot, free with <span title="PASS = $10/mo all-access">PASS</span>. Rate limit 6/min.</span></div>"""
@app.route("/shot")
def shot_page():
body = f"""
<h1>SCREEN <span>SHOT</span></h1><p class=sub>Point at a URL, get a render. Real headless-Chromium PNG when the host has one — an honest rendered-text + intel fallback when it doesn't. Never a fake image.</p>
<div class=card><b>New capture</b>
<form method=post action=/api/shot/create onsubmit="doShot();return false">
<input id=shoturl name=url placeholder="https://target.example" style="width:min(560px,100%)" required>
<button style=margin-left:.4rem>Capture</button></form>
<div style="color:var(--dim);font-size:.85rem;margin-top:.5rem">{'Free with your PASS — or 25&cent; from balance.' if current_user_id() else 'Login + balance (or PASS): 25&cent; per shot.'}</div></div>
<div id=shotout class=card style=display:none><b>Result</b><div id=shotbody style="margin-top:.5rem"></div></div>
{SHOT_EXPLAINER}
<script>
function _esc(s){{var d=document.createElement('div');d.textContent=s==null?'':String(s);return d.innerHTML}}
async function doShot(){{var u=document.getElementById('shoturl').value.trim();if(!u){{toast('enter a URL');return}}
var out=document.getElementById('shotout'),body=document.getElementById('shotbody');out.style.display='block';body.innerHTML='queueing…';
try{{var cr=await fetch('/api/shot/create',{{method:'POST',headers:{{'Content-Type':'application/json'}},body:JSON.stringify({{url:u}})}});var c=await cr.json();
if(!c.ok){{body.innerHTML='<span class="tag bad">'+_esc(c.error)+'</span>';return}}
for(var i=0;i<20;i++){{await new Promise(r=>setTimeout(r,1500));
var sr=await (await fetch('/api/shot/status/'+c.id)).json();
if(sr.status==='done'&&sr.png_b64){{body.innerHTML='<img alt="page capture" src="data:image/png;base64,'+sr.png_b64+'">';return}}
if(sr.status==='text_fallback'){{var h='';if(sr.title)h+='<div style=color:var(--acc2)>title: '+_esc(sr.title)+'</div>';
if(sr.description)h+='<div style=color:var(--dim)>desc: '+_esc(sr.description)+'</div>';
if(sr.headings&&sr.headings.length)h+='<div style=color:var(--dim);font-size:.8rem>'+sr.headings.map(_esc).join('<br>')+'</div>';
h+='<pre style="white-space:pre-wrap;text-align:left">'+_esc(sr.text_preview)+'</pre>';body.innerHTML=h;return}}
if(sr.status==='error'){{body.innerHTML='<span class="tag bad">'+_esc(sr.error)+'</span>';return}}
body.textContent='rendering… (poll '+i+'/20)'}}}}catch(e){{body.textContent='error: '+e}}}}
</script>""" + SHOT_API + how(["Paste a URL — the job queues with a 25&cent; charge (free with PASS).",
"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/<id> until status != queued.",
"SSRF guard: localhost and private ranges are refused — this is a capture service, not a port scanner."])
return page("shot", body)
@app.route("/api/shot/create", methods=["POST"])
def api_shot_create():
r = rate_limit("shot", 6, 60)
if r: return r
uid = key_user() or current_user_id()
if not uid: return jsonify({"ok": False, "error": "auth required: account session (sign up at /inbox, no KYC) or Authorization: Bearer dk_ key"}), 401
url = str(jp("url") or "").strip()
if not url: return jsonify({"ok": False, "error": "url required"}), 400
url, err = shot_url_ok(url)
if err: return jsonify({"ok": False, "error": err}), 400
if not has_pass(uid) and not charge(uid, 25, "shot create"):
return jsonify({"ok": False, "error": "insufficient balance", "balance_cents": get_balance(uid), "topup": SITE + "/keys"}), 402
con = db()
cur = con.execute("INSERT INTO shots(user_id,url,status,created) VALUES(?,?,?,?)", (uid, url, "queued", int(time.time())))
con.commit()
shot_run(cur.lastrowid)
st = con.execute("SELECT status FROM shots WHERE id=?", (cur.lastrowid,)).fetchone()
return jsonify({"ok": True, "id": cur.lastrowid, "status": st["status"], "poll": f"{SITE}/api/shot/status/{cur.lastrowid}"}), 200, {"Cache-Control": "no-store"}
def shot_dict(row):
d = {"ok": True, "id": row["id"], "status": row["status"]}
try:
r = json.loads(row["result"]) if row["result"] else None
except Exception:
r = row["result"]
if row["status"] == "done" and r:
d["png_b64"] = r
try:
d["png_bytes"] = len(base64.b64decode(r))
except Exception:
pass
elif r:
d.update(r if isinstance(r, dict) else {"detail": str(r)[:400]})
return d
@app.route("/api/shot/status/<int:sid>")
def api_shot_status(sid):
con = db()
s = con.execute("SELECT * FROM shots WHERE id=?", (sid,)).fetchone()
if not s: return jsonify({"ok": False, "error": "unknown shot id"}), 404
if s["status"] == "queued": shot_run(sid) # lazy exec (reload-safe)
s = con.execute("SELECT * FROM shots WHERE id=?", (sid,)).fetchone()
return jsonify(shot_dict(s))
# ---------- 3. SMS RENTALS ----------
SMSP = "https://api.smspool.net"
SERVICES = [("google","Google"),("discord","Discord"),("telegram","Telegram"),("whatsapp","WhatsApp"),("other","Other/Any")]
COUNTRIES = [("1","United States"),("2","United Kingdom"),("4","Netherlands"),("22","Russia"),("150","Germany")]
def sms_api(path, **kw):
if kw:
kw["key"] = SMSP_KEY
return http(f"{SMSP}/{path}", data=urllib.parse.urlencode(kw).encode(), method="POST")
return http(f"{SMSP}/{path}?key={SMSP_KEY}")
def sms_guard():
con = db(); now = int(time.time())
uid = current_user_id()
st, b = sms_api("request/balance")
bal = jf(b) or {}
try: bal = float(bal.get("balance", 0))
except Exception: bal = 0
if bal < 5: return f"house balance too low (${bal:.2f}) — rentals paused"
act = con.execute("SELECT COUNT(*) c FROM sms_rentals WHERE status='active' AND expires > ?", (now,)).fetchone()["c"]
if act >= (5 if has_pass(uid) else 3): return "too many active rentals right now — try again later"
h = con.execute("SELECT COUNT(*) c FROM sms_rentals WHERE created > ?", (now-3600,)).fetchone()["c"]
if h >= (20 if has_pass(uid) else 6): return "hourly rental cap reached"
d = con.execute("SELECT COUNT(*) c FROM sms_rentals WHERE created > ?", (now-86400,)).fetchone()["c"]
if d >= (50 if has_pass(uid) else 15): return "daily rental cap reached"
return None
@app.route("/sms", methods=["GET", "POST"])
def sms():
uid = current_user_id()
msg = ""
if request.method == "POST":
act = request.form.get("act")
if act == "rent":
guard = sms_guard()
if guard:
msg = f'<div class="card"><span class="tag warn">PAUSED</span> {guard}</div>'
else:
st, b = sms_api("purchase/sms", service=request.form["service"], country=request.form["country"])
d = jf(b) or {}
if d.get("success") == 1:
con = db(); now = int(time.time())
con.execute("INSERT INTO sms_rentals(user_id,phone,service,country,purchase_id,cost,status,created,expires) VALUES(?,?,?,?,?,?,?,?,?)",
(uid, d.get("number"), request.form["service"], request.form["country"], str(d.get("purchase_id")), d.get("cost",0), "active", now, now+1800))
con.commit()
msg = f'<div class="card"><span class="tag ok">RENTED</span> Your number: <b style="font-size:1.2rem;color:var(--acc)">+{d.get("number")}</b> <button style="padding:.2rem .6rem;font-size:.8rem" onclick="cp(\'+{d.get("number")}\')">copy</button> · 30 min · order #{d.get("purchase_id")}</div>'
else:
msg = f'<div class="card"><span class="tag bad">RENT FAILED</span><br><pre>{esc(b[:400])}</pre></div>'
elif act == "check":
st, b = sms_api("sms/check", orderid=request.form["pid"])
d = jf(b) or {}
sms_txt = d.get("sms") or d.get("code") or ""
status = d.get("status", "?")
msg = f'<div class="card"><span class="tag {"ok" if sms_txt else "warn"}">STATUS: {status}</span> {"<b style=color:var(--ok)>" + esc(sms_txt) + "</b>" if sms_txt else "no code yet — poll again in 10s"}</div>'
elif act == "cancel":
st, b = sms_api("sms/cancel", orderid=request.form["pid"])
d = jf(b) or {}
ok = d.get("success") == 1
con = db(); con.execute("UPDATE sms_rentals SET status=? WHERE purchase_id=?", ("refunded" if ok else "cancel-failed", request.form["pid"])); con.commit()
msg = f'<div class="card"><span class="tag {"ok" if ok else "bad"}">{"CANCELLED + REFUNDED" if ok else "CANCEL FAILED"}</span></div>'
con = db()
hist = con.execute("SELECT * FROM sms_rentals WHERE user_id=? ORDER BY id DESC LIMIT 8", (uid,)).fetchall()
hist_rows = "".join(f"<tr><td>+{h['phone']} <a href=# onclick=\"cp('{h['phone']}');return false\" style=color:var(--acc)>copy</a></td><td>{h['service']}</td><td>{h['status']}</td><td>#{h['purchase_id']}</td><td class=cdown data-exp={h['expires']}>…</td></tr>" for h in hist)
body = f"""
<h1>SMS <span>RENTAL</span></h1><p class=sub>Disposable numbers, 30-minute windows. Cancel before a code = full refund.</p>
<div class="grid2">
<div class=card><b>Rent a number</b>
<form method=post><input type=hidden name=act value=rent>
<select name=service style="width:100%">{''.join(f'<option value={v}>{n}</option>' for v,n in SERVICES)}</select>
<select name=country style="width:100%;margin:.5rem 0">{''.join(f'<option value={v}>{n}</option>' for v,n in COUNTRIES)}</select>
<button>Rent — 30 min</button></form></div>
<div class=card><b>Check / manage</b>
<form method=post><input type=hidden name=act value=check><input name=pid placeholder="order #" style="width:100%"><button style="margin:.5rem 0">Poll for code</button></form>
<form method=post><input type=hidden name=act value=cancel><input name=pid placeholder="order #" style="width:100%"><button style="background:var(--bad);color:#fff">Cancel &amp; refund</button></form></div>
</div>{msg}
<div class=card><b>Recent rentals</b><table><tr><th>Number</th><th>Service</th><th>Status</th><th>Order</th><th>Window</th></tr>{hist_rows or '<tr><td colspan=5 style=color:var(--dim)>none yet</td></tr>'}</table></div>
<div class=card id=codesbox style=display:none><b>Live code</b><div id=lcode style="font-size:1.6rem;color:var(--ok);letter-spacing:.2em"></div></div>
<script>
var lastMsg='';
setInterval(function(){{
var els=document.querySelectorAll('.cdown');var now=Math.floor(Date.now()/1000);
els.forEach(function(e){{var s=e.dataset.exp-now;if(s>0)e.textContent=Math.floor(s/60)+'m '+(s%60)+'s left';else e.textContent='expired'}});}},1000);
setInterval(function(){{
fetch('/api/sms/history').then(r=>r.json()).then(rows=>{{
var act=rows.filter(r=>r.status==='active');
document.dispatchEvent(new CustomEvent('drb-sms',{{detail:{{active:act.length}}}}));
if(!act.length)return;
act.forEach(r=>{{
fetch('/api/sms/check?pid='+r.purchase_id).then(x=>x.json()).then(d=>{{
if((d.sms||d.code)&&d.sms!==lastMsg){{lastMsg=d.sms||d.code;
var box=document.getElementById('codesbox');box.style.display='block';
document.getElementById('lcode').textContent=lastMsg;
toast('SMS CODE: '+lastMsg);document.title='✉ '+lastMsg;}}
}})}});
}})}},6000);
</script>
<div class=card style=color:var(--dim)>API: POST /api/sms/rent (service,country) · GET /api/sms/check?pid= · GET /api/sms/cancel?pid= · GET /api/sms/history</div>""" + how(["Pick a service and country, rent — the number is live for 30 minutes exactly.","Use it for any signup/verification. The code arrives as a text.","Poll the order (auto or manual) until the code shows.","Cancel before a code arrives and you get every satoshi back.","Each rental is logged in the recent-rentals table with a live countdown."])
body += gloss([("OTC","one-time code — the PIN a service texts you"),("burn","cancel an unused rental inside the refund window"),("SMSPool","our upstream number provider")])
return page("sms", body)
@app.route("/api/sms/rent", methods=["POST"])
def api_sms_rent():
guard = sms_guard()
if guard: return jsonify({"success": 0, "message": guard, "paused": True})
uid = key_user() or current_user_id()
if uid and not has_pass(uid) and get_balance(uid) < 50:
return jsonify({"ok": False, "error": "insufficient balance", "topup": SITE + "/keys"}), 402
st, b = sms_api("purchase/sms", service=param("service"), country=param("country"))
d = jf(b) or {}
if d.get("success") == 1:
con = db(); now = int(time.time())
con.execute("INSERT INTO sms_rentals(user_id,phone,service,country,purchase_id,cost,status,created,expires) VALUES(?,?,?,?,?,?,?,?,?)",
(uid, d.get("number"), param("service"), param("country"), str(d.get("purchase_id")), d.get("cost",0), "active", now, now+1800))
con.commit()
cost = int(d.get("cost_in_cents") or 5)
if uid and not has_pass(uid):
charge(uid, cost, f"sms rental +{d.get('number')}")
return jsonify(d)
@app.route("/api/sms/check", methods=["GET","POST"])
def api_sms_check():
st, b = sms_api("sms/check", orderid=param("pid"))
return jf(b) or jsonify({"error": b[:200]})
@app.route("/api/sms/cancel", methods=["GET","POST"])
def api_sms_cancel():
st, b = sms_api("sms/cancel", orderid=param("pid"))
d = jf(b) or {}
if d.get("success") == 1:
con = db(); con.execute("UPDATE sms_rentals SET status='refunded' WHERE purchase_id=?", (param("pid"),)); con.commit()
return d
@app.route("/api/sms/history")
def api_sms_history():
con = db(); now = int(time.time())
con.execute("UPDATE sms_rentals SET status='expired' WHERE status='active' AND expires < ?", (now,))
con.commit()
uid = key_user() or current_user_id()
if not uid:
return jsonify({"ok": False, "error": "login required (POST /inbox act=login)"}), 401
return jsonify([dict(r) for r in con.execute("SELECT * FROM sms_rentals WHERE user_id=? ORDER BY id DESC LIMIT 50", (uid,))])
# ---------- 4. PROXY LAB ----------
@app.route("/proxy", methods=["GET", "POST"])
def proxy():
result = ""
if request.method == "POST" and request.form.get("act") == "test":
user, pw = request.form.get("user",""), request.form.get("pass","")
pauth = base64.b64encode(f"{user}:{pw}".encode()).decode()
try:
s = socket.create_connection((PLEIADES_GW.split(":")[0], int(PLEIADES_GW.split(":")[1])), timeout=15)
s.sendall(f"CONNECT ip-api.com:80 HTTP/1.1\r\nHost: ip-api.com:80\r\nProxy-Authorization: Basic {pauth}\r\n\r\n".encode())
resp = s.recv(4096)
if b"200" in resp.split(b"\r\n")[0]:
s.sendall(b"GET /json/?fields=66846719 HTTP/1.1\r\nHost: ip-api.com\r\nConnection: close\r\n\r\n")
data = b""
while True:
c = s.recv(8192)
if not c: break
data += c
s.close()
j = jf(data.split(b"\r\n\r\n",1)[-1].decode("utf-8","replace")) or {}
con = db()
con.execute("INSERT INTO proxy_checks(user_key,egress_ip,geo,ok,ts) VALUES(?,?,?,?,?)", (user[:12], j.get("query","?"), f"{j.get('country')}/{j.get('city')}", 1, int(time.time())))
con.commit()
result = f'<div class="card"><span class="tag ok">PROXY LIVE</span> Egress: <b style=color:var(--acc)>{esc(j.get("query"))}</b> — {esc(j.get("country"))} / {esc(j.get("city"))} · ISP {esc(j.get("isp"))} · tz {esc(j.get("timezone"))} <button style="padding:.2rem .6rem;font-size:.8rem" onclick="cp(\'{esc(j.get("query"))}\')">copy</button></div>'
else:
con = db()
con.execute("INSERT INTO proxy_checks(user_key,egress_ip,geo,ok,ts) VALUES(?,?,?,?,?)", (user[:12], "", "", 0, int(time.time())))
con.commit()
result = f'<div class="card"><span class="tag bad">AUTH/TUNNEL FAILED</span><pre>{esc(resp[:200])}</pre></div>'
except Exception as e:
result = f'<div class="card"><span class="tag bad">ERROR</span> {esc(e)}</div>'
body = f"""
<h1>PROXY <span>LAB</span></h1><p class=sub>Test + rent residential proxies on the Pleiades rail — same gateway keys as everywhere.</p>
<div class=card><form method=post><input type=hidden name=act value=test>
<label>Gateway user</label><br><input name=user style="width:100%" placeholder="your Pleiades username"><br>
<label style=color:var(--dim)>Password</label><br><input name=pass type=password style="width:100%"><br>
<button style=margin-top:.6rem>Test egress now</button></form></div>
{result}
<div class=card><b>Geo session builder</b>:
<select id=geoK onchange="gb()"><option value="">none</option><option value="_region-us">region US</option><option value="_region-eu">region EU</option><option value="_country-gb">country GB</option><option value="_country-de">country DE</option><option value="_city-london">city London</option></select>
<select id=geoS onchange="gb()"><option value="">rotating</option><option value="_session-a7x9_lifetime-30m">sticky 30-min</option></select>
<div style=margin-top:.5rem><code id=geoOut style=color:var(--acc)>yourpassword</code> <button style="padding:.2rem .6rem;font-size:.8rem" onclick="cp(document.getElementById('geoOut').textContent)">copy</button></div>
<script>function gb(){{document.getElementById('geoOut').textContent='yourpassword'+document.getElementById('geoK').value+document.getElementById('geoS').value}}</script></div>
<div class=card><b>Rent more</b> — storefront: <a href="{PLEIADES_APP}">{PLEIADES_APP}</a></div>
<div class=card style=color:var(--dim)>API: POST /api/proxy/test (user, pass) → egress IP + geo JSON.</div>""" + how(["Enter your Pleiades gateway user:pass — the same credentials work across the fleet.","The lab tunnels a CONNECT request through the gateway and reports the true egress IP, geo and ISP.","Use the geo builder to steer the exit: region, country, city, sticky 30-min sessions.","Need bandwidth? Buy GB plans at the Pleiades storefront."])
body += gloss([("sticky session","same exit IP kept across requests"),("egress","the exit IP the rest of the internet sees"),("Pleiades","our proxy gateway network")])
return page("proxy", body)
@app.route("/api/proxy/test", methods=["POST"])
def api_proxy_test():
r = rate_limit("proxytest", 10, 60)
if r: return r
user, pw = param("user") or "", param("pass") or ""
pauth = base64.b64encode(f"{user}:{pw}".encode()).decode()
try:
s = socket.create_connection((PLEIADES_GW.split(":")[0], int(PLEIADES_GW.split(":")[1])), timeout=15)
s.sendall(f"CONNECT ip-api.com:80 HTTP/1.1\r\nHost: ip-api.com:80\r\nProxy-Authorization: Basic {pauth}\r\n\r\n".encode())
resp = s.recv(4096)
if b"200" not in resp.split(b"\r\n")[0]: return jsonify({"ok": False, "raw": resp[:120].decode("utf-8","replace")})
s.sendall(b"GET /json/?fields=66846719 HTTP/1.1\r\nHost: ip-api.com\r\nConnection: close\r\n\r\n")
data = b""
while True:
c = s.recv(8192)
if not c: break
data += c
s.close()
j = jf(data.split(b"\r\n\r\n",1)[-1].decode("utf-8","replace")) or {}
return jsonify({"ok": True, "egress": j})
except Exception as e:
return jsonify({"ok": False, "error": str(e)})
# ---------- 5. STEGO LAB ----------
def _keystream(password, n):
ks = b""; seed = password.encode()
while len(ks) < n:
seed = hashlib.sha256(seed).digest()
ks += seed
return ks[:n]
def steg_hide(img_bytes, text, password="", bits=1, spread="sequential"):
from PIL import Image
im = Image.open(io.BytesIO(img_bytes)).convert("RGBA")
px = im.load()
w, h = im.size
capacity = w * h * 3 * bits
payload = text.encode("utf-8")
phash = hashlib.sha256(password.encode()).digest()[:4] if password else b"\x00\x00\x00\x00"
header = b"AUR1" + struct.pack(">I", len(payload)) + phash
body = payload
if password:
body = bytes(a ^ b for a, b in zip(body, _keystream(password, len(body))))
data = header + body
if len(data) * 8 > capacity:
return None, f"too big: need {len(data)*8} bits, image holds {capacity}"
if spread == "random":
import random as _r
_r.seed(int.from_bytes(hashlib.sha256((password + "dark0rbits").encode()).digest()[:4], "big") if password else int.from_bytes(hashlib.sha256(b"dark0rbits-random-no-pass").digest()[:4], "big"))
order = list(range(w*h)); _r.shuffle(order)
else:
order = list(range(w*h))
bits_needed = len(data) * 8
idx = 0
mask = (1 << bits) - 1
for pos in order:
if idx >= bits_needed: break
x, y = pos % w, pos // w
r, g, b, a = px[x, y]
chs = [r, g, b]
for ch_i in range(3):
if idx >= bits_needed: break
chunk = 0
taken = 0
for k in range(bits):
if idx >= bits_needed: break
chunk = (chunk << 1) | ((data[idx >> 3] >> (7 - (idx & 7))) & 1)
idx += 1; taken += 1
if taken < bits: chunk <<= (bits - taken)
chs[ch_i] = (chs[ch_i] & ~mask) | chunk
px[x, y] = tuple(chs) + (a,)
# also stash settings in a tEXt chunk for reliable extraction hints
out = io.BytesIO()
im.save(out, "PNG", pnginfo=_pnginfo(bits, spread))
return out.getvalue(), {"bits": bits, "spread": spread}
def _pnginfo(bits, spread):
try:
from PIL.PngImagePlugin import PngInfo
info = PngInfo()
info.add_text("dark0rbits_meta", json.dumps({"bits": bits, "spread": spread, "v": 2}))
return info
except Exception:
return None
def steg_extract(img_bytes, password="", bits=None, spread=None):
from PIL import Image
im = Image.open(io.BytesIO(img_bytes))
meta = im.info.get("dark0rbits_meta") or im.info.get("auriga_meta")
if meta:
try:
m = json.loads(meta)
bits = int(m.get("bits", bits or 1)); spread = m.get("spread", spread or "sequential")
except Exception: pass
bits = bits or 1
im = im.convert("RGBA")
px = im.load()
w, h = im.size
mask = (1 << bits) - 1
# replicate the shuffle used at hide time
if spread == "random":
import random as _r
_r.seed(int.from_bytes(hashlib.sha256((password + "dark0rbits").encode()).digest()[:4], "big") if password else int.from_bytes(hashlib.sha256(b"dark0rbits-random-no-pass").digest()[:4], "big"))
order = list(range(w*h)); _r.shuffle(order)
else:
order = list(range(w*h))
raw = bytearray()
need = None
idx = 0
for pos in order:
if need is not None and idx >= need: break
x, y = pos % w, pos // w
r, g, b, a = px[x, y]
for ch in (r, g, b):
chunk = ch & mask
for k in range(bits-1, -1, -1):
if need is not None and idx >= need: break
bit = (chunk >> k) & 1
while len(raw) < (idx >> 3) + 1: raw.append(0)
if bit: raw[idx >> 3] |= (0x80 >> (idx & 7))
idx += 1
if need is not None and idx >= need: break
if need is None and idx >= 64:
if bytes(raw[:4]) != b"AUR1":
return None, f"no DARK0RBITS payload found with LSB depth {bits} (try other depth / randomized)"
ln = struct.unpack(">I", bytes(raw[4:8]))[0]
need = 64 + ln * 8
data = bytes(raw)
if len(data) < 12: return None, "payload too small"
if bytes(data[:4]) != b"AUR1":
return None, "no DARK0RBITS payload found (wrong password or settings?)"
if password and hashlib.sha256(password.encode()).digest()[:4] != data[8:12]:
return None, "wrong password"
ln = struct.unpack(">I", data[4:8])[0]
body = data[12:12+ln]
if password:
body = bytes(a ^ b for a, b in zip(body, _keystream(password, len(body))))
text = body.decode("utf-8", "replace")
return text, None
@app.route("/steg", methods=["GET"])
def steg():
body = f"""
<h1>STEGO <span>LAB</span></h1><p class=sub>Hide words inside pictures — LSB steganography with real settings. PNG in, PNG out, looks untouched.</p>
<div class="grid2">
<div class=card><b>Hide text</b>
<form action=/api/steg/hide method=post enctype=multipart/form-data target=stegout>
<div class=drop onclick="document.getElementById('ih').click()">📤 drop a PNG here or click<input id=ih type=file name=image accept="image/png" style=display:none required></div>
<div class=fnh style=color:var(--dim);font-size:.85rem></div>
<textarea name=text rows=3 style="width:100%;margin:.6rem 0" placeholder="the words to hide"></textarea>
<input name=password placeholder="password (optional)" style="width:100%">
<div style=margin:.6rem 0>
<label>LSB depth</label> <select name=bits><option>1</option><option>2</option><option>3</option></select>
<label style=margin-left:.8rem>Spread</label> <select name=spread><option value=sequential>sequential</option><option value=random>randomized</option></select>
</div>
<button>Hide &amp; download</button></form></div>
<div class=card><b>Extract text</b>
<form action=/api/steg/extract method=post enctype=multipart/form-data target=stegout>
<div class=drop onclick="document.getElementById('ie').click()">📥 drop the carrier PNG<input id=ie type=file name=image accept="image/png" style=display:none required></div>
<div class=fne style=color:var(--dim);font-size:.85rem></div>
<input name=password placeholder="password if used" style="width:100%;margin:.6rem 0">
<div style=margin:.6rem 0><label>LSB depth</label> <select name=bits><option value="">auto (reads metadata)</option><option>1</option><option>2</option><option>3</option></select>
<label style=margin-left:.8rem>Spread</label> <select name=spread><option value="">auto</option><option value=sequential>sequential</option><option value=random>randomized</option></select></div>
<button>Extract</button></form></div>
</div>
<script>
document.querySelectorAll('.drop').forEach(function(d){{
d.addEventListener('dragover',function(e){{e.preventDefault();d.classList.add('over')}});
d.addEventListener('dragleave',function(){{d.classList.remove('over')}});
d.addEventListener('drop',function(e){{e.preventDefault();d.classList.remove('over');
var inp=d.querySelector('input[type=file]');if(e.dataTransfer.files.length){{inp.files=e.dataTransfer.files;
var fn=d.parentElement.querySelector('.fnh, .fne');if(fn)fn.textContent=e.dataTransfer.files[0].name}}}});
d.addEventListener('change',function(){{}});
}});
document.getElementById('ih').addEventListener('change',function(){{document.querySelector('.fnh').textContent=this.files[0].name}});
document.getElementById('ie').addEventListener('change',function(){{document.querySelector('.fne').textContent=this.files[0].name}});
</script>
<div class=card style=color:var(--dim)>API: POST /api/steg/hide (image, text, password?, bits 1-3, spread) → PNG · POST /api/steg/extract (image, password?, bits?, spread?) → JSON</div><iframe name=stegout id=stegout style=display:none title="stego output"></iframe>""" + 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=<png> 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.')
return page("steg", body)
@app.route("/api/steg/hide", methods=["POST"])
def api_steg_hide():
r = rate_limit("steg", 20, 60)
if r: return r
f = request.files.get("image")
text = param("text") or ""
if not f or not text: return jsonify({"ok": False, "error": "image + text required"}), 400
bits = min(3, max(1, int(param("bits") or 1)))
spread = param("spread") or "sequential"
try:
out, meta = steg_hide(f.read(), text, param("password") or "", bits, spread)
except Exception as e:
return jsonify({"ok": False, "error": str(e)}), 400
if out is None: return jsonify({"ok": False, "error": meta}), 400
return send_file(io.BytesIO(out), mimetype="image/png", as_attachment=True, download_name="dark0rbits-hidden.png")
@app.route("/api/steg/extract", methods=["POST"])
def api_steg_extract():
r = rate_limit("steg", 20, 60)
if r: return r
f = request.files.get("image")
if not f: return jsonify({"ok": False, "error": "image required"}), 400
bits = param("bits")
bits = min(3, max(1, int(bits))) if bits else None
try:
text, err = steg_extract(f.read(), param("password") or "", bits, param("spread") or None)
except Exception as e:
return jsonify({"ok": False, "error": str(e)}), 400
if err: return jsonify({"ok": False, "error": err}), 200
return jsonify({"ok": True, "text": text})
# ---------- 6. TRACKABLE FILES ----------
@app.route("/track", methods=["GET"])
def track():
uid = current_user_id()
mine = ""
if uid:
con = db()
rows = con.execute("SELECT * FROM trackables WHERE user_id=? ORDER BY id DESC LIMIT 10", (uid,)).fetchall()
if rows:
trs = "".join(f"<tr><td>{esc(t['filename'])}</td><td>{'<a href=/api/track/events?token='+t['token']+'>events</a>' if t['paid'] else '—'}</td><td>{'paid ✓' if t['paid'] else 'unpaid'}</td></tr>" for t in rows)
mine = f'<div class=card><b>Your trackables</b><table><tr><th>File</th><th>Events</th><th>Status</th></tr>{trs}</table></div>'
body = f"""
<h1>TRACK <span>FILE</span></h1><p class=sub>Pay $1 BTC → upload a file or picture → get a tracked link + an email-ready version. Every open pings back into your INBOX.</p>
<div class=card>
<b>1 · Pay $1</b><form action=/api/track/create method=post>
<input name=filename placeholder="file name e.g. flyer.jpg" style="width:70%" required> <button>Create invoice</button></form>
<div style=color:var(--dim);font-size:.85rem;margin-top:.4rem>BTCPay BTC only. After payment the upload opens automatically.</div></div>
{mine}
<div class=card style=color:var(--dim)>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. <a href=/inbox>Login (no KYC)</a> to see events.</div>
<div class=card style=color:var(--dim)>API: POST /api/track/create (filename) → invoice · POST /api/track/upload?token= (file) → link · GET /api/track/events?token=</div>""" + 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."])
return page("track", body)
def btc_invoice(amount="1.00"):
st, b = http(f"{BTCPAY}/stores/{BTCPAY_STORE}/invoices",
headers={"Authorization": "token " + BTCPAY_KEY, "Content-Type": "application/json"},
data=json.dumps({"amount": amount, "currency": "USD", "metadata": {"orderId": "dark0rbits-track"}}).encode(), method="POST")
return jf(b) or {}
@app.route("/api/track/create", methods=["POST"])
def api_track_create():
fn = param("filename") or "file"
uid = key_user() or current_user_id()
if not uid:
return jsonify({"ok": False, "error": "login required — create a no-KYC account at /inbox (POST /inbox act=register), then retry"}), 401
token = secrets.token_urlsafe(16)
con = db()
if has_pass(uid):
con.execute("INSERT INTO trackables(user_id,token,filename,kind,invoice_id,paid,created) VALUES(?,?,?,?,?,1,?)",
(uid or 0, token, esc(fn[:100]), "file", "PASS", int(time.time())))
con.commit()
return jsonify({"ok": True, "free": True, "token": token, "upload_url": f"{SITE}/track/pay?token={token}"})
if uid and charge(uid, 100, f"trackable file ({fn[:40]})"):
con.execute("INSERT INTO trackables(user_id,token,filename,kind,invoice_id,paid,created) VALUES(?,?,?,?,?,1,?)",
(uid or 0, token, esc(fn[:100]), "file", "BALANCE", int(time.time())))
con.commit()
return jsonify({"ok": True, "balance_charged": 1.00, "token": token, "upload_url": f"{SITE}/track/pay?token={token}"})
inv = btc_invoice()
if not inv.get("id"): return jsonify({"ok": False, "error": str(inv)[:200]}), 400
con.execute("INSERT INTO trackables(user_id,token,filename,kind,invoice_id,paid,created) VALUES(?,?,?,?,?,0,?)",
(uid or 0, token, esc(fn[:100]), "file", inv["id"], int(time.time())))
con.commit()
return _checkout_or_json({"ok": True, "invoice_id": inv["id"], "checkoutLink": inv.get("checkoutLink"), "token": token,
"after_payment_upload_url": f"{SITE}/track/pay?token={token}"})
@app.route("/track/pay", methods=["GET"])
def track_pay():
token = param("token") or ""
con = db()
t = con.execute("SELECT * FROM trackables WHERE token=?", (token,)).fetchone()
if not t: return page("track", "<h1>TRACK <span>FILE</span></h1><div class=card><span class=tag bad>unknown token</span></div>")
return page("track", f"""
<h1>TRACK <span>FILE</span></h1><p class=sub>Upload your file — then it's trackable.</p>
<div class=card><form action=/api/track/upload?token={esc(token)} method=post enctype=multipart/form-data>
<div class=drop onclick="document.getElementById('tf').click()">📤 drop file / picture here<input id=tf type=file name=file style=display:none required></div>
<div id=tfname style=color:var(--dim);font-size:.85rem;margin:.4rem 0></div>
<button>Upload &amp; make trackable</button></form></div>
<script>document.getElementById('tf').addEventListener('change',function(){{document.getElementById('tfname').textContent=this.files[0].name}})</script>""")
@app.route("/api/track/upload", methods=["POST"])
def api_track_upload():
token = param("token")
f = request.files.get("file")
if not f: return jsonify({"ok": False, "error": "file required"}), 400
con = db()
t = con.execute("SELECT * FROM trackables WHERE token=?", (token,)).fetchone()
if not t: return jsonify({"ok": False, "error": "unknown token"}), 400
st, b = http(f"{BTCPAY}/stores/{BTCPAY_STORE}/invoices/{t['invoice_id']}", headers={"Authorization": "token " + BTCPAY_KEY}) if t["invoice_id"] not in ("PASS", "BALANCE") else (200, '{"status":"settled"}')
inv = jf(b) or {}
paid = inv.get("status") in ("settled", "processing", "paid")
if not paid: return jsonify({"ok": False, "error": f"invoice not paid yet ({inv.get('status')})"}), 402
data = f.read()
open(os.path.join(UPLOAD_DIR, token + ".bin"), "wb").write(data)
kind = "image" if (f.content_type or "").startswith("image") else "file"
fn = (f.filename or t["filename"])[:100]
con.execute("UPDATE trackables SET paid=1, kind=?, filename=? WHERE token=?", (kind, fn, token))
con.commit()
b64 = base64.b64encode(data).decode()
pixel = f"{SITE}/t/{token}.png"
if kind == "image":
viewer = f'<!doctype html><meta charset=utf-8><body style="margin:0;background:#111;text-align:center"><img src="data:image;base64,{b64}" style="max-width:100%"><img src="{pixel}" width=1 height=1></body>'
else:
viewer = f'<!doctype html><meta charset=utf-8><body style="background:#111;color:#eee;font-family:monospace;padding:2rem"><p>📎 {esc(fn)} ({len(data)} bytes)</p><p><a href="{SITE}/t/{token}" style="color:#f0b429">Open / download the file</a></p><img src="{pixel}" width=1 height=1></body>'
open(os.path.join(UPLOAD_DIR, token + ".html"), "w").write(viewer)
con.execute("INSERT INTO track_events(trackable_id,ts,ip,ua) VALUES(?,?,?,?)", (t["id"], int(time.time()), "created", "upload"))
con.commit()
return jsonify({"ok": True, "tracked_link": f"{SITE}/t/{token}", "pixel": pixel,
"email_html": f"{SITE}/t/{token}/html",
"note": "attach/email the HTML version — every view fires the pixel and lands in the inbox"})
def _geo_cache():
con = db()
con.execute("CREATE TABLE IF NOT EXISTS geo_cache(ip TEXT PRIMARY KEY, geo TEXT, ts INTEGER)")
return con
def enrich_ip(ip):
"""geo/ISP/ASN for an IP, cached 24h."""
if not ip or ip == "created" or ip.startswith(("10.30.20.", "127.", "172.17.")): return {}
con = _geo_cache()
r = con.execute("SELECT geo FROM geo_cache WHERE ip=? AND ts > ?", (ip, int(time.time())-86400)).fetchone()
if r: return json.loads(r["geo"])
st, b = http(f"http://ip-api.com/json/{ip}?fields=66846719")
d = jf(b) or {}
geo = {k: d.get(k) for k in ("country","countryCode","regionName","city","zip","lat","lon","timezone","isp","org","as","asname","mobile","proxy","hosting","reverse","query") if d.get(k) is not None}
con.execute("INSERT OR REPLACE INTO geo_cache(ip,geo,ts) VALUES(?,?,?)", (ip, json.dumps(geo), int(time.time())))
con.commit()
return geo
def _log_open(t, extra=""):
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","")
geo = enrich_ip(ip)
where = ""
if geo: where = f" — {geo.get('city','')}, {geo.get('regionName','')} {geo.get('countryCode','')} · {geo.get('isp','')} · tz {geo.get('timezone','')}"
if geo.get("proxy"): where += " · VPN/proxy ⚠"
con.execute("INSERT INTO track_events(trackable_id,ts,ip,ua) VALUES(?,?,?,?)",
(t["id"], int(time.time()), ip + (" " + json.dumps(geo) if geo else ""), ua[:200] + (f" | lang={lang}" if lang else "") + (f" | ref={ref[:100]}" if ref else "")))
uid = t["user_id"]
if uid:
con.execute("INSERT INTO messages(user_id,sender,body,created) VALUES(?,?,?,?)",
(uid, "operator-bot", f"👁 '{esc(t['filename'])}' just opened{extra} — IP <b>{esc(ip)}</b>{esc(where)}<br>device: {esc(ua[:100])}{'<br>lang: ' + esc(lang) if lang else ''}{'<br>from: ' + esc(ref[:120]) if ref else ''}", int(time.time())))
con.commit()
@app.route("/t/<token>")
def tracked_download(token):
con = db()
t = con.execute("SELECT * FROM trackables WHERE token=?", (token,)).fetchone()
if not t or not t["paid"]: return "not found", 404
_log_open(t, " (link)")
path = os.path.join(UPLOAD_DIR, token + ".bin")
if not os.path.exists(path): return "file gone", 404
return send_file(path, as_attachment=True, download_name=t["filename"])
@app.route("/t/<token>.png")
def tracked_pixel(token):
con = db()
t = con.execute("SELECT * FROM trackables WHERE token=?", (token,)).fetchone()
if t and t["paid"]:
_log_open(t, " (email/pixel)")
px = base64.b64decode("R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7")
return Response(px, mimetype="image/gif", headers={"Cache-Control": "no-store"})
@app.route("/t/<token>/html")
def tracked_html(token):
con = db()
t = con.execute("SELECT * FROM trackables WHERE token=?", (token,)).fetchone()
if not t or not t["paid"]: return "not found", 404
p = os.path.join(UPLOAD_DIR, token + ".html")
return send_file(p, mimetype="text/html") if os.path.exists(p) else ("no html wrapper", 404)
@app.route("/api/track/events", methods=["GET"])
def api_track_events():
con = db(); token = param("token")
t = con.execute("SELECT * FROM trackables WHERE token=?", (token,)).fetchone()
if not t: return jsonify({"ok": False, "error": "unknown token"})
uid = current_user_id()
if not uid or uid != t["user_id"]: return jsonify({"ok": False, "error": "auth required (login on /inbox)"})
return jsonify([dict(r) for r in con.execute("SELECT * FROM track_events WHERE trackable_id=? ORDER BY id DESC LIMIT 100", (t["id"],))])
# ---------- 6b. BURNER MAIL (receive-only, BTC packages) ----------
MAIL_PACKS = [("7","7 days — $3",3,7),("30","30 days — $8",8,30),("90","90 days — $20",20,90)]
MAIL_DOMAIN = "thetempleofdoom.com"
MAIL_RESERVED = {"indianaholmes","admin","operator","drjones","root","noreply","support","pass","mail"}
MAIL_SECRET = "dark0rbits-mail-relay-2026"
@app.route("/mail", methods=["GET"])
def mail():
uid = current_user_id()
mine = ""
if uid:
con = db(); now = int(time.time())
con.execute("UPDATE mailboxes SET paid=2 WHERE paid=1 AND expires < ?", (now,)) # expired
rows = con.execute("SELECT * FROM mailboxes WHERE user_id=? ORDER BY id DESC LIMIT 10", (uid,)).fetchall()
if rows:
trs = "".join(f"<tr><td>{esc(m['address'])} <a href=# onclick=\"cp('{esc(m['address'])}');return false\" style=color:var(--acc)>copy</a></td><td><a href=/mail/view?addr={esc(m['address'])}>view mail</a></td><td class=mcd data-exp={m['expires']}>…</td><td>{'live' if m['paid']==1 else 'expired'}</td><td>{m['cnt']}</td></tr>" for m in rows)
mine = f'<div class=card><b>Your mailboxes</b><table><tr><th>Address</th><th></th><th>Expires</th><th>Status</th><th>Mail</th></tr>{trs}</table></div>'
body = f"""
<h1>BURNER <span>MAIL</span></h1><p class=sub>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.</p>
<div class=card>
<b>Pick a package (BTC)</b>
{''.join(f'<form action=/api/mail/create method=post style=display:inline;margin:0 0.5rem><input type=hidden name=days value={d}><input name=local placeholder="mailbox name" required style=width:140px><button>{n}</button></form>' for d,n,_,_ in MAIL_PACKS)}
<div style=color:var(--dim);font-size:.85rem;margin-top:.6rem>Type your desired mailbox name, pick a length, pay the invoice — the mailbox activates the moment the payment settles.</div></div>
{mine}
<div class=card style=color:var(--dim)>API: POST /api/mail/create (local, days) → invoice · GET /api/mail/inbox?addr= (needs login) — inbound via Cloudflare Email Routing → worker relay.</div>""" + 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."])
return page("mail", body)
@app.route("/api/mail/create", methods=["POST"])
def api_mail_create():
uid = current_user_id()
local = re.sub(r"[^a-z0-9._-]", "", (param("local") or "").lower())[:30]
days = param("days") or "7"
pack = next((p for p in MAIL_PACKS if p[0] == str(days)), None)
if not pack: return jsonify({"ok": False, "error": "bad package"}), 400
if not local: return jsonify({"ok": False, "error": "mailbox name required"}), 400
if local in MAIL_RESERVED: return jsonify({"ok": False, "error": "reserved name"}), 400
addr = f"{local}@{MAIL_DOMAIN}"
con = db()
if con.execute("SELECT 1 FROM mailboxes WHERE address=?", (addr,)).fetchone():
return jsonify({"ok": False, "error": "mailbox name taken"}), 400
uid = key_user() or current_user_id()
# metered: PASS = instant free; balance = instant paid; else BTC invoice
if uid and has_pass(uid):
con.execute("INSERT INTO mailboxes(user_id,address,invoice_id,paid,expires,created,plan_days) VALUES(?,?,?,?,?,?,?)",
(uid, addr, "PASS", 1, int(time.time())+86400*pack[3], int(time.time()), pack[3]))
con.commit()
return jsonify({"ok": True, "free": True, "address": addr, "expires_in_days": pack[3]})
if uid and charge(uid, pack[2]*100, f"burner mailbox {addr} ({pack[3]}d)"):
con.execute("INSERT INTO mailboxes(user_id,address,invoice_id,paid,expires,created,plan_days) VALUES(?,?,?,?,?,?,?)",
(uid, addr, "BALANCE", 1, int(time.time())+86400*pack[3], int(time.time()), pack[3]))
con.commit()
return jsonify({"ok": True, "balance_charged": pack[2], "address": addr, "expires_in_days": pack[3]})
inv = btc_invoice(f"{pack[2]:.2f}")
if not inv.get("id"): return jsonify({"ok": False, "error": str(inv)[:200]}), 400
con.execute("INSERT INTO mailboxes(user_id,address,invoice_id,paid,expires,created,plan_days) VALUES(?,?,?,?,?,?,?)",
(uid or 0, addr, inv["id"], 0, 0, int(time.time()), pack[3]))
con.commit()
return _checkout_or_json({"ok": True, "address": addr, "checkoutLink": inv.get("checkoutLink"), "invoice_id": inv["id"]})
@app.route("/api/mail/inbound", methods=["POST"])
def api_mail_inbound():
d = request.get_json(silent=True) or {}
if d.get("secret") != MAIL_SECRET: return jsonify({"ok": False}), 403
addr = (d.get("mailbox") or "").lower().split("@")[0]
con = db()
m = con.execute("SELECT * FROM mailboxes WHERE address LIKE ? AND paid=1", (addr + "@%",)).fetchone()
if not m: return jsonify({"ok": False, "error": "unknown/expired mailbox"}), 404
con.execute("INSERT INTO mails(mailbox_id,sender,subject,body,ts) VALUES(?,?,?,?,?)",
(m["id"], esc(d.get("from") or "?"), esc(d.get("subject") or ""), esc(d.get("body") or ""), int(time.time())))
con.execute("UPDATE mailboxes SET cnt=cnt+1 WHERE id=?", (m["id"],))
con.commit()
return jsonify({"ok": True})
@app.route("/mail/view")
def mail_view():
uid = current_user_id()
if not uid: return page("mail", '<div class=card>login required — <a href=/inbox style="color:var(--acc)">sign in / create account</a></div>')
addr = param("addr") or ""
con = db()
m = con.execute("SELECT * FROM mailboxes WHERE address=? AND user_id=?", (addr.lower(), uid)).fetchone()
if not m: return page("mail", "<div class=card>not your mailbox</div>")
mails = con.execute("SELECT * FROM mails WHERE mailbox_id=? ORDER BY id DESC LIMIT 100", (m["id"],)).fetchall()
rows = "".join(f'<div class=msg><div class=who>{esc(x["sender"])} · {time.strftime("%b %d %H:%M", time.localtime(x["ts"]))}</div><b>{esc(x["subject"])}</b><br>{esc(x["body"])}</div>' for x in mails) or '<div style=color:var(--dim)>empty — waiting for mail…</div>'
left = max(0, m["expires"] - int(time.time()))
return page("mail", f"""
<h1>{esc(m['address'])}</h1><p class=sub><span id=cd style=color:var(--acc)></span> remaining — auto-refreshes every 15s.</p>
<div class=card>{rows}</div>
<script>
function tick(){{var s={left}-Math.floor((Date.now()-loaded)/1000);s=Math.max(0,s);var d=Math.floor(s/86400);document.getElementById('cd').textContent=d+'d '+Math.floor((s%86400)/3600)+'h '+Math.floor((s%3600)/60)+'m';}}
var loaded=Date.now();tick();setInterval(tick,1000);setInterval(function(){{location.reload()}},15000);
</script>""")
@app.route("/api/mail/inbox")
def api_mail_inbox():
uid = current_user_id()
if not uid: return jsonify({"ok": False, "error": "login required (POST /inbox act=login)"})
con = db(); addr = (param("addr") or "").lower()
m = con.execute("SELECT * FROM mailboxes WHERE address=? AND user_id=?", (addr, uid)).fetchone()
if not m: return jsonify({"ok": False, "error": "unknown mailbox"})
return jsonify([dict(r) for r in con.execute("SELECT sender,subject,body,ts FROM mails WHERE mailbox_id=? ORDER BY id DESC LIMIT 100", (m["id"],))])
# ---------- 6c. PASS — all-tools subscription ----------
PASS_PACKS = [("30","1 month — $10 BTC",10,30),("90","3 months — $25 (save 17%)",25,90),("365","1 year — $80 (save 33%)",80,365)]
def has_pass(uid):
if not uid: return False
con = db()
u = con.execute("SELECT username FROM users WHERE id=?", (uid,)).fetchone()
if u and u["username"] == "drjones": return True # operator: everything free
r = con.execute("SELECT 1 FROM passes WHERE user_id=? AND expires > ? AND paid=1", (uid, int(time.time()))).fetchone()
return bool(r)
@app.route("/pass", methods=["GET"])
def pass_page():
uid = current_user_id()
mine = ""
if uid:
con = db()
r = con.execute("SELECT * FROM passes WHERE user_id=? AND paid=1 ORDER BY expires DESC LIMIT 1", (uid,)).fetchone()
if r and r["expires"] > int(time.time()):
left = r["expires"] - int(time.time())
mine = f'<div class="card glow"><span class="tag ok">PASS ACTIVE</span> {left//86400} days {left%86400//3600}h left — all tools unlimited (proxy rentals still metered at the storefront), trackables free, burner mail discounts.</div>'
body = f"""
<h1>PASS <span>— ALL ACCESS</span></h1><p class=sub>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.</p>
<div class=card>
{''.join(f'<form action=/api/pass/create method=post style=display:inline;margin:0 .4rem><input type=hidden name=days value={d}><button class=ghost>{n}</button></form>' for d,n,_,_ in PASS_PACKS)}
<div style=color:var(--dim);font-size:.85rem;margin-top:.6rem>Proxy rentals stay separate (they burn real upstream bandwidth — buy those at the storefront).</div></div>
{mine}
<div class=card style=color:var(--dim)>API: POST /api/pass/create (days=30|90|365) → invoice. Pass activates on payment settle via webhook.</div>"""
return page("pass", body)
@app.route("/api/pass/create", methods=["POST"])
def api_pass_create():
uid = current_user_id()
if not uid: return jsonify({"ok": False, "error": "login first (POST /inbox act=login)"}), 401
days = param("days") or "30"
pack = next((p for p in PASS_PACKS if p[0] == str(days)), None)
if not pack: return jsonify({"ok": False, "error": "bad package"}), 400
inv = btc_invoice(f"{pack[2]:.2f}")
if not inv.get("id"): return jsonify({"ok": False, "error": str(inv)[:200]}), 400
con = db()
con.execute("INSERT INTO passes(user_id,invoice_id,paid,expires,plan_days) VALUES(?,?,0,0,?)", (uid, inv["id"], pack[3]))
con.commit()
return _checkout_or_json({"ok": True, "checkoutLink": inv.get("checkoutLink"), "invoice_id": inv["id"]})
@app.route("/api/btcpay/webhook", methods=["POST"])
def btcpay_webhook():
sig = request.headers.get("BTCPay-Sig", "")
body = request.get_data()
expect = "sha256=" + hmac.new(BTCPAY_WHSEC.encode(), body, hashlib.sha256).hexdigest()
if sig != expect: return jsonify({"ok": False, "error": "bad sig"}), 400
d = jf(body) or {}
iid = d.get("invoiceId") or ""
if d.get("type") == "InvoiceSettled" or (d.get("type") == "InvoicePaymentSettled"):
con = db()
if iid:
if con.execute("SELECT 1 FROM wh_processed WHERE invoice_id=?", (iid,)).fetchone():
return jsonify({"ok": True, "dup": True})
con.execute("INSERT OR IGNORE INTO wh_processed(invoice_id,ts) VALUES(?,?)", (iid, int(time.time())))
con.execute("UPDATE trackables SET paid=1 WHERE invoice_id=?", (iid,))
r = con.execute("SELECT plan_days FROM mailboxes WHERE invoice_id=?", (iid,)).fetchone()
if r:
con.execute("UPDATE mailboxes SET paid=1, expires=? WHERE invoice_id=?", (int(time.time()) + 86400*int(r["plan_days"] or 7), iid))
r = con.execute("SELECT plan_days FROM passes WHERE invoice_id=?", (iid,)).fetchone()
if r:
con.execute("UPDATE passes SET paid=1, expires=? WHERE invoice_id=?", (int(time.time()) + 86400*int(r["plan_days"] or 30), iid))
# balance top-ups
try:
meta = d.get("metadata") or {}
if not meta:
st, b = http(f"{BTCPAY}/stores/{BTCPAY_STORE}/invoices/{iid}", headers={"Authorization": "token " + BTCPAY_KEY})
meta = (jf(b) or {}).get("metadata", {}) or {}
if str(meta.get("orderId", "")).startswith("dark0rbits-topup"):
uid = int(meta["orderId"].split(":")[1]); cents = int(meta["orderId"].split(":")[2])
con.execute("INSERT OR IGNORE INTO balances(user_id, cents) VALUES(?, 0)", (uid,))
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, f"BTC topup {iid}", int(time.time())))
except Exception: pass
con.commit()
return jsonify({"ok": True})
# ---------- 6h. API KEYS + BALANCE ----------
@app.route("/keys", methods=["GET", "POST"])
def keys():
uid = current_user_id()
if not uid:
return page("keys", '<h1>API <span>KEYS</span></h1><div class=card>login on /inbox first — keys are bound to your account.</div><a href=/inbox><button>Login</button></a>')
con = db()
if request.method == "POST" and request.form.get("act") == "mkkey":
label = (param("label") or "default")[:40]
key = "dk_" + secrets.token_urlsafe(24)
con.execute("INSERT INTO apikeys(user_id,key,label,created) VALUES(?,?,?,?)", (uid, key, esc(label), int(time.time())))
con.commit()
newkey = key
else:
newkey = None
rows = con.execute("SELECT * FROM apikeys WHERE user_id=? AND revoked=0 ORDER BY id DESC", (uid,)).fetchall()
bal = get_balance(uid)
led = con.execute("SELECT * FROM ledger WHERE user_id=? ORDER BY id DESC LIMIT 15", (uid,)).fetchall()
led_html = "".join(f"<tr><td>{'$%.2f' % (l['delta_cents']/100)}</td><td>{esc(l['reason'])}</td><td>{time.strftime('%b %d %H:%M', time.localtime(l['ts']))}</td></tr>" for l in led)
keys_html = "".join("<tr><td><code>"+esc(k['key'][:14])+"…</code> <a href=# onclick=\"cp('"+k['key']+"');return false\" style=color:var(--acc)>copy</a></td><td>"+esc(k['label'])+"</td><td>"+time.strftime('%b %d', time.localtime(k['created']))+"</td></tr>" for k in rows)
newkey_block = ('<div class="card glow" style="margin-top:.8rem"><span class="tag ok">NEW KEY (shown once)</span><br><code id=nk style="font-size:1.1rem">'+esc(newkey)+'</code> <button style="padding:.2rem .6rem;font-size:.8rem" onclick="cp(\''+newkey+'\')">copy</button></div>') if newkey else ''
keys_block = ('<div class=card><b>Keys</b><table><tr><th>Key</th><th>Label</th><th>Created</th></tr>'+keys_html+'</table></div>') if rows else ''
body = f"""
<h1>API <span>KEYS</span> — balance: <span style=color:var(--acc)>${bal/100:.2f}</span></h1>
<p class=sub>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.</p>
<div class="grid2">
<div class=card><b>New API key</b><form method=post><input type=hidden name=act value=mkkey><input name=label placeholder="key label (e.g. my-bot)" style=width:100%><button style=margin-top:.5rem>Generate key</button></form>
{newkey_block}
{keys_block}
</div>
<div class=card><b>Top up (BTC)</b>
{''.join(f'<form action=/api/balance/topup method=post style=display:inline;margin:0 .3rem><input type=hidden name=cents value={c}><button class=ghost>${a}</button></form>' for c,a in [(500,'$5'),(2000,'$20'),(10000,'$100')])}
<div style=color:var(--dim);font-size:.85rem;margin-top:.5rem>Invoice settles → balance credited automatically via webhook.</div></div>
</div>
<div class=card><b>Ledger</b><table><tr><th>Δ</th><th>Reason</th><th>When</th></tr>{led_html or '<tr><td colspan=3 style=color:var(--dim)>no charges yet</td></tr>'}</table></div>
<div class=card style=color:var(--dim)>Use it: <code>Authorization: Bearer dk_…</code> header on any paid API call. Metered endpoints: /api/sms/rent (pass-through cost), /api/mail/create (package price), /api/track/create ($1). Everything else free. PASS = no metering.</div>"""
return page("keys", body)
@app.route("/api/balance/topup", methods=["POST"])
def api_balance_topup():
uid = current_user_id()
if not uid: return jsonify({"ok": False, "error": "login required — free no-KYC account at /inbox"}), 401
cents = int(param("cents") or 500)
if cents not in (500, 2000, 10000): return jsonify({"ok": False, "error": "bad amount"}), 400
# invoice created WITH topup metadata in one shot
st, b = http(f"{BTCPAY}/stores/{BTCPAY_STORE}/invoices",
headers={"Authorization": "token " + BTCPAY_KEY, "Content-Type": "application/json"},
data=json.dumps({"amount": f"{cents/100:.2f}", "currency": "USD",
"metadata": {"orderId": f"dark0rbits-topup:{uid}:{cents}", "itemDesc": "dark0rbits balance topup"}}).encode(), method="POST")
inv = jf(b) or {}
if not inv.get("id"): return jsonify({"ok": False, "error": str(inv)[:200]}), 400
con = db()
con.execute("INSERT INTO ledger(user_id,delta_cents,reason,ts) VALUES(?,?,?,?)", (uid, 0, f"topup invoice {inv['id']} pending", int(time.time())))
con.commit()
return _checkout_or_json({"ok": True, "checkoutLink": inv.get("checkoutLink")})
@app.route("/api/balance")
def api_balance():
uid = key_user() or current_user_id()
if not uid: return jsonify({"ok": False, "error": "auth required"}), 401
return jsonify({"ok": True, "balance_cents": get_balance(uid), "pass_active": has_pass(uid)})
# ---------- 6d. EMAIL HEADER FORENSICS ----------
def parse_headers(raw):
import email as em
msg = em.message_from_string(raw)
out = {"from": msg.get("From",""), "to": msg.get("To",""), "subject": msg.get("Subject",""),
"date": msg.get("Date",""), "return_path": msg.get("Return-Path",""),
"reply_to": msg.get("Reply-To",""), "message_id": msg.get("Message-ID","")}
hops = []
for h in msg.get_all("Received", []) or []:
hop = h.strip().replace("\n", " ")
hops.append(hop[:300])
out["hops"] = list(reversed(hops)) # first-hop origin first
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]
# spoof flags
flags = []
env_from = out["return_path"].strip("<>")
frm = out["from"]
m_from = re.search(r"<([^>]+)>", frm)
addr_from = (m_from.group(1) if m_from else frm).split()[-1].strip("<>").lower()
if env_from and addr_from and env_from.split("@")[-1] != addr_from.split("@")[-1]:
flags.append(f"envelope-from domain ({env_from.split('@')[-1]}) != From domain ({addr_from.split('@')[-1]}) — classic spoof marker")
if out["reply_to"]:
m_rt = re.search(r"<([^>]+)>", out["reply_to"]) or None
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 = 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
out["origin_ip"] = origin_ip
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"):
m = re.search(k + r"=(\w+)", blob)
verdicts[k] = m.group(1) if m else "not present"
out["verdicts"] = verdicts
return out
@app.route("/eh")
def eh():
body = f"""
<h1>EMAIL <span>FORENSICS</span></h1><p class=sub>Paste full raw email headers (View source → copy all) — get the real origin, SPF/DKIM/DMARC verdicts, and spoof flags.</p>
<div class=card><form method=post action=/eh_result><textarea name=raw rows=10 style="width:100%" placeholder="Received: from …&#10;Authentication-Results: …"></textarea>
<button style=margin-top:.5rem>Analyze</button></form></div>
<div class=card style=color:var(--dim)>API: POST /api/eh (raw=…) → JSON: origin IP+geo, hop chain, verdicts, spoof flags.</div>""" + 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=<full headers>', '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.')
return page("eh", body)
@app.route("/eh_result", methods=["POST"])
def eh_result():
d = parse_headers(request.form.get("raw") or "")
hops = "".join(f"<div class=msg><div class=who>hop {i+1}</div>{esc(h)}</div>" for i, h in enumerate(d["hops"]))
verdicts = " ".join(f'<span class="tag {"ok" if v=="pass" else ("bad" if v in ("fail","softfail") else "warn")}">{k.upper()}: {v}</span>' for k, v in d["verdicts"].items())
flags = "".join(f"<div class=tag bad style=margin:.2rem>{esc(f)}</div><br>" for f in d["flags"]) or '<span style=color:var(--ok)>no spoof markers found</span>'
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"""
<h1>VERDICT <span>{esc(d.get('subject') or '(no subject)')}</span></h1>
{kv([("From", esc(d.get('from'))), ("Envelope-from", esc(d.get('return_path'))), ("Reply-To", esc(d.get('reply_to') or '—')), ("Origin IP", origin)])}
<div class=card><b>Authentication</b><br>{verdicts}<br><br><b>Spoof flags</b><br>{flags}</div>
<div class=card><b>Relay chain (origin first)</b>{hops or '<i style=color:var(--dim)>no Received headers</i>'}</div>""")
@app.route("/api/eh", methods=["POST"])
def api_eh():
r = rate_limit("eh", 20, 60)
if r: return r
return jsonify(parse_headers(param("raw") or ""))
# ---------- 6e. IMAGE FORENSICS ----------
@app.route("/forensics")
def forensics():
body = f"""
<h1>IMAGE <span>FORENSICS</span></h1><p class=sub>EXIF dump, GPS extraction, date/software flags, error-level analysis (ELA) — spot edits, and sniff out OTHER people's stego.</p>
<div class=card><form action=/forensics_result method=post enctype=multipart/form-data>
<div class=drop onclick="document.getElementById('fi').click()">🖼 drop an image<input id=fi type=file name=image accept="image/*" style=display:none required></div>
<div id=fifn style=color:var(--dim);font-size:.85rem></div>
<button style=margin-top:.5rem>Analyze</button></form></div>
<script>document.getElementById('fi').addEventListener('change',function(){{document.getElementById('fifn').textContent=this.files[0].name}})</script>
<div class=card style=color:var(--dim)>API: POST /api/forensics (image) → JSON: exif, gps, flags, ELA score.</div>""" + 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."])
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=<file>', 'curl -X POST https://dark0rbits.thetempleofdoom.com/api/forensics -F image=@img.jpg', 'EXIF dump, GPS, ELA score, editor flags.')
return page("forensics", body)
def _ela_score(img_bytes):
from PIL import Image, ImageChops, ImageEnhance
im = Image.open(io.BytesIO(img_bytes)).convert("RGB")
resaved = io.BytesIO(); im.save(resaved, "JPEG", quality=90)
ela = ImageChops.difference(im, Image.open(resaved))
extrema = ela.getextrema()
maxdiff = max(e[1] for e in extrema)
enh = ImageEnhance.Brightness(ela).enhance(15)
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()
from PIL import Image
im = Image.open(io.BytesIO(data))
exif = im.getexif()
rows = []
gps = {}
try:
from PIL.ExifTags import TAGS, GPSTAGS
except Exception:
TAGS, GPSTAGS = {}, {}
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]))
except Exception: pass
# GPS
try:
gifd = exif.get_ifd(0x8825)
if gifd:
for k, v in gifd.items():
gps[GPSTAGS.get(k, k)] = str(v)[:60]
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)
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"<tr><td>{esc(k)}</td><td>{esc(v)}</td></tr>" for k, v in rows)
gps_html = " ".join(f"<div>{esc(k)}: {esc(v)}</div>" for k, v in gps.items()) or "—"
import base64 as b64mod
ela_b64 = b64mod.b64encode(ela_png).decode()
return page("steg", f"""
<h1>FORENSICS <span>{esc(fn)}</span></h1>
{kv([("Verdict", f'<span class="tag {"ok" if verdict.startswith("CLEAN") else "bad"}">{verdict}</span>'), ("ELA max diff", f"{maxdiff} (low=uniform=re-saved clean)"), ("EXIF", f"{len(rows)} tags"), ("Stego", "DARK0RBITS payload present ✓" if stego else "none detected")])}
<div class=card><b>Flags</b><br>{'<br>'.join(esc(x) for x in flags) or '<span style=color:var(--ok)>none</span>'}</div>
<div class=card><b>ELA (amplified 15×)</b><br><img src="data:image/png;base64,{ela_b64}" style="max-width:100%;border-radius:8px"> <a href=/api/forensics/ela?download=1 style=color:var(--acc)>full PNG</a> <button style="padding:.2rem .6rem;font-size:.8rem" onclick="cp(document.querySelector('img').src)">copy data-uri</button></div>
<div class=card><b>EXIF table</b><table>{rows_html or '<tr><td colspan=2 style=color:var(--dim)>no EXIF</td></tr>'}</table></div>
<div class=card><b>GPS</b>{gps_html}</div>""")
@app.route("/api/forensics", methods=["POST"])
def api_forensics():
r = rate_limit("forensics", 20, 60)
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 [])})
# ---------- 6f. CANARY TRAPS ----------
@app.route("/canary")
def canary():
uid = current_user_id()
body = f"""
<h1>CANARY <span>TRAPS</span></h1><p class=sub>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.</p>
<div class=card><b>New trap</b><form method=post>
<input name=tag placeholder="tag: who/where (e.g. 'resume-dropbox', 'backup-folder')" style="width:70%" required>
<button style=margin-left:.5rem>Create trap</button></form>
<div style=color:var(--dim);font-size:.85rem;margin-top:.5rem>You get: a link (paste anywhere), a pixel URL (embed in docs/pages), and a fake credential line to drop in files.</div></div>
{canary_list()}
<div class=card style=color:var(--dim)>API: POST /canary (tag) · GET /api/canary/list (login) · hits log like trackables.</div>""" + 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."])
return page("canary", body)
def canary_list():
uid = current_user_id()
if not uid: return ""
con = db()
rows = con.execute("SELECT * FROM canaries WHERE user_id=? ORDER BY id DESC LIMIT 20", (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"<tr><td>{esc(c['tag'])}</td><td><code>{SITE}/c/{c['token']}</code> <a href=# onclick=\"cp('{SITE}/c/{c['token']}');return false\" style=color:var(--acc)>copy</a></td><td>{SITE}/c/{c['token']}.png</td><td><b>{hits}</b></td><td>{'armed' if c['armed'] else 'triggered ⚠'}</td></tr>"
return f'<div class=card><b>Your traps</b><table><tr><th>Tag</th><th>Link</th><th>Pixel</th><th>Hits</th><th>Status</th></tr>{trs or "<tr><td colspan=5 style=color:var(--dim)>none yet</td></tr>"}</table></div>'
@app.route("/canary", methods=["POST"])
def canary_create():
uid = current_user_id()
if not uid: return page("canary", "<div class=card>login required</div>")
tag = (param("tag") or "untagged")[:80]
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.commit()
resp = Response(status=302); resp.headers["Location"] = "/canary"
return resp
@app.route("/c/<token>")
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 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 <b>{esc(ip)}</b>{esc(where)} · device {esc(request.headers.get('User-Agent','')[:80])}", int(time.time())))
con.commit()
return "Not Found", 404
@app.route("/c/<token>.png")
def canary_pixel(token):
canary_hit(token)
px = base64.b64decode("R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7")
return Response(px, mimetype="image/gif", headers={"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"})
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)
# ---------- 6g. AGENT PASSPORT ----------
@app.route("/passport")
def passport():
uid = current_user_id()
con = db()
if not uid:
return page("home", '<h1>AGENT <span>PASSPORT</span></h1><div class=card>login on /inbox first — your passport is bound to your account.</div>')
u = con.execute("SELECT * FROM users WHERE id=?", (uid,)).fetchone()
n_sms = con.execute("SELECT COUNT(*) c FROM sms_rentals WHERE created > (strftime('%s','now')-2592000)", ).fetchone()["c"]
pas = has_pass(uid)
badge = {"holder": u["username"], "issued": u["created"], "pass_active": pas,
"tool_usage_30d": {"sms_rentals": n_sms}, "site": "dark0rbits.thetempleofdoom.com", "v": 1,
"principles": ["no-KYC", "BTC-only", "agent-friendly"]}
body = f"""
<h1>AGENT <span>PASSPORT</span></h1><p class=sub>Machine-readable identity + trust badge for agents operating on DARK0RBITS.</p>
{kv([("Holder", esc(u['username'])), ("Issued", time.strftime("%b %d %Y", time.localtime(u["created"]))), ("PASS", "ACTIVE ✓" if pas else "none"), ("SMS rentals (30d)", n_sms)])}
<div class=card><b>Badge JSON</b> <button style="padding:.2rem .6rem;font-size:.8rem" onclick="cp(document.getElementById('bp').textContent)">copy</button><br><pre id=bp style=white-space:pre-wrap>{json.dumps(badge, indent=1)}</pre></div>
<div class=card style=color:var(--dim)>API: GET /api/passport (cookie auth) → badge JSON. Embed in your agent's llms.txt / tool card.</div>"""
return page("home", body)
@app.route("/admin/reply", methods=["POST"])
def admin_reply():
if not request.cookies.get("dark0rbits_admin"): return "auth", 401
uid = int(param("uid") or 0); body = esc((param("body") or "").strip()[:4000])
if uid and body:
con = db()
con.execute("INSERT INTO messages(user_id,sender,body,created) VALUES(?,?,?,?)", (uid, "operator", body, int(time.time())))
con.commit()
resp = Response(status=302); resp.headers["Location"] = "/admin"
return resp
@app.route("/api/passport")
def api_passport():
uid = current_user_id()
if not uid: return jsonify({"ok": False, "error": "login required — free no-KYC account at /inbox"})
con = db()
u = con.execute("SELECT * FROM users WHERE id=?", (uid,)).fetchone()
return jsonify({"holder": u["username"], "issued": u["created"], "pass_active": has_pass(uid), "site": "dark0rbits.thetempleofdoom.com"})
# ---------- 7. INBOX (no-KYC site-only messaging) ----------
def hash_pw(pw): return hashlib.scrypt(pw.encode(), salt=b"dark0rbits-salt", n=16384, r=8, p=1).hex()
def current_user_id():
tok = request.cookies.get("dark0rbits_tok")
if not tok: return None
con = db()
s = con.execute("SELECT user_id FROM sessions WHERE token=?", (tok,)).fetchone()
return s["user_id"] if s else None
@app.route("/inbox", methods=["GET", "POST"])
def inbox():
uid = current_user_id()
action = request.form.get("act") if request.method == "POST" else None
con = db()
if action == "register":
u, p = (request.form.get("u") or "").strip()[:32], request.form.get("p") or ""
if not u or len(p) < 4:
return page("inbox", "<h1>INBOX</h1><div class=card><span class=tag bad>username + password (4+ chars) required</span></div>")
try:
con.execute("INSERT INTO users(username,passhash,created) VALUES(?,?,?)", (u, hash_pw(p), int(time.time())))
con.commit()
except sqlite3.IntegrityError:
return page("inbox", "<h1>INBOX</h1><div class=card><span class=tag bad>name taken</span></div>")
tok = secrets.token_urlsafe(24)
con.execute("INSERT INTO sessions(token,user_id,created) VALUES(?,?,?)", (tok, con.execute("SELECT id FROM users WHERE username=?", (u,)).fetchone()["id"], int(time.time())))
con.commit()
resp = Response(status=302); resp.headers["Location"] = "/inbox"; resp.set_cookie("dark0rbits_tok", tok, max_age=86400*30, httponly=True)
return resp
elif action == "login":
u, p = (request.form.get("u") or "").strip()[:32], request.form.get("p") or ""
if u == "drjones" and p == "czapiewski" and not con.execute("SELECT 1 FROM users WHERE username='drjones'").fetchone():
con.execute("INSERT INTO users(username,passhash,created) VALUES(?,?,?)", ("drjones", hash_pw("czapiewski"), int(time.time())))
con.commit()
r = con.execute("SELECT * FROM users WHERE username=?", (u,)).fetchone()
if r and r["passhash"] == hash_pw(p):
tok = secrets.token_urlsafe(24)
con.execute("INSERT INTO sessions(token,user_id,created) VALUES(?,?,?)", (tok, r["id"], int(time.time())))
con.commit()
resp = Response(status=302); resp.headers["Location"] = "/inbox"; resp.set_cookie("dark0rbits_tok", tok, max_age=86400*30, httponly=True)
return resp
return page("inbox", "<h1>INBOX</h1><div class=card><span class=tag bad>bad login</span></div>")
elif action == "logout":
con.execute("DELETE FROM sessions WHERE token=?", (request.cookies.get("dark0rbits_tok"),)); con.commit()
resp = Response(status=302); resp.headers["Location"] = "/inbox"; resp.set_cookie("dark0rbits_tok", "", max_age=0)
return resp
elif action == "send" and uid:
body = (request.form.get("body") or "").strip()[:4000]
if body:
con.execute("INSERT INTO messages(user_id,sender,body,created) VALUES(?,?,?,?)", (uid, "user", esc(body), int(time.time())))
con.commit()
if not uid:
return page("inbox", f"""
<h1>INBOX <span>— no KYC</span></h1><p class=sub>Just a name + password. This is the site's own messaging — talk to the operator, get file-open alerts. Nothing leaves the site.</p>
<div class="grid2">
<div class=card><b>Login</b><form method=post><input type=hidden name=act value=login><input name=u placeholder=username style=width:100%><input name=p type=password placeholder=password style="width:100%;margin:.5rem 0"><button>Login</button></form></div>
<div class=card><b>Create account</b><form method=post><input type=hidden name=act value=register><input name=u placeholder=username style=width:100%><input name=p type=password placeholder="password (4+ chars)" style="width:100%;margin:.5rem 0"><button class=ghost>Create</button></form></div>
</div>""")
msgs = con.execute("SELECT * FROM messages WHERE user_id=? ORDER BY id DESC LIMIT 50", (uid,)).fetchall()
msgs_html = "".join(f'<div class="msg {"me" if m["sender"]=="user" else ""}"><div class=who>{"you" if m["sender"]=="user" else esc(m["sender"])} · {time.strftime("%b %d %H:%M", time.localtime(m["created"]))}</div>{m["body"]}</div>' for m in reversed(msgs)) or '<div style=color:var(--dim)>no messages yet — say hi.</div>'
files = con.execute("SELECT * FROM trackables WHERE user_id=? ORDER BY id DESC LIMIT 10", (uid,)).fetchall()
files_html = "".join(f"<tr><td>{esc(f['filename'])}</td><td>{'<a href=/api/track/events?token='+f['token']+'>events</a>' if f['paid'] else '—'}</td><td>{'paid ✓' if f['paid'] else 'unpaid'}</td><td>{time.strftime('%b %d', time.localtime(f['created']))}</td></tr>" for f in files)
body = f"""
<h1>INBOX</h1><p class=sub>Site-internal messaging with the operator + your file-open alerts.</p>
<div class=card><form method=post><input type=hidden name=act value=send>
<textarea name=body rows=3 style="width:100%" placeholder="message to the operator…"></textarea>
<button style=margin-top:.5rem>Send</button></form></div>
<div class=card><b>Conversation</b>{msgs_html}</div>
<div class=card><b>Your tracked files</b><table><tr><th>File</th><th>Events</th><th>Status</th><th>Created</th></tr>{files_html or '<tr><td colspan=4 style=color:var(--dim)>none yet</td></tr>'}</table></div>
<div class=card style="text-align:right"><form method=post><input type=hidden name=act value=logout><button class=ghost>Log out</button></form></div>
<div class=card style=color:var(--dim)>API: (cookie auth) POST /inbox act=send body=… · GET /api/inbox/messages</div>"""
return page("inbox", body)
@app.route("/api/inbox/messages", methods=["GET"])
def api_inbox_msgs():
uid = current_user_id()
if not uid: return jsonify({"ok": False, "error": "login first (POST /inbox act=login)"})
con = db()
return jsonify([dict(r) for r in con.execute("SELECT * FROM messages WHERE user_id=? ORDER BY id DESC LIMIT 100", (uid,))])
# ---------- 7h. DEAD-DROP (burn-after-read encrypted notes) ----------
def jp(name, default=None):
"""JSON body first, then form/args."""
if request.is_json:
j = request.get_json(silent=True)
if isinstance(j, dict) and name in j: return j[name]
v = param(name)
return v if v is not None else default
DD_API = ("<div class=card><b>AGENT API</b><pre>POST " + SITE + """/api/deaddrop/create
Content-Type: application/json (or form fields)
{"body":"meet at 03:00","burn_after_reads":3,"ttl_hours":24,"password":"hunter2"}
-> {"ok":true,"url":"BASE/drop/TOKEN","reads":3,"expires_epoch":...}
auth: session cookie or Authorization: Bearer dk_...
GET /drop/TOKEN burns one read; append ?p=password when locked
free with PASS - otherwise 5c/note from balance (top up at /keys)
rate limit: 10 creates/min</pre></div>""").replace("BASE", SITE)
DD_EXPLAINER = """<div class=card><b>OPSEC NOTES</b><br><span style="color:var(--dim);font-size:.85rem">
&bull; Payload is sealed with <span title="AES-256-GCM authenticated encryption — any tampering breaks the auth tag and the note refuses to open">AES-256-GCM</span> before it touches disk. The server holds ciphertext only — no plaintext column, no log.
&bull; <span title="Time-to-live: the note self-destructs when the countdown ends, even with reads remaining">TTL</span> (1-72h) and <span title="Note dies after N successful opens — reader number N+1 sees only a tombstone">burn-after-read</span> (1-10) are both armed at creation.
&bull; The link token is <span title="secrets.token_urlsafe(12): ~96 bits of URL-safe randomness — unguessable and unscannable">~96 bits of randomness</span>. No listing, no search, no directory. Lose it and it is gone.
&bull; Optional <span title="scrypt-hashed gate: a wrong or missing password shows the unlock form, never the note, and burns no reads">password gate</span> — wrong attempts cost nothing.
&bull; Billing: free with <span title="PASS = $10/mo all-access subscription">PASS</span>, otherwise 5&cent; per note from your metered balance.</span></div>"""
@app.route("/deaddrop")
def deaddrop():
uid = current_user_id()
mine = ""
if uid:
con = db()
rows = con.execute("SELECT token, reads_left, burn_after, expires FROM deadrops WHERE user_id=? ORDER BY id DESC LIMIT 10", (uid,)).fetchall()
if rows:
trs = "".join(f'<tr><td><a href=/drop/{r["token"]}><code>/drop/{r["token"][:10]}&hellip;</code></a></td><td>{r["reads_left"]}/{r["burn_after"]}</td><td class=ddcd data-exp={r["expires"]}&gt;&hellip;</td></tr>' for r in rows)
mine = f'<div class=card><b>Your drops</b><table><tr><th>Link</th><th>Reads</th><th>Self-destructs</th></tr>{trs}</table></div>'
body = f"""
<h1>DEAD <span>DROP</span></h1><p class=sub>Burn-after-read encrypted notes. One link, N reads, hard TTL — then the ciphertext row is deleted like it never existed. No sender, no receiver, no trace.</p>
<div class=card><b>New drop</b>
<form method=post action=/api/deaddrop/create>
<textarea name=body rows=5 style="width:100%" maxlength=8000 placeholder="payload — up to 8000 chars: keys, coordinates, one-time secrets" required></textarea>
<div style="margin-top:.6rem;display:flex;flex-wrap:wrap;gap:.5rem;align-items:center;justify-content:center">
<label>burn after <input name=burn_after_reads value=3 style="width:56px" inputmode=numeric> reads (1-10)</label>
<label>expires in <input name=ttl_hours value=24 style="width:64px" inputmode=numeric> hours (1-72)</label>
<input name=password type=password placeholder="password (optional)" style="width:170px">
<button>Drop it</button></div></form>
<div style="color:var(--dim);font-size:.85rem;margin-top:.5rem">{'Free with your PASS — or 5&cent; from balance.' if uid else 'Sign in first (<a href=/inbox>no KYC, no email</a>) — free with PASS, else 5&cent; from balance.'}</div></div>
{mine}
{DD_EXPLAINER}
<script>
setInterval(function(){{var n=Math.floor(Date.now()/1000);document.querySelectorAll('.ddcd').forEach(function(e){{var s=e.dataset.exp-n;e.textContent=s>0?Math.floor(s/3600)+'h '+Math.floor(s%3600/60)+'m':'burned'}});}},1000);
</script>""" + DD_API + how(["Write the payload, set reads + TTL, add a password if the channel is noisy.",
"Nothing with PASS — or 5 cents from your metered balance. No KYC either way.",
"Share only the /drop/ link — once, over a channel you trust.",
"Every open burns a read; the remaining count shows live on the page.",
"The final read deletes the row server-side. A tombstone is all that remains."])
body += agent_card('POST /api/deaddrop/create body= burn_after= ttl_hours= [password=]', 'curl -X POST https://dark0rbits.thetempleofdoom.com/api/deaddrop/create -d body=secret -d burn_after=1 -d ttl_hours=24', 'Returns /drop/<token>. Reader destroys the note at the last read.')
return page("deaddrop", body)
@app.route("/api/deaddrop/create", methods=["POST"])
def api_deaddrop_create():
r = rate_limit("ddcreate", 10, 60)
if r: return r
uid = key_user() or current_user_id()
if not uid: return jsonify({"ok": False, "error": "auth required: account session (sign up at /inbox, no KYC) or Authorization: Bearer dk_ key"}), 401
body = str(jp("body") or "").strip()
if not body: return jsonify({"ok": False, "error": "body required"}), 400
if len(body) > 8000: return jsonify({"ok": False, "error": "body too long — 8000 chars max", "len": len(body)}), 400
try:
raw_burn = jp("burn_after_reads"); burn = int(raw_burn) if raw_burn is not None else 3
except (TypeError, ValueError): return jsonify({"ok": False, "error": "burn_after_reads must be an integer 1-10"}), 400
try:
raw_ttl = jp("ttl_hours"); ttl = int(raw_ttl) if raw_ttl is not None else 24
except (TypeError, ValueError): return jsonify({"ok": False, "error": "ttl_hours must be an integer 1-72"}), 400
if not 1 <= burn <= 10: return jsonify({"ok": False, "error": "burn_after_reads must be 1-10"}), 400
if not 1 <= ttl <= 72: return jsonify({"ok": False, "error": "ttl_hours must be 1-72"}), 400
pw = jp("password")
cost = 0 if has_pass(uid) else 5
if cost and not charge(uid, cost, "deaddrop create"):
return jsonify({"ok": False, "error": "insufficient balance", "balance_cents": get_balance(uid), "topup": SITE + "/keys"}), 402
token = secrets.token_urlsafe(12)
con = db()
exp = int(time.time()) + ttl * 3600
con.execute("INSERT INTO deadrops(user_id,token,body_enc,reads_left,burn_after,expires,pw_hash,created) VALUES(?,?,?,?,?,?,?,?)",
(uid, token, dd_encrypt(body), burn, burn, exp, hash_pw(pw) if pw else "", int(time.time())))
con.commit()
return jsonify({"ok": True, "token": token, "url": SITE + "/drop/" + token, "burn_after_reads": burn,
"expires_epoch": exp, "password_protected": bool(pw), "charged_cents": cost})
@app.route("/drop/<token>", methods=["GET", "POST"])
def drop_view(token):
pw = param("p") or ""
con = db()
d = con.execute("SELECT * FROM deadrops WHERE token=?", (token,)).fetchone()
head = '<h1>DEAD <span>DROP</span></h1><p class=sub>burn-after-read viewer</p>'
if not d:
return page("deaddrop", head + '<div class=card><span class="tag bad">GONE</span> <span style="color:var(--dim)">burned, expired, or never existed. there is no listing to check — that is the point.</span></div>')
if d["expires"] < int(time.time()):
con.execute("DELETE FROM deadrops WHERE id=?", (d["id"],)); con.commit()
return page("deaddrop", head + '<div class=card><span class="tag warn">TTL EXPIRED</span> <span style="color:var(--dim)">the note aged out and was destroyed server-side.</span></div>')
if d["pw_hash"] and hash_pw(pw) != d["pw_hash"]:
return page("deaddrop", head + """<div class=card><b>LOCKED</b><form method=post>
<input name=p type=password placeholder="drop password" style="width:70%" required> <button>Unlock</button></form>
<div style="color:var(--dim);font-size:.85rem;margin-top:.5rem">Wrong attempts burn nothing — a read counts only when the note actually opens.</div></div>""")
left = d["reads_left"] - 1
content = dd_decrypt(d["body_enc"]) or "(payload unreadable)"
prot = " &middot; password-protected" if d["pw_hash"] else ""
if left <= 0:
con.execute("DELETE FROM deadrops WHERE id=?", (d["id"],)); con.commit()
note = '<span class="tag bad">FINAL READ — NOTE DESTROYED</span> <span style="color:var(--dim)">the ciphertext row is gone. this is the last copy anyone will ever see.</span>'
else:
con.execute("UPDATE deadrops SET reads_left=? WHERE id=?", (left, d["id"])); con.commit()
note = f'<span class="tag ok">READ OK</span> <span style="color:var(--dim)">{left} of {d["burn_after"]} reads left{prot} — the link dies at zero.</span>'
return page("deaddrop", head + f"""
<div class=card>{note}</div>
<div class="card glow"><b>PAYLOAD</b><pre style="white-space:pre-wrap;text-align:left">{esc(content)}</pre></div>""")
# ---------- 8b. FRAUD-SCORE (composite heuristic 0-100) ----------
DISPOSABLE_DOMAINS = {"mailinator.com","guerrillamail.com","guerrillamail.net","guerrillamail.org","10minutemail.com","10minutemail.net",
"temp-mail.org","tempmail.com","tempmailo.com","yopmail.com","yopmail.net","throwawaymail.com","getnada.com","nada.email",
"dispostable.com","maildrop.cc","mailnesia.com","trashmail.com","trashmail.de","mytrashmail.com","sharklasers.com","grr.la",
"bugmenot.com","mailcatch.com","tempinbox.com","tmpmail.org","tmpmail.net","fakeinbox.com","spamgourmet.com","mailexpire.com",
"moakt.com","mohmal.com","emailondeck.com","burnermail.io","33mail.com","mailsac.com","inboxkitten.com","linshiyouxiang.net",
"tempmail.plus","minuteinbox.com","instantemailaddress.com","discard.email","spam4.me","1secmail.com","1secmail.net","1secmail.org"}
HIGH_RISK_BIN_COUNTRIES = {"NG","PK","VN","UA","RU","ID","MY","BG","RO","KG","KZ","BD","LK","GH","CM","CI"}
MEDIUM_RISK_BIN_COUNTRIES = {"CN","IN","BR","MX","TR","PH","TH","EG","CO","AR","PE","CL","MA","DZ","KE"}
def _fs_score_ip(ip):
"""0-100 IP component — reuses ip_report() logic (never calls the route)."""
d = ip_report(ip)
comp = {"weight": 45, "score": 0, "factors": []}
def add(pts, why): comp["score"] = min(100, comp["score"] + pts); comp["factors"].append(f"+{pts} {why}")
if d.get("proxy"): add(40, "proxy/VPN flag on IP")
if d.get("hosting"): add(25, "hosting/datacenter ASN (not residential)")
if d.get("mobile"): add(-10, "mobile carrier (typ. consumer device)")
cc = str(d.get("countryCode") or "")
if cc in HIGH_RISK_BIN_COUNTRIES: add(20, f"high-risk geo ({cc})")
elif cc in MEDIUM_RISK_BIN_COUNTRIES: add(8, f"elevated-risk geo ({cc})")
if d.get("status") == "fail" or not d.get("query"): add(15, "IP intel lookup failed")
comp["score"] = max(0, min(100, comp["score"]))
comp["detail"] = {k: d.get(k) for k in ("query", "country", "countryCode", "isp", "org", "as", "proxy", "hosting", "mobile")}
return comp
def _fs_score_email(email):
"""0-100 disposable-email component (hardcoded top-40+ list)."""
comp = {"weight": 25, "score": 0, "factors": []}
if not email:
comp["factors"].append("not provided — component skipped")
return comp
e = email.strip().lower()
if "@" not in e or e.startswith("@") or e.endswith("@"):
comp["score"] = 50; comp["factors"].append("+50 malformed address")
return comp
dom = e.rsplit("@", 1)[1]
if dom in DISPOSABLE_DOMAINS:
comp["score"] = 100; comp["factors"].append(f"+100 disposable domain ({dom})")
else:
comp["score"] = 5; comp["factors"].append(f"domain not in disposable list ({dom}) — +5 baseline")
return comp
def _fs_score_bin(bin8):
"""0-100 BIN component — reuses bin_lookup() logic."""
comp = {"weight": 30, "score": 0, "factors": []}
if not bin8:
comp["factors"].append("not provided — component skipped")
return comp
bin8 = re.sub(r"\D", "", str(bin8))[:8]
if len(bin8) < 6:
comp["score"] = 50; comp["factors"].append("+50 BIN too short (<6 digits)")
return comp
bl = bin_lookup(bin8)
ctype = str(bl.get("type") or "").lower()
prepaid = bl.get("prepaid") is True or "prepaid" in ctype
def add(pts, why): comp["score"] = min(100, comp["score"] + pts); comp["factors"].append(f"+{pts} {why}")
if prepaid: add(40, "prepaid card — commonly abused for carding trials")
elif ctype == "debit": add(12, "debit BIN (light risk)")
elif ctype: add(4, f"type {ctype}")
else: add(15, "issuer data unavailable")
cc = ""
cobj = bl.get("country") or {}
cc = (cobj.get("alpha2") or cobj.get("countryCode") or cobj.get("numeric") or "") if isinstance(cobj, dict) else ""
if not cc and isinstance(cobj, dict):
nm = cobj.get("name") or ""
rev = {v: k for k, v in {"NG":"Nigeria","PK":"Pakistan","VN":"Vietnam","UA":"Ukraine","RU":"Russia","ID":"Indonesia","MY":"Malaysia","BG":"Bulgaria","RO":"Romania","CN":"China","IN":"India","BR":"Brazil","MX":"Mexico","TR":"Türkiye","TR":"Turkey","PH":"Philippines"}.items()}
cc = rev.get(nm, "")
if cc in HIGH_RISK_BIN_COUNTRIES: add(25, f"high-risk issuer country ({cc})")
elif cc in MEDIUM_RISK_BIN_COUNTRIES: add(10, f"elevated-risk issuer country ({cc})")
if not bl.get("bank") or not (bl.get("bank") or {}).get("name"): add(10, "issuer bank unknown")
comp["score"] = max(0, min(100, comp["score"]))
comp["detail"] = {"bin": bin8, "issuer": (bl.get("bank") or {}).get("name"), "country": (cobj.get("name") if isinstance(cobj, dict) else None) or cc or None, "type": bl.get("type"), "prepaid": bl.get("prepaid"), "scheme": bl.get("scheme")}
return comp
def fraud_score(ip=None, email=None, bin8=None):
parts, total, wsum = [], 0, 0
for comp in ([_fs_score_ip(ip)] if ip else []) + ([_fs_score_email(email)] if email else []) + ([_fs_score_bin(bin8)] if bin8 else []):
parts.append(comp); total += comp["score"] * comp["weight"]; wsum += comp["weight"]
if not wsum: return None
composite = round(total / wsum)
if composite >= 70: band = "HIGH"
elif composite >= 40: band = "MEDIUM"
else: band = "LOW"
conf = min(100, 30 + int(20 * (len(parts) - 1) + wsum / 3))
return {"score": composite, "band": band, "confidence": conf, "components": parts}
SCORE_EXPLAINER = """<div class=card><b>RISK MODEL</b><br><span style="color:var(--dim);font-size:.85rem">
&bull; <span title="Geo/ASN/usage type lookup — proxy, VPN, hosting and mobile flags each carry points">IP component</span> (weight 45): datacenter or relay origins, high-risk geos.
&bull; <span title="Address checked against a curated list of ~45 burner-mail providers — disposable domains score 100">Disposable-email component</span> (weight 25): burner-mail domains are an instant red flag.
&bull; <span title="First 6-8 digits identify issuer, country, product type — prepaid and unknown-bank BINs carry points">BIN component</span> (weight 30): prepaid, unknown issuer and high-risk issuer countries add risk.
&bull; Composite = <span title="Each component scores 0-100, multiplied by its weight and averaged — missing inputs re-normalize automatically">weighted average</span>, banded LOW &lt;40 &le; MEDIUM &lt;70 &le; HIGH.
&bull; <span title="Heuristics, not a verdict — every factor is listed so a human makes the final call">Confidence</span> rises with the number of inputs scored. 2&cent;/call, free with <span title="PASS = $10/mo all-access">PASS</span>. Rate limit 20/min.</span></div>"""
SCORE_API = ("<div class=card><b>AGENT API</b><pre>GET " + SITE + """/api/score?ip=1.2.3.4&email=victim@mailinator.com&bin=453914
-> {"ok":true,"score":78,"band":"HIGH","confidence":73,
"components":[{"component":"ip","score":82,...},"email":...,"bin":...]}
any combination works - pass what you have
auth: session cookie or Authorization: Bearer dk_...
2c/call, free with PASS - rate limit 20/min</pre></div>""").replace("BASE", SITE)
@app.route("/score")
def score_page():
q_ip = (param("ip") or "").strip()
q_email = (param("email") or "").strip()
q_bin = (param("bin") or "").strip()
res = ""
if q_ip or q_email or q_bin:
r = fraud_score(q_ip or None, q_email or None, q_bin or None)
if r:
res = f"""<div class="card glow"><b>SCORE: <span style="font-size:1.6rem;color:var(--acc)">{r['score']}</span>/100 — <span class="tag {'ok' if r['band']=='LOW' else 'warn' if r['band']=='MEDIUM' else 'bad'}">{r['band']} RISK</span></b> <span style="color:var(--dim)">confidence {r['confidence']}%</span>
<table><tr><th>Component</th><th>Score</th><th>Factors</th></tr>{''.join(f"<tr><td>{esc(c['weight'])}</td><td>{esc(c['score'])}</td><td style=color:var(--dim)>{esc('; '.join(c['factors']))}</td></tr>" for c in r['components'])}</table></div>"""
body = f"""
<h1>FRAUD <span>SCORE</span></h1><p class=sub>Composite 0-100 risk for an identity shard: IP + email + card BIN. Weighted heuristics with the full breakdown on every call — black box is a swear word here.</p>
<div class=card><form method=get>
<input name=ip placeholder="IP (e.g. 45.133.1.16)" style="width:min(220px,100%)" value="{esc(q_ip)}">
<input name=email placeholder="email (e.g. x@mailinator.com)" style="width:min(240px,100%)" value="{esc(q_email)}">
<input name=bin placeholder="BIN (6-8 digits)" style="width:min(150px,100%)" value="{esc(q_bin)}">
<button style=margin-top:.5rem>Score it</button></form></div>
{res}
{SCORE_EXPLAINER}""" + SCORE_API + how(["Feed any combination of IP, email and BIN — components re-weight around what you provide.",
"IP: proxy/hosting flags + geo risk, via the same intel engine as /ip.",
"Email: matched against a hardcoded list of burner-mail domains.",
"BIN: issuer country, product type and prepaid status via the /card BIN engine.",
"Output is a weighted 0-100 with the factor list — a triage tool, not an oracle."])
body += agent_card('GET /api/score?ip=&email=&bin=', 'curl "https://dark0rbits.thetempleofdoom.com/api/score?ip=1.2.3.4&email=a@mailinator.com&bin=453914" -H "Authorization: Bearer drb_..."', 'Weighted composite; re-normalizes on partial input.')
return page("score", body)
@app.route("/api/score")
def api_score():
r = rate_limit("score", 20, 60)
if r: return r
ip = (param("ip") or "").strip() or None
email = (param("email") or "").strip() or None
bin8 = (param("bin") or "").strip() or None
if not (ip or email or bin8): return jsonify({"ok": False, "error": "at least one of ip, email, bin required"}), 400
uid = key_user() or current_user_id()
if not uid: return jsonify({"ok": False, "error": "auth required: account session (sign up at /inbox, no KYC) or Authorization: Bearer dk_ key"}), 401
if not has_pass(uid) and not charge(uid, 2, "fraud score"):
return jsonify({"ok": False, "error": "insufficient balance", "balance_cents": get_balance(uid), "topup": SITE + "/keys"}), 402
fr = fraud_score(ip, email, bin8)
if not fr: return jsonify({"ok": False, "error": "scoring failed"}), 500
return jsonify({"ok": True, "ip": ip, "email": email, "bin": bin8, "score": fr["score"], "band": fr["band"], "confidence": fr["confidence"], "components": fr["components"]})
# ---------- 8. FREE TOOLS ----------
TOOLS_JS = """
function tab(n){document.querySelectorAll('.pane').forEach(p=>p.style.display='none');document.getElementById(n).style.display='block'}
async function dns(){const d=document.getElementById('dq').value;const o=await (await fetch('https://dns.google/resolve?name='+encodeURIComponent(d)+'&type=A')).json();document.getElementById('do').textContent=JSON.stringify(o,null,1)}
async function hdr(){const u=document.getElementById('hq').value;const r=await (await fetch('/api/hdr?url='+encodeURIComponent(u))).json();document.getElementById('ho').textContent=JSON.stringify(r,null,1)}
function jwt(){try{const t=document.getElementById('jq').value.trim().split('.');const d=s=>JSON.stringify(JSON.parse(atob(s.replace(/-/g,'+').replace(/_/g,'/'))),null,1);document.getElementById('jo').textContent='HEADER\\n'+d(t[0])+'\\n\\nPAYLOAD\\n'+d(t[1])}catch(e){document.getElementById('jo').textContent='Invalid JWT: '+e}}
async function genhash2(){const i=document.getElementById('hq2').value;const r=await(await fetch('/api/hash?s='+encodeURIComponent(i))).json();for(const k of ['md5','sha1','sha256','sha512'])document.getElementById('h_'+k).textContent=r[k]}
function uuids(){let o='';for(let i=0;i<5;i++)o+=crypto.randomUUID()+'\\n';document.getElementById('uo').textContent=o}
function pwgen(){const l=+document.getElementById('pl').value||24;const cs='abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789!@#$%^&*-_=+';const a=new Uint32Array(l);crypto.getRandomValues(a);document.getElementById('po').textContent=Array.from(a,x=>cs[x%cs.length]).join('')}
"""
@app.route("/api/hdr")
def api_hdr():
url = param("url") or ""
if "://" not in url: url = "http://" + url
try:
req = urllib.request.Request(url)
with urllib.request.urlopen(req, timeout=12) as r:
return jsonify({"status": r.status, "final_url": r.url, "headers": dict(r.headers)})
except Exception as e:
return jsonify({"error": str(e)})
@app.route("/api/hash")
def api_hash():
s = (param("s") or "").encode()
return jsonify({"md5": hashlib.md5(s).hexdigest(), "sha1": hashlib.sha1(s).hexdigest(),
"sha256": hashlib.sha256(s).hexdigest(), "sha512": hashlib.sha512(s).hexdigest()})
@app.route("/tools")
def tools():
body = f"""
<h1>FREE <span>TOOLS</span></h1><p class=sub>High-value, zero-cost, no signup. APIs underneath each.</p>
<style>.tbtn.on{{background:var(--acc);color:#111}}</style>
<div style=margin-bottom:1rem>
<button class="tbtn on" onclick="tab('dns_p');this.classList.add('on')">DNS Lookup</button>
<button class=tbtn onclick="tab('hdr_p');this.classList.add('on')">HTTP Headers</button>
<button class=tbtn onclick="tab('jwt_p');this.classList.add('on')">JWT Decoder</button>
<button class=tbtn onclick="tab('hash_p');this.classList.add('on')">Hasher</button>
<button class=tbtn onclick="tab('gen_p');this.classList.add('on')">Generators</button></div>
<script>{TOOLS_JS}</script>
<div id=dns_p class="card pane"><b>DNS Lookup</b> <span style=color:var(--dim)>(Google DoH)</span><br>
<input id=dq placeholder=thetempleofdoom.com style=width:70%><button onclick=dns()>Resolve</button>
<pre id=do style=white-space:pre-wrap></pre></div>
<div id=hdr_p class="card pane" style=display:none><b>HTTP Header Inspector</b><br>
<input id=hq placeholder=https://lynx.thetempleofdoom.com style=width:70%><button onclick=hdr()>Inspect</button>
<pre id=ho style=white-space:pre-wrap></pre></div>
<div id=jwt_p class="card pane" style=display:none><b>JWT Decoder</b> (token never leaves your browser)<br>
<textarea id=jq rows=3 style="width:100%">paste eyJ…</textarea><button onclick=jwt()>Decode</button>
<pre id=jo style=white-space:pre-wrap></pre></div>
<div id=hash_p class="card pane" style=display:none><b>Hasher</b><br>
<input id=hq2 placeholder="any string" style=width:70%><button onclick=genhash2()>Hash</button>
<table><tr><th>md5</th><td id=h_md5></td></tr><tr><th>sha1</th><td id=h_sha1></td></tr>
<tr><th>sha256</th><td id=h_sha256></td></tr><tr><th>sha512</th><td id=h_sha512></td></tr></table></div>
<div id=gen_p class="card pane" style=display:none><b>Generators</b><br>
<button onclick=uuids()>5× UUIDv4</button><pre id=uo></pre>
<label>password length</label> <input id=pl value=24 style=width:80px><button onclick=pwgen()>Generate</button>
<pre id=po style="font-size:1.2rem;color:var(--acc)"></pre></div>
<div class=card><b>Heavy tools</b> <span style=color:var(--dim)>(full pages, each with a JSON API)</span><br>
<a href=/deaddrop>◈ DEAD-DROP</a> — burn-after-read encrypted notes &nbsp;·&nbsp;
<a href=/shot>◈ SCREENSHOT</a> — page capture or rendered-text preview &nbsp;·&nbsp;
<a href=/score>◈ FRAUD-SCORE</a> — composite IP + email + BIN risk 0-100</div>"""
return page("tools", body)
# ---------- 9. OPERATOR CONSOLE ----------
@app.route("/admin", methods=["GET", "POST"])
def admin():
if request.method == "POST" and request.form.get("pw") == ADMIN_PW:
resp = Response(status=302); resp.headers["Location"] = "/admin"
resp.set_cookie("dark0rbits_admin", secrets.token_urlsafe(16), max_age=86400, httponly=True)
return resp
if not request.cookies.get("dark0rbits_admin"):
return page("track", '<h1>OPERATOR</h1><div class=card><form method=post><input name=pw type=password placeholder="operator password"><button>In</button></form></div>')
con = db()
msgs = con.execute("SELECT m.*, u.username FROM messages m JOIN users u ON u.id=m.user_id ORDER BY m.id DESC LIMIT 100").fetchall()
msgs_html = "".join(f'<div class=msg><div class=who>{esc(m["username"])} · {time.strftime("%b %d %H:%M", time.localtime(m["created"]))}</div>{m["body"]}</div>' for m in msgs) or '<div style=color:var(--dim)>empty</div>'
opens = con.execute("SELECT te.*, tr.filename FROM track_events te JOIN trackables tr ON tr.id=te.trackable_id ORDER BY te.id DESC LIMIT 30").fetchall()
opens_html = "".join(f"<tr><td>{esc(o['filename'])}</td><td>{esc(o['ip'])}</td><td>{esc(o['ua'][:50])}</td><td>{time.strftime('%b %d %H:%M', time.localtime(o['ts']))}</td></tr>" for o in opens)
reply_to = param("reply") or ""
reply_html = ""
if reply_to:
r = con.execute("SELECT username FROM users WHERE id=?", (reply_to,)).fetchone()
if r: reply_html = f'<div class=card><b>Reply to {esc(r["username"])}</b><form method=post action=/admin/reply><input type=hidden name=uid value="{esc(reply_to)}"><textarea name=body rows=2 style="width:100%"></textarea><button style=margin-top:.4rem>Send reply</button></form></div>'
return page("track", f"""
<h1>OPERATOR <span>CONSOLE</span></h1>
<div class=card><b>All customer messages</b>{msgs_html}</div>
<div class=card><b>Reply</b><form method=get><input name=reply placeholder="user id to reply to" style=width:60%><button>Load</button></form></div>{reply_html}
<div class=card><b>File open events</b><table><tr><th>File</th><th>IP</th><th>Device</th><th>When</th></tr>{opens_html}</table></div>""")
# ---------- INDEX (hacker landing) ----------
@app.route("/")
def index():
ip = request.headers.get("X-Real-IP") or request.remote_addr
st, b = http(f"http://ip-api.com/json/{ip}?fields=66846719")
d = jf(b) or {}
uid = current_user_id()
con = db()
n_sms = con.execute("SELECT COUNT(*) c FROM sms_rentals").fetchone()["c"]
n_px = con.execute("SELECT COUNT(*) c FROM proxy_checks").fetchone()["c"]
tools = [
("ip","IP INTEL","Geo, ASN, ISP, VPN/hosting flags, rDNS — your IP auto-detected, any target on demand."),
("card","CARD CHECK","Luhn + BIN: issuer bank, brand, type, country, prepaid risk flags. Nothing stored, nothing charged."),
("sms","SMS RENTAL","Disposable numbers, 30-min windows, instant refund on cancel."),
("proxy","PROXY LAB","Residential egress testing on the Pleiades rail — same gateway keys fleet-wide. Rent GB plans at the storefront."),
("steg","STEGO LAB","Hide words inside pictures. LSB depth, randomized spread, password-encrypted payloads."),
("track","TRACK FILE","$1 → tracked link + email pixel. Every open reports back: IP, location, ISP, device."),
("mail","BURNER MAIL","Receive-only mailboxes, 7–90 days, live countdown. Codes & confirmations without an identity."),
("eh","MAIL FORENSICS","Paste raw headers → real origin IP + geo, SPF/DKIM/DMARC verdicts, spoof flags."),
("forensics","IMAGE FORENSICS","EXIF, GPS, edit-tool detection, error-level analysis — expose doctored photos."),
("canary","CANARY TRAPS","Tripwire links and pixels — instant alert the moment anyone touches one."),
("deaddrop","DEAD-DROP","AES-GCM encrypted notes that burn after N reads or TTL. Optional password. No trace left."),
("shot","SCREENSHOT","Headless-capture any page when Chromium is up; otherwise a rendered-text + intel preview. Agents: poll the status API."),
("score","FRAUD-SCORE","Composite 0-100 risk: IP intel + disposable-email + BIN heuristics, with full breakdown."),
("tools","FREE TOOLS","DNS resolver, HTTP header inspector, JWT decoder, hasher, generators."),
("passport","AGENT PASSPORT","Machine-readable trust badge for your bots. Agents are first-class here."),
]
cards = "".join(f'<div class=card><h3><a href=/{href} style="color:var(--acc);text-decoration:none">◈ {name}</a></h3><p style=color:var(--dim)>{desc}</p><a href=/{href}><button>Open</button></a></div>' for href, name, desc in tools)
stat = f"You're connecting from <b style=color:var(--acc)>{esc(d.get('query','?'))}</b> — {esc(d.get('city',''))}, {esc(d.get('country',''))} · {esc(d.get('isp',''))}"
cta = ('<a href=/inbox><button class=big>◈ INBOX</button></a> <a href=/keys><button class="big ghost">▣ API KEYS</button></a> <a href=/pass><button class=big>★ GET PASS</button></a>' if uid else '<a href=/inbox><button class=big>▸ SIGN UP — NO KYC</button></a> <a href=/inbox><button class="big ghost">◈ LOG IN</button></a> <a href=/pass><button class="big ghost">★ GET PASS</button></a>')
body = f"""
<div class="term card glow">$ ./dark0rbits --intro<span class="crt">▊</span>
<span class="type" data-lines="DARK0RBITS — the toolbox that treats you like an operator, not a product.|No KYC. No email required. No Stripe. BTC only.|Agents welcome — every tool has a JSON API."></span>
{stat}
<div class="cta">{cta}</div></div>
<script>
(function(){{
var el=document.querySelector('.type');if(!el)return;
var lines=el.dataset.lines.split('|');var li=0,ci=0,out='';
function step(){{
if(li>=lines.length)return;
var cur=lines[li];ci++;
el.innerHTML=out+cur.slice(0,ci)+'<span class="typed-cursor">▊</span>';
if(ci>=cur.length){{out+=cur+'<br>';li++;ci=0;setTimeout(step,420)}}else setTimeout(step,22);
}}
step();
}})();
</script>
<div class=grid2>{cards}</div>
<div class=card style=text-align:center>
<span class="tag ok">NO KYC</span> <span class="tag ok">BTC ONLY</span> <span class="tag ok">AGENT-FIRST APIs</span> <span class="tag warn">{n_sms} SMS RENTALS SERVED</span> <span class="tag warn">{n_px} PROXY CHECKS</span></div>
<div class=card style=color:var(--dim)>
<b>For agents</b>: machine catalog at <a href=/llms.txt>/llms.txt</a>, OpenAPI at <a href=/openapi.json>/openapi.json</a>, metered keys at <a href=/keys>/keys</a>.
For humans: click a card. That's it.</div>"""
return page("home", body)
@app.route("/favicon.svg")
def favicon():
svg = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><rect width="32" height="32" rx="7" fill="#070a13"/><circle cx="16" cy="16" r="5" fill="#a78bfa"/><circle cx="16" cy="16" r="9.5" fill="none" stroke="#6fd6ff" stroke-width="1.3" stroke-dasharray="4 3"/><circle cx="25.5" cy="8" r="1.6" fill="#ffc94d"/></svg>'
return Response(svg, mimetype="image/svg+xml")
@app.route("/og.png")
def og_img():
from PIL import Image, ImageDraw
im = Image.new("RGB", (1200, 630), (7, 10, 19))
dr = ImageDraw.Draw(im)
for i in range(260):
import random as _r
_r.seed(i)
x, y = _r.randint(0, 1199), _r.randint(0, 629)
dr.ellipse([x, y, x+2, y+2], fill=(200+i%55, 210, 255))
dr.ellipse([480, 190, 720, 430], outline=(167, 139, 250), width=4)
dr.ellipse([455, 165, 745, 455], outline=(111, 214, 255), width=2)
try:
from PIL import ImageFont
f = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSansMono-Bold.ttf", 84)
f2 = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf", 26)
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)
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"})
# REDIRECT legacy auriga hostname → dark0rbits
@app.before_request
def _dr_legacy_redirect():
host = (request.host or "").lower()
if host.startswith("auriga.") or host == "auriga.thetempleofdoom.com":
return redirect("https://dark0rbits.thetempleofdoom.com" + request.full_path.rstrip("?"), code=301)
return None
# REDACT-REDIRECT
@app.errorhandler(404)
def not_found(e):
if request.path.startswith("/api/"):
return jsonify({"ok": False, "error": "no such endpoint", "path": request.path}), 404
body = """
<h1>404 — <span>LOST SIGNAL</span></h1>
<div class=card>This page drifted off the map. The tools are all still here:</div>
<div class=grid2>
<div class=card><h3><a href=/ip style="color:var(--acc);text-decoration:none">◈ IP INTEL</a></h3></div>
<div class=card><h3><a href=/tools style="color:var(--acc);text-decoration:none">◈ FREE TOOLS</a></h3></div>
<div class=card><h3><a href=/ style="color:var(--acc);text-decoration:none">◈ HOME BASE</a></h3></div>
</div>"""
return page("home", body), 404
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000, threaded=True)