Autarch/web/templates/android_exploit.html
DigiJ ffe47c51b5 Initial public release — AUTARCH v1.0.0
Full security platform with web dashboard, 16 Flask blueprints, 26 modules,
autonomous AI agent, WebUSB hardware support, and Archon Android companion app.

Includes Hash Toolkit, debug console, anti-stalkerware shield, Metasploit/RouterSploit
integration, WireGuard VPN, OSINT reconnaissance, and multi-backend LLM support.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 03:57:32 -08:00

1225 lines
65 KiB
HTML

{% extends "base.html" %}
{% block title %}Android Exploit - AUTARCH{% endblock %}
{% block content %}
<div class="page-header">
<h1>Android Exploitation</h1>
</div>
<!-- Status Cards -->
<div class="stats-grid" style="grid-template-columns:repeat(auto-fit,minmax(140px,1fr))">
<div class="stat-card">
<div class="stat-label">ADB</div>
<div class="stat-value small">
<span class="status-dot {{ 'active' if status.adb else 'inactive' }}"></span>
{{ 'Ready' if status.adb else 'N/A' }}
</div>
</div>
<div class="stat-card">
<div class="stat-label">Fastboot</div>
<div class="stat-value small">
<span class="status-dot {{ 'active' if status.fastboot else 'inactive' }}"></span>
{{ 'Ready' if status.fastboot else 'N/A' }}
</div>
</div>
<div class="stat-card" id="card-devices">
<div class="stat-label">Devices</div>
<div class="stat-value small" id="device-count">--</div>
</div>
<div class="stat-card" id="card-root">
<div class="stat-label">Root</div>
<div class="stat-value small" id="root-status">--</div>
</div>
</div>
<!-- ADB Connection Mode -->
<div class="card" style="margin:0.5rem 0 0.5rem 0;padding:0.6rem 1rem;display:flex;align-items:center;gap:0.6rem;flex-wrap:wrap">
<span style="font-weight:600;font-size:0.85rem;color:var(--text-secondary)">ADB Mode:</span>
<button id="ae-mode-server" class="btn btn-sm active" onclick="aeSetMode('server')">Server (Local ADB)</button>
<button id="ae-mode-direct" class="btn btn-sm" onclick="aeSetMode('direct')">Direct (WebUSB)</button>
<span id="ae-direct-bar" style="display:none;align-items:center;gap:0.5rem">
<span id="ae-device-label" style="font-size:0.85rem;color:var(--text-secondary)">Not connected</span>
<button class="btn btn-sm" onclick="aeDirectConnect()">Connect</button>
<button class="btn btn-sm btn-danger" id="ae-disconnect-btn" style="display:none" onclick="aeDirectDisconnect()">Disconnect</button>
</span>
<span id="ae-webusb-warning" style="display:none;color:#f97316;font-size:0.8rem;margin-left:0.5rem"></span>
</div>
<!-- Device Selector (server mode) -->
<div id="ae-server-selector" class="card" style="margin:0.5rem 0 1rem 0;padding:0.8rem 1rem;display:flex;align-items:center;gap:0.8rem;flex-wrap:wrap">
<label style="font-weight:600">Device:</label>
<select id="device-select" style="flex:1;min-width:200px;padding:0.4rem;background:var(--bg-secondary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
<option value="">-- Select --</option>
</select>
<button class="btn btn-sm" onclick="refreshDevices()">Refresh</button>
</div>
<!-- Tabs -->
<div class="tabs" style="display:flex;gap:0;border-bottom:2px solid var(--border-color);margin-bottom:1rem">
<button class="tab-btn active" data-tab="apps" onclick="switchTab('apps',this)">Apps</button>
<button class="tab-btn" data-tab="recon" onclick="switchTab('recon',this)">Recon</button>
<button class="tab-btn" data-tab="payloads" onclick="switchTab('payloads',this)">Payloads</button>
<button class="tab-btn" data-tab="boot" onclick="switchTab('boot',this)">Boot</button>
<button class="tab-btn" data-tab="root" onclick="switchTab('root',this)">Root</button>
<button class="tab-btn" data-tab="sms" onclick="switchTab('sms',this)">SMS/RCS</button>
<button class="tab-btn" data-tab="screen" onclick="switchTab('screen',this)">Screen</button>
<button class="tab-btn" data-tab="advanced" onclick="switchTab('advanced',this)">Advanced</button>
</div>
<!-- ── Apps Tab ── -->
<div class="tab-panel active" id="tab-apps">
<div class="card" style="padding:1rem;margin-bottom:1rem">
<h3>App Extraction</h3>
<div style="display:flex;gap:0.5rem;flex-wrap:wrap;margin:0.8rem 0">
<label><input type="checkbox" id="apps-system"> Include system apps</label>
</div>
<div style="display:flex;gap:0.5rem;flex-wrap:wrap;margin-bottom:0.8rem">
<button class="btn" onclick="appsList()">List Packages</button>
</div>
<div style="display:flex;gap:0.5rem;flex-wrap:wrap;align-items:end">
<div>
<label style="font-size:0.85rem">Package name:</label>
<input type="text" id="apps-pkg" placeholder="com.example.app" style="width:250px;padding:0.4rem;background:var(--bg-secondary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
</div>
<button class="btn" onclick="appsPullApk()">Pull APK</button>
<button class="btn" onclick="appsPullData()">Pull Data</button>
<button class="btn" onclick="appsSharedPrefs()">Shared Prefs</button>
</div>
</div>
<div class="card output-panel" id="apps-output" style="padding:1rem;max-height:400px;overflow-y:auto">
<pre style="margin:0;white-space:pre-wrap;font-size:0.85rem">Select a device and run a command...</pre>
</div>
</div>
<!-- ── Recon Tab ── -->
<div class="tab-panel" id="tab-recon" style="display:none">
<div class="card" style="padding:1rem;margin-bottom:1rem">
<h3>Device Reconnaissance</h3>
<div style="display:flex;gap:0.5rem;flex-wrap:wrap;margin:0.8rem 0">
<button class="btn" onclick="reconDump()">Full Dump</button>
<button class="btn" onclick="reconAccounts()">Accounts</button>
<button class="btn btn-warning" onclick="reconWifi()">WiFi Passwords [ROOT]</button>
<button class="btn" onclick="reconCalls()">Call Logs</button>
<button class="btn" onclick="reconSms()">SMS</button>
<button class="btn" onclick="reconContacts()">Contacts</button>
<button class="btn btn-warning" onclick="reconBrowser()">Browser History [ROOT]</button>
<button class="btn btn-warning" onclick="reconCreds()">Saved Creds [ROOT]</button>
</div>
<div style="display:flex;gap:0.5rem;flex-wrap:wrap">
<button class="btn btn-primary" onclick="reconExport()">Export Full Report</button>
</div>
</div>
<div class="card output-panel" id="recon-output" style="padding:1rem;max-height:400px;overflow-y:auto">
<pre style="margin:0;white-space:pre-wrap;font-size:0.85rem">Select a device and run a recon command...</pre>
</div>
</div>
<!-- ── Payloads Tab ── -->
<div class="tab-panel" id="tab-payloads" style="display:none">
<div class="card" style="padding:1rem;margin-bottom:1rem">
<h3>Payload Deployment</h3>
<!-- Deploy Binary -->
<div style="margin:0.8rem 0;padding:0.8rem;background:var(--bg-secondary);border-radius:4px">
<strong>Deploy Binary</strong>
<form id="deploy-form" style="display:flex;gap:0.5rem;flex-wrap:wrap;align-items:end;margin-top:0.5rem">
<div>
<label style="font-size:0.85rem">Binary file:</label>
<input type="file" id="deploy-file" style="font-size:0.85rem">
</div>
<div>
<label style="font-size:0.85rem">Remote path:</label>
<input type="text" id="deploy-remote" value="/data/local/tmp/" style="width:200px;padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
</div>
<button type="button" class="btn" onclick="payloadDeploy()">Deploy</button>
</form>
</div>
<!-- Execute -->
<div style="margin:0.8rem 0;padding:0.8rem;background:var(--bg-secondary);border-radius:4px">
<strong>Execute Payload</strong>
<div style="display:flex;gap:0.5rem;flex-wrap:wrap;align-items:end;margin-top:0.5rem">
<div>
<label style="font-size:0.85rem">Remote path:</label>
<input type="text" id="exec-path" placeholder="/data/local/tmp/payload" style="width:250px;padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
</div>
<div>
<label style="font-size:0.85rem">Args:</label>
<input type="text" id="exec-args" style="width:120px;padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
</div>
<label><input type="checkbox" id="exec-bg" checked> Background</label>
<button class="btn" onclick="payloadExec()">Execute</button>
</div>
</div>
<!-- Reverse Shell -->
<div style="margin:0.8rem 0;padding:0.8rem;background:var(--bg-secondary);border-radius:4px">
<strong>Reverse Shell</strong>
<div style="display:flex;gap:0.5rem;flex-wrap:wrap;align-items:end;margin-top:0.5rem">
<div>
<label style="font-size:0.85rem">LHOST:</label>
<input type="text" id="rshell-host" placeholder="192.168.1.100" style="width:150px;padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
</div>
<div>
<label style="font-size:0.85rem">LPORT:</label>
<input type="text" id="rshell-port" value="4444" style="width:80px;padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
</div>
<div>
<label style="font-size:0.85rem">Method:</label>
<select id="rshell-method" style="padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
<option value="nc">nc (netcat)</option>
<option value="bash">bash</option>
<option value="python">python</option>
</select>
</div>
<button class="btn btn-warning" onclick="payloadReverseShell()">Connect</button>
</div>
</div>
<!-- Persistence + Management -->
<div style="display:flex;gap:0.5rem;flex-wrap:wrap;margin:0.8rem 0">
<button class="btn btn-warning" onclick="payloadPersistence()">Install Persistence [ROOT]</button>
<button class="btn" onclick="payloadListRunning()">List Running</button>
<div style="display:flex;gap:0.3rem;align-items:center">
<input type="text" id="kill-pid" placeholder="PID" style="width:70px;padding:0.4rem;background:var(--bg-secondary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
<button class="btn btn-danger" onclick="payloadKill()">Kill</button>
</div>
</div>
</div>
<div class="card output-panel" id="payload-output" style="padding:1rem;max-height:400px;overflow-y:auto">
<pre style="margin:0;white-space:pre-wrap;font-size:0.85rem">Ready for payload operations...</pre>
</div>
</div>
<!-- ── Boot Tab ── -->
<div class="tab-panel" id="tab-boot" style="display:none">
<div class="card" style="padding:1rem;margin-bottom:1rem">
<h3>Boot / Recovery</h3>
<div style="background:#442;color:#ffa;padding:0.5rem 0.8rem;border-radius:4px;margin-bottom:0.8rem;font-size:0.9rem">
WARNING: These operations can BRICK your device or WIPE data. Use with caution.
</div>
<div style="display:flex;gap:0.5rem;flex-wrap:wrap;margin:0.8rem 0">
<button class="btn" onclick="bootInfo()">Bootloader Info</button>
<button class="btn" onclick="bootBackup()">Backup Boot Image</button>
<button class="btn btn-danger" onclick="bootUnlock()">Unlock Bootloader [WIPES]</button>
</div>
<!-- Flash Recovery -->
<div style="margin:0.8rem 0;padding:0.8rem;background:var(--bg-secondary);border-radius:4px">
<strong>Flash Image</strong>
<div style="display:flex;gap:0.5rem;flex-wrap:wrap;align-items:end;margin-top:0.5rem">
<div>
<label style="font-size:0.85rem">Image file:</label>
<input type="file" id="boot-file" accept=".img,.bin" style="font-size:0.85rem">
</div>
<button class="btn btn-warning" onclick="bootFlashRecovery()">Flash Recovery</button>
<button class="btn btn-warning" onclick="bootFlashBoot()">Flash Boot</button>
<button class="btn" onclick="bootTempBoot()">Temp Boot</button>
</div>
</div>
<!-- Disable verity -->
<div style="margin:0.8rem 0;padding:0.8rem;background:var(--bg-secondary);border-radius:4px">
<strong>Disable dm-verity / AVB</strong>
<div style="display:flex;gap:0.5rem;flex-wrap:wrap;align-items:end;margin-top:0.5rem">
<div>
<label style="font-size:0.85rem">vbmeta image (optional):</label>
<input type="file" id="verity-file" accept=".img" style="font-size:0.85rem">
</div>
<button class="btn btn-warning" onclick="bootDisableVerity()">Disable Verity</button>
</div>
</div>
</div>
<div class="card output-panel" id="boot-output" style="padding:1rem;max-height:400px;overflow-y:auto">
<pre style="margin:0;white-space:pre-wrap;font-size:0.85rem">Ready for boot operations...</pre>
</div>
</div>
<!-- ── Root Tab ── -->
<div class="tab-panel" id="tab-root" style="display:none">
<div class="card" style="padding:1rem;margin-bottom:1rem">
<h3>Root Methods</h3>
<div style="display:flex;gap:0.5rem;flex-wrap:wrap;margin:0.8rem 0">
<button class="btn" onclick="rootCheck()">Check Root Status</button>
<button class="btn" onclick="rootAdbRoot()">ADB Root (debug builds)</button>
<button class="btn" onclick="rootPullPatched()">Pull Patched Boot</button>
</div>
<!-- Install Magisk -->
<div style="margin:0.8rem 0;padding:0.8rem;background:var(--bg-secondary);border-radius:4px">
<strong>Install Magisk APK</strong>
<div style="display:flex;gap:0.5rem;flex-wrap:wrap;align-items:end;margin-top:0.5rem">
<div>
<label style="font-size:0.85rem">Magisk APK:</label>
<input type="file" id="magisk-file" accept=".apk" style="font-size:0.85rem">
</div>
<button class="btn" onclick="rootInstallMagisk()">Install</button>
</div>
</div>
<!-- Root via exploit -->
<div style="margin:0.8rem 0;padding:0.8rem;background:var(--bg-secondary);border-radius:4px">
<strong>Root via Exploit Binary</strong>
<div style="display:flex;gap:0.5rem;flex-wrap:wrap;align-items:end;margin-top:0.5rem">
<div>
<label style="font-size:0.85rem">Exploit binary:</label>
<input type="file" id="exploit-file" style="font-size:0.85rem">
</div>
<button class="btn btn-warning" onclick="rootExploit()">Run Exploit</button>
</div>
</div>
</div>
<div class="card output-panel" id="root-output" style="padding:1rem;max-height:400px;overflow-y:auto">
<pre style="margin:0;white-space:pre-wrap;font-size:0.85rem">Ready for root operations...</pre>
</div>
</div>
<!-- ── SMS/RCS Tab ── -->
<div class="tab-panel" id="tab-sms" style="display:none">
<div class="card" style="padding:1rem;margin-bottom:1rem">
<h3>SMS / RCS Manipulation</h3>
<!-- SMS List -->
<div style="margin:0.8rem 0;padding:0.8rem;background:var(--bg-secondary);border-radius:4px">
<strong>List Messages</strong>
<div style="display:flex;gap:0.5rem;flex-wrap:wrap;align-items:end;margin-top:0.5rem">
<div>
<label style="font-size:0.85rem">Phone # filter:</label>
<input type="text" id="sms-filter-addr" placeholder="(all)" style="width:150px;padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
</div>
<div>
<label style="font-size:0.85rem">Limit:</label>
<input type="number" id="sms-limit" value="50" style="width:70px;padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
</div>
<button class="btn" onclick="smsList()">List SMS</button>
<button class="btn btn-warning" onclick="rcsList()">List RCS [ROOT]</button>
</div>
</div>
<!-- SMS Insert -->
<div style="margin:0.8rem 0;padding:0.8rem;background:var(--bg-secondary);border-radius:4px">
<strong>Insert Spoofed SMS</strong>
<div style="display:flex;gap:0.5rem;flex-wrap:wrap;align-items:end;margin-top:0.5rem">
<div>
<label style="font-size:0.85rem">Phone #:</label>
<input type="text" id="sms-addr" placeholder="+15551234567" style="width:150px;padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
</div>
<div>
<label style="font-size:0.85rem">Type:</label>
<select id="sms-type" style="padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
<option value="inbox">Inbox (received)</option>
<option value="sent">Sent</option>
<option value="draft">Draft</option>
</select>
</div>
<div>
<label style="font-size:0.85rem">Date:</label>
<input type="date" id="sms-date" style="padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
</div>
<div>
<label style="font-size:0.85rem">Time:</label>
<input type="time" id="sms-time" step="1" style="padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
</div>
<label style="font-size:0.85rem"><input type="checkbox" id="sms-read" checked> Read</label>
</div>
<div style="margin-top:0.5rem">
<label style="font-size:0.85rem">Message body:</label>
<textarea id="sms-body" rows="2" style="width:100%;padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px;resize:vertical;font-family:inherit"></textarea>
</div>
<div style="margin-top:0.5rem;display:flex;gap:0.5rem">
<button class="btn btn-primary" onclick="smsInsert()">Insert SMS</button>
</div>
</div>
<!-- SMS Edit -->
<div style="margin:0.8rem 0;padding:0.8rem;background:var(--bg-secondary);border-radius:4px">
<strong>Edit Existing SMS</strong>
<div style="display:flex;gap:0.5rem;flex-wrap:wrap;align-items:end;margin-top:0.5rem">
<div>
<label style="font-size:0.85rem">SMS ID:</label>
<input type="text" id="sms-edit-id" placeholder="_id" style="width:70px;padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
</div>
<div>
<label style="font-size:0.85rem">New body:</label>
<input type="text" id="sms-edit-body" placeholder="(keep)" style="width:200px;padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
</div>
<div>
<label style="font-size:0.85rem">New date:</label>
<input type="date" id="sms-edit-date" style="padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
</div>
<div>
<label style="font-size:0.85rem">New time:</label>
<input type="time" id="sms-edit-time" step="1" style="padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
</div>
<button class="btn" onclick="smsUpdate()">Update</button>
</div>
</div>
<!-- SMS Delete -->
<div style="margin:0.8rem 0;padding:0.8rem;background:var(--bg-secondary);border-radius:4px">
<strong>Delete SMS</strong>
<div style="display:flex;gap:0.5rem;flex-wrap:wrap;align-items:end;margin-top:0.5rem">
<div>
<label style="font-size:0.85rem">By ID:</label>
<input type="text" id="sms-del-id" placeholder="_id" style="width:70px;padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
</div>
<button class="btn btn-danger" onclick="smsDeleteById()">Delete by ID</button>
<div style="margin-left:1rem">
<label style="font-size:0.85rem">By number:</label>
<input type="text" id="sms-del-addr" placeholder="+15551234567" style="width:150px;padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
</div>
<button class="btn btn-danger" onclick="smsDeleteByAddr()">Delete All From #</button>
<button class="btn btn-danger" onclick="smsDeleteAll()" style="margin-left:auto">WIPE ALL SMS</button>
</div>
</div>
<!-- RCS Section -->
<div style="margin:0.8rem 0;padding:0.8rem;background:var(--bg-secondary);border-radius:4px;border-left:3px solid #a85">
<strong>RCS Spoofing</strong> <span style="font-size:0.8rem;color:var(--text-secondary)">[ROOT required]</span>
<div style="margin-top:0.3rem;margin-bottom:0.5rem">
<button class="btn btn-sm" onclick="rcsCheck()">Check RCS Support</button>
</div>
<div style="display:flex;gap:0.5rem;flex-wrap:wrap;align-items:end;margin-top:0.5rem">
<div>
<label style="font-size:0.85rem">Phone #:</label>
<input type="text" id="rcs-addr" placeholder="+15551234567" style="width:150px;padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
</div>
<div>
<label style="font-size:0.85rem">Sender name:</label>
<input type="text" id="rcs-sender" placeholder="(optional)" style="width:130px;padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
</div>
<div>
<label style="font-size:0.85rem">Direction:</label>
<select id="rcs-dir" style="padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
<option value="incoming">Incoming</option>
<option value="outgoing">Outgoing</option>
</select>
</div>
<div>
<label style="font-size:0.85rem">Date:</label>
<input type="date" id="rcs-date" style="padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
</div>
<div>
<label style="font-size:0.85rem">Time:</label>
<input type="time" id="rcs-time" step="1" style="padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
</div>
</div>
<div style="margin-top:0.5rem">
<label style="font-size:0.85rem">Message body:</label>
<textarea id="rcs-body" rows="2" style="width:100%;padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px;resize:vertical;font-family:inherit"></textarea>
</div>
<div style="margin-top:0.5rem;display:flex;gap:0.5rem;flex-wrap:wrap">
<button class="btn btn-warning" onclick="rcsInsert()">Insert RCS Message</button>
<div style="display:flex;gap:0.3rem;align-items:center;margin-left:1rem">
<input type="text" id="rcs-del-id" placeholder="msg ID" style="width:70px;padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
<button class="btn btn-danger" onclick="rcsDelete()">Delete RCS</button>
</div>
</div>
</div>
</div>
<div class="card output-panel" id="sms-output" style="padding:1rem;max-height:400px;overflow-y:auto">
<pre style="margin:0;white-space:pre-wrap;font-size:0.85rem">Ready for SMS/RCS operations...</pre>
</div>
</div>
<!-- ── Screen Tab ── -->
<div class="tab-panel" id="tab-screen" style="display:none">
<div class="card" style="padding:1rem;margin-bottom:1rem">
<h3>Screen & Input Control</h3>
<!-- Capture -->
<div style="margin:0.8rem 0;padding:0.8rem;background:var(--bg-secondary);border-radius:4px">
<strong>Capture</strong>
<div style="display:flex;gap:0.5rem;flex-wrap:wrap;align-items:end;margin-top:0.5rem">
<button class="btn" onclick="screenCapture()">Screenshot</button>
<div>
<label style="font-size:0.85rem">Duration (s):</label>
<input type="number" id="screen-rec-dur" value="10" style="width:60px;padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
</div>
<button class="btn" onclick="screenRecord()">Record Screen</button>
</div>
</div>
<!-- Input Injection -->
<div style="margin:0.8rem 0;padding:0.8rem;background:var(--bg-secondary);border-radius:4px">
<strong>Input Injection</strong>
<div style="display:flex;gap:0.5rem;flex-wrap:wrap;align-items:end;margin-top:0.5rem">
<div>
<label style="font-size:0.85rem">X:</label>
<input type="number" id="tap-x" placeholder="540" style="width:70px;padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
</div>
<div>
<label style="font-size:0.85rem">Y:</label>
<input type="number" id="tap-y" placeholder="960" style="width:70px;padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
</div>
<button class="btn" onclick="screenTap()">Tap</button>
</div>
<div style="display:flex;gap:0.5rem;flex-wrap:wrap;align-items:end;margin-top:0.5rem">
<div>
<label style="font-size:0.85rem">From X:</label>
<input type="number" id="swipe-x1" style="width:60px;padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
</div>
<div>
<label style="font-size:0.85rem">Y:</label>
<input type="number" id="swipe-y1" style="width:60px;padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
</div>
<div>
<label style="font-size:0.85rem">To X:</label>
<input type="number" id="swipe-x2" style="width:60px;padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
</div>
<div>
<label style="font-size:0.85rem">Y:</label>
<input type="number" id="swipe-y2" style="width:60px;padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
</div>
<button class="btn" onclick="screenSwipe()">Swipe</button>
</div>
<div style="display:flex;gap:0.5rem;flex-wrap:wrap;align-items:end;margin-top:0.5rem">
<div>
<label style="font-size:0.85rem">Text:</label>
<input type="text" id="input-text" placeholder="Hello world" style="width:200px;padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
</div>
<button class="btn" onclick="screenText()">Type Text</button>
<div>
<label style="font-size:0.85rem">Key:</label>
<input type="text" id="input-key" placeholder="3=HOME" style="width:100px;padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
</div>
<button class="btn" onclick="screenKey()">Send Key</button>
</div>
</div>
<!-- Lock & Keylogger -->
<div style="display:flex;gap:0.5rem;flex-wrap:wrap;margin:0.8rem 0">
<button class="btn" onclick="screenDismissLock()">Dismiss Lock</button>
<button class="btn btn-warning" onclick="screenDisableLock()">Disable Lock</button>
<button class="btn btn-warning" onclick="screenKeylogStart()">Start Keylogger</button>
<button class="btn" onclick="screenKeylogStop()">Stop & Pull Keylog</button>
</div>
</div>
<div class="card output-panel" id="screen-output" style="padding:1rem;max-height:400px;overflow-y:auto">
<pre style="margin:0;white-space:pre-wrap;font-size:0.85rem">Ready for screen/input operations...</pre>
</div>
</div>
<!-- ── Advanced Tab ── -->
<div class="tab-panel" id="tab-advanced" style="display:none">
<div class="card" style="padding:1rem;margin-bottom:1rem">
<h3>Advanced Exploits</h3>
<!-- Data Exfil -->
<div style="margin:0.8rem 0;padding:0.8rem;background:var(--bg-secondary);border-radius:4px">
<strong>Data Exfiltration</strong>
<div style="display:flex;gap:0.5rem;flex-wrap:wrap;margin-top:0.5rem">
<button class="btn" onclick="advClipboard()">Clipboard</button>
<button class="btn" onclick="advNotifications()">Notifications</button>
<button class="btn" onclick="advLocation()">Location</button>
<button class="btn" onclick="advFingerprint()">Fingerprint</button>
<button class="btn" onclick="advSettings()">Dump Settings</button>
</div>
<div style="display:flex;gap:0.5rem;flex-wrap:wrap;align-items:end;margin-top:0.5rem">
<div>
<label style="font-size:0.85rem">Media type:</label>
<select id="adv-media-type" style="padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
<option value="photos">Photos</option>
<option value="downloads">Downloads</option>
<option value="screenshots">Screenshots</option>
<option value="whatsapp_media">WhatsApp Media</option>
</select>
</div>
<button class="btn" onclick="advMediaList()">List Media</button>
<div>
<label style="font-size:0.85rem">Limit:</label>
<input type="number" id="adv-media-limit" value="50" style="width:60px;padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
</div>
<button class="btn btn-warning" onclick="advMediaPull()">Pull Media</button>
</div>
<div style="display:flex;gap:0.5rem;flex-wrap:wrap;margin-top:0.5rem">
<button class="btn btn-warning" onclick="advWhatsapp()">WhatsApp DB [ROOT]</button>
<button class="btn btn-warning" onclick="advTelegram()">Telegram DB [ROOT]</button>
<button class="btn btn-warning" onclick="advSignal()">Signal DB [ROOT]</button>
</div>
</div>
<!-- Network -->
<div style="margin:0.8rem 0;padding:0.8rem;background:var(--bg-secondary);border-radius:4px">
<strong>Network</strong>
<div style="display:flex;gap:0.5rem;flex-wrap:wrap;margin-top:0.5rem">
<button class="btn" onclick="advNetInfo()">Network Info</button>
<button class="btn" onclick="advWifiScan()">WiFi Scan</button>
<button class="btn" onclick="advProxyClear()">Clear Proxy</button>
</div>
<div style="display:flex;gap:0.5rem;flex-wrap:wrap;align-items:end;margin-top:0.5rem">
<div>
<label style="font-size:0.85rem">Proxy host:</label>
<input type="text" id="adv-proxy-host" placeholder="192.168.1.100" style="width:130px;padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
</div>
<div>
<label style="font-size:0.85rem">Port:</label>
<input type="text" id="adv-proxy-port" placeholder="8080" style="width:70px;padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
</div>
<button class="btn" onclick="advProxySet()">Set Proxy (MITM)</button>
</div>
<div style="display:flex;gap:0.5rem;flex-wrap:wrap;align-items:end;margin-top:0.5rem">
<div>
<label style="font-size:0.85rem">SSID:</label>
<input type="text" id="adv-wifi-ssid" style="width:130px;padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
</div>
<div>
<label style="font-size:0.85rem">Password:</label>
<input type="text" id="adv-wifi-pass" style="width:130px;padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
</div>
<button class="btn" onclick="advWifiConnect()">WiFi Connect</button>
</div>
<div style="display:flex;gap:0.5rem;flex-wrap:wrap;align-items:end;margin-top:0.5rem">
<div>
<label style="font-size:0.85rem">ADB WiFi port:</label>
<input type="number" id="adv-adb-port" value="5555" style="width:70px;padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
</div>
<button class="btn" onclick="advAdbWifi()">ADB over WiFi</button>
<div>
<label style="font-size:0.85rem">Capture (s):</label>
<input type="number" id="adv-cap-dur" value="30" style="width:60px;padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
</div>
<button class="btn btn-warning" onclick="advCapture()">Capture Traffic [ROOT]</button>
</div>
</div>
<!-- App Control -->
<div style="margin:0.8rem 0;padding:0.8rem;background:var(--bg-secondary);border-radius:4px">
<strong>App Control</strong>
<div style="display:flex;gap:0.5rem;flex-wrap:wrap;align-items:end;margin-top:0.5rem">
<div>
<label style="font-size:0.85rem">Package:</label>
<input type="text" id="adv-pkg" placeholder="com.example.app" style="width:220px;padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
</div>
<button class="btn" onclick="advAppLaunch()">Launch</button>
<button class="btn btn-warning" onclick="advAppDisable()">Disable</button>
<button class="btn" onclick="advAppEnable()">Enable</button>
<button class="btn btn-danger" onclick="advAppClear()">Clear Data</button>
</div>
</div>
<!-- System -->
<div style="margin:0.8rem 0;padding:0.8rem;background:var(--bg-secondary);border-radius:4px">
<strong>System</strong>
<div style="display:flex;gap:0.5rem;flex-wrap:wrap;margin-top:0.5rem">
<button class="btn btn-warning" onclick="advSelinux()">SELinux Permissive [ROOT]</button>
<button class="btn btn-warning" onclick="advRemount()">Remount /system [ROOT]</button>
<button class="btn" onclick="advProcesses()">Processes</button>
<button class="btn" onclick="advPorts()">Open Ports</button>
</div>
<div style="display:flex;gap:0.5rem;flex-wrap:wrap;align-items:end;margin-top:0.5rem">
<div>
<label style="font-size:0.85rem">Logcat scan (s):</label>
<input type="number" id="adv-logcat-dur" value="10" style="width:60px;padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
</div>
<button class="btn" onclick="advLogcat()">Logcat Sensitive Data</button>
</div>
<div style="display:flex;gap:0.5rem;flex-wrap:wrap;align-items:end;margin-top:0.5rem">
<div>
<label style="font-size:0.85rem">Namespace:</label>
<select id="adv-set-ns" style="padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
<option value="system">system</option>
<option value="secure">secure</option>
<option value="global">global</option>
</select>
</div>
<div>
<label style="font-size:0.85rem">Key:</label>
<input type="text" id="adv-set-key" style="width:150px;padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
</div>
<div>
<label style="font-size:0.85rem">Value:</label>
<input type="text" id="adv-set-val" style="width:100px;padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
</div>
<button class="btn btn-warning" onclick="advModifySetting()">Modify Setting</button>
</div>
<!-- Content Query -->
<div style="display:flex;gap:0.5rem;flex-wrap:wrap;align-items:end;margin-top:0.5rem">
<div>
<label style="font-size:0.85rem">Content URI:</label>
<input type="text" id="adv-cq-uri" placeholder="content://sms/" style="width:250px;padding:0.4rem;background:var(--bg-primary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:4px">
</div>
<button class="btn" onclick="advContentQuery()">Content Query</button>
</div>
</div>
</div>
<div class="card output-panel" id="adv-output" style="padding:1rem;max-height:400px;overflow-y:auto">
<pre style="margin:0;white-space:pre-wrap;font-size:0.85rem">Ready for advanced operations...</pre>
</div>
</div>
<style>
.tab-btn{padding:0.6rem 1.2rem;background:none;border:none;color:var(--text-secondary);cursor:pointer;font-size:0.95rem;border-bottom:2px solid transparent;margin-bottom:-2px}
.tab-btn.active{color:var(--accent-primary);border-bottom-color:var(--accent-primary);font-weight:600}
.tab-btn:hover{color:var(--text-primary)}
.btn-warning{background:#a85;}
.btn-danger{background:#a44;}
.btn-warning:hover{background:#b96;}
.btn-danger:hover{background:#b55;}
.output-panel pre{color:var(--text-secondary)}
</style>
<script>
const API = '/android-exploit';
let currentSerial = '';
function switchTab(name, btn) {
document.querySelectorAll('.tab-panel').forEach(p => p.style.display = 'none');
document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active'));
document.getElementById('tab-' + name).style.display = '';
btn.classList.add('active');
}
function getSerial() {
if (hwConnectionMode === 'direct') {
if (!HWDirect.adbIsConnected()) { alert('Connect a device first (Direct mode)'); return null; }
return '__webusb__';
}
currentSerial = document.getElementById('device-select').value;
if (!currentSerial) { alert('Select a device first'); return null; }
return currentSerial;
}
function out(panel, html) {
document.querySelector('#' + panel + ' pre').innerHTML = html;
}
function outJson(panel, data) {
out(panel, escHtml(JSON.stringify(data, null, 2)));
}
function escHtml(s) {
return s.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
}
async function api(endpoint, body, panel) {
out(panel, 'Working...');
try {
if (hwConnectionMode === 'direct') {
return await apiDirect(endpoint, body, panel);
}
const res = await fetch(API + endpoint, {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(body)
});
const data = await res.json();
outJson(panel, data);
return data;
} catch(e) {
out(panel, 'Error: ' + escHtml(e.message));
return null;
}
}
async function apiDirect(endpoint, body, panel) {
if (!HWDirect.adbIsConnected()) {
out(panel, 'Error: No WebUSB device connected. Click Connect first.');
return null;
}
// Step 1: ask server what command(s) to run
let cmdData;
try {
const r = await fetch(API + '/cmd', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({op: endpoint, params: body})
});
cmdData = await r.json();
} catch(e) {
out(panel, 'Error fetching command: ' + escHtml(e.message));
return null;
}
if (cmdData.error) { out(panel, 'Error: ' + escHtml(cmdData.error)); return null; }
let rawOutput = '';
if (cmdData.pullPath) {
// File pull — download blob directly to browser
out(panel, 'Pulling file via WebUSB...');
try {
const blob = await HWDirect.adbPull(cmdData.pullPath);
const filename = cmdData.pullPath.split('/').pop();
HWDirect.downloadBlob(blob, filename);
rawOutput = 'Pulled: ' + cmdData.pullPath + ' (' + blob.size + ' bytes)';
} catch(e) {
out(panel, 'Pull failed: ' + escHtml(e.message));
return null;
}
} else {
// Shell command(s)
const cmds = cmdData.commands || [];
out(panel, 'Running ' + cmds.length + ' command(s) via WebUSB...');
for (const cmd of cmds) {
try {
const r = await HWDirect.adbShell(cmd);
rawOutput += (r.stdout || r.output || '') + '\n';
} catch(e) {
rawOutput += '[error: ' + e.message + ']\n';
}
}
}
// Step 2: parse output on server
try {
const parseRes = await fetch(API + '/parse', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({op: endpoint, params: body, raw: rawOutput})
});
const result = await parseRes.json();
outJson(panel, result);
return result;
} catch(e) {
// Fallback: show raw output
out(panel, escHtml(rawOutput));
return {output: rawOutput};
}
}
async function apiForm(endpoint, formData, panel) {
out(panel, 'Uploading...');
try {
const res = await fetch(API + endpoint, {method:'POST', body: formData});
const data = await res.json();
outJson(panel, data);
return data;
} catch(e) {
out(panel, 'Error: ' + escHtml(e.message));
return null;
}
}
async function refreshDevices() {
if (hwConnectionMode === 'direct') {
aeUpdateDirectStatus();
return;
}
try {
const res = await fetch('/hardware/adb/devices');
const data = await res.json();
const sel = document.getElementById('device-select');
const prev = sel.value;
sel.innerHTML = '<option value="">-- Select --</option>';
(data.devices || []).forEach(d => {
const opt = document.createElement('option');
opt.value = d.serial;
opt.textContent = d.serial + (d.model ? ' (' + d.model + ')' : '') + ' [' + d.state + ']';
sel.appendChild(opt);
});
document.getElementById('device-count').textContent = (data.devices || []).length;
if (prev) sel.value = prev;
} catch(e) {
console.error('Device refresh failed:', e);
}
}
// ── ADB Mode Management ──────────────────────────────────────────
function aeSetMode(mode) {
hwConnectionMode = mode;
localStorage.setItem('hw_connection_mode', mode);
document.getElementById('ae-mode-server').classList.toggle('active', mode === 'server');
document.getElementById('ae-mode-direct').classList.toggle('active', mode === 'direct');
document.getElementById('ae-direct-bar').style.display = mode === 'direct' ? 'flex' : 'none';
document.getElementById('ae-server-selector').style.display = mode === 'server' ? '' : 'none';
if (mode === 'direct') {
const warn = document.getElementById('ae-webusb-warning');
if (!navigator.usb) {
warn.textContent = location.protocol !== 'https:'
? 'WebUSB requires HTTPS — enable it in autarch_settings.conf'
: 'WebUSB not supported — requires Chrome, Edge, or Brave';
warn.style.display = '';
} else {
warn.style.display = 'none';
}
aeUpdateDirectStatus();
document.getElementById('device-count').textContent = HWDirect.adbIsConnected() ? '1 (direct)' : '0';
} else {
refreshDevices();
}
}
async function aeDirectConnect() {
const lbl = document.getElementById('ae-device-label');
lbl.textContent = 'Connecting...';
try {
const deviceObj = await HWDirect.adbRequestDevice();
if (!deviceObj) { lbl.textContent = 'Cancelled'; return; }
await HWDirect.adbConnect(deviceObj);
aeUpdateDirectStatus();
// Prefetch device info for label
HWDirect.adbGetInfo().then(function() { aeUpdateDirectStatus(); }).catch(function(){});
} catch(e) {
lbl.textContent = 'Error: ' + e.message;
}
}
function aeDirectDisconnect() {
HWDirect.adbDisconnect();
aeUpdateDirectStatus();
document.getElementById('device-count').textContent = '0';
}
function aeUpdateDirectStatus() {
const connected = HWDirect.adbIsConnected();
document.getElementById('ae-device-label').textContent = connected ? HWDirect.adbGetDeviceLabel() : 'Not connected';
document.getElementById('ae-disconnect-btn').style.display = connected ? '' : 'none';
if (connected) document.getElementById('device-count').textContent = '1 (direct)';
}
// ── Apps ──
function appsList() {
const s = getSerial(); if (!s) return;
api('/apps/list', {serial: s, include_system: document.getElementById('apps-system').checked}, 'apps-output');
}
function appsPullApk() {
const s = getSerial(); if (!s) return;
const pkg = document.getElementById('apps-pkg').value.trim();
if (!pkg) { alert('Enter package name'); return; }
api('/apps/pull-apk', {serial: s, package: pkg}, 'apps-output');
}
function appsPullData() {
const s = getSerial(); if (!s) return;
const pkg = document.getElementById('apps-pkg').value.trim();
if (!pkg) { alert('Enter package name'); return; }
api('/apps/pull-data', {serial: s, package: pkg}, 'apps-output');
}
function appsSharedPrefs() {
const s = getSerial(); if (!s) return;
const pkg = document.getElementById('apps-pkg').value.trim();
if (!pkg) { alert('Enter package name'); return; }
api('/apps/shared-prefs', {serial: s, package: pkg}, 'apps-output');
}
// ── Recon ──
function reconDump() { const s=getSerial();if(!s)return; api('/recon/device-dump',{serial:s},'recon-output'); }
function reconAccounts() { const s=getSerial();if(!s)return; api('/recon/accounts',{serial:s},'recon-output'); }
function reconWifi() { const s=getSerial();if(!s)return; api('/recon/wifi',{serial:s},'recon-output'); }
function reconCalls() { const s=getSerial();if(!s)return; api('/recon/calls',{serial:s},'recon-output'); }
function reconSms() { const s=getSerial();if(!s)return; api('/recon/sms',{serial:s},'recon-output'); }
function reconContacts() { const s=getSerial();if(!s)return; api('/recon/contacts',{serial:s},'recon-output'); }
function reconBrowser() { const s=getSerial();if(!s)return; api('/recon/browser',{serial:s},'recon-output'); }
function reconCreds() { const s=getSerial();if(!s)return; api('/recon/credentials',{serial:s},'recon-output'); }
function reconExport() { const s=getSerial();if(!s)return; api('/recon/export',{serial:s},'recon-output'); }
// ── Payloads ──
function payloadDeploy() {
const s = getSerial(); if (!s) return;
const file = document.getElementById('deploy-file').files[0];
if (!file) { alert('Select a file'); return; }
const fd = new FormData();
fd.append('serial', s);
fd.append('remote_path', document.getElementById('deploy-remote').value);
fd.append('file', file);
apiForm('/payload/deploy', fd, 'payload-output');
}
function payloadExec() {
const s = getSerial(); if (!s) return;
api('/payload/execute', {
serial: s,
remote_path: document.getElementById('exec-path').value.trim(),
args: document.getElementById('exec-args').value,
background: document.getElementById('exec-bg').checked
}, 'payload-output');
}
function payloadReverseShell() {
const s = getSerial(); if (!s) return;
api('/payload/reverse-shell', {
serial: s,
lhost: document.getElementById('rshell-host').value.trim(),
lport: document.getElementById('rshell-port').value.trim(),
method: document.getElementById('rshell-method').value
}, 'payload-output');
}
function payloadPersistence() {
const s = getSerial(); if (!s) return;
if (!confirm('Install persistence? Requires root.')) return;
api('/payload/persistence', {serial: s, method: 'init.d'}, 'payload-output');
}
function payloadListRunning() {
const s = getSerial(); if (!s) return;
api('/payload/list', {serial: s}, 'payload-output');
}
function payloadKill() {
const s = getSerial(); if (!s) return;
const pid = document.getElementById('kill-pid').value.trim();
if (!pid) { alert('Enter PID'); return; }
api('/payload/kill', {serial: s, pid: pid}, 'payload-output');
}
// ── Boot ──
function bootInfo() { const s=getSerial();if(!s)return; api('/boot/info',{serial:s},'boot-output'); }
function bootBackup() { const s=getSerial();if(!s)return; api('/boot/backup',{serial:s},'boot-output'); }
function bootUnlock() {
const s=getSerial();if(!s)return;
if(!confirm('UNLOCK BOOTLOADER?\nThis will WIPE ALL DATA on the device!\nAre you sure?'))return;
api('/boot/unlock',{serial:s},'boot-output');
}
function _bootUpload(endpoint) {
const s = getSerial(); if (!s) return;
const file = document.getElementById('boot-file').files[0];
if (!file) { alert('Select an image file'); return; }
const fd = new FormData();
fd.append('serial', s);
fd.append('file', file);
apiForm(endpoint, fd, 'boot-output');
}
function bootFlashRecovery() { _bootUpload('/boot/flash-recovery'); }
function bootFlashBoot() { _bootUpload('/boot/flash-boot'); }
function bootTempBoot() { _bootUpload('/boot/temp-boot'); }
function bootDisableVerity() {
const s = getSerial(); if (!s) return;
const file = document.getElementById('verity-file').files[0];
if (file) {
const fd = new FormData();
fd.append('serial', s);
fd.append('file', file);
apiForm('/boot/disable-verity', fd, 'boot-output');
} else {
api('/boot/disable-verity', {serial: s}, 'boot-output');
}
}
// ── Root ──
function rootCheck() {
const s=getSerial();if(!s)return;
api('/root/check',{serial:s},'root-output').then(data => {
if(data) document.getElementById('root-status').textContent = data.rooted ? 'YES ('+data.method+')' : 'No';
});
}
function rootAdbRoot() {
const s=getSerial();if(!s)return;
// adb root is on the hardware manager directly
fetch('/hardware/adb/shell', {
method:'POST',
headers:{'Content-Type':'application/json'},
body:JSON.stringify({serial:s,command:'id'})
}).then(r=>r.json()).then(d=>{
// Actually use the exploit manager
api('/root/check',{serial:s},'root-output');
});
// Call the actual adb root endpoint via raw shell
api('/root/check',{serial:s},'root-output');
}
function rootPullPatched() { const s=getSerial();if(!s)return; api('/root/pull-patched',{serial:s},'root-output'); }
function rootInstallMagisk() {
const s = getSerial(); if (!s) return;
const file = document.getElementById('magisk-file').files[0];
if (!file) { alert('Select Magisk APK'); return; }
const fd = new FormData();
fd.append('serial', s);
fd.append('file', file);
apiForm('/root/install-magisk', fd, 'root-output');
}
function rootExploit() {
const s = getSerial(); if (!s) return;
const file = document.getElementById('exploit-file').files[0];
if (!file) { alert('Select exploit binary'); return; }
if (!confirm('Run root exploit on device?')) return;
const fd = new FormData();
fd.append('serial', s);
fd.append('file', file);
apiForm('/root/exploit', fd, 'root-output');
}
// ── SMS ──
function smsList() {
const s=getSerial();if(!s)return;
api('/sms/list', {
serial: s,
limit: parseInt(document.getElementById('sms-limit').value) || 50,
address: document.getElementById('sms-filter-addr').value.trim()
}, 'sms-output');
}
function smsInsert() {
const s=getSerial();if(!s)return;
const addr = document.getElementById('sms-addr').value.trim();
const body = document.getElementById('sms-body').value.trim();
if (!addr || !body) { alert('Enter phone number and message body'); return; }
const payload = {serial: s, address: addr, body: body,
type: document.getElementById('sms-type').value,
read: document.getElementById('sms-read').checked};
const d = document.getElementById('sms-date').value;
const t = document.getElementById('sms-time').value;
if (d) payload.date = d;
if (t) payload.time = t;
api('/sms/insert', payload, 'sms-output');
}
function smsUpdate() {
const s=getSerial();if(!s)return;
const id = document.getElementById('sms-edit-id').value.trim();
if (!id) { alert('Enter SMS ID'); return; }
const payload = {serial: s, id: id};
const b = document.getElementById('sms-edit-body').value.trim();
const d = document.getElementById('sms-edit-date').value;
const t = document.getElementById('sms-edit-time').value;
if (b) payload.body = b;
if (d) payload.date = d;
if (t) payload.time = t;
api('/sms/update', payload, 'sms-output');
}
function smsDeleteById() {
const s=getSerial();if(!s)return;
const id = document.getElementById('sms-del-id').value.trim();
if (!id) { alert('Enter SMS ID'); return; }
api('/sms/delete', {serial: s, id: id}, 'sms-output');
}
function smsDeleteByAddr() {
const s=getSerial();if(!s)return;
const addr = document.getElementById('sms-del-addr').value.trim();
if (!addr) { alert('Enter phone number'); return; }
if (!confirm('Delete ALL SMS from ' + addr + '?')) return;
api('/sms/delete', {serial: s, address: addr, delete_all_from: true}, 'sms-output');
}
function smsDeleteAll() {
const s=getSerial();if(!s)return;
if (!confirm('DELETE ALL SMS on device? This cannot be undone!')) return;
api('/sms/delete-all', {serial: s}, 'sms-output');
}
// ── RCS ──
function rcsCheck() {
const s=getSerial();if(!s)return;
api('/rcs/check', {serial: s}, 'sms-output');
}
function rcsList() {
const s=getSerial();if(!s)return;
api('/rcs/list', {serial: s, limit: parseInt(document.getElementById('sms-limit').value) || 50}, 'sms-output');
}
function rcsInsert() {
const s=getSerial();if(!s)return;
const addr = document.getElementById('rcs-addr').value.trim();
const body = document.getElementById('rcs-body').value.trim();
if (!addr || !body) { alert('Enter phone number and message body'); return; }
const payload = {serial: s, address: addr, body: body,
is_outgoing: document.getElementById('rcs-dir').value === 'outgoing'};
const sn = document.getElementById('rcs-sender').value.trim();
const d = document.getElementById('rcs-date').value;
const t = document.getElementById('rcs-time').value;
if (sn) payload.sender_name = sn;
if (d) payload.date = d;
if (t) payload.time = t;
api('/rcs/insert', payload, 'sms-output');
}
function rcsDelete() {
const s=getSerial();if(!s)return;
const id = document.getElementById('rcs-del-id').value.trim();
if (!id) { alert('Enter RCS message ID'); return; }
if (!confirm('Delete RCS message #' + id + '?')) return;
api('/rcs/delete', {serial: s, id: id}, 'sms-output');
}
// ── Screen ──
function screenCapture() { const s=getSerial();if(!s)return; api('/screen/capture',{serial:s},'screen-output'); }
function screenRecord() {
const s=getSerial();if(!s)return;
const dur = parseInt(document.getElementById('screen-rec-dur').value) || 10;
api('/screen/record',{serial:s, duration:dur},'screen-output');
}
function screenTap() {
const s=getSerial();if(!s)return;
api('/screen/tap',{serial:s, x:parseInt(document.getElementById('tap-x').value)||0, y:parseInt(document.getElementById('tap-y').value)||0},'screen-output');
}
function screenSwipe() {
const s=getSerial();if(!s)return;
api('/screen/swipe',{serial:s,
x1:parseInt(document.getElementById('swipe-x1').value)||0,
y1:parseInt(document.getElementById('swipe-y1').value)||0,
x2:parseInt(document.getElementById('swipe-x2').value)||0,
y2:parseInt(document.getElementById('swipe-y2').value)||0},'screen-output');
}
function screenText() {
const s=getSerial();if(!s)return;
const t = document.getElementById('input-text').value;
if(!t){alert('Enter text');return;}
api('/screen/text',{serial:s, text:t},'screen-output');
}
function screenKey() {
const s=getSerial();if(!s)return;
const k = document.getElementById('input-key').value.trim();
if(!k){alert('Enter keycode');return;}
api('/screen/key',{serial:s, keycode:k},'screen-output');
}
function screenDismissLock() { const s=getSerial();if(!s)return; api('/screen/dismiss-lock',{serial:s},'screen-output'); }
function screenDisableLock() { const s=getSerial();if(!s)return; api('/screen/disable-lock',{serial:s},'screen-output'); }
function screenKeylogStart() { const s=getSerial();if(!s)return; api('/screen/keylogger-start',{serial:s},'screen-output'); }
function screenKeylogStop() { const s=getSerial();if(!s)return; api('/screen/keylogger-stop',{serial:s},'screen-output'); }
// ── Advanced ──
function advClipboard() { const s=getSerial();if(!s)return; api('/adv/clipboard',{serial:s},'adv-output'); }
function advNotifications() { const s=getSerial();if(!s)return; api('/adv/notifications',{serial:s},'adv-output'); }
function advLocation() { const s=getSerial();if(!s)return; api('/adv/location',{serial:s},'adv-output'); }
function advFingerprint() { const s=getSerial();if(!s)return; api('/adv/fingerprint',{serial:s},'adv-output'); }
function advSettings() { const s=getSerial();if(!s)return; api('/adv/settings',{serial:s},'adv-output'); }
function advMediaList() {
const s=getSerial();if(!s)return;
api('/adv/media-list',{serial:s, type:document.getElementById('adv-media-type').value},'adv-output');
}
function advMediaPull() {
const s=getSerial();if(!s)return;
api('/adv/media-pull',{serial:s, type:document.getElementById('adv-media-type').value,
limit:parseInt(document.getElementById('adv-media-limit').value)||50},'adv-output');
}
function advWhatsapp() { const s=getSerial();if(!s)return; api('/adv/whatsapp',{serial:s},'adv-output'); }
function advTelegram() { const s=getSerial();if(!s)return; api('/adv/telegram',{serial:s},'adv-output'); }
function advSignal() { const s=getSerial();if(!s)return; api('/adv/signal',{serial:s},'adv-output'); }
function advNetInfo() { const s=getSerial();if(!s)return; api('/adv/network-info',{serial:s},'adv-output'); }
function advWifiScan() { const s=getSerial();if(!s)return; api('/adv/wifi-scan',{serial:s},'adv-output'); }
function advProxyClear() { const s=getSerial();if(!s)return; api('/adv/proxy-clear',{serial:s},'adv-output'); }
function advProxySet() {
const s=getSerial();if(!s)return;
api('/adv/proxy-set',{serial:s, host:document.getElementById('adv-proxy-host').value.trim(),
port:document.getElementById('adv-proxy-port').value.trim()},'adv-output');
}
function advWifiConnect() {
const s=getSerial();if(!s)return;
api('/adv/wifi-connect',{serial:s, ssid:document.getElementById('adv-wifi-ssid').value.trim(),
password:document.getElementById('adv-wifi-pass').value},'adv-output');
}
function advAdbWifi() {
const s=getSerial();if(!s)return;
api('/adv/adb-wifi',{serial:s, port:parseInt(document.getElementById('adv-adb-port').value)||5555},'adv-output');
}
function advCapture() {
const s=getSerial();if(!s)return;
api('/adv/capture-traffic',{serial:s, duration:parseInt(document.getElementById('adv-cap-dur').value)||30},'adv-output');
}
function advAppLaunch() {
const s=getSerial();if(!s)return;
const p=document.getElementById('adv-pkg').value.trim();if(!p){alert('Enter package');return;}
api('/adv/app-launch',{serial:s, package:p},'adv-output');
}
function advAppDisable() {
const s=getSerial();if(!s)return;
const p=document.getElementById('adv-pkg').value.trim();if(!p){alert('Enter package');return;}
api('/adv/app-disable',{serial:s, package:p},'adv-output');
}
function advAppEnable() {
const s=getSerial();if(!s)return;
const p=document.getElementById('adv-pkg').value.trim();if(!p){alert('Enter package');return;}
api('/adv/app-enable',{serial:s, package:p},'adv-output');
}
function advAppClear() {
const s=getSerial();if(!s)return;
const p=document.getElementById('adv-pkg').value.trim();if(!p){alert('Enter package');return;}
if(!confirm('Clear ALL data for '+p+'?'))return;
api('/adv/app-clear',{serial:s, package:p},'adv-output');
}
function advSelinux() { const s=getSerial();if(!s)return; api('/adv/selinux',{serial:s, mode:'permissive'},'adv-output'); }
function advRemount() { const s=getSerial();if(!s)return; api('/adv/remount',{serial:s},'adv-output'); }
function advProcesses() { const s=getSerial();if(!s)return; api('/adv/processes',{serial:s},'adv-output'); }
function advPorts() { const s=getSerial();if(!s)return; api('/adv/ports',{serial:s},'adv-output'); }
function advLogcat() {
const s=getSerial();if(!s)return;
api('/adv/logcat-sensitive',{serial:s, duration:parseInt(document.getElementById('adv-logcat-dur').value)||10},'adv-output');
}
function advModifySetting() {
const s=getSerial();if(!s)return;
const ns=document.getElementById('adv-set-ns').value;
const key=document.getElementById('adv-set-key').value.trim();
const val=document.getElementById('adv-set-val').value.trim();
if(!key){alert('Enter key');return;}
api('/adv/modify-setting',{serial:s, namespace:ns, key:key, value:val},'adv-output');
}
function advContentQuery() {
const s=getSerial();if(!s)return;
const uri=document.getElementById('adv-cq-uri').value.trim();
if(!uri){alert('Enter content URI');return;}
api('/adv/content-query',{serial:s, uri:uri},'adv-output');
}
// Init
document.addEventListener('DOMContentLoaded', function() {
const saved = localStorage.getItem('hw_connection_mode') || 'server';
aeSetMode(saved);
});
</script>
{% endblock %}