Full command surface for Niel's Phreakbyte fork: standalone modes, device & slot management,
HF14A / MIFARE Classic, LF read/write/emulation, and MF0/NTAG emulation — all over Web Bluetooth.
Connect once, then switch tabs; every tab shares the same connection.
FirmwareStandaloneISO14443A / LFBLE
Author
Niel Nielsen
Platform
ChameleonUltra
Transport
Web Bluetooth
Commands
~90 wired
01Connection
Not connectedConnect once — every tab below shares this link.
Local onlyNot shared. No login: anyone with the join link gets full control.
02Device control
Connect to see whether the device is armed.
relay idle
Per-mode result (7011–7013)
GET_AVAILABLE greys out modes this build doesn't have compiled in. GET_RESULT_FOR / CLEAR_RESULT_FOR read or wipe a mode's stored log without first switching the active mode to it.
03Saved on device
Reads the device's own log (windows that have already closed), including ones from while this page was offline.
04Live events
No events yet. Press both buttons briefly on the device to send a test event.
Note
Needs Chrome or Edge on Android/desktop, or the Bluefy browser on iOS. The device allows one BLE connection, so close other Chameleon apps first. Alerts only arrive while this page stays open and connected; anything missed is still in the device log (standalone get-result).
D1Identity & status
D2Device mode
Lite ignores reader mode (not implemented on that hardware).
D3BLE name & pairing
D4Behaviour
D5Settings & power
Factory wipe and entering the bootloader are destructive / disruptive — both ask to confirm and will drop the BLE link.
D6Button actions & pairing requirement
"Required" means a BLE pairing key (see D3) must be supplied before a host can connect. Turning it off removes that check.
D7Debug log
Persistent debug log stored in flash, survives reboot. "Fetch full log text" pages through it 512 bytes at a time (LOG_READ) until it runs dry.
D8Flash diagnostics
A read on a protected or non-existent record fails the same way either way (no "protected" disclosure) — this fork deliberately hides the U2F master key / attestation private key records this way. "Read record" pages the whole thing in 240-byte slices.
S1Slot overview
S2Active slot
S3Slot type & enable
"Delete {sense} data in slot" wipes just the HF or LF tag data for that slot (per the Sense dropdown above) without touching the other sense or the slot's nickname — use it to clear a slot's old tag before reusing it with a different type.
The DESFire tab needs the active slot's HF type set to one of the DESFire types. On a slot that's never held DESFire data, "Set slot tag type" alone is not enough — the device only reloads existing flash data, and there is none yet. You also need this slot to be the active slot (Set active slot) before "Set slot data default", since that's the step that only writes live if the slot is already active. See DESFire tab → F0 for a one-click helper that does this in the right order.
S4Slot nickname
H1Field & scan
H2HF14A anticollision config
H3MF1 one-block auth / read / write
H4Key check (dictionary attack)
Checks a key list against one block, or against many sectors at once. Comes pre-filled with common/public default keys — add your own, one 12-hex-digit key per line.
H5Live reader-side auth trace
Full anticoll + Crypto1 AUTH against a real card, every frame returned — decoded the same way as the authtrace standalone mode.
H6Emulation data (active slot)
H7Anti-collision data (active slot)
H8Emulator behaviour & detection
When on, the emulated MF1 card's internal state (authentication, value-block session) resets whenever the reader's RF field drops — matches real card behaviour. Off keeps state across field drops.
H9Mfkey32 detection log
H10Raw ISO14443A bytes
Sends arbitrary bits to any 14A tag (card or reader-mode emulation), below the MF1/APDU layer. This is HF14A_RAW (not the DESFire tab's F4, which only talks to the active slot's own DESFire emulation).
H11MF1 value block (increment / decrement / restore)
Authenticates against a source block, runs the value-block operation, then (if different) authenticates the destination block and transfers the result into it. Source = destination is the common case (operate in place).
H12Magic auth (gen1a-style raw auth, reader mode)
Sends a raw backdoor auth command (e.g. 0x80 for GDM/gen1a magic cards) directly to the RC522, bypassing the normal MF1 authenticate flow. Ultra only — not available on Lite.
Low-level building block behind this fork's EMV/smartcard emulation profile: canned responses keyed off the incoming command bytes, plus manual anti-collision data (UID/ATQA/SAK/ATS) and a one-shot push/poll pair for a custom reader loop.
H14Key-recovery attacks (offline cracking)
Nonce acquisition only — the device collects what an offline tool (mfoc/mfcuk/proxmark3-style darkside/nested/hardnested crackers) needs; no crypto1 math runs here. Darkside/hardnested/enc-nested can run long on-device; their reply timeouts scale with the attack's own parameters instead of the usual fixed 6s.
H15ISO14443A sniff
Classic mode: the device emulates a tag and answers the reader itself — reader commands and the device's own emulated replies are both logged. Passive-tap mode: the device stays silent and listens in on a real card/reader exchange it's physically between.
L1Search / generic
L2EM410x
L3HID Prox
L4ioProx
L5Viking / PAC / Jablotron / Indala / IDTECK
L6FDX-B / EM4x05 / raw T55xx
L7Raw LF sniff
Raw 125kHz ADC samples, ~0x80 = field on. Passive mode keeps this device's own LF field off, for observing another active transmitter (e.g. another Chameleon emulating) without the two fields beating against each other.
Note
Records chip-select and field-LED edges and every RC522 register access while you run other commands. Arm it, switch to the HF tab and scan or read a card, come back and press Stop & show. The device must be in reader mode for HF activity. Zoom with the mouse wheel, drag to pan, double-click to reset.
G1Capture
M1Emulation pages (active slot)
M2UID magic mode, version & signature
Version/signature data lives on NTAG21x and MF0UL* chips only — "invalid slot type" means the active slot's tag type doesn't carry them (plain MF0ICU1, for instance).
M3Counters
M4Write mode & mfkey-style detection
M5Password-auth detection log
Every PWD_AUTH attempt against this slot (MF0UL/NTAG password auth) logs the 4-byte password tried — same idea as the MF1 mfkey32 log, for the password-protected UL/NTAG variants.
Note
The active slot's DESFire credential is an opaque .dfcb blob — apps, files and keys packed by chameleon_dfc.py. This tab backs it up/restores it as raw bytes and reads the device's own counters; it doesn't build a credential from scratch (use the CLI / chameleon_dfc.py for that and paste the result here).
F0Prepare a slot for DESFire
GET_INFO / GET_CREDENTIAL / FACTORY_BLANK act on a live in-RAM buffer, not on the slot's flash record directly. Set slot tag type alone only tries to reload that buffer from an existing flash record — on a slot that's never held DESFire data there is none yet, so the buffer stays empty and every DESFire command keeps returning PAR_ERR. Set slot data default writes the factory record to flash, but only reloads the live buffer immediately if the slot is already the active slot — otherwise the record sits on flash until the slot is activated. This button runs the three steps in the one order that always works: set tag type → make this the active slot → set slot data default (now live). Do this once per slot before using F1-F3 below.
F1Active slot info & stats
Factory blank re-initializes the active slot to an empty, emulatable DESFire card (random UID if none given) — this overwrites whatever credential is loaded. Run F0 above first if this slot has never held DESFire data.
F2Credential backup / restore
F3Reader mode (against a physical DESFire card)
F4Real card — raw command & auto-dump
Note
All of F3/F4 needs the device itself in Reader mode (Device tab → Device mode), not Tag/emulation mode — that's a separate requirement from the slot prep in F0, which only matters for the emulated side. Auto-dump only reads files whose comm_settings is plain (0x00, no secure messaging) and only applications/files the card lets you see without authenticating first — encrypted/MAC'd files and anything gated behind auth are reported, not read. This talks to native DESFire command bytes directly (dfc_command.c / dfc_common.h in the fork), wrapped as 90 INS 00 00 [Lc data] 00 over HF14A_4_READER_APDU.
Known limit:HF14A_4_READER_APDU re-selects the card (full antenna-off/reset/RATS) on every call, so it can't carry a multi-frame reply (native status 0x91/0xAF) — you'll get a clear error instead of silent garbage; use F3's GetVersion button for that one case, and keep ReadData/ReadRecords lengths short enough to fit one frame. Unverified: whether SelectApplication's effect survives into the next separate call (same re-select-per-call behavior) is not something I could confirm from source alone — if auto-dump's files all come back as if nothing were selected (wrong AID's files, or application-not-found), that's the likely reason; the raw sender above is the way to test SelectApplication followed by GetFileIDs by hand.
Walks GetApplicationIDs → SelectApplication → GetFileIDs → GetFileSettings → reads whatever's readable without auth. Place the card in the field first.
Note
Ported from this fork's emv scan CLI command (chameleon_cli_unit.py), built on the firmware's single-call HF14A_4_EMV_SCAN (6005) — the whole PPSE → SELECT AID → GPO → READ RECORD sequence runs inside one firmware call with the field held continuously, so it doesn't hit the per-call-reselect problem DESFire's generic reader path does. Needs the device in Reader mode (Device tab). Place a contactless EMV card (bank card) on the antenna first.
E1Scan card
E2Raw APDU exchange
O1SEOS emulation
O2ST25TA (NFC Type 4) emulation
Reads/writes chunk at 240 bytes per call (matches chameleon_cmd.py's ST25TA_CHUNK), looping automatically for larger NDEF payloads.
O3MIFARE Plus perso
WritePerso only works while the card is in SL0. Addr 0x9000/0x9001/0x9003 are the three mandatory admin keys (CardMasterKey/CardConfigKey/L3SwitchKey); write all three before Commit.
Note
Sends one raw DATA_CMD_* frame and shows the raw reply. Command accepts a name from fullcmd.js's CU map (e.g. GET_BATTERY_INFO), a decimal id, or 0x-hex. Payload is hex bytes, big-endian per-field as each command documents in data_cmd.h — this sends exactly what you type, with no per-command validation. ↑/↓ recall history, Enter sends.
S1Console
Note
Mirrors the real Python CLI's command tree (chameleon_cli_unit.py) with the same group/command/flag names. Batch 1 covers hw, hw slot, hw settings, hf 14a, and hf mf rdbl/wrbl. Everything else (hf mf's crypto attacks, hf mfu/des/seos/st25ta/mfplus, most of lf, data, emv, standalone) answers with "not ported yet" rather than faking a result. Type help for the live command tree, Tab to complete, ↑/↓ for history.