mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2024-09-20 15:26:13 +08:00
Add hf mf gload, ggetblk, gsetblk
This commit is contained in:
parent
42b48fec85
commit
876abf2818
|
@ -5,6 +5,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
|
|||
## [unreleased][unreleased]
|
||||
- Fixed `trace list -c` - annotation of CRC bytes now is colored or squared if no ansi colors is supported (@iceman1001)
|
||||
- Fixed `trace list -t mf` - now also finds UID if anticollision is partial captured, to be used for mfkey (@iceman1001)
|
||||
- Added `hf mf gload, ggetblk, gsetblk` for Gen4 GTU in mifare classic mode (@DidierA)
|
||||
|
||||
## [Radium.4.15864][2022-10-29]
|
||||
- Changed `lf indala sim` - now accepts fc / cn (@iceman1001)
|
||||
|
|
|
@ -1656,6 +1656,17 @@ static void PacketReceived(PacketCommandNG *packet) {
|
|||
MifareG4ReadBlk(payload->blockno, payload->pwd);
|
||||
break;
|
||||
}
|
||||
|
||||
case CMD_HF_MIFARE_G4_WRBL: {
|
||||
struct p {
|
||||
uint8_t blockno;
|
||||
uint8_t pwd[4];
|
||||
uint8_t data[16]; // data to be written
|
||||
} PACKED;
|
||||
struct p *payload = (struct p *) packet->data.asBytes;
|
||||
MifareG4WriteBlk(payload->blockno, payload->pwd, payload->data);
|
||||
break;
|
||||
}
|
||||
case CMD_HF_MIFARE_PERSONALIZE_UID: {
|
||||
struct p {
|
||||
uint8_t keytype;
|
||||
|
|
|
@ -2723,6 +2723,51 @@ OUT:
|
|||
BigBuf_free();
|
||||
}
|
||||
|
||||
void MifareG4WriteBlk(uint8_t blockno, uint8_t *pwd, uint8_t *data) {
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||
clear_trace();
|
||||
set_tracing(true);
|
||||
|
||||
int res = 0;
|
||||
int retval = PM3_SUCCESS;
|
||||
uint8_t *par = BigBuf_malloc(MAX_PARITY_SIZE);
|
||||
uint8_t *buf = BigBuf_malloc(PM3_CMD_DATA_SIZE);
|
||||
uint8_t *uid = BigBuf_malloc(10);
|
||||
if (iso14443a_select_card(uid, NULL, NULL, true, 0, true) == false) {
|
||||
retval = PM3_ESOFT;
|
||||
goto OUT;
|
||||
}
|
||||
|
||||
LED_B_ON();
|
||||
uint32_t save_iso14a_timeout = iso14a_get_timeout();
|
||||
iso14a_set_timeout(13560000 / 1000 / (8 * 16) * 1000); // 2 seconds timeout
|
||||
|
||||
uint8_t cmd[] = { 0xCF, 0x00, 0x00, 0x00, 0x00, 0xCD, blockno,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00
|
||||
};
|
||||
|
||||
memcpy(cmd + 1, pwd, 4);
|
||||
memcpy(cmd + 7, data, 16);
|
||||
|
||||
AddCrc14A(cmd, sizeof(cmd) - 2);
|
||||
|
||||
ReaderTransmit(cmd, sizeof(cmd), NULL);
|
||||
res = ReaderReceive(buf, par);
|
||||
if ((res != 4) || (memcmp(buf, "\x90\x00\xfd\x07", 4) != 0)) {
|
||||
retval = PM3_ESOFT;
|
||||
}
|
||||
iso14a_set_timeout(save_iso14a_timeout);
|
||||
LED_B_OFF();
|
||||
|
||||
OUT:
|
||||
reply_ng(CMD_HF_MIFARE_G4_WRBL, retval, buf, res);
|
||||
// turns off
|
||||
OnSuccessMagic();
|
||||
BigBuf_free();
|
||||
}
|
||||
|
||||
void MifareSetMod(uint8_t *datain) {
|
||||
|
||||
uint8_t mod = datain[0];
|
||||
|
|
|
@ -58,6 +58,7 @@ void MifareGen3Freez(void); // Gen 3 magic card lock further UID changes
|
|||
|
||||
// MFC GEN4 GTU
|
||||
void MifareG4ReadBlk(uint8_t blockno, uint8_t *pwd);
|
||||
void MifareG4WriteBlk(uint8_t blockno, uint8_t *pwd, uint8_t *data);
|
||||
|
||||
void MifareSetMod(uint8_t *datain);
|
||||
void MifarePersonalizeUID(uint8_t keyType, uint8_t perso_option, uint64_t key);
|
||||
|
|
|
@ -6749,6 +6749,313 @@ static int CmdHF14AMfView(const char *Cmd) {
|
|||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
// Read block from Gen4 GTU card
|
||||
static int CmdHF14AGen4GetBlk(const char *cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf mf ggetblk",
|
||||
"Get block data from magic gen4 GTU card.",
|
||||
"hf mf ggetblk --blk 0 --> get block 0 (manufacturer)\n"
|
||||
"hf mf ggetblk --blk 3 -v --> get block 3, decode sector trailer\n"
|
||||
);
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_int1("b", "blk", "<dec>", "block number"),
|
||||
arg_lit0("v", "verbose", "verbose output"),
|
||||
arg_str0("p", "pwd", "<hex>", "password 4bytes"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, cmd, argtable, false);
|
||||
int b = arg_get_int_def(ctx, 1, 0);
|
||||
bool verbose = arg_get_lit(ctx, 2);
|
||||
|
||||
int pwd_len = 0;
|
||||
uint8_t pwd[4] = {0};
|
||||
CLIGetHexWithReturn(ctx, 3, pwd, &pwd_len);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
//validate args
|
||||
if (b > MIFARE_4K_MAXBLOCK) {
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
if (pwd_len != 4 && pwd_len != 0) {
|
||||
PrintAndLogEx(FAILED, "Must specify 4 bytes, got " _YELLOW_("%u"), pwd_len);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
uint8_t blockno = (uint8_t)b;
|
||||
uint8_t data[16] = {0};
|
||||
|
||||
PrintAndLogEx(NORMAL, "Block: %x", blockno) ;
|
||||
|
||||
int res = mfG4GetBlock(pwd, blockno, data);
|
||||
if (res) {
|
||||
PrintAndLogEx(ERR, "Can't read block. error=%d", res);
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
uint8_t sector = mfSectorNum(blockno);
|
||||
mf_print_sector_hdr(sector);
|
||||
mf_print_block(blockno, data, verbose);
|
||||
|
||||
if (verbose) {
|
||||
decode_print_st(blockno, data);
|
||||
} else {
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
}
|
||||
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
// Load dump to Gen4 GTU card
|
||||
static int CmdHF14AGen4Load(const char *cmd) {
|
||||
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf mf gload",
|
||||
"Load magic gen4 gtu card with data from (bin/eml/json) dump file\n"
|
||||
"or from emulator memory.",
|
||||
"hf mf gload --emu\n"
|
||||
"hf mf gload -f hf-mf-01020304.eml\n"
|
||||
"hf mf gload -p AABBCCDD --4k -v -f hf-mf-01020304-dump.bin\n"
|
||||
"\n"
|
||||
"Card must be configured beforehand with `script run hf_mf_ultimatecard`.\n"
|
||||
"Blocks are 16 bytes long."
|
||||
);
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_lit0(NULL, "mini", "MIFARE Classic Mini / S20"),
|
||||
arg_lit0(NULL, "1k", "MIFARE Classic 1k / S50 (def)"),
|
||||
arg_lit0(NULL, "2k", "MIFARE Classic/Plus 2k"),
|
||||
arg_lit0(NULL, "4k", "MIFARE Classic 4k / S70"),
|
||||
arg_str0("p", "pwd", "<hex>", "password 4bytes"),
|
||||
arg_lit0("v", "verbose", "verbose output"),
|
||||
arg_str0("f", "file", "<fn>", "filename of dump"),
|
||||
arg_lit0(NULL, "emu", "from emulator memory"),
|
||||
arg_int0(NULL, "start", "<dec>", "index of block to start writing (default 0)"),
|
||||
arg_int0(NULL, "end", "<dec>", "index of block to end writing (default last block)"),
|
||||
arg_param_end
|
||||
};
|
||||
|
||||
CLIExecWithReturn(ctx, cmd, argtable, false);
|
||||
bool m0 = arg_get_lit(ctx, 1);
|
||||
bool m1 = arg_get_lit(ctx, 2);
|
||||
bool m2 = arg_get_lit(ctx, 3);
|
||||
bool m4 = arg_get_lit(ctx, 4);
|
||||
|
||||
int pwd_len = 0;
|
||||
uint8_t pwd[4] = {0};
|
||||
CLIGetHexWithReturn(ctx, 5, pwd, &pwd_len);
|
||||
|
||||
bool verbose = arg_get_lit(ctx, 6);
|
||||
|
||||
int fnlen = 0;
|
||||
char filename[FILE_PATH_SIZE] = {0};
|
||||
CLIParamStrToBuf(arg_get_str(ctx, 7), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
|
||||
|
||||
bool fill_from_emulator = arg_get_lit(ctx, 8);
|
||||
|
||||
int start = arg_get_int_def(ctx, 9, 0);
|
||||
int end = arg_get_int_def(ctx, 10, -1);
|
||||
|
||||
CLIParserFree(ctx);
|
||||
|
||||
// validations
|
||||
if (pwd_len != 4 && pwd_len != 0) {
|
||||
PrintAndLogEx(FAILED, "Must specify 4 bytes, got " _YELLOW_("%u"), pwd_len);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
if ((m0 + m1 + m2 + m4) > 1) {
|
||||
PrintAndLogEx(WARNING, "Only specify one MIFARE Type");
|
||||
return PM3_EINVARG;
|
||||
} else if ((m0 + m1 + m2 + m4) == 0) {
|
||||
m1 = true;
|
||||
}
|
||||
|
||||
char s[6];
|
||||
memset(s, 0, sizeof(s));
|
||||
uint16_t block_cnt = MIFARE_1K_MAXBLOCK;
|
||||
if (m0) {
|
||||
block_cnt = MIFARE_MINI_MAXBLOCK;
|
||||
strncpy(s, "Mini", 5);
|
||||
} else if (m1) {
|
||||
block_cnt = MIFARE_1K_MAXBLOCK;
|
||||
strncpy(s, "1K", 3);
|
||||
} else if (m2) {
|
||||
block_cnt = MIFARE_2K_MAXBLOCK;
|
||||
strncpy(s, "2K", 3);
|
||||
} else if (m4) {
|
||||
block_cnt = MIFARE_4K_MAXBLOCK;
|
||||
strncpy(s, "4K", 3);
|
||||
} else {
|
||||
PrintAndLogEx(WARNING, "Please specify a MIFARE Type");
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
if (fill_from_emulator && (fnlen != 0)) {
|
||||
PrintAndLogEx(WARNING, "Please specify file or emulator memory, but not both");
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
if (!fill_from_emulator && (fnlen == 0)) {
|
||||
PrintAndLogEx(WARNING, "Please specify file or emulator memory");
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
if (end == -1) {
|
||||
end = block_cnt - 1;
|
||||
}
|
||||
|
||||
if (start < 0 || end < 0) {
|
||||
PrintAndLogEx(WARNING, "start and end must be positive integers");
|
||||
return PM3_EINVARG ;
|
||||
}
|
||||
|
||||
if (start > end) {
|
||||
PrintAndLogEx(WARNING, "start cannot be more than end");
|
||||
return PM3_EINVARG ;
|
||||
}
|
||||
|
||||
if (start >= block_cnt) {
|
||||
PrintAndLogEx(WARNING, "Last block for Mifare %s is %d. Start is too high.", s, block_cnt - 1) ;
|
||||
return PM3_EINVARG ;
|
||||
}
|
||||
|
||||
if (end >= block_cnt) {
|
||||
PrintAndLogEx(WARNING, "Last block for Mifare %s is %d. End is too high.", s, block_cnt - 1) ;
|
||||
return PM3_EINVARG ;
|
||||
}
|
||||
|
||||
uint8_t *data = NULL;
|
||||
size_t bytes_read = 0;
|
||||
|
||||
if (fill_from_emulator) {
|
||||
data = calloc(block_cnt * MFBLOCK_SIZE, sizeof(uint8_t));
|
||||
if (data == NULL) {
|
||||
PrintAndLogEx(WARNING, "Fail, cannot allocate memory");
|
||||
return PM3_EMALLOC;
|
||||
}
|
||||
PrintAndLogEx(INFO, "downloading emulator memory");
|
||||
if (!GetFromDevice(BIG_BUF_EML, data, block_cnt * MFBLOCK_SIZE, 0, NULL, 0, NULL, 2500, false)) {
|
||||
PrintAndLogEx(WARNING, "Fail, transfer from device time-out");
|
||||
free(data);
|
||||
return PM3_ETIMEOUT;
|
||||
}
|
||||
} else {
|
||||
// read from file
|
||||
int res = pm3_load_dump(filename, (void **)&data, &bytes_read, (MFBLOCK_SIZE * MIFARE_4K_MAXBLOCK));
|
||||
if (res != PM3_SUCCESS) {
|
||||
return res;
|
||||
}
|
||||
|
||||
// check file size corresponds to card size.
|
||||
if (bytes_read != (block_cnt * MFBLOCK_SIZE)) {
|
||||
PrintAndLogEx(ERR, "File content error. Read %zu bytes, expected %zu", bytes_read, block_cnt * MFBLOCK_SIZE);
|
||||
if (data != NULL) free(data);
|
||||
return PM3_EFILE;
|
||||
}
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
if (fnlen != 0) {
|
||||
PrintAndLogEx(INFO, "File: " _YELLOW_("%s"), filename);
|
||||
PrintAndLogEx(INFO, "File size %zu bytes, file blocks %d (0x%x)", bytes_read, block_cnt, block_cnt);
|
||||
} else {
|
||||
PrintAndLogEx(INFO, "Read %zu blocks from emulator memory", block_cnt);
|
||||
}
|
||||
}
|
||||
|
||||
PrintAndLogEx(INFO, "Copying to magic gen4 GTU MIFARE Classic " _GREEN_("%s"), s);
|
||||
PrintAndLogEx(INFO, "Starting block: %d. Ending block: %d.", start, end);
|
||||
|
||||
// copy to card
|
||||
for (uint16_t blockno = start; blockno <= end; blockno++) {
|
||||
|
||||
// 4k writes can be long, so we split status each 64 block boundary.
|
||||
if (blockno % 64 == 0 || blockno == start) {
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(INFO, "" NOLF) ;
|
||||
}
|
||||
PrintAndLogEx(NORMAL, "." NOLF);
|
||||
fflush(stdout);
|
||||
|
||||
// write block
|
||||
if (mfG4SetBlock(pwd, blockno, data + (blockno * MFBLOCK_SIZE)) != PM3_SUCCESS) {
|
||||
PrintAndLogEx(WARNING, "Can't set magic card block: %d", blockno);
|
||||
PrintAndLogEx(HINT, "Verify your card size, and try again or try another tag position");
|
||||
if (data != NULL) free(data);
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
}
|
||||
PrintAndLogEx(NORMAL, "\n");
|
||||
|
||||
if (data != NULL) free(data);
|
||||
|
||||
PrintAndLogEx(SUCCESS, "Card loaded " _YELLOW_("%d") " blocks from %s", end - start + 1,
|
||||
(fill_from_emulator ? "emulator memory" : "file"));
|
||||
PrintAndLogEx(INFO, "Done!");
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
// Write block to Gen4 GTU card
|
||||
static int CmdHF14AGen4SetBlk(const char *cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf mf gsetblk",
|
||||
"Set block data on a magic gen4 GTU card",
|
||||
"hf mf gsetblk --blk 1 -d 000102030405060708090a0b0c0d0e0f"
|
||||
);
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_int1("b", "blk", "<dec>", "block number"),
|
||||
arg_str0("d", "data", "<hex>", "bytes to write, 16 hex bytes"),
|
||||
arg_str0("p", "pwd", "<hex>", "password 4bytes"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, cmd, argtable, false);
|
||||
|
||||
int b = arg_get_int_def(ctx, 1, -1);
|
||||
|
||||
uint8_t data[MFBLOCK_SIZE] = {0x00};
|
||||
int datalen = 0;
|
||||
CLIGetHexWithReturn(ctx, 2, data, &datalen);
|
||||
|
||||
int pwd_len = 0;
|
||||
uint8_t pwd[4] = {0};
|
||||
CLIGetHexWithReturn(ctx, 3, pwd, &pwd_len);
|
||||
|
||||
CLIParserFree(ctx);
|
||||
|
||||
// validations
|
||||
if (pwd_len != 4 && pwd_len != 0) {
|
||||
PrintAndLogEx(FAILED, "Must specify 4 bytes, got " _YELLOW_("%u"), pwd_len);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (b < 0 || b >= MIFARE_4K_MAXBLOCK) {
|
||||
PrintAndLogEx(FAILED, "target block number out-of-range, got %i", b);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
if (datalen != MFBLOCK_SIZE) {
|
||||
PrintAndLogEx(FAILED, "expected 16 bytes data, got %i", datalen);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
// write block
|
||||
PrintAndLogEx(INFO, "Writing block number:%2d data:%s", b, sprint_hex_inrow(data, sizeof(data)));
|
||||
|
||||
uint8_t blockno = (uint8_t)b;
|
||||
int res = mfG4SetBlock(pwd, blockno, data);
|
||||
if (res) {
|
||||
PrintAndLogEx(ERR, "Can't write block. error=%d", res);
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int CmdHF14AGen4View(const char *Cmd) {
|
||||
|
||||
CLIParserContext *ctx;
|
||||
|
@ -6813,7 +7120,6 @@ static int CmdHF14AGen4View(const char *Cmd) {
|
|||
return PM3_EINVARG;
|
||||
}
|
||||
PrintAndLogEx(SUCCESS, "View magic gen4 GTU MIFARE Classic " _GREEN_("%s"), s);
|
||||
PrintAndLogEx(INFO, "." NOLF);
|
||||
|
||||
// Select card to get UID/UIDLEN information
|
||||
clearCommandBuffer();
|
||||
|
@ -6850,14 +7156,20 @@ static int CmdHF14AGen4View(const char *Cmd) {
|
|||
|
||||
for (uint16_t i = 0; i < block_cnt; i++) {
|
||||
|
||||
// 4k READs can be long, so we split status each 64 blocks.
|
||||
if (i % 64 == 0) {
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(INFO, "" NOLF) ;
|
||||
}
|
||||
PrintAndLogEx(NORMAL, "." NOLF);
|
||||
fflush(stdout);
|
||||
|
||||
if (mfG4GetBlock(pwd, i, dump + (i * MFBLOCK_SIZE)) != PM3_SUCCESS) {
|
||||
PrintAndLogEx(WARNING, "Can't get magic card block: %u", i);
|
||||
PrintAndLogEx(HINT, "Verify your card size, and try again or try another tag position");
|
||||
free(dump);
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
PrintAndLogEx(NORMAL, "." NOLF);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
|
@ -7131,6 +7443,9 @@ static command_t CommandTable[] = {
|
|||
{"gen3blk", CmdHf14AGen3Block, IfPm3Iso14443a, "Overwrite manufacturer block"},
|
||||
{"gen3freeze", CmdHf14AGen3Freeze, IfPm3Iso14443a, "Perma lock UID changes. irreversible"},
|
||||
{"-----------", CmdHelp, IfPm3Iso14443a, "-------------------- " _CYAN_("magic gen4 GTU") " --------------------------"},
|
||||
{"ggetblk", CmdHF14AGen4GetBlk, IfPm3Iso14443a, "Read block from card"},
|
||||
{"gload", CmdHF14AGen4Load, IfPm3Iso14443a, "Load dump to card"},
|
||||
{"gsetblk", CmdHF14AGen4SetBlk, IfPm3Iso14443a, "Write block to card"},
|
||||
{"gview", CmdHF14AGen4View, IfPm3Iso14443a, "View card"},
|
||||
{"-----------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("ndef") " -----------------------"},
|
||||
// {"ice", CmdHF14AMfice, IfPm3Iso14443a, "collect MIFARE Classic nonces to file"},
|
||||
|
|
|
@ -1181,6 +1181,29 @@ int mfG4GetBlock(uint8_t *pwd, uint8_t blockno, uint8_t *data) {
|
|||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
int mfG4SetBlock(uint8_t *pwd, uint8_t blockno, uint8_t *data) {
|
||||
struct p {
|
||||
uint8_t blockno;
|
||||
uint8_t pwd[4];
|
||||
uint8_t data[16];
|
||||
} PACKED payload;
|
||||
payload.blockno = blockno;
|
||||
memcpy(payload.pwd, pwd, sizeof(payload.pwd));
|
||||
memcpy(payload.data, data, sizeof(payload.data));
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommandNG(CMD_HF_MIFARE_G4_WRBL, (uint8_t *)&payload, sizeof(payload));
|
||||
PacketResponseNG resp;
|
||||
if (WaitForResponseTimeout(CMD_HF_MIFARE_G4_WRBL, &resp, 1500)) {
|
||||
if (resp.status != PM3_SUCCESS) {
|
||||
return PM3_EUNDEF;
|
||||
}
|
||||
} else {
|
||||
PrintAndLogEx(WARNING, "command execute timeout");
|
||||
return PM3_ETIMEOUT;
|
||||
}
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
// variables
|
||||
uint32_t cuid = 0; // uid part used for crypto1.
|
||||
|
|
|
@ -96,6 +96,7 @@ int mfGen3Block(uint8_t *block, int blockLen, uint8_t *newBlock);
|
|||
int mfGen3Freeze(void);
|
||||
|
||||
int mfG4GetBlock(uint8_t *pwd, uint8_t blockno, uint8_t *data);
|
||||
int mfG4SetBlock(uint8_t *pwd, uint8_t blockno, uint8_t *data);
|
||||
|
||||
int tryDecryptWord(uint32_t nt, uint32_t ar_enc, uint32_t at_enc, uint8_t *data, int len);
|
||||
|
||||
|
|
|
@ -200,7 +200,8 @@ const static vocabulory_t vocabulory[] = {
|
|||
{ 1, "hf cipurse test" },
|
||||
{ 1, "hf epa help" },
|
||||
{ 0, "hf epa cnonces" },
|
||||
{ 0, "hf epa preplay" },
|
||||
{ 0, "hf epa replay" },
|
||||
{ 0, "hf epa sim" },
|
||||
{ 1, "hf emrtd help" },
|
||||
{ 0, "hf emrtd dump" },
|
||||
{ 1, "hf emrtd info" },
|
||||
|
@ -346,6 +347,9 @@ const static vocabulory_t vocabulory[] = {
|
|||
{ 0, "hf mf gen3uid" },
|
||||
{ 0, "hf mf gen3blk" },
|
||||
{ 0, "hf mf gen3freeze" },
|
||||
{ 0, "hf mf ggetblk" },
|
||||
{ 0, "hf mf gload" },
|
||||
{ 0, "hf mf gsetblk" },
|
||||
{ 0, "hf mf gview" },
|
||||
{ 0, "hf mf ndefformat" },
|
||||
{ 0, "hf mf ndefread" },
|
||||
|
@ -583,6 +587,7 @@ const static vocabulory_t vocabulory[] = {
|
|||
{ 0, "lf idteck clone" },
|
||||
{ 0, "lf idteck sim" },
|
||||
{ 1, "lf indala help" },
|
||||
{ 0, "lf indala brute" },
|
||||
{ 1, "lf indala demod" },
|
||||
{ 1, "lf indala altdemod" },
|
||||
{ 0, "lf indala reader" },
|
||||
|
|
|
@ -4303,6 +4303,64 @@
|
|||
],
|
||||
"usage": "hf mf gen3uid [-h] [-u <hex>]"
|
||||
},
|
||||
"hf mf ggetblk": {
|
||||
"command": "hf mf ggetblk",
|
||||
"description": "Get block data from magic gen4 GTU card.",
|
||||
"notes": [
|
||||
"hf mf ggetblk --blk 0 -> get block 0 (manufacturer)",
|
||||
"hf mf ggetblk --blk 3 -v -> get block 3, decode sector trailer"
|
||||
],
|
||||
"offline": false,
|
||||
"options": [
|
||||
"-h, --help This help",
|
||||
"-b, --blk <dec> block number",
|
||||
"-v, --verbose verbose output",
|
||||
"-p, --pwd <hex> password 4bytes"
|
||||
],
|
||||
"usage": "hf mf ggetblk [-hv] -b <dec> [-p <hex>]"
|
||||
},
|
||||
"hf mf gload": {
|
||||
"command": "hf mf gload",
|
||||
"description": "Load magic gen4 gtu card with data from (bin/eml/json) dump file or from emulator memory.",
|
||||
"notes": [
|
||||
"hf mf gload --emu",
|
||||
"hf mf gload -f hf-mf-01020304.eml",
|
||||
"hf mf gload -p AABBCCDD --4k -v -f hf-mf-01020304-dump.bin",
|
||||
"",
|
||||
"Card must be configured beforehand with `script run hf_mf_ultimatecard`.",
|
||||
"Blocks are 16 bytes long."
|
||||
],
|
||||
"offline": false,
|
||||
"options": [
|
||||
"-h, --help This help",
|
||||
"--mini MIFARE Classic Mini / S20",
|
||||
"--1k MIFARE Classic 1k / S50 (def)",
|
||||
"--2k MIFARE Classic/Plus 2k",
|
||||
"--4k MIFARE Classic 4k / S70",
|
||||
"-p, --pwd <hex> password 4bytes",
|
||||
"-v, --verbose verbose output",
|
||||
"-f, --file <fn> filename of dump",
|
||||
"--emu from emulator memory",
|
||||
"--start <dec> index of block to start writing (default 0)",
|
||||
"--end <dec> index of block to end writing (default last block)"
|
||||
],
|
||||
"usage": "hf mf gload [-hv] [--mini] [--1k] [--2k] [--4k] [-p <hex>] [-f <fn>] [--emu] --start <dec> --end <dec>"
|
||||
},
|
||||
"hf mf gsetblk": {
|
||||
"command": "hf mf gsetblk",
|
||||
"description": "Set block data on a magic gen4 GTU card",
|
||||
"notes": [
|
||||
"hf mf gsetblk --blk 1 -d 000102030405060708090a0b0c0d0e0f"
|
||||
],
|
||||
"offline": false,
|
||||
"options": [
|
||||
"-h, --help This help",
|
||||
"-b, --blk <dec> block number",
|
||||
"-d, --data <hex> bytes to write, 16 hex bytes",
|
||||
"-p, --pwd <hex> password 4bytes"
|
||||
],
|
||||
"usage": "hf mf gsetblk [-h] -b <dec> [-d <hex>] [-p <hex>]"
|
||||
},
|
||||
"hf mf gview": {
|
||||
"command": "hf mf gview",
|
||||
"description": "View `magic gen4 gtu` card memory",
|
||||
|
@ -11537,8 +11595,8 @@
|
|||
}
|
||||
},
|
||||
"metadata": {
|
||||
"commands_extracted": 728,
|
||||
"commands_extracted": 731,
|
||||
"extracted_by": "PM3Help2JSON v1.00",
|
||||
"extracted_on": "2022-10-30T15:28:49"
|
||||
"extracted_on": "2022-11-05T18:17:23"
|
||||
}
|
||||
}
|
|
@ -510,6 +510,9 @@ Check column "offline" for their availability.
|
|||
|`hf mf gen3uid `|N |`Set UID without changing manufacturer block`
|
||||
|`hf mf gen3blk `|N |`Overwrite manufacturer block`
|
||||
|`hf mf gen3freeze `|N |`Perma lock UID changes. irreversible`
|
||||
|`hf mf ggetblk `|N |`Read block from card`
|
||||
|`hf mf gload `|N |`Load dump to card`
|
||||
|`hf mf gsetblk `|N |`Write block to card`
|
||||
|`hf mf gview `|N |`View card`
|
||||
|`hf mf ndefformat `|N |`Format MIFARE Classic Tag as NFC Tag`
|
||||
|`hf mf ndefread `|N |`Read and print NDEF records from card`
|
||||
|
|
|
@ -676,6 +676,7 @@ typedef struct {
|
|||
|
||||
// Gen 4 GTU magic cards
|
||||
#define CMD_HF_MIFARE_G4_RDBL 0x0860
|
||||
#define CMD_HF_MIFARE_G4_WRBL 0x0861
|
||||
|
||||
#define CMD_UNKNOWN 0xFFFF
|
||||
|
||||
|
|
Loading…
Reference in a new issue