keyfabe 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -12
- package/dist/commands/clone.js +26 -3
- package/dist/commands/clone.js.map +1 -1
- package/dist/commands/read.js +27 -5
- package/dist/commands/read.js.map +1 -1
- package/dist/lib/parsers.d.ts +1 -0
- package/dist/lib/parsers.js +22 -0
- package/dist/lib/parsers.js.map +1 -1
- package/package.json +6 -1
package/README.md
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
A TypeScript CLI tool that wraps the Proxmark3 client to provide an ergonomic keyfob cloning workflow.
|
|
4
4
|
|
|
5
|
+
<p align="center">
|
|
6
|
+
<img src="demo.gif" alt="keyfabe demo" width="800" />
|
|
7
|
+
</p>
|
|
8
|
+
|
|
5
9
|
## What it does
|
|
6
10
|
|
|
7
11
|
- Automates the multi-step read/detect/clone/verify process into a single guided flow
|
|
@@ -35,7 +39,12 @@ npx keyfabe
|
|
|
35
39
|
|
|
36
40
|
## Usage
|
|
37
41
|
|
|
42
|
+
Running `keyfabe` with no arguments launches an interactive wizard menu that guides you through all available actions.
|
|
43
|
+
|
|
38
44
|
```sh
|
|
45
|
+
# launch interactive wizard
|
|
46
|
+
keyfabe
|
|
47
|
+
|
|
39
48
|
# check device connection, firmware, and antenna health
|
|
40
49
|
keyfabe doctor
|
|
41
50
|
|
|
@@ -49,19 +58,19 @@ keyfabe clone
|
|
|
49
58
|
keyfabe read
|
|
50
59
|
|
|
51
60
|
# write a previously-saved identity to a blank fob
|
|
52
|
-
keyfabe write
|
|
61
|
+
keyfabe write [name]
|
|
53
62
|
|
|
54
63
|
# list saved identities
|
|
55
64
|
keyfabe list
|
|
56
65
|
|
|
57
66
|
# show details of a saved identity
|
|
58
|
-
keyfabe show
|
|
67
|
+
keyfabe show [name]
|
|
59
68
|
|
|
60
69
|
# rename a saved identity
|
|
61
|
-
keyfabe rename
|
|
70
|
+
keyfabe rename [old-name] [new-name]
|
|
62
71
|
|
|
63
72
|
# delete a saved identity
|
|
64
|
-
keyfabe delete
|
|
73
|
+
keyfabe delete [name]
|
|
65
74
|
|
|
66
75
|
# export all saved identities as JSON
|
|
67
76
|
keyfabe export > fobs.json
|
|
@@ -70,6 +79,8 @@ keyfabe export > fobs.json
|
|
|
70
79
|
keyfabe import fobs.json
|
|
71
80
|
```
|
|
72
81
|
|
|
82
|
+
Commands that take `[name]` arguments are fully optional — when omitted, you'll get an interactive fob picker.
|
|
83
|
+
|
|
73
84
|
## Commands
|
|
74
85
|
|
|
75
86
|
### `keyfabe doctor`
|
|
@@ -88,25 +99,25 @@ Guided clone flow: reads the original fob, detects a blank T55x7, writes the ID,
|
|
|
88
99
|
|
|
89
100
|
Reads and identifies whatever fob is on the antenna. Supports EM410x and HID Prox. Optionally saves the identity.
|
|
90
101
|
|
|
91
|
-
### `keyfabe write
|
|
102
|
+
### `keyfabe write [name]`
|
|
92
103
|
|
|
93
|
-
Writes a previously-saved identity to a blank T55x7 fob.
|
|
104
|
+
Writes a previously-saved identity to a blank T55x7 fob. Without a name, presents an interactive picker.
|
|
94
105
|
|
|
95
106
|
### `keyfabe list`
|
|
96
107
|
|
|
97
108
|
Lists all saved fob identities from `~/.keyfabe/fobs.json`.
|
|
98
109
|
|
|
99
|
-
### `keyfabe show
|
|
110
|
+
### `keyfabe show [name]`
|
|
100
111
|
|
|
101
|
-
Displays full details of a saved fob identity (type, ID, encoding, save date).
|
|
112
|
+
Displays full details of a saved fob identity (type, ID, encoding, save date). Without a name, presents an interactive picker.
|
|
102
113
|
|
|
103
|
-
### `keyfabe rename
|
|
114
|
+
### `keyfabe rename [old-name] [new-name]`
|
|
104
115
|
|
|
105
|
-
Renames a saved fob identity.
|
|
116
|
+
Renames a saved fob identity. Missing arguments are prompted interactively.
|
|
106
117
|
|
|
107
|
-
### `keyfabe delete
|
|
118
|
+
### `keyfabe delete [name]`
|
|
108
119
|
|
|
109
|
-
Deletes a saved fob identity.
|
|
120
|
+
Deletes a saved fob identity. Without a name, presents an interactive picker.
|
|
110
121
|
|
|
111
122
|
### `keyfabe export`
|
|
112
123
|
|
package/dist/commands/clone.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as p from "@clack/prompts";
|
|
2
2
|
import { writeAndVerify } from "../lib/card-ops.js";
|
|
3
3
|
import { printCardInfo, printDoctorHint } from "../lib/display.js";
|
|
4
|
-
import { parseLfSearch } from "../lib/parsers.js";
|
|
4
|
+
import { parseHfSearch, parseLfSearch } from "../lib/parsers.js";
|
|
5
5
|
import { Pm3Error, pm3Exec, requireDevice } from "../lib/pm3.js";
|
|
6
6
|
import { promptName, waitForEnter } from "../lib/prompts.js";
|
|
7
7
|
import { saveFob } from "../lib/store.js";
|
|
@@ -45,9 +45,32 @@ export async function clone() {
|
|
|
45
45
|
await new Promise((r) => setTimeout(r, READ_RETRY_DELAY));
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
|
+
// If LF search failed, try HF
|
|
48
49
|
if (!card) {
|
|
49
|
-
|
|
50
|
-
|
|
50
|
+
const hfSpinner = p.spinner();
|
|
51
|
+
hfSpinner.start("No LF card found, trying HF...");
|
|
52
|
+
try {
|
|
53
|
+
const { stdout } = await pm3Exec("hf search");
|
|
54
|
+
const hfCard = parseHfSearch(stdout);
|
|
55
|
+
if (hfCard) {
|
|
56
|
+
hfSpinner.stop("HF card detected");
|
|
57
|
+
printCardInfo(hfCard);
|
|
58
|
+
p.log.warn(`HF card cloning (${hfCard.type}) is not yet supported. Only LF keyfobs (EM410x, HID Prox) can be cloned.`);
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
if (err instanceof Pm3Error) {
|
|
64
|
+
hfSpinner.stop(err.message);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
hfSpinner.stop("HF search failed.");
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (!card) {
|
|
71
|
+
p.log.error("Failed to read original card after all attempts.");
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
51
74
|
}
|
|
52
75
|
printCardInfo(card);
|
|
53
76
|
// Step 2: Write to blank
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clone.js","sourceRoot":"","sources":["../../src/commands/clone.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"clone.js","sourceRoot":"","sources":["../../src/commands/clone.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/read.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as p from "@clack/prompts";
|
|
2
2
|
import { printCardInfo, printDoctorHint } from "../lib/display.js";
|
|
3
|
-
import { parseLfSearch } from "../lib/parsers.js";
|
|
3
|
+
import { parseHfSearch, parseLfSearch } from "../lib/parsers.js";
|
|
4
4
|
import { Pm3Error, pm3Exec, requireDevice } from "../lib/pm3.js";
|
|
5
5
|
import { promptName } from "../lib/prompts.js";
|
|
6
6
|
import { saveFob } from "../lib/store.js";
|
|
@@ -26,11 +26,33 @@ export async function read() {
|
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
if (!card) {
|
|
29
|
-
s.stop("No card
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
s.stop("No LF card found, trying HF...");
|
|
30
|
+
const hf = p.spinner();
|
|
31
|
+
hf.start("Searching for card (HF)...");
|
|
32
|
+
try {
|
|
33
|
+
const { stdout } = await pm3Exec("hf search");
|
|
34
|
+
card = parseHfSearch(stdout);
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
if (err instanceof Pm3Error) {
|
|
38
|
+
hf.stop(err.message);
|
|
39
|
+
p.log.error(err.message);
|
|
40
|
+
if (err.message.includes("not found")) {
|
|
41
|
+
printDoctorHint();
|
|
42
|
+
}
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (!card) {
|
|
47
|
+
hf.stop("No card detected. Make sure the card is flat against the antenna.");
|
|
48
|
+
p.log.error("No card detected. Make sure the card is flat against the antenna.");
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
hf.stop("Card detected");
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
s.stop("Card detected");
|
|
32
55
|
}
|
|
33
|
-
s.stop("Card detected");
|
|
34
56
|
printCardInfo(card);
|
|
35
57
|
// Prompt to save
|
|
36
58
|
const name = await promptName();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"read.js","sourceRoot":"","sources":["../../src/commands/read.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"read.js","sourceRoot":"","sources":["../../src/commands/read.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/parsers.d.ts
CHANGED
|
@@ -23,4 +23,5 @@ export declare function parseHwStatus(output: string): HwStatus;
|
|
|
23
23
|
export declare function parseHwTune(output: string): HwTune;
|
|
24
24
|
export declare function parseLfSearch(output: string): CardInfo | null;
|
|
25
25
|
export declare function parseT55xxDetect(output: string): T55xxInfo | null;
|
|
26
|
+
export declare function parseHfSearch(output: string): CardInfo | null;
|
|
26
27
|
export declare function parseCloneResult(output: string): CloneResult;
|
package/dist/lib/parsers.js
CHANGED
|
@@ -51,6 +51,28 @@ export function parseT55xxDetect(output) {
|
|
|
51
51
|
passwordSet,
|
|
52
52
|
};
|
|
53
53
|
}
|
|
54
|
+
export function parseHfSearch(output) {
|
|
55
|
+
// Extract UID — formats: "UID: AB CD EF 01" or "UID: ABCDEF01" or "UID[4]: AB CD EF 01"
|
|
56
|
+
const uidMatch = output.match(/UID\s*(?:\[\d+\])?\s*[:=]\s*([0-9A-Fa-f]{2}(?:\s+[0-9A-Fa-f]{2})*)/i);
|
|
57
|
+
if (!uidMatch)
|
|
58
|
+
return null;
|
|
59
|
+
const uid = uidMatch[1].replace(/\s+/g, "").toUpperCase();
|
|
60
|
+
// Determine card type from SAK, ATQA, or text
|
|
61
|
+
let type = "ISO 14443-A";
|
|
62
|
+
if (/MIFARE\s*Classic.*4K/i.test(output)) {
|
|
63
|
+
type = "MIFARE Classic 4K";
|
|
64
|
+
}
|
|
65
|
+
else if (/MIFARE\s*Classic/i.test(output)) {
|
|
66
|
+
type = "MIFARE Classic 1K";
|
|
67
|
+
}
|
|
68
|
+
else if (/MIFARE\s*Ultralight|NTAG/i.test(output)) {
|
|
69
|
+
type = "MIFARE Ultralight";
|
|
70
|
+
}
|
|
71
|
+
else if (/MIFARE\s*DESFire/i.test(output)) {
|
|
72
|
+
type = "MIFARE DESFire";
|
|
73
|
+
}
|
|
74
|
+
return { type, id: uid };
|
|
75
|
+
}
|
|
54
76
|
export function parseCloneResult(output) {
|
|
55
77
|
const hasError = /error/i.test(output) && !/errorrate/i.test(output);
|
|
56
78
|
const hasDone = /done/i.test(output) || /written/i.test(output) || /cloned/i.test(output);
|
package/dist/lib/parsers.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parsers.js","sourceRoot":"","sources":["../../src/lib/parsers.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"parsers.js","sourceRoot":"","sources":["../../src/lib/parsers.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "keyfabe",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "CLI tool for Proxmark3 keyfob cloning",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -13,6 +13,11 @@
|
|
|
13
13
|
"engines": {
|
|
14
14
|
"node": ">=20"
|
|
15
15
|
},
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "https://github.com/edobry/keyfabe.git"
|
|
19
|
+
},
|
|
20
|
+
"homepage": "https://github.com/edobry/keyfabe",
|
|
16
21
|
"keywords": [
|
|
17
22
|
"proxmark3",
|
|
18
23
|
"rfid",
|