REBRAND: Dark0rbits — billing engine (balances, dk_ API keys, per-call metering, BTC topups idempotent), hacker landing, per-tool explainers, SEO kit (meta/sitemap/robots), auriga→dark0rbits 301
This commit is contained in:
326
app.py
326
app.py
@@ -1,13 +1,14 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
"""AURIGA v2 — toolbox: IP intel, card validator, SMS rentals, proxy lab, stego lab,
|
"""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."""
|
trackable files (BTCPay), no-KYC site-only messaging inbox. Single-file Flask + SQLite."""
|
||||||
import base64, binascii, hashlib, hmac, html, io, json, os, re, secrets, socket, sqlite3, struct, time, uuid
|
import base64, binascii, hashlib, hmac, html, io, json, os, re, secrets, socket, sqlite3, struct, time, uuid
|
||||||
import urllib.request, urllib.parse
|
import urllib.request, urllib.parse
|
||||||
from flask import Flask, request, jsonify, render_template_string, Response, send_file
|
from flask import Flask, request, jsonify, render_template_string, Response, send_file
|
||||||
|
|
||||||
|
from flask import redirect
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
DB_PATH = os.environ.get("AURIGA_DB", "/opt/auriga/auriga.db")
|
DB_PATH = os.environ.get("DARK0RBITS_DB", "/opt/dark0rbits/dark0rbits.db")
|
||||||
UPLOAD_DIR = os.environ.get("AURIGA_UPLOADS", "/opt/auriga/uploads")
|
UPLOAD_DIR = os.environ.get("DARK0RBITS_UPLOADS", "/opt/dark0rbits/uploads")
|
||||||
os.makedirs(UPLOAD_DIR, exist_ok=True)
|
os.makedirs(UPLOAD_DIR, exist_ok=True)
|
||||||
SMSP_KEY = os.environ.get("SMSP_KEY", "")
|
SMSP_KEY = os.environ.get("SMSP_KEY", "")
|
||||||
PLEIADES_GW = os.environ.get("PLEIADES_GW", "10.30.20.178:8080")
|
PLEIADES_GW = os.environ.get("PLEIADES_GW", "10.30.20.178:8080")
|
||||||
@@ -16,10 +17,10 @@ BTCPAY = "https://10.30.20.140/api/v1"
|
|||||||
BTCPAY_KEY = os.environ.get("BTCPAY_KEY", "6026288e2e315984661c748baafd509e81a75f22")
|
BTCPAY_KEY = os.environ.get("BTCPAY_KEY", "6026288e2e315984661c748baafd509e81a75f22")
|
||||||
BTCPAY_STORE = os.environ.get("BTCPAY_STORE", "7h79ndYyZX2yF6CPa12xt2uVGQ5Fd6nrSDG4Koy86x6u")
|
BTCPAY_STORE = os.environ.get("BTCPAY_STORE", "7h79ndYyZX2yF6CPa12xt2uVGQ5Fd6nrSDG4Koy86x6u")
|
||||||
WEBCHECK = os.environ.get("WEBCHECK", "http://10.30.20.13:3000")
|
WEBCHECK = os.environ.get("WEBCHECK", "http://10.30.20.13:3000")
|
||||||
ADMIN_PW = os.environ.get("AURIGA_ADMIN", "Czapiewski1!")
|
ADMIN_PW = os.environ.get("DARK0RBITS_ADMIN", "Czapiewski1!")
|
||||||
BTCPAY_WHSEC = os.environ.get("BTCPAY_WHSEC", "TgJhmoBcNf9ATK2SFCg1VS")
|
BTCPAY_WHSEC = os.environ.get("BTCPAY_WHSEC", "TgJhmoBcNf9ATK2SFCg1VS")
|
||||||
BMAC = "https://buymeacoffee.com/r26xrthzttg"
|
BMAC = "https://buymeacoffee.com/r26xrthzttg"
|
||||||
SITE = "https://auriga.thetempleofdoom.com"
|
SITE = "https://dark0rbits.thetempleofdoom.com"
|
||||||
|
|
||||||
def db():
|
def db():
|
||||||
con = sqlite3.connect(DB_PATH); con.row_factory = sqlite3.Row
|
con = sqlite3.connect(DB_PATH); con.row_factory = sqlite3.Row
|
||||||
@@ -34,16 +35,54 @@ def db():
|
|||||||
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 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 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 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 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);""")
|
||||||
return con
|
return con
|
||||||
|
|
||||||
|
# ---------- 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
|
||||||
|
|
||||||
import ssl as _ssl
|
import ssl as _ssl
|
||||||
_CTX = _ssl.create_default_context()
|
_CTX = _ssl.create_default_context()
|
||||||
_CTX.check_hostname = False
|
_CTX.check_hostname = False
|
||||||
_CTX.verify_mode = _ssl.CERT_NONE
|
_CTX.verify_mode = _ssl.CERT_NONE
|
||||||
|
|
||||||
def http(url, headers=None, data=None, method="GET", timeout=12):
|
def http(url, headers=None, data=None, method="GET", timeout=12):
|
||||||
h = {"User-Agent": "Mozilla/5.0 (Auriga toolbox)"}
|
h = {"User-Agent": "Mozilla/5.0 (Dark0rbits toolbox)"}
|
||||||
h.update(headers or {})
|
h.update(headers or {})
|
||||||
req = urllib.request.Request(url, headers=h, data=data, method=method)
|
req = urllib.request.Request(url, headers=h, data=data, method=method)
|
||||||
try:
|
try:
|
||||||
@@ -64,7 +103,15 @@ def param(name):
|
|||||||
def esc(s): return html.escape(str(s))
|
def esc(s): return html.escape(str(s))
|
||||||
|
|
||||||
BASE = """<!doctype html><html><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1">
|
BASE = """<!doctype html><html><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1">
|
||||||
<title>AURIGA — Toolbox</title>
|
<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:url" content="https://dark0rbits.thetempleofdoom.com">
|
||||||
|
<meta name=robots content="index,follow">
|
||||||
|
<link rel=canonical href="https://dark0rbits.thetempleofdoom.com">
|
||||||
<style>
|
<style>
|
||||||
:root{--bg:#0b0e17;--card:#141a2b;--fg:#e8ecf7;--dim:#8b95b3;--acc:#f0b429;--acc2:#7dd3fc;--ok:#3ecf8e;--bad:#ff5d5d}
|
:root{--bg:#0b0e17;--card:#141a2b;--fg:#e8ecf7;--dim:#8b95b3;--acc:#f0b429;--acc2:#7dd3fc;--ok:#3ecf8e;--bad:#ff5d5d}
|
||||||
*{box-sizing:border-box}body{margin:0;background:var(--bg);color:var(--fg);font:16px/1.5 ui-monospace,Menlo,Consolas,monospace}
|
*{box-sizing:border-box}body{margin:0;background:var(--bg);color:var(--fg);font:16px/1.5 ui-monospace,Menlo,Consolas,monospace}
|
||||||
@@ -84,6 +131,10 @@ input,select,button,textarea{font:inherit;background:#0e1424;color:var(--fg);bor
|
|||||||
button{background:var(--acc);color:#111;border:0;font-weight:700;cursor:pointer;transition:.2s}
|
button{background:var(--acc);color:#111;border:0;font-weight:700;cursor:pointer;transition:.2s}
|
||||||
button:hover{filter:brightness(1.15);transform:translateY(-1px)}
|
button:hover{filter:brightness(1.15);transform:translateY(-1px)}
|
||||||
button.ghost{background:transparent;color:var(--acc);border:1px solid var(--acc)}
|
button.ghost{background:transparent;color:var(--acc);border:1px solid var(--acc)}
|
||||||
|
button.big{font-size:1.05rem;padding:.7rem 1.4rem;margin:.25rem}
|
||||||
|
.term{font-size:1.05rem;line-height:1.7}
|
||||||
|
.term .crt{color:var(--acc);animation:blink 1s steps(1) infinite}@keyframes blink{50%{opacity:0}}
|
||||||
|
.cta{margin-top:1rem}
|
||||||
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:1rem}
|
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:1rem}
|
||||||
@media(max-width:700px){.grid2{grid-template-columns:1fr}.kv{grid-template-columns:1fr}}
|
@media(max-width:700px){.grid2{grid-template-columns:1fr}.kv{grid-template-columns:1fr}}
|
||||||
.tag{display:inline-block;padding:.15rem .6rem;border-radius:999px;font-size:.8rem;border:1px solid}
|
.tag{display:inline-block;padding:.15rem .6rem;border-radius:999px;font-size:.8rem;border:1px solid}
|
||||||
@@ -100,13 +151,13 @@ a{color:var(--acc2)}
|
|||||||
.bar{height:6px;background:#0e1424;border-radius:3px;overflow:hidden}.bar>i{display:block;height:100%;background:var(--acc);width:0;transition:width .6s}
|
.bar{height:6px;background:#0e1424;border-radius:3px;overflow:hidden}.bar>i{display:block;height:100%;background:var(--acc);width:0;transition:width .6s}
|
||||||
</style></head><body>
|
</style></head><body>
|
||||||
<nav>
|
<nav>
|
||||||
<a href=/ class={{o(home)}}>◈ AURIGA</a><a href=/ip class={{o(ip)}}>◈ IP INTEL</a><a href=/card class={{o(card)}}>◈ CARD CHECK</a>
|
<a href=/ class={{o(home)}}>◈ DARK0RBITS</a><a href=/ip class={{o(ip)}}>◈ IP INTEL</a><a href=/card class={{o(card)}}>◈ CARD CHECK</a>
|
||||||
<a href=/sms class={{o(sms)}}>◈ SMS RENTAL</a><a href=/proxy class={{o(proxy)}}>◈ PROXY LAB</a>
|
<a href=/sms class={{o(sms)}}>◈ SMS RENTAL</a><a href=/proxy class={{o(proxy)}}>◈ PROXY LAB</a>
|
||||||
<a href=/steg class={{o(steg)}}>◈ STEGO</a><a href=/track class={{o(track)}}>◈ TRACK FILE</a>
|
<a href=/steg class={{o(steg)}}>◈ STEGO</a><a href=/track class={{o(track)}}>◈ TRACK FILE</a>
|
||||||
<a href=/eh class={{o(eh)}}>◈ MAIL FORENSICS</a><a href=/forensics class={{o(forensics)}}>◈ IMG FORENSICS</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=/canary class={{o(canary)}}>◈ CANARY</a>
|
||||||
<a href=/mail class={{o(steg2)}}>◈ MAIL</a><a href=/inbox class={{o(inbox)}}>◈ INBOX</a>
|
<a href=/mail class={{o(steg2)}}>◈ MAIL</a><a href=/inbox class={{o(inbox)}}>◈ INBOX</a>
|
||||||
<a href=/passport class={{o(passport)}}>◈ PASSPORT</a><a href=/pass class={{o(sms2)}}>◈ PASS</a><a href=/tools class={{o(tools)}}>◈ TOOLS</a>
|
<a href=/passport class={{o(passport)}}>◈ PASSPORT</a><a href=/pass class={{o(sms2)}}>◈ PASS</a><a href=/keys class={{o(keys)}}>◈ KEYS</a><a href=/tools class={{o(tools)}}>◈ TOOLS</a>
|
||||||
</nav><main>{{body}}</main>
|
</nav><main>{{body}}</main>
|
||||||
<footer>Built for agents & humans · <a href="{{bmac}}" target=_blank rel=noopener>☕ fuel the lab</a></footer>
|
<footer>Built for agents & humans · <a href="{{bmac}}" target=_blank rel=noopener>☕ fuel the lab</a></footer>
|
||||||
<script defer src="https://analytics.thetempleofdoom.com/script.js" data-website-id="953c15df-ba4c-453a-a7c6-465fa9e3f202"></script>
|
<script defer src="https://analytics.thetempleofdoom.com/script.js" data-website-id="953c15df-ba4c-453a-a7c6-465fa9e3f202"></script>
|
||||||
@@ -123,9 +174,13 @@ def kv(pairs):
|
|||||||
rows = "".join(f"<div>{k}</div><div>{v}</div>" for k, v in pairs)
|
rows = "".join(f"<div>{k}</div><div>{v}</div>" for k, v in pairs)
|
||||||
return f'<div class="card glow"><div class="kv">{rows}</div></div>'
|
return f'<div class="card glow"><div class="kv">{rows}</div></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 ----------
|
# ---------- AGENT DISCOVERY ----------
|
||||||
API_INDEX = {
|
API_INDEX = {
|
||||||
"service": "AURIGA toolbox",
|
"service": "dark0rbits",
|
||||||
"description": "IP intel, card BIN validation, 30-min SMS rentals, residential proxy lab, steganography, trackable files, no-KYC messaging, utilities.",
|
"description": "IP intel, card BIN validation, 30-min SMS rentals, residential proxy lab, steganography, trackable files, no-KYC messaging, utilities.",
|
||||||
"endpoints": [
|
"endpoints": [
|
||||||
{"method": "GET", "path": "/api/ip?target=", "desc": "Caller IP intel (auto) or any IP you pass: geo, ASN, ISP, VPN/hosting flags, rDNS."},
|
{"method": "GET", "path": "/api/ip?target=", "desc": "Caller IP intel (auto) or any IP you pass: geo, ASN, ISP, VPN/hosting flags, rDNS."},
|
||||||
@@ -149,22 +204,29 @@ API_INDEX = {
|
|||||||
def api_index(): return jsonify(API_INDEX)
|
def api_index(): return jsonify(API_INDEX)
|
||||||
|
|
||||||
@app.route("/robots.txt")
|
@app.route("/robots.txt")
|
||||||
def robots(): return "User-agent: *\nAllow: /\n", 200, {"Content-Type": "text/plain"}
|
def robots(): return "User-agent: *\nAllow: /\nSitemap: https://dark0rbits.thetempleofdoom.com/sitemap.xml\n", 200, {"Content-Type": "text/plain"}
|
||||||
|
|
||||||
|
@app.route("/sitemap.xml")
|
||||||
|
def sitemap():
|
||||||
|
S = "https://dark0rbits.thetempleofdoom.com"
|
||||||
|
pages = ["", "ip", "card", "sms", "proxy", "steg", "track", "eh", "forensics", "canary", "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")
|
@app.route("/llms.txt")
|
||||||
def llms():
|
def llms():
|
||||||
eps = "\n".join(f"- `{e['method']} {e['path']}` — {e['desc']}" for e in API_INDEX["endpoints"])
|
eps = "\n".join(f"- `{e['method']} {e['path']}` — {e['desc']}" for e in API_INDEX["endpoints"])
|
||||||
return f"# AURIGA toolbox\n\nBase: {SITE}\n\n## API\n{eps}\n", 200, {"Content-Type": "text/plain"}
|
return f"# Dark0rbits\n\nBase: {SITE}\n\n## API\n{eps}\n", 200, {"Content-Type": "text/plain"}
|
||||||
|
|
||||||
@app.route("/ai-plugin.json")
|
@app.route("/ai-plugin.json")
|
||||||
def aiplugin():
|
def aiplugin():
|
||||||
return jsonify({"name_for_model": "auriga", "schema_version": "v1",
|
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.",
|
"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"})
|
"api": {"type": "openapi", "url": SITE + "/openapi.json"}, "auth": {"type": "none"}, "contact_email": "indianaholmes1@icloud.com"})
|
||||||
|
|
||||||
@app.route("/openapi.json")
|
@app.route("/openapi.json")
|
||||||
def openapi():
|
def openapi():
|
||||||
ps = {"openapi": "3.0.0", "info": {"title": "AURIGA", "version": "2.0.0"}, "paths": {}}
|
ps = {"openapi": "3.0.0", "info": {"title": "DARK0RBITS", "version": "2.0.0"}, "paths": {}}
|
||||||
def add(path, method, desc, params=None, req=False, files=None):
|
def add(path, method, desc, params=None, req=False, files=None):
|
||||||
item = {"summary": desc}
|
item = {"summary": desc}
|
||||||
if files:
|
if files:
|
||||||
@@ -233,7 +295,7 @@ def ip_page():
|
|||||||
{kv(rows)}
|
{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>
|
<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}
|
{extra}
|
||||||
<div class=card style=color:var(--dim)>API: GET /api/ip (caller) · GET /api/ip?target=1.2.3.4 (any target)</div>"""
|
<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."])
|
||||||
return page("ip", body)
|
return page("ip", body)
|
||||||
|
|
||||||
def ip_form():
|
def ip_form():
|
||||||
@@ -302,7 +364,7 @@ def card():
|
|||||||
result = f"""
|
result = f"""
|
||||||
{kv([("Brand",brand),("BIN",num[:8]),("Bank / Issuer",esc(bank)),("Country",esc(country)),("Type",str(ctype)),("Prepaid",str(prepaid))])}
|
{kv([("Brand",brand),("BIN",num[:8]),("Bank / Issuer",esc(bank)),("Country",esc(country)),("Type",str(ctype)),("Prepaid",str(prepaid))])}
|
||||||
<div class=card><b>Fraud & structure flags</b><br>{' '.join(tags)}{'<br>⚠ ' + ' · '.join(flags) if flags else ''}</div>
|
<div class=card><b>Fraud & 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>"""
|
<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"""
|
body = f"""
|
||||||
<h1>CARD <span>CHECK</span></h1><p class=sub>Luhn + BIN intelligence: issuer, brand, type, country, prepaid risk flags.</p>
|
<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 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>
|
||||||
@@ -405,13 +467,16 @@ def sms():
|
|||||||
setInterval(function(){{var els=document.querySelectorAll('.cdown');var now=Math.floor(Date.now()/1000);
|
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);
|
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);
|
||||||
</script>
|
</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>"""
|
<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."])
|
||||||
return page("sms", body)
|
return page("sms", body)
|
||||||
|
|
||||||
@app.route("/api/sms/rent", methods=["POST"])
|
@app.route("/api/sms/rent", methods=["POST"])
|
||||||
def api_sms_rent():
|
def api_sms_rent():
|
||||||
guard = sms_guard()
|
guard = sms_guard()
|
||||||
if guard: return jsonify({"success": 0, "message": guard, "paused": True})
|
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"))
|
st, b = sms_api("purchase/sms", service=param("service"), country=param("country"))
|
||||||
d = jf(b) or {}
|
d = jf(b) or {}
|
||||||
if d.get("success") == 1:
|
if d.get("success") == 1:
|
||||||
@@ -419,6 +484,9 @@ def api_sms_rent():
|
|||||||
con.execute("INSERT INTO sms_rentals(phone,service,country,purchase_id,cost,status,created,expires) VALUES(?,?,?,?,?,?,?,?)",
|
con.execute("INSERT INTO sms_rentals(phone,service,country,purchase_id,cost,status,created,expires) VALUES(?,?,?,?,?,?,?,?)",
|
||||||
(d.get("number"), param("service"), param("country"), str(d.get("purchase_id")), d.get("cost",0), "active", now, now+1800))
|
(d.get("number"), param("service"), param("country"), str(d.get("purchase_id")), d.get("cost",0), "active", now, now+1800))
|
||||||
con.commit()
|
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)
|
return jsonify(d)
|
||||||
|
|
||||||
@app.route("/api/sms/check", methods=["GET","POST"])
|
@app.route("/api/sms/check", methods=["GET","POST"])
|
||||||
@@ -485,7 +553,7 @@ def proxy():
|
|||||||
<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>
|
<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>
|
<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><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>"""
|
<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."])
|
||||||
return page("proxy", body)
|
return page("proxy", body)
|
||||||
|
|
||||||
@app.route("/api/proxy/test", methods=["POST"])
|
@app.route("/api/proxy/test", methods=["POST"])
|
||||||
@@ -534,7 +602,7 @@ def steg_hide(img_bytes, text, password="", bits=1, spread="sequential"):
|
|||||||
return None, f"too big: need {len(data)*8} bits, image holds {capacity}"
|
return None, f"too big: need {len(data)*8} bits, image holds {capacity}"
|
||||||
if spread == "random":
|
if spread == "random":
|
||||||
import random as _r
|
import random as _r
|
||||||
_r.seed(int.from_bytes(hashlib.sha256((password + "auriga").encode()).digest()[:4], "big") if password else int.from_bytes(hashlib.sha256(b"auriga-random-no-pass").digest()[:4], "big"))
|
_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)
|
order = list(range(w*h)); _r.shuffle(order)
|
||||||
else:
|
else:
|
||||||
order = list(range(w*h))
|
order = list(range(w*h))
|
||||||
@@ -566,7 +634,7 @@ def _pnginfo(bits, spread):
|
|||||||
try:
|
try:
|
||||||
from PIL.PngImagePlugin import PngInfo
|
from PIL.PngImagePlugin import PngInfo
|
||||||
info = PngInfo()
|
info = PngInfo()
|
||||||
info.add_text("auriga_meta", json.dumps({"bits": bits, "spread": spread, "v": 2}))
|
info.add_text("dark0rbits_meta", json.dumps({"bits": bits, "spread": spread, "v": 2}))
|
||||||
return info
|
return info
|
||||||
except Exception:
|
except Exception:
|
||||||
return None
|
return None
|
||||||
@@ -574,7 +642,7 @@ def _pnginfo(bits, spread):
|
|||||||
def steg_extract(img_bytes, password="", bits=None, spread=None):
|
def steg_extract(img_bytes, password="", bits=None, spread=None):
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
im = Image.open(io.BytesIO(img_bytes))
|
im = Image.open(io.BytesIO(img_bytes))
|
||||||
meta = im.info.get("auriga_meta")
|
meta = im.info.get("dark0rbits_meta") or im.info.get("auriga_meta")
|
||||||
if meta:
|
if meta:
|
||||||
try:
|
try:
|
||||||
m = json.loads(meta)
|
m = json.loads(meta)
|
||||||
@@ -588,7 +656,7 @@ def steg_extract(img_bytes, password="", bits=None, spread=None):
|
|||||||
# replicate the shuffle used at hide time
|
# replicate the shuffle used at hide time
|
||||||
if spread == "random":
|
if spread == "random":
|
||||||
import random as _r
|
import random as _r
|
||||||
_r.seed(int.from_bytes(hashlib.sha256((password + "auriga").encode()).digest()[:4], "big") if password else int.from_bytes(hashlib.sha256(b"auriga-random-no-pass").digest()[:4], "big"))
|
_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)
|
order = list(range(w*h)); _r.shuffle(order)
|
||||||
else:
|
else:
|
||||||
order = list(range(w*h))
|
order = list(range(w*h))
|
||||||
@@ -610,13 +678,13 @@ def steg_extract(img_bytes, password="", bits=None, spread=None):
|
|||||||
if need is not None and idx >= need: break
|
if need is not None and idx >= need: break
|
||||||
if need is None and idx >= 64:
|
if need is None and idx >= 64:
|
||||||
if bytes(raw[:4]) != b"AUR1":
|
if bytes(raw[:4]) != b"AUR1":
|
||||||
return None, f"no AURIGA payload found with LSB depth {bits} (try other depth / randomized)"
|
return None, f"no DARK0RBITS payload found with LSB depth {bits} (try other depth / randomized)"
|
||||||
ln = struct.unpack(">I", bytes(raw[4:8]))[0]
|
ln = struct.unpack(">I", bytes(raw[4:8]))[0]
|
||||||
need = 64 + ln * 8
|
need = 64 + ln * 8
|
||||||
data = bytes(raw)
|
data = bytes(raw)
|
||||||
if len(data) < 12: return None, "payload too small"
|
if len(data) < 12: return None, "payload too small"
|
||||||
if bytes(data[:4]) != b"AUR1":
|
if bytes(data[:4]) != b"AUR1":
|
||||||
return None, "no AURIGA payload found (wrong password or settings?)"
|
return None, "no DARK0RBITS payload found (wrong password or settings?)"
|
||||||
if password and hashlib.sha256(password.encode()).digest()[:4] != data[8:12]:
|
if password and hashlib.sha256(password.encode()).digest()[:4] != data[8:12]:
|
||||||
return None, "wrong password"
|
return None, "wrong password"
|
||||||
ln = struct.unpack(">I", data[4:8])[0]
|
ln = struct.unpack(">I", data[4:8])[0]
|
||||||
@@ -663,7 +731,7 @@ d.addEventListener('change',function(){{}});
|
|||||||
document.getElementById('ih').addEventListener('change',function(){{document.querySelector('.fnh').textContent=this.files[0].name}});
|
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}});
|
document.getElementById('ie').addEventListener('change',function(){{document.querySelector('.fne').textContent=this.files[0].name}});
|
||||||
</script>
|
</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>"""
|
<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>""" + 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."])
|
||||||
return page("steg", body)
|
return page("steg", body)
|
||||||
|
|
||||||
@app.route("/api/steg/hide", methods=["POST"])
|
@app.route("/api/steg/hide", methods=["POST"])
|
||||||
@@ -678,7 +746,7 @@ def api_steg_hide():
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
return jsonify({"ok": False, "error": str(e)}), 400
|
return jsonify({"ok": False, "error": str(e)}), 400
|
||||||
if out is None: return jsonify({"ok": False, "error": meta}), 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="auriga-hidden.png")
|
return send_file(io.BytesIO(out), mimetype="image/png", as_attachment=True, download_name="dark0rbits-hidden.png")
|
||||||
|
|
||||||
@app.route("/api/steg/extract", methods=["POST"])
|
@app.route("/api/steg/extract", methods=["POST"])
|
||||||
def api_steg_extract():
|
def api_steg_extract():
|
||||||
@@ -712,19 +780,19 @@ def track():
|
|||||||
<div style=color:var(--dim);font-size:.85rem;margin-top:.4rem>BTCPay BTC only. After payment the upload opens automatically.</div></div>
|
<div style=color:var(--dim);font-size:.85rem;margin-top:.4rem>BTCPay BTC only. After payment the upload opens automatically.</div></div>
|
||||||
{mine}
|
{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)>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>"""
|
<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)
|
return page("track", body)
|
||||||
|
|
||||||
def btc_invoice(amount="1.00"):
|
def btc_invoice(amount="1.00"):
|
||||||
st, b = http(f"{BTCPAY}/stores/{BTCPAY_STORE}/invoices",
|
st, b = http(f"{BTCPAY}/stores/{BTCPAY_STORE}/invoices",
|
||||||
headers={"Authorization": "token " + BTCPAY_KEY, "Content-Type": "application/json"},
|
headers={"Authorization": "token " + BTCPAY_KEY, "Content-Type": "application/json"},
|
||||||
data=json.dumps({"amount": amount, "currency": "USD", "metadata": {"orderId": "auriga-track"}}).encode(), method="POST")
|
data=json.dumps({"amount": amount, "currency": "USD", "metadata": {"orderId": "dark0rbits-track"}}).encode(), method="POST")
|
||||||
return jf(b) or {}
|
return jf(b) or {}
|
||||||
|
|
||||||
@app.route("/api/track/create", methods=["POST"])
|
@app.route("/api/track/create", methods=["POST"])
|
||||||
def api_track_create():
|
def api_track_create():
|
||||||
fn = param("filename") or "file"
|
fn = param("filename") or "file"
|
||||||
uid = current_user_id()
|
uid = key_user() or current_user_id()
|
||||||
token = secrets.token_urlsafe(16)
|
token = secrets.token_urlsafe(16)
|
||||||
con = db()
|
con = db()
|
||||||
if has_pass(uid):
|
if has_pass(uid):
|
||||||
@@ -732,6 +800,11 @@ def api_track_create():
|
|||||||
(uid or 0, token, esc(fn[:100]), "file", "PASS", int(time.time())))
|
(uid or 0, token, esc(fn[:100]), "file", "PASS", int(time.time())))
|
||||||
con.commit()
|
con.commit()
|
||||||
return jsonify({"ok": True, "free": True, "token": token, "upload_url": f"{SITE}/track/pay?token={token}"})
|
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()
|
inv = btc_invoice()
|
||||||
if not inv.get("id"): return jsonify({"ok": False, "error": str(inv)[:200]}), 400
|
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,?)",
|
con.execute("INSERT INTO trackables(user_id,token,filename,kind,invoice_id,paid,created) VALUES(?,?,?,?,?,0,?)",
|
||||||
@@ -762,7 +835,7 @@ def api_track_upload():
|
|||||||
con = db()
|
con = db()
|
||||||
t = con.execute("SELECT * FROM trackables WHERE token=?", (token,)).fetchone()
|
t = con.execute("SELECT * FROM trackables WHERE token=?", (token,)).fetchone()
|
||||||
if not t: return jsonify({"ok": False, "error": "unknown token"}), 400
|
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"] != "PASS" else (200, '{"status":"settled"}')
|
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 {}
|
inv = jf(b) or {}
|
||||||
paid = inv.get("status") in ("settled", "processing", "paid")
|
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
|
if not paid: return jsonify({"ok": False, "error": f"invoice not paid yet ({inv.get('status')})"}), 402
|
||||||
@@ -861,7 +934,7 @@ def api_track_events():
|
|||||||
MAIL_PACKS = [("7","7 days — $3",3,7),("30","30 days — $8",8,30),("90","90 days — $20",20,90)]
|
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_DOMAIN = "thetempleofdoom.com"
|
||||||
MAIL_RESERVED = {"indianaholmes","admin","operator","drjones","root","noreply","support","pass","mail"}
|
MAIL_RESERVED = {"indianaholmes","admin","operator","drjones","root","noreply","support","pass","mail"}
|
||||||
MAIL_SECRET = "auriga-mail-relay-2026"
|
MAIL_SECRET = "dark0rbits-mail-relay-2026"
|
||||||
|
|
||||||
@app.route("/mail", methods=["GET"])
|
@app.route("/mail", methods=["GET"])
|
||||||
def mail():
|
def mail():
|
||||||
@@ -881,7 +954,7 @@ def mail():
|
|||||||
{''.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)}
|
{''.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>
|
<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}
|
{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>"""
|
<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("steg", body)
|
return page("steg", body)
|
||||||
|
|
||||||
@app.route("/api/mail/create", methods=["POST"])
|
@app.route("/api/mail/create", methods=["POST"])
|
||||||
@@ -897,6 +970,18 @@ def api_mail_create():
|
|||||||
con = db()
|
con = db()
|
||||||
if con.execute("SELECT 1 FROM mailboxes WHERE address=?", (addr,)).fetchone():
|
if con.execute("SELECT 1 FROM mailboxes WHERE address=?", (addr,)).fetchone():
|
||||||
return jsonify({"ok": False, "error": "mailbox name taken"}), 400
|
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}")
|
inv = btc_invoice(f"{pack[2]:.2f}")
|
||||||
if not inv.get("id"): return jsonify({"ok": False, "error": str(inv)[:200]}), 400
|
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(?,?,?,?,?,?,?)",
|
con.execute("INSERT INTO mailboxes(user_id,address,invoice_id,paid,expires,created,plan_days) VALUES(?,?,?,?,?,?,?)",
|
||||||
@@ -995,9 +1080,13 @@ def btcpay_webhook():
|
|||||||
expect = "sha256=" + hmac.new(BTCPAY_WHSEC.encode(), body, hashlib.sha256).hexdigest()
|
expect = "sha256=" + hmac.new(BTCPAY_WHSEC.encode(), body, hashlib.sha256).hexdigest()
|
||||||
if sig != expect: return jsonify({"ok": False, "error": "bad sig"}), 400
|
if sig != expect: return jsonify({"ok": False, "error": "bad sig"}), 400
|
||||||
d = jf(body) or {}
|
d = jf(body) or {}
|
||||||
|
iid = d.get("invoiceId") or ""
|
||||||
if d.get("type") == "InvoiceSettled" or (d.get("type") == "InvoicePaymentSettled"):
|
if d.get("type") == "InvoiceSettled" or (d.get("type") == "InvoicePaymentSettled"):
|
||||||
iid = d.get("invoiceId")
|
|
||||||
con = db()
|
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,))
|
con.execute("UPDATE trackables SET paid=1 WHERE invoice_id=?", (iid,))
|
||||||
r = con.execute("SELECT plan_days FROM mailboxes WHERE invoice_id=?", (iid,)).fetchone()
|
r = con.execute("SELECT plan_days FROM mailboxes WHERE invoice_id=?", (iid,)).fetchone()
|
||||||
if r:
|
if r:
|
||||||
@@ -1005,9 +1094,83 @@ def btcpay_webhook():
|
|||||||
r = con.execute("SELECT plan_days FROM passes WHERE invoice_id=?", (iid,)).fetchone()
|
r = con.execute("SELECT plan_days FROM passes WHERE invoice_id=?", (iid,)).fetchone()
|
||||||
if r:
|
if r:
|
||||||
con.execute("UPDATE passes SET paid=1, expires=? WHERE invoice_id=?", (int(time.time()) + 86400*int(r["plan_days"] or 30), iid))
|
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()
|
con.commit()
|
||||||
return jsonify({"ok": True})
|
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("inbox", '<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("inbox", 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"}), 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 jsonify({"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 ----------
|
# ---------- 6d. EMAIL HEADER FORENSICS ----------
|
||||||
def parse_headers(raw):
|
def parse_headers(raw):
|
||||||
import email as em
|
import email as em
|
||||||
@@ -1060,7 +1223,7 @@ def eh():
|
|||||||
<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>
|
<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 … Authentication-Results: …"></textarea>
|
<div class=card><form method=post action=/eh_result><textarea name=raw rows=10 style="width:100%" placeholder="Received: from … Authentication-Results: …"></textarea>
|
||||||
<button style=margin-top:.5rem>Analyze</button></form></div>
|
<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>"""
|
<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."])
|
||||||
return page("tools", body)
|
return page("tools", body)
|
||||||
|
|
||||||
@app.route("/eh_result", methods=["POST"])
|
@app.route("/eh_result", methods=["POST"])
|
||||||
@@ -1091,7 +1254,7 @@ def forensics():
|
|||||||
<div id=fifn style=color:var(--dim);font-size:.85rem></div>
|
<div id=fifn style=color:var(--dim);font-size:.85rem></div>
|
||||||
<button style=margin-top:.5rem>Analyze</button></form></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>
|
<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>"""
|
<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."])
|
||||||
return page("steg", body)
|
return page("steg", body)
|
||||||
|
|
||||||
def _ela_score(img_bytes):
|
def _ela_score(img_bytes):
|
||||||
@@ -1136,7 +1299,7 @@ def forensics_result():
|
|||||||
for k, v in rows:
|
for k, v in rows:
|
||||||
if "software" in k.lower(): flags.append(f"software: {v}")
|
if "software" in k.lower(): flags.append(f"software: {v}")
|
||||||
if "Photoshop" in v or "GIMP" in v: flags.append(f"⚠ EDITED IN {v}")
|
if "Photoshop" in v or "GIMP" in v: flags.append(f"⚠ EDITED IN {v}")
|
||||||
stego = "auriga_meta" in im.info
|
stego = ("auriga_meta" in im.info or "dark0rbits_meta" in im.info)
|
||||||
ela_png, maxdiff = _ela_score(data)
|
ela_png, maxdiff = _ela_score(data)
|
||||||
fn = (f.filename or "image")[:60]
|
fn = (f.filename or "image")[:60]
|
||||||
verdict = "CLEAN-ISH" if maxdiff < 12 and not flags else "SUSPECT — check ELA"
|
verdict = "CLEAN-ISH" if maxdiff < 12 and not flags else "SUSPECT — check ELA"
|
||||||
@@ -1146,7 +1309,7 @@ def forensics_result():
|
|||||||
ela_b64 = b64mod.b64encode(ela_png).decode()
|
ela_b64 = b64mod.b64encode(ela_png).decode()
|
||||||
return page("steg", f"""
|
return page("steg", f"""
|
||||||
<h1>FORENSICS <span>{esc(fn)}</span></h1>
|
<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", "AURIGA payload present ✓" if stego else "none detected")])}
|
{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>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>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>EXIF table</b><table>{rows_html or '<tr><td colspan=2 style=color:var(--dim)>no EXIF</td></tr>'}</table></div>
|
||||||
@@ -1170,7 +1333,7 @@ def api_forensics():
|
|||||||
except Exception: pass
|
except Exception: pass
|
||||||
_, maxdiff = _ela_score(data)
|
_, maxdiff = _ela_score(data)
|
||||||
return jsonify({"ok": True, "exif": ex, "gps_present": bool(exif.get_ifd(0x8825)) if hasattr(exif, "get_ifd") else False,
|
return jsonify({"ok": True, "exif": ex, "gps_present": bool(exif.get_ifd(0x8825)) if hasattr(exif, "get_ifd") else False,
|
||||||
"stego_auriga": "auriga_meta" in im.info, "ela_max_diff": maxdiff,
|
"stego_auriga": ("auriga_meta" in im.info or "dark0rbits_meta" in im.info), "ela_max_diff": maxdiff,
|
||||||
"flags": (["exif-stripped"] if not ex else [])})
|
"flags": (["exif-stripped"] if not ex else [])})
|
||||||
|
|
||||||
# ---------- 6f. CANARY TRAPS ----------
|
# ---------- 6f. CANARY TRAPS ----------
|
||||||
@@ -1184,7 +1347,7 @@ def canary():
|
|||||||
<button style=margin-left:.5rem>Create trap</button></form>
|
<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>
|
<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()}
|
{canary_list()}
|
||||||
<div class=card style=color:var(--dim)>API: POST /canary (tag) · GET /api/canary/list (login) · hits log like trackables.</div>"""
|
<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("track", body)
|
return page("track", body)
|
||||||
|
|
||||||
def canary_list():
|
def canary_list():
|
||||||
@@ -1252,10 +1415,10 @@ def passport():
|
|||||||
n_sms = con.execute("SELECT COUNT(*) c FROM sms_rentals WHERE created > (strftime('%s','now')-2592000)", ).fetchone()["c"]
|
n_sms = con.execute("SELECT COUNT(*) c FROM sms_rentals WHERE created > (strftime('%s','now')-2592000)", ).fetchone()["c"]
|
||||||
pas = has_pass(uid)
|
pas = has_pass(uid)
|
||||||
badge = {"holder": u["username"], "issued": u["created"], "pass_active": pas,
|
badge = {"holder": u["username"], "issued": u["created"], "pass_active": pas,
|
||||||
"tool_usage_30d": {"sms_rentals": n_sms}, "site": "auriga.thetempleofdoom.com", "v": 1,
|
"tool_usage_30d": {"sms_rentals": n_sms}, "site": "dark0rbits.thetempleofdoom.com", "v": 1,
|
||||||
"principles": ["no-KYC", "BTC-only", "agent-friendly"]}
|
"principles": ["no-KYC", "BTC-only", "agent-friendly"]}
|
||||||
body = f"""
|
body = f"""
|
||||||
<h1>AGENT <span>PASSPORT</span></h1><p class=sub>Machine-readable identity + trust badge for agents operating on AURIGA.</p>
|
<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)])}
|
{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><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>"""
|
<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>"""
|
||||||
@@ -1267,13 +1430,13 @@ def api_passport():
|
|||||||
if not uid: return jsonify({"ok": False, "error": "login required"})
|
if not uid: return jsonify({"ok": False, "error": "login required"})
|
||||||
con = db()
|
con = db()
|
||||||
u = con.execute("SELECT * FROM users WHERE id=?", (uid,)).fetchone()
|
u = con.execute("SELECT * FROM users WHERE id=?", (uid,)).fetchone()
|
||||||
return jsonify({"holder": u["username"], "issued": u["created"], "pass_active": has_pass(uid), "site": "auriga.thetempleofdoom.com"})
|
return jsonify({"holder": u["username"], "issued": u["created"], "pass_active": has_pass(uid), "site": "dark0rbits.thetempleofdoom.com"})
|
||||||
|
|
||||||
# ---------- 7. INBOX (no-KYC site-only messaging) ----------
|
# ---------- 7. INBOX (no-KYC site-only messaging) ----------
|
||||||
def hash_pw(pw): return hashlib.scrypt(pw.encode(), salt=b"auriga-salt", n=16384, r=8, p=1).hex()
|
def hash_pw(pw): return hashlib.scrypt(pw.encode(), salt=b"dark0rbits-salt", n=16384, r=8, p=1).hex()
|
||||||
|
|
||||||
def current_user_id():
|
def current_user_id():
|
||||||
tok = request.cookies.get("auriga_tok")
|
tok = request.cookies.get("dark0rbits_tok")
|
||||||
if not tok: return None
|
if not tok: return None
|
||||||
con = db()
|
con = db()
|
||||||
s = con.execute("SELECT user_id FROM sessions WHERE token=?", (tok,)).fetchone()
|
s = con.execute("SELECT user_id FROM sessions WHERE token=?", (tok,)).fetchone()
|
||||||
@@ -1296,7 +1459,7 @@ def inbox():
|
|||||||
tok = secrets.token_urlsafe(24)
|
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.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()
|
con.commit()
|
||||||
resp = Response(status=302); resp.headers["Location"] = "/inbox"; resp.set_cookie("auriga_tok", tok, max_age=86400*30, httponly=True)
|
resp = Response(status=302); resp.headers["Location"] = "/inbox"; resp.set_cookie("dark0rbits_tok", tok, max_age=86400*30, httponly=True)
|
||||||
return resp
|
return resp
|
||||||
elif action == "login":
|
elif action == "login":
|
||||||
u, p = (request.form.get("u") or "").strip()[:32], request.form.get("p") or ""
|
u, p = (request.form.get("u") or "").strip()[:32], request.form.get("p") or ""
|
||||||
@@ -1305,12 +1468,12 @@ def inbox():
|
|||||||
tok = secrets.token_urlsafe(24)
|
tok = secrets.token_urlsafe(24)
|
||||||
con.execute("INSERT INTO sessions(token,user_id,created) VALUES(?,?,?)", (tok, r["id"], int(time.time())))
|
con.execute("INSERT INTO sessions(token,user_id,created) VALUES(?,?,?)", (tok, r["id"], int(time.time())))
|
||||||
con.commit()
|
con.commit()
|
||||||
resp = Response(status=302); resp.headers["Location"] = "/inbox"; resp.set_cookie("auriga_tok", tok, max_age=86400*30, httponly=True)
|
resp = Response(status=302); resp.headers["Location"] = "/inbox"; resp.set_cookie("dark0rbits_tok", tok, max_age=86400*30, httponly=True)
|
||||||
return resp
|
return resp
|
||||||
return page("inbox", "<h1>INBOX</h1><div class=card><span class=tag bad>bad login</span></div>")
|
return page("inbox", "<h1>INBOX</h1><div class=card><span class=tag bad>bad login</span></div>")
|
||||||
elif action == "logout":
|
elif action == "logout":
|
||||||
con.execute("DELETE FROM sessions WHERE token=?", (request.cookies.get("auriga_tok"),)); con.commit()
|
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("auriga_tok", "", max_age=0)
|
resp = Response(status=302); resp.headers["Location"] = "/inbox"; resp.set_cookie("dark0rbits_tok", "", max_age=0)
|
||||||
return resp
|
return resp
|
||||||
elif action == "send" and uid:
|
elif action == "send" and uid:
|
||||||
body = (request.form.get("body") or "").strip()[:4000]
|
body = (request.form.get("body") or "").strip()[:4000]
|
||||||
@@ -1410,9 +1573,9 @@ def tools():
|
|||||||
def admin():
|
def admin():
|
||||||
if request.method == "POST" and request.form.get("pw") == ADMIN_PW:
|
if request.method == "POST" and request.form.get("pw") == ADMIN_PW:
|
||||||
resp = Response(status=302); resp.headers["Location"] = "/admin"
|
resp = Response(status=302); resp.headers["Location"] = "/admin"
|
||||||
resp.set_cookie("auriga_admin", secrets.token_urlsafe(16), max_age=86400, httponly=True)
|
resp.set_cookie("dark0rbits_admin", secrets.token_urlsafe(16), max_age=86400, httponly=True)
|
||||||
return resp
|
return resp
|
||||||
if not request.cookies.get("auriga_admin"):
|
if not request.cookies.get("dark0rbits_admin"):
|
||||||
return page("ip", '<h1>OPERATOR</h1><div class=card><form method=post><input name=pw type=password placeholder="operator password"><button>In</button></form></div>')
|
return page("ip", '<h1>OPERATOR</h1><div class=card><form method=post><input name=pw type=password placeholder="operator password"><button>In</button></form></div>')
|
||||||
con = db()
|
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 = 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()
|
||||||
@@ -1424,38 +1587,59 @@ def admin():
|
|||||||
<div class=card><b>All customer messages</b>{msgs_html}</div>
|
<div class=card><b>All customer messages</b>{msgs_html}</div>
|
||||||
<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>""")
|
<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 ----------
|
# ---------- INDEX (hacker landing) ----------
|
||||||
@app.route("/")
|
@app.route("/")
|
||||||
def index():
|
def index():
|
||||||
ip = request.headers.get("X-Real-IP") or request.remote_addr
|
ip = request.headers.get("X-Real-IP") or request.remote_addr
|
||||||
st, b = http(f"http://ip-api.com/json/{ip}?fields=66846719")
|
st, b = http(f"http://ip-api.com/json/{ip}?fields=66846719")
|
||||||
d = jf(b) or {}
|
d = jf(b) or {}
|
||||||
|
uid = current_user_id()
|
||||||
con = db()
|
con = db()
|
||||||
n_sms = con.execute("SELECT COUNT(*) c FROM sms_rentals").fetchone()["c"]
|
n_sms = con.execute("SELECT COUNT(*) c FROM sms_rentals").fetchone()["c"]
|
||||||
n_px = con.execute("SELECT COUNT(*) c FROM proxy_checks").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."),
|
||||||
|
("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"""
|
body = f"""
|
||||||
<h1>AURIGA <span>TOOLBOX</span></h1>
|
<div class="term card glow">$ ./dark0rbits --intro<span class="crt">▊</span>
|
||||||
<p class=sub>One page. Every network weapon you actually use. You're connecting from <b style=color:var(--acc)>{esc(d.get('query','?'))}</b> — {esc(d.get('city',''))}, {esc(d.get('country',''))}.</p>
|
DARK0RBITS — the toolbox that treats you like an operator, not a product.
|
||||||
<div class=grid2>
|
No KYC. No email required. No Stripe. BTC only. Agents welcome.
|
||||||
<div class=card><h3>◈ IP Intel</h3><p style=color:var(--dim)>Geo, ASN, ISP, VPN flags, rDNS — auto for you, any target on demand.</p><a href=/ip><button>Open</button></a></div>
|
{stat}
|
||||||
<div class=card><h3>◈ Card Check</h3><p style=color:var(--dim)>Luhn + BIN: issuer, brand, type, prepaid risk flags.</p><a href=/card><button>Open</button></a></div>
|
<div class="cta">{cta}</div></div>
|
||||||
<div class=card><h3>◈ SMS Rental</h3><p style=color:var(--dim)>30-min numbers, cancel = refund. {n_sms} served.</p><a href=/sms><button>Open</button></a></div>
|
<div class=grid2>{cards}</div>
|
||||||
<div class=card><h3>◈ Proxy Lab</h3><p style=color:var(--dim)>Same gateway keys as the fleet. {n_px} checks.</p><a href=/proxy><button>Open</button></a></div>
|
<div class=card style=text-align:center>
|
||||||
<div class=card><h3>◈ Stego Lab</h3><p style=color:var(--dim)>Hide words in pictures. LSB depth, spread, passwords.</p><a href=/steg><button>Open</button></a></div>
|
<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><h3>◈ Track File</h3><p style=color:var(--dim)>$1 BTC → tracked link + email pixel → opens ping your inbox.</p><a href=/track><button>Open</button></a></div>
|
<div class=card style=color:var(--dim)>
|
||||||
<div class=card><h3>◈ Burner Mail</h3><p style=color:var(--dim)>Receive-only mailboxes, 7d/$3 → 90d/$20, live countdown.</p><a href=/mail><button>Open</button></a></div>
|
<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>.
|
||||||
<div class=card><h3>◈ PASS</h3><p style=color:var(--dim)>$10/mo all-access (3mo $25 · 1yr $80) — every tool, proxy rentals excluded.</p><a href=/pass><button>Open</button></a></div>
|
For humans: click a card. That's it.</div>"""
|
||||||
<div class=card><h3>◈ Inbox</h3><p style=color:var(--dim)>No-KYC site messaging with the operator.</p><a href=/inbox><button>Open</button></a></div>
|
|
||||||
<div class=card><h3>◈ Mail Forensics</h3><p style=color:var(--dim)>Real origin, SPF/DKIM/DMARC verdicts, spoof flags.</p><a href=/eh><button>Open</button></a></div>
|
|
||||||
<div class=card><h3>◈ Image Forensics</h3><p style=color:var(--dim)>EXIF + GPS + ELA — expose edits and hidden stego.</p><a href=/forensics><button>Open</button></a></div>
|
|
||||||
<div class=card><h3>◈ Canary Traps</h3><p style=color:var(--dim)>Tripwire links & pixels — instant alerts when touched.</p><a href=/canary><button>Open</button></a></div>
|
|
||||||
<div class=card><h3>◈ Agent Passport</h3><p style=color:var(--dim)>Machine-readable trust badge for agents.</p><a href=/passport><button>Open</button></a></div>
|
|
||||||
<div class=card><h3>◈ Free Tools</h3><p style=color:var(--dim)>DNS, headers, JWT, hasher, generators.</p><a href=/tools><button>Open</button></a></div>
|
|
||||||
</div>"""
|
|
||||||
return page("home", body)
|
return page("home", body)
|
||||||
|
|
||||||
@app.route("/health")
|
@app.route("/health")
|
||||||
def health(): return jsonify({"ok": True, "service": "auriga", "version": "2.0"})
|
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
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
app.run(host="0.0.0.0", port=5000, threaded=True)
|
app.run(host="0.0.0.0", port=5000, threaded=True)
|
||||||
|
|||||||
Reference in New Issue
Block a user