███████╗ ██████╗ ██████╗ ██╗███╗ ██╗ ██╔════╝██╔════╝██╔═══██╗██║████╗ ██║ █████╗ ██║ ██║ ██║██║██╔██╗ ██║ ██╔══╝ ██║ ██║ ██║██║██║╚██╗██║ ██║ ╚██████╗╚██████╔╝██║██║ ╚████║ ╚═╝ ╚═════╝ ╚═════╝ ╚═╝╚═╝ ╚═══╝
Acquire. Validate. Understand. Plan. Record. Verify. Recover.
FCOIN is an offline-first toolkit for examining and safely maintaining MIFARE Classic cards that you own or are explicitly authorized to test. It replaces the original single-script prototype with a structured package, deterministic analysis engine, immutable snapshots, exact access-condition decoding, surgical change plans, tamper-evident write journals, post-write verification, and recovery planning.
FCOIN does not silently write cards, install packages with sudo, upload dumps, or treat heuristic guesses as facts.
Run FCOIN without arguments:
fcoinThis opens a colorful full-screen dashboard instead of printing raw command help. Navigate with:
↑/↓orj/kto move.ENTERto open the selected workflow.- Number keys for immediate shortcuts.
borESCto go back.qto exit cleanly.
The dashboard provides guided menus for:
- Reader and imported-dump backups.
- Live-card inspection with automatic backup, saved-backup browsing, validation, comparison, and evidence questions.
- Reports, conversion, inference, and inventory.
- Owned-laboratory profile and value-plan workflows.
- Transaction preparation, verification, recovery, history, and journals.
File prompts automatically list compatible files in the current directory and always provide a manual-path option. Session prompts display the UID, transaction state, card type, and session ID.
Every menu also displays a live status rail:
● NFC TOOL │ ● READER ONLINE │ ● CARD 04453501DB2480
The rail updates while a menu remains open. Green indicates available/present, amber indicates no card, red indicates unavailable/offline, and violet indicates that hardware monitoring is intentionally paused.
The monitor is read-only and has strict operation isolation:
- It pauses and waits for any in-progress probe to finish before card acquisition, verification, recovery, or transaction commands begin.
- It never writes card data or modifies FCOIN files.
- When a session is
write_pendingorrecovery_planned, all hardware probing stops—not only card polling—so an external writer cannot compete with FCOIN for the reader. - The rail then displays
MONITOR PAUSED │ SAFE WRITE MODEuntil the protected state is resolved.
Incomplete direct commands also enter the relevant wizard when used in a terminal:
fcoin inspect
fcoin compare
fcoin backupFully specified commands remain unchanged for scripts and automation. Friendly aliases such as fcoin --inspect and fcoin --doctor are also accepted.
| Area | Capability |
|---|---|
| Backup | Two-read hardware acquisition, immutable snapshots, SHA-256 identity, 0600 files |
| Protocol | Mini, Classic 1K, and Classic 4K geometry |
| Integrity | Exact value-block redundancy, BCC indication, all access-bit complements |
| Analysis | Value blocks, text, UTF-16, timestamps, duplicate blocks, entropy, CRC candidates |
| Intelligence | Cross-dump inference, controlled comparisons, evidence-backed questions |
| Editing | UID-bound owned-lab profiles, exact decimal math, mirror-aware surgical plans |
| Transactions | Durable hash-chained journal written before external block writes |
| Verification | Target-byte verification plus detection of every collateral block change |
| Recovery | Restoration plans generated from the immutable trusted snapshot |
| Reporting | Styled terminal, JSON output, self-contained HTML reports |
| Formats | Binary MFD and Mifare Classic Tool text-dump conversion |
| Operations | Inventory, history, reader diagnostics, automation-friendly JSON |
FCOIN is intended for:
- Backing up cards you own.
- Recovering owned cards from accidental data-block corruption.
- Laboratory cards and synthetic fixtures.
- Authorized security research and format reverse engineering.
- Comparing known-before and known-after states from controlled experiments.
Writable value profiles must:
- Set
lab_onlytotrue. - Bind to an exact UID prefix.
- Explicitly list writable fields and blocks.
- Define permitted minimum and maximum values.
- Receive the exact authorization phrase required by the CLI.
FCOIN always refuses automatic changes to manufacturer block 0 and sector trailers. It does not offer unrestricted third-party payment, transit, access-control, or stored-value alteration.
┌─────────────┐
│ ACQUIRE ×2 │ Two reads must match
└──────┬──────┘
▼
┌───────────────────┐
│ IMMUTABLE SNAPSHOT│ SHA-256 + 0600 permissions
└─────────┬─────────┘
▼
┌─────────────────────────┐
│ VALIDATE · INSPECT · DIFF│ Deterministic evidence
└────────────┬────────────┘
▼
┌─────────────────────────┐
│ UID-BOUND CHANGE PLAN │ Exact blocks and preconditions
└────────────┬────────────┘
▼
┌─────────────────────────┐
│ DURABLE WRITE JOURNAL │ Pending event persisted first
└────────────┬────────────┘
▼
┌─────────────────────────┐
│ EXTERNAL BLOCK-WISE WRITE│ MCT or another authorized writer
└────────────┬────────────┘
▼
┌─────────────────────────┐
│ READ ×2 · VERIFY ALL │ Target + collateral comparison
└───────┬─────────┬───────┘
│ pass │ fail
▼ ▼
VERIFIED RECOVERY PLAN
FCOIN itself has no third-party Python runtime dependencies.
git clone https://github.com/Nour833/Fcoin.git
cd Fcoin
python3 -m pip install -e .
fcoinIt can also run directly from a checkout:
./fcoin.pyHardware acquisition is optional. On Linux, install these through your operating-system package manager when needed:
mfocfor authorized MIFARE Classic acquisition.libnfcutilities fornfc-listdiagnostics.
FCOIN reports missing tools but never invokes sudo or changes the system.
fcoin doctorAcquire twice with mfoc; the snapshot is accepted only when both reads match:
fcoin backup --readerUse an optional, user-managed key dictionary:
fcoin backup --reader --keys ~/.config/fcoin/owned-lab.keysImport an existing dump:
fcoin backup --from-dump card.mfdRequire two independently acquired imports to match:
fcoin backup \
--from-dump read-1.mfd \
--confirmation read-2.mfdAnalysis can use a single imported dump. Any writable plan requires a session backed by two identical independent reads.
Snapshots are stored under:
~/.local/share/fcoin/sessions/<timestamp>-<uid>/
Override that location with FCOIN_HOME or --home.
Open the guided Inspect source menu:
fcoin inspectThe menu offers:
- Read card now + auto-backup: reads the live card twice, requires both images to match, creates an immutable session backup, then analyzes it.
- Open a saved FCOIN backup: browses existing sessions by UID, state, card type, and session ID.
- Open a dump file: selects an MFD, dump, or binary file from disk.
Use the same sources directly from the CLI:
# Live card: two reads, automatic secure backup, then inspection
fcoin inspect --reader
# Live card with an owned key dictionary
fcoin inspect --reader --keys ~/.config/fcoin/owned-lab.keys
# Existing immutable backup
fcoin inspect --session <session-id>
# Ordinary file
fcoin inspect card.mfdLive inspection stores the verified image under the normal session directory and prints both the session ID and backup path before displaying findings.
Validate or inspect a file directly:
fcoin validate card.mfd
fcoin inspect card.mfd
fcoin inspect card.mfd --all
fcoin inspect card.mfd --jsonThe analyzer reports protocol facts and candidates separately. A structurally valid value block is a fact; calling that value a balance requires a trusted profile or controlled evidence.
The default terminal view hides routine empty blocks and valid sector trailers so important findings remain readable. Use --all for the complete forensic table.
fcoin compare before.mfd after.mfd
fcoin compare before.mfd after.mfd --jsonThe diff includes:
- Changed blocks and sectors.
- Exact changed byte offsets.
- Number of changed bits.
- Before and after hex.
- Value-block interpretation when both states are structurally valid.
fcoin infer baseline.mfd event-1.mfd event-2.mfd \
--output inference.jsonAll samples must use the same card geometry and UID prefix. FCOIN identifies valid value blocks across every sample and records which values changed.
fcoin ask card.mfd "what value blocks were found?"
fcoin ask card.mfd "is anything corrupt?"
fcoin ask card.mfd "show possible timestamps"This assistant is deterministic, offline, and does not send card data anywhere.
fcoin report card.mfd --format html --output report.html
fcoin report card.mfd --format json --output report.jsonThe HTML report is self-contained and can be archived with a case or laboratory notebook.
Convert a complete binary MFD dump to Mifare Classic Tool text format:
fcoin convert card.mfd --from mfd --to mct --output card.mctConvert a complete MCT text dump back to binary:
fcoin convert card.mct --from mct --to mfd --output card.mfdIncomplete sector maps are rejected because they cannot serve as trusted recovery snapshots.
FCOIN does not edit a value because a heuristic merely “looks like a wallet.” A writable operation requires a reviewed profile bound to the exact owned card.
fcoin inspect owned-lab.mfd
fcoin infer lab-before.mfd lab-after-controlled-event.mfdfcoin profile-init owned-lab.mfd \
--block 4 \
--mirror 5 \
--output owned-lab.profile.jsonReview the generated file:
{
"name": "owned-lab-card",
"description": "UID-bound profile for an owned laboratory card.",
"lab_only": true,
"allowed_uids": ["DEADBEEF"],
"fields": [
{
"name": "test_value",
"type": "value_block",
"block": 4,
"mirrors": [5],
"scale": 100,
"unit": "test credits",
"minimum": "0.00",
"maximum": "100.00",
"writable": true
}
]
}Find the session ID:
fcoin historyIn the interactive dashboard, choose:
Safe laboratory editing
└── Plan a value change
├── Select the verified backup once
└── Detect valid value blocks in this backup
The backup is not requested again. FCOIN displays structurally valid and writable value-block candidates from that selected backup. It can create the exact-UID profile inside the session, or you can explicitly choose an existing reviewed profile.
Equal values in the same sector are suggested as possible mirrors, but they are not silently accepted as mirrors. You must explicitly confirm the group; otherwise, choose one primary block.
Create the plan:
fcoin plan-value \
--session 20260622T120000.000000Z-DEADBEEF \
--profile owned-lab.profile.json \
--field test_value \
--value 50.00 \
--authorize "I OWN THIS LAB CARD"Before accepting the plan, FCOIN verifies:
- The profile UID exactly matches the snapshot.
- Every primary and mirror block is a complete valid MIFARE value block.
- All mirror values agree.
- Access-condition redundancy is valid.
- The block is not write-prohibited.
- The requested decimal is exact at the configured scale.
- The signed 32-bit encoded value is in range.
- The value is inside profile bounds.
- The encoded address bytes are preserved.
- No manufacturer block or sector trailer is targeted.
fcoin apply-plan \
~/.local/share/fcoin/sessions/<session>/before.mfd \
~/.local/share/fcoin/sessions/<session>/value-plan.json \
--output preview.mfd
fcoin compare \
~/.local/share/fcoin/sessions/<session>/before.mfd \
preview.mfdOnly planned blocks may differ.
fcoin prepare-write \
--session <session> \
--plan ~/.local/share/fcoin/sessions/<session>/value-plan.jsonThis durably creates:
write-plan.json Integrity-hashed plan
intended.mfd Exact expected complete image
write-instructions.json Minimal block/payload list
journal.jsonl Append-only hash-chained event log
Each block is recorded as pending before any external write occurs. Use MCT or another authorized block-wise tool to write only those listed data blocks.
Read the card twice independently and provide both matching acquisitions:
fcoin verify-write \
--session <session> \
--observed after-1.mfd \
--confirmation after-2.mfdOr acquire two matching post-write reads:
fcoin verify-write --session <session> --readerVerification fails if:
- The UID differs.
- Any target block differs from the plan.
- Any unrelated block changed.
- The final complete image differs from
intended.mfd. - The journal hash chain is damaged.
If verification fails, acquire the current card and generate a restoration plan:
fcoin recover \
--session <session> \
--current current-card.mfd \
--authorize "RESTORE MY OWN CARD"The recovery plan restores exact data-block bytes from before.mfd. FCOIN refuses automatic recovery when manufacturer block 0 or a sector trailer differs, because changing keys or access conditions requires a separate specialist procedure.
Apply and inspect the recovery plan offline:
fcoin apply-plan \
current-card.mfd \
~/.local/share/fcoin/sessions/<session>/recovery-plan.json \
--output recovery-preview.mfd
fcoin compare current-card.mfd recovery-preview.mfdThen use the generated block payloads with an authorized block-wise writer and verify again.
Display and cryptographically verify the event chain:
fcoin journal --session <session>Typical events:
transaction_prepared
block_pending
block_pending
block_verified
block_verified
transaction_verified
Failed sessions retain the observed image, block-level failure events, collateral-change evidence, and recovery-plan reference.
sessions/<timestamp>-<uid>/
├── metadata.json
├── before.mfd
├── confirmation.mfd
├── acquisition.log
├── value-plan.json
├── write-plan.json
├── intended.mfd
├── write-instructions.json
├── journal.jsonl
├── after.mfd
└── recovery-plan.json
Sensitive artifacts use mode 0600; session directories use 0700. Dumps, keys, sessions, reports, and plans are ignored by Git.
| Command | Purpose |
|---|---|
doctor |
Check mfoc, libnfc tools, and reader visibility |
backup |
Create an immutable imported or double-read snapshot |
validate |
Validate geometry, dump size, BCC indication, and access bits |
inspect |
Inspect a file, saved backup, or live card with automatic backup |
compare |
Produce a block-, byte-, and bit-level diff |
infer |
Correlate structural value blocks across controlled samples |
ask |
Query deterministic analysis evidence |
report |
Create JSON or self-contained HTML reports |
convert |
Convert complete MFD and MCT dumps |
inventory |
Index dump files recursively or non-recursively |
history |
List snapshot and write-session state |
profile-init |
Create an exact-UID owned-lab profile template |
plan-value |
Build an integrity-hashed surgical value plan |
apply-plan |
Apply and verify a plan against an offline image |
prepare-write |
Persist intended state, payloads, and pending journal events |
verify-write |
Verify target blocks and detect collateral changes |
recover |
Generate restoration operations from the immutable snapshot |
journal |
Verify and display the transaction hash chain |
Every analysis-oriented command supports plain terminal output or JSON where appropriate. Set NO_COLOR=1 or use --no-color for non-ANSI output.
Use fcoin --help when you specifically want the complete non-interactive argparse reference instead of the dashboard.
src/fcoin/
├── geometry.py Mini / 1K / 4K memory mapping
├── access.py Access-bit and permission decoding
├── value.py Exact signed value-block codec
├── dump.py Validated immutable card images
├── acquisition.py mfoc and libnfc diagnostics adapters
├── analysis.py Explainable deterministic detectors
├── intelligence.py Cross-dump inference and evidence questions
├── compare.py Exact block, byte, and bit comparisons
├── formats.py MFD ↔ MCT conversion
├── profiles.py UID-bound laboratory schemas
├── plans.py Integrity-hashed surgical and recovery plans
├── journal.py Durable hash-chained operation records
├── transactions.py Prepare, verify, and recover workflows
├── storage.py Secure immutable session storage
├── reporting.py JSON and HTML reports
├── ui.py Dependency-free styled terminal interface
├── interactive.py Guided menus, file/session selection, and workflow wizards
├── status.py Read-only live reader/card monitor with operation lock
└── cli.py Command orchestration
See Architecture and Profile schema for implementation details.
Run the complete standard-library test suite:
PYTHONPATH=src python3 -m unittest discover -v
python3 -m compileall -q src tests fcoin.pyThe suite covers:
- Mini, 1K, and 4K geometry.
- Every access-condition triplet.
- Corrupt redundant access bits.
- Signed value-block boundaries.
- Every address redundancy byte.
- Exact decimal scaling.
- MFD/MCT round trips.
- Explainable detection and comparison.
- UID/profile authorization.
- Detected value grouping and in-session profile creation.
- Surgical collateral protection.
- Live reader/card status parsing and zero-probe safe-write mode.
- Monitor drain barriers before card operations.
- Plan-hash tampering.
- Snapshot permissions and mismatched reads.
- Journal tampering.
- Successful verification and failed-session recovery.
- No software can guarantee recovery from physical card failure or interrupted sector-trailer changes.
mfocworks only where its attack assumptions and at least one usable known key are satisfied.- A valid MIFARE value block does not prove that the value represents money.
- The manufacturer BCC indication is based on the four-byte UID-prefix layout; other UID layouts may show it as a variant.
- FCOIN prepares and verifies block-wise writes but does not hide external writer behavior. Confirm that your chosen tool writes only the listed blocks.
Do not publish card dumps, keys, personally identifying data, or reproducible details of a live vulnerable system. See SECURITY.md for reporting guidance.
MIT. See LICENSE.