Autarch/web/templates/rfid_tools.html
DigiJ 2322f69516 v2.2.0 — Full arsenal expansion: 16 new security modules
Add WiFi Audit, API Fuzzer, Cloud Scanner, Threat Intel, Log Correlator,
Steganography, Anti-Forensics, BLE Scanner, Forensics, RFID/NFC, Malware
Sandbox, Password Toolkit, Web Scanner, Report Engine, Net Mapper, and
C2 Framework. Each module includes CLI interface, Flask routes, and web
UI template. Also includes Go DNS server source + binary, IP Capture
service, SYN Flood, Gone Fishing mail server, and hack hijack modules
from v2.0 work.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 05:20:39 -08:00

287 lines
11 KiB
HTML

{% extends "base.html" %}
{% block title %}AUTARCH — RFID/NFC Tools{% endblock %}
{% block content %}
<div class="page-header">
<h1>RFID/NFC Tools</h1>
<p style="margin:0;font-size:0.85rem;color:var(--text-secondary)">
Proxmark3 interface for RFID/NFC scanning, cloning, and card management.
</p>
</div>
<!-- Tab Bar -->
<div class="tab-bar">
<button class="tab active" data-tab-group="rfid" data-tab="scan" onclick="showTab('rfid','scan')">Scan</button>
<button class="tab" data-tab-group="rfid" data-tab="clone" onclick="showTab('rfid','clone')">Clone</button>
<button class="tab" data-tab-group="rfid" data-tab="cards" onclick="showTab('rfid','cards')">Cards</button>
</div>
<!-- ==================== SCAN TAB ==================== -->
<div class="tab-content active" data-tab-group="rfid" data-tab="scan">
<div class="section">
<h2>Tools Status</h2>
<div class="stats-grid" style="grid-template-columns:repeat(auto-fit,minmax(140px,1fr))">
<div class="stat-card">
<div class="stat-label">Proxmark3</div>
<div class="stat-value small">
<span class="status-dot" id="rfid-pm3-dot"></span>
<span id="rfid-pm3-status">Checking...</span>
</div>
</div>
<div class="stat-card">
<div class="stat-label">libnfc</div>
<div class="stat-value small">
<span class="status-dot" id="rfid-libnfc-dot"></span>
<span id="rfid-libnfc-status">Checking...</span>
</div>
</div>
</div>
</div>
<div class="section">
<h2>Scan for Cards</h2>
<div class="tool-actions" style="margin-bottom:12px">
<button id="btn-lf-search" class="btn btn-primary" onclick="rfidLFSearch()">LF Search (125kHz)</button>
<button id="btn-hf-search" class="btn btn-primary" onclick="rfidHFSearch()">HF Search (13.56MHz)</button>
<button id="btn-nfc-scan" class="btn btn-primary" onclick="rfidNFCScan()">NFC Scan</button>
</div>
<pre class="output-panel scrollable" id="rfid-scan-output" style="max-height:250px"></pre>
</div>
<div class="section">
<h2>Last Read Card</h2>
<table class="data-table" style="max-width:500px">
<tbody>
<tr><td>Type</td><td id="rfid-last-type">--</td></tr>
<tr><td>ID / UID</td><td id="rfid-last-id" style="font-family:monospace">--</td></tr>
<tr><td>Frequency</td><td id="rfid-last-freq">--</td></tr>
<tr><td>Technology</td><td id="rfid-last-tech">--</td></tr>
</tbody>
</table>
</div>
</div>
<!-- ==================== CLONE TAB ==================== -->
<div class="tab-content" data-tab-group="rfid" data-tab="clone">
<div class="section">
<h2>EM410x Clone</h2>
<p style="font-size:0.8rem;color:var(--text-muted);margin-bottom:8px">
Clone an EM410x LF card by writing a known card ID to a T55x7 blank.
</p>
<div class="input-row">
<input type="text" id="rfid-em-id" placeholder="Card ID (hex, e.g. 0102030405)" maxlength="10">
<button id="btn-em-clone" class="btn btn-primary" onclick="rfidEMClone()">Clone EM410x</button>
</div>
<pre class="output-panel" id="rfid-em-output" style="min-height:0"></pre>
</div>
<div class="section">
<h2>MIFARE Classic</h2>
<div class="tool-actions" style="margin-bottom:12px">
<button id="btn-mf-dump" class="btn btn-primary" onclick="rfidMFDump()">Dump MIFARE Card</button>
</div>
<pre class="output-panel" id="rfid-mf-dump-output" style="min-height:0"></pre>
<h3 style="margin-top:16px">Clone from Dump</h3>
<div class="input-row">
<input type="text" id="rfid-mf-dump-path" placeholder="Path to dump file (e.g. /tmp/card.mfd)">
<button id="btn-mf-clone" class="btn btn-primary" onclick="rfidMFClone()">Clone from Dump</button>
</div>
<pre class="output-panel" id="rfid-mf-clone-output" style="min-height:0"></pre>
<h3 style="margin-top:16px">Default Keys</h3>
<div class="output-panel" id="rfid-default-keys" style="font-family:monospace;font-size:0.8rem">
FFFFFFFFFFFF (factory default)<br>
A0A1A2A3A4A5 (MAD key)<br>
D3F7D3F7D3F7 (NFC NDEF)<br>
000000000000 (null key)<br>
B0B1B2B3B4B5 (common transport)<br>
4D3A99C351DD (Mifare Application Directory)
</div>
</div>
</div>
<!-- ==================== CARDS TAB ==================== -->
<div class="tab-content" data-tab-group="rfid" data-tab="cards">
<div class="section">
<h2>Saved Cards</h2>
<table class="data-table">
<thead><tr><th>Name</th><th>Type</th><th>ID / UID</th><th>Saved</th><th>Action</th></tr></thead>
<tbody id="rfid-cards-table">
<tr><td colspan="5" class="empty-state">No saved cards yet. Scan and save cards from the Scan tab.</td></tr>
</tbody>
</table>
</div>
<div class="section">
<h2>Card Dumps</h2>
<div class="tool-actions" style="margin-bottom:12px">
<button class="btn btn-small" onclick="rfidRefreshDumps()">Refresh</button>
</div>
<table class="data-table">
<thead><tr><th>Filename</th><th>Size</th><th>Date</th><th>Action</th></tr></thead>
<tbody id="rfid-dumps-table">
<tr><td colspan="4" class="empty-state">No dumps found.</td></tr>
</tbody>
</table>
</div>
</div>
<script>
function esc(s) { return String(s).replace(/&/g,'&amp;').replace(/</g,'&lt;'); }
/* ── Status ── */
function rfidCheckStatus() {
fetchJSON('/rfid/status').then(function(data) {
var pm3Dot = document.getElementById('rfid-pm3-dot');
var pm3Txt = document.getElementById('rfid-pm3-status');
var nfcDot = document.getElementById('rfid-libnfc-dot');
var nfcTxt = document.getElementById('rfid-libnfc-status');
if (pm3Dot) pm3Dot.className = 'status-dot ' + (data.proxmark3 ? 'active' : 'inactive');
if (pm3Txt) pm3Txt.textContent = data.proxmark3 ? 'Connected' : 'Not found';
if (nfcDot) nfcDot.className = 'status-dot ' + (data.libnfc ? 'active' : 'inactive');
if (nfcTxt) nfcTxt.textContent = data.libnfc ? 'Available' : 'Not installed';
}).catch(function() {
document.getElementById('rfid-pm3-status').textContent = 'Error';
document.getElementById('rfid-libnfc-status').textContent = 'Error';
});
}
/* ── Scan ── */
function rfidLFSearch() {
var btn = document.getElementById('btn-lf-search');
setLoading(btn, true);
postJSON('/rfid/scan', {mode: 'lf'}).then(function(data) {
setLoading(btn, false);
if (data.error) { renderOutput('rfid-scan-output', 'Error: ' + data.error); return; }
renderOutput('rfid-scan-output', data.output || 'No card detected.');
if (data.card) rfidUpdateLastCard(data.card);
}).catch(function() { setLoading(btn, false); });
}
function rfidHFSearch() {
var btn = document.getElementById('btn-hf-search');
setLoading(btn, true);
postJSON('/rfid/scan', {mode: 'hf'}).then(function(data) {
setLoading(btn, false);
if (data.error) { renderOutput('rfid-scan-output', 'Error: ' + data.error); return; }
renderOutput('rfid-scan-output', data.output || 'No card detected.');
if (data.card) rfidUpdateLastCard(data.card);
}).catch(function() { setLoading(btn, false); });
}
function rfidNFCScan() {
var btn = document.getElementById('btn-nfc-scan');
setLoading(btn, true);
postJSON('/rfid/scan', {mode: 'nfc'}).then(function(data) {
setLoading(btn, false);
if (data.error) { renderOutput('rfid-scan-output', 'Error: ' + data.error); return; }
renderOutput('rfid-scan-output', data.output || 'No NFC tag detected.');
if (data.card) rfidUpdateLastCard(data.card);
}).catch(function() { setLoading(btn, false); });
}
function rfidUpdateLastCard(card) {
document.getElementById('rfid-last-type').textContent = card.type || '--';
document.getElementById('rfid-last-id').textContent = card.id || '--';
document.getElementById('rfid-last-freq').textContent = card.frequency || '--';
document.getElementById('rfid-last-tech').textContent = card.technology || '--';
}
/* ── Clone ── */
function rfidEMClone() {
var id = document.getElementById('rfid-em-id').value.trim();
if (!id) return;
var btn = document.getElementById('btn-em-clone');
setLoading(btn, true);
postJSON('/rfid/clone/em410x', {card_id: id}).then(function(data) {
setLoading(btn, false);
renderOutput('rfid-em-output', data.message || data.error || 'Done');
}).catch(function() { setLoading(btn, false); });
}
function rfidMFDump() {
var btn = document.getElementById('btn-mf-dump');
setLoading(btn, true);
postJSON('/rfid/dump/mifare', {}).then(function(data) {
setLoading(btn, false);
renderOutput('rfid-mf-dump-output', data.output || data.error || 'No output');
}).catch(function() { setLoading(btn, false); });
}
function rfidMFClone() {
var path = document.getElementById('rfid-mf-dump-path').value.trim();
if (!path) return;
var btn = document.getElementById('btn-mf-clone');
setLoading(btn, true);
postJSON('/rfid/clone/mifare', {dump_path: path}).then(function(data) {
setLoading(btn, false);
renderOutput('rfid-mf-clone-output', data.message || data.error || 'Done');
}).catch(function() { setLoading(btn, false); });
}
/* ── Cards ── */
function rfidLoadCards() {
fetchJSON('/rfid/cards').then(function(data) {
var tb = document.getElementById('rfid-cards-table');
if (!data.cards || !data.cards.length) {
tb.innerHTML = '<tr><td colspan="5" class="empty-state">No saved cards yet.</td></tr>';
return;
}
var html = '';
data.cards.forEach(function(c) {
html += '<tr><td>' + esc(c.name) + '</td><td>' + esc(c.type) + '</td>'
+ '<td style="font-family:monospace">' + esc(c.id) + '</td>'
+ '<td>' + esc(c.saved_date) + '</td>'
+ '<td><button class="btn btn-danger btn-small" onclick="rfidDeleteCard(\'' + esc(c.id) + '\')">Delete</button></td></tr>';
});
tb.innerHTML = html;
});
}
function rfidDeleteCard(id) {
if (!confirm('Delete this saved card?')) return;
postJSON('/rfid/cards/delete', {id: id}).then(function(data) {
if (data.success) rfidLoadCards();
});
}
function rfidRefreshDumps() {
fetchJSON('/rfid/dumps').then(function(data) {
var tb = document.getElementById('rfid-dumps-table');
if (!data.dumps || !data.dumps.length) {
tb.innerHTML = '<tr><td colspan="4" class="empty-state">No dumps found.</td></tr>';
return;
}
var html = '';
data.dumps.forEach(function(d) {
html += '<tr><td>' + esc(d.filename) + '</td><td>' + esc(d.size) + '</td>'
+ '<td>' + esc(d.date) + '</td>'
+ '<td><button class="btn btn-danger btn-small" onclick="rfidDeleteDump(\'' + esc(d.filename) + '\')">Delete</button></td></tr>';
});
tb.innerHTML = html;
});
}
function rfidDeleteDump(filename) {
if (!confirm('Delete dump file "' + filename + '"?')) return;
postJSON('/rfid/dumps/delete', {filename: filename}).then(function(data) {
if (data.success) rfidRefreshDumps();
});
}
/* ── Init ── */
document.addEventListener('DOMContentLoaded', function() {
rfidCheckStatus();
rfidLoadCards();
rfidRefreshDumps();
});
</script>
{% endblock %}