mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2026-05-12 11:18:11 -07:00
@@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file.
|
||||
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
|
||||
|
||||
## [unreleased][unreleased]
|
||||
- Added `hf secc` to build a base for simulating basic function of iclass SE config cards (@antiklesys)
|
||||
- Improved SIO parsing for `hf iclass view` based on Iceman's "Dismantling the SEOS Protocol" talk (@antiklesys)
|
||||
- Added live fc/cn update to `hf iclass tagsim` refreshing the csn with each update (@antiklesys)
|
||||
- Added `--live` option to `hf iclass lookup` command to perform a live recovery of the reader's key by simulating a tag and running the lookup command against both standard and elite dictionaries (@antiklesys)
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ APP_CFLAGS = $(PLATFORM_DEFS) \
|
||||
SRC_LF = lfops.c lfsampling.c pcf7931.c lfdemod.c lfadc.c
|
||||
SRC_HF = hfops.c
|
||||
SRC_ISO15693 = iso15693.c iso15693tools.c
|
||||
SRC_ISO14443a = iso14443a.c mifareutil.c mifarecmd.c epa.c mifaresim.c sam_common.c sam_mfc.c sam_seos.c
|
||||
SRC_ISO14443a = iso14443a.c secc.c mifareutil.c mifarecmd.c epa.c mifaresim.c sam_common.c sam_mfc.c sam_seos.c
|
||||
|
||||
#UNUSED: mifaresniff.c
|
||||
SRC_ISO14443b = iso14443b.c
|
||||
|
||||
+582
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,84 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// See LICENSE.txt for the text of the license.
|
||||
//-----------------------------------------------------------------------------
|
||||
// HID Config Card (JCOP / GlobalPlatform SCP02) simulation helpers.
|
||||
// Called from iso14443a.c; isolated here to keep HID-specific logic separate.
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef SECC_H__
|
||||
#define SECC_H__
|
||||
|
||||
#include "common.h"
|
||||
#include "mifare.h" // tag_response_info_t
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Shared payload structs (used by both ARM and client via CMD_HF_HIDCONFIG_SIM)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#define HID_APDU_MAX_ENTRIES 8
|
||||
#define HID_APDU_MAX_CMD 20 // max APDU command bytes to prefix-match
|
||||
#define HID_APDU_MAX_RESP 32 // max response bytes (without PCB/CID/CRC)
|
||||
|
||||
// One custom APDU override entry: if the incoming APDU starts with
|
||||
// apdu[0..apdu_len-1], respond with resp[0..resp_len-1] (raw APDU payload).
|
||||
typedef struct {
|
||||
uint8_t apdu[HID_APDU_MAX_CMD];
|
||||
uint8_t apdu_len;
|
||||
uint8_t resp[HID_APDU_MAX_RESP];
|
||||
uint8_t resp_len;
|
||||
} PACKED hid_apdu_entry_t;
|
||||
|
||||
// Full simulation payload sent from client to ARM via CMD_HF_HIDCONFIG_SIM.
|
||||
// ATQA is stored big-endian: atqa[0] = high byte (used as rATQA[0] in SimulateIso14443aInit).
|
||||
typedef struct {
|
||||
uint8_t tagtype;
|
||||
uint16_t flags;
|
||||
uint8_t uid[10];
|
||||
uint8_t exitAfter;
|
||||
uint8_t atqa[2]; // ATQA override (big-endian: [0]=high, [1]=low)
|
||||
uint8_t sak; // SAK override
|
||||
uint8_t scp02_key[16]; // SCP02 master key (from JSON "SCP02Key")
|
||||
uint8_t ats[20]; // ATS bytes without CRC (from JSON "ATS")
|
||||
uint8_t ats_len; // actual number of valid bytes in ats[]
|
||||
uint8_t apdu_count;
|
||||
hid_apdu_entry_t apdu_table[HID_APDU_MAX_ENTRIES];
|
||||
} PACKED hid_sim_payload_t;
|
||||
|
||||
// Load a custom APDU response table into static storage (call before sim loop).
|
||||
void hid_config_card_set_apdu_table(const hid_apdu_entry_t *table, uint8_t count);
|
||||
|
||||
// Run a complete HID Config Card simulation using payload received from the client.
|
||||
void SimulateHIDConfigCard(const hid_sim_payload_t *payload);
|
||||
|
||||
// Sniff ISO 14443-A with optional jamming of A0 D4 00 00 00 (param bit 0x04).
|
||||
void SniffHIDConfigCard(uint8_t param);
|
||||
|
||||
// Handle an I-block received during HID Config Card (tagType=16) simulation.
|
||||
// Fills dynamic_response_info with the appropriate response payload (without CRC).
|
||||
// Returns true if a response was prepared, false if the command was not handled.
|
||||
bool hid_config_card_handle_iblock(const uint8_t *cmd, int len, tag_response_info_t *response_info);
|
||||
|
||||
// CID-aware ISO 14443-4 APDU exchange for HID Config Card reader interaction.
|
||||
// Sends I-blocks with PCB=0x0A (CID present, CID=0) as negotiated in RATS.
|
||||
// Strips PCB+CID from received responses. API mirrors iso14_apdu().
|
||||
int hid_config_card_iso14_apdu(uint8_t *cmd, uint16_t cmd_len, bool send_chaining, void *data, uint16_t data_len, uint8_t *res);
|
||||
|
||||
// Handle a sniff-mode jam: inspect cmd and, if it matches A0 D4 00 00 00,
|
||||
// transmit the jam response and restore sniffer FPGA mode + re-arm DMA.
|
||||
// dma_buf: pointer to the DMA ring buffer start (passed to FpgaSetupSscDma).
|
||||
// Returns true if the frame was jammed; caller must then reset its data pointer
|
||||
// back to the DMA buffer start and continue the sniff loop.
|
||||
bool hid_config_card_jam(const uint8_t *cmd, int len, uint8_t *dma_buf);
|
||||
|
||||
#endif // SECC_H__
|
||||
@@ -390,6 +390,7 @@ set (TARGET_SOURCES
|
||||
${PM3_ROOT}/client/src/cmdhfgallagher.c
|
||||
${PM3_ROOT}/client/src/cmdhfgst.c
|
||||
${PM3_ROOT}/client/src/cmdhfcipurse.c
|
||||
${PM3_ROOT}/client/src/cmdhfsecc.c
|
||||
${PM3_ROOT}/client/src/cmdhficlass.c
|
||||
${PM3_ROOT}/client/src/cmdhfict.c
|
||||
${PM3_ROOT}/client/src/cmdhfjooki.c
|
||||
|
||||
@@ -696,6 +696,7 @@ SRCS = mifare/aiddesfire.c \
|
||||
cmdhfgst.c \
|
||||
cmdhfksx6924.c \
|
||||
cmdhfcipurse.c \
|
||||
cmdhfsecc.c \
|
||||
cmdhficlass.c \
|
||||
cmdhfict.c \
|
||||
cmdhflegic.c \
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"UID": "8F042795",
|
||||
"AID": "A0000003820013000101",
|
||||
"SCP02Key": "404142434445464748494A4B4C4D4E4F",
|
||||
"ATS": "1478F7B10280590180415254454346477300011B",
|
||||
"APDUResponses": [
|
||||
{
|
||||
"_comment": "Prefix-match SELECT by AID (17) -> 9000 (ok)",
|
||||
"APDU": "00A404000AA000000382001700010100",
|
||||
"Response": "9000"
|
||||
},
|
||||
{
|
||||
"_comment": "Prefix-match SELECT by AID (13) -> 6A82 (file not found)",
|
||||
"APDU": "00A404000AA000000382001300010100",
|
||||
"Response": "6A82"
|
||||
},
|
||||
{
|
||||
"_comment": "Check card credits: A0 D4 00 00 00 -> 00 00 90 00 (reply 0)",
|
||||
"APDU": "A0D4000000",
|
||||
"Response": "00009000"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,313 @@
|
||||
|
||||
#include "cmdhfsecc.h"
|
||||
|
||||
#include <string.h>
|
||||
#include "cmdparser.h" // command_t
|
||||
#include "cliparser.h" // CLIParser*
|
||||
#include "comms.h" // SendCommandNG, WaitForResponseTimeout, clearCommandBuffer
|
||||
#include "ui.h" // PrintAndLogEx
|
||||
#include "util.h" // kbd_enter_pressed, hex_to_bytes
|
||||
#include "cmdhf14a.h" // IfPm3Iso14443a
|
||||
#include "pm3_cmd.h" // CMD_HF_ISO14443A_SIMULATE, CMD_HF_ISO14443A_SNIFF, CMD_BREAK_LOOP, FLAG_SET_UID_IN_DATA
|
||||
#include "jansson.h" // json_load_file, json_object_get, json_string_value, json_decref
|
||||
#include "fileutils.h" // searchFile, RESOURCES_SUBDIR
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Payload structs shared with armsrc/secc.h
|
||||
// Must stay in sync with hid_apdu_entry_t / hid_sim_payload_t.
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#define HID_APDU_MAX_ENTRIES 8
|
||||
#define HID_APDU_MAX_CMD 20
|
||||
#define HID_APDU_MAX_RESP 32
|
||||
|
||||
typedef struct {
|
||||
uint8_t apdu[HID_APDU_MAX_CMD];
|
||||
uint8_t apdu_len;
|
||||
uint8_t resp[HID_APDU_MAX_RESP];
|
||||
uint8_t resp_len;
|
||||
} PACKED hid_apdu_entry_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t tagtype;
|
||||
uint16_t flags;
|
||||
uint8_t uid[10];
|
||||
uint8_t exitAfter;
|
||||
uint8_t atqa[2]; // big-endian: [0]=high byte, [1]=low byte
|
||||
uint8_t sak;
|
||||
uint8_t scp02_key[16]; // SCP02 master key (from JSON "SCP02Key")
|
||||
uint8_t ats[20]; // ATS bytes without CRC (from JSON "ATS")
|
||||
uint8_t ats_len; // actual number of valid bytes in ats[]
|
||||
uint8_t apdu_count;
|
||||
hid_apdu_entry_t apdu_table[HID_APDU_MAX_ENTRIES];
|
||||
} PACKED hid_sim_payload_t;
|
||||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// hf hidconfig sim
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
static int CmdHFHIDConfigSim(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf hidconfig sim",
|
||||
"Simulate a HID iCLASS SE Config Card (JCOP / GlobalPlatform SCP02).\n"
|
||||
"Responds to SELECT AID (0013/0017), A0 D4, INITIALIZE UPDATE, and EXTERNAL AUTH.\n"
|
||||
"Load card parameters (UID, AID, SCP02Key) from a JSON file.",
|
||||
"hf hidconfig sim -f hidconfig_sample\n"
|
||||
"hf hidconfig sim -f hidconfig_sample -n 5 -> stop after 5 reader interactions");
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_str1("f", "file", "<fn>", "JSON file with UID, AID, SCP02Key (without .json extension)"),
|
||||
arg_int0("n", "num", "<dec>", "Exit after <n> reader interactions. 0 = infinite"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
char filename[FILE_PATH_SIZE] = {0};
|
||||
int filenamelen = sizeof(filename) - 1;
|
||||
CLIGetStrWithReturn(ctx, 1, (uint8_t *)filename, &filenamelen);
|
||||
uint8_t exitAfterNReads = (uint8_t)arg_get_int_def(ctx, 2, 0);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
// Load JSON from client/resources/
|
||||
char *filepath = NULL;
|
||||
if (searchFile(&filepath, RESOURCES_SUBDIR, filename, ".json", false) != PM3_SUCCESS) {
|
||||
PrintAndLogEx(ERR, "JSON file '%s.json' not found in resources directory", filename);
|
||||
return PM3_EFILE;
|
||||
}
|
||||
|
||||
json_error_t jerr;
|
||||
json_t *root = json_load_file(filepath, 0, &jerr);
|
||||
free(filepath);
|
||||
if (root == NULL) {
|
||||
PrintAndLogEx(ERR, "Failed to load JSON file '%s.json': %s", filename, jerr.text);
|
||||
return PM3_EFILE;
|
||||
}
|
||||
|
||||
// Parse UID
|
||||
uint8_t uid[10] = {0};
|
||||
int uidlen = 0;
|
||||
json_t *juid = json_object_get(root, "UID");
|
||||
if (json_is_string(juid) == false) {
|
||||
PrintAndLogEx(ERR, "JSON missing or invalid 'UID' field");
|
||||
json_decref(root);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
uidlen = hex_to_bytes(json_string_value(juid), uid, sizeof(uid));
|
||||
if (uidlen != 4 && uidlen != 7 && uidlen != 10) {
|
||||
PrintAndLogEx(ERR, "UID must be 4, 7, or 10 bytes (got %d)", uidlen);
|
||||
json_decref(root);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
// Parse AID (informational only)
|
||||
char aid_str[32] = {0};
|
||||
json_t *jaid = json_object_get(root, "AID");
|
||||
if (json_is_string(jaid))
|
||||
snprintf(aid_str, sizeof(aid_str), "%s", json_string_value(jaid));
|
||||
|
||||
// Parse SCP02Key (16 bytes)
|
||||
uint8_t scp02_key[16] = {0};
|
||||
json_t *jkey = json_object_get(root, "SCP02Key");
|
||||
if (json_is_string(jkey) == false) {
|
||||
PrintAndLogEx(ERR, "JSON missing or invalid 'SCP02Key' field");
|
||||
json_decref(root);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
if (hex_to_bytes(json_string_value(jkey), scp02_key, sizeof(scp02_key)) != 16) {
|
||||
PrintAndLogEx(ERR, "SCP02Key must be exactly 16 bytes (32 hex chars)");
|
||||
json_decref(root);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
// Parse ATS (1-20 bytes, without CRC)
|
||||
uint8_t ats[20] = {0};
|
||||
int ats_len = 0;
|
||||
json_t *jats = json_object_get(root, "ATS");
|
||||
if (json_is_string(jats) == false) {
|
||||
PrintAndLogEx(ERR, "JSON missing or invalid 'ATS' field");
|
||||
json_decref(root);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
ats_len = hex_to_bytes(json_string_value(jats), ats, sizeof(ats));
|
||||
if (ats_len <= 0 || ats_len > 20) {
|
||||
PrintAndLogEx(ERR, "ATS must be 1-20 bytes (got %d)", ats_len);
|
||||
json_decref(root);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
// Parse optional APDUResponses array
|
||||
hid_apdu_entry_t apdu_table[HID_APDU_MAX_ENTRIES];
|
||||
uint8_t apdu_count = 0;
|
||||
memset(apdu_table, 0, sizeof(apdu_table));
|
||||
|
||||
json_t *jresps = json_object_get(root, "APDUResponses");
|
||||
if (json_is_array(jresps)) {
|
||||
size_t n = json_array_size(jresps);
|
||||
for (size_t i = 0; i < n && apdu_count < HID_APDU_MAX_ENTRIES; i++) {
|
||||
json_t *entry = json_array_get(jresps, i);
|
||||
json_t *japdu = json_object_get(entry, "APDU");
|
||||
json_t *jresp = json_object_get(entry, "Response");
|
||||
if (!json_is_string(japdu) || !json_is_string(jresp))
|
||||
continue;
|
||||
int alen = hex_to_bytes(json_string_value(japdu),
|
||||
apdu_table[apdu_count].apdu, HID_APDU_MAX_CMD);
|
||||
int rlen = hex_to_bytes(json_string_value(jresp),
|
||||
apdu_table[apdu_count].resp, HID_APDU_MAX_RESP);
|
||||
if (alen <= 0 || rlen <= 0) {
|
||||
PrintAndLogEx(WARNING, "APDUResponses[%zu]: invalid hex, skipping", i);
|
||||
continue;
|
||||
}
|
||||
apdu_table[apdu_count].apdu_len = (uint8_t)alen;
|
||||
apdu_table[apdu_count].resp_len = (uint8_t)rlen;
|
||||
PrintAndLogEx(INFO, "APDU override [%u]: %s -> %s",
|
||||
apdu_count, json_string_value(japdu), json_string_value(jresp));
|
||||
apdu_count++;
|
||||
}
|
||||
}
|
||||
|
||||
json_decref(root);
|
||||
|
||||
uint16_t flags = 0;
|
||||
FLAG_SET_UID_IN_DATA(flags, uidlen);
|
||||
|
||||
char uid_str[21] = {0};
|
||||
for (int i = 0; i < uidlen; i++)
|
||||
snprintf(uid_str + i * 2, sizeof(uid_str) - i * 2, "%02X", uid[i]);
|
||||
|
||||
PrintAndLogEx(INFO, "HID Config Card sim:"
|
||||
" UID " _YELLOW_("%s")
|
||||
" AID " _YELLOW_("%s")
|
||||
" ATS len " _YELLOW_("%d")
|
||||
" APDU overrides " _YELLOW_("%u"),
|
||||
uid_str, aid_str, ats_len, apdu_count);
|
||||
PrintAndLogEx(INFO, "Press " _GREEN_("pm3 button") " or " _GREEN_("<Enter>") " to abort simulation");
|
||||
|
||||
hid_sim_payload_t payload;
|
||||
memset(&payload, 0, sizeof(payload));
|
||||
payload.tagtype = 4; // ISO14443-4 base type; ATQA/SAK/ATS overridden by ARM
|
||||
payload.flags = flags;
|
||||
payload.exitAfter = exitAfterNReads;
|
||||
payload.atqa[0] = 0x02; // HID Config Card ATQA high byte
|
||||
payload.atqa[1] = 0x00; // HID Config Card ATQA low byte
|
||||
payload.sak = 0x38; // HID Config Card SAK
|
||||
payload.ats_len = (uint8_t)ats_len;
|
||||
payload.apdu_count = apdu_count;
|
||||
memcpy(payload.uid, uid, uidlen);
|
||||
memcpy(payload.scp02_key, scp02_key, sizeof(scp02_key));
|
||||
memcpy(payload.ats, ats, ats_len);
|
||||
memcpy(payload.apdu_table, apdu_table, apdu_count * sizeof(hid_apdu_entry_t));
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommandNG(CMD_HF_HIDCONFIG_SIM, (uint8_t *)&payload, sizeof(payload));
|
||||
|
||||
PacketResponseNG resp = {0};
|
||||
while (true) {
|
||||
if (WaitForResponseTimeout(CMD_HF_HIDCONFIG_SIM, &resp, 1500)) {
|
||||
if (resp.status != PM3_SUCCESS)
|
||||
break;
|
||||
}
|
||||
if (kbd_enter_pressed()) {
|
||||
SendCommandNG(CMD_BREAK_LOOP, NULL, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// hf hidconfig sniff
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
static int CmdHFHIDConfigSniff(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf hidconfig sniff",
|
||||
"Sniff the communication between a HID Config Card reader and card.\n"
|
||||
"Use `hf 14a list` to view collected data.",
|
||||
"hf hidconfig sniff\n"
|
||||
"hf hidconfig sniff -j -> jam A0 D4 00 00 00, respond 00 00 90 00\n"
|
||||
"hf hidconfig sniff -c -r -> trigger on card or reader data");
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_lit0("c", "card", "triggered by first data from card"),
|
||||
arg_lit0("r", "reader", "triggered by first 7-bit request from reader (REQ, WUP)"),
|
||||
arg_lit0("i", "interactive", "console will not be returned until sniff finishes or is aborted"),
|
||||
arg_lit0("j", "jam", "jam APDU A0 D4 00 00 00, respond with 00 00 90 00"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
||||
uint8_t param = 0;
|
||||
|
||||
if (arg_get_lit(ctx, 1))
|
||||
param |= 0x01;
|
||||
|
||||
if (arg_get_lit(ctx, 2))
|
||||
param |= 0x02;
|
||||
|
||||
bool interactive = arg_get_lit(ctx, 3);
|
||||
bool jam = arg_get_lit(ctx, 4);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (jam) {
|
||||
param |= 0x04;
|
||||
PrintAndLogEx(INFO, "Sniff with jam of APDU " _YELLOW_("A0 D4 00 00 00") " -> " _YELLOW_("00 00 90 00"));
|
||||
}
|
||||
|
||||
uint16_t sniff_cmd = jam ? CMD_HF_HIDCONFIG_SNIFF : CMD_HF_ISO14443A_SNIFF;
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommandNG(sniff_cmd, (uint8_t *)¶m, sizeof(uint8_t));
|
||||
|
||||
if (interactive) {
|
||||
PrintAndLogEx(INFO, "Press " _GREEN_("pm3 button") " or " _GREEN_("<Enter>") " to abort sniffing");
|
||||
|
||||
PacketResponseNG resp;
|
||||
bool keypress = kbd_enter_pressed();
|
||||
while (keypress == false) {
|
||||
keypress = kbd_enter_pressed();
|
||||
if (WaitForResponseTimeout(sniff_cmd, &resp, 500))
|
||||
break;
|
||||
}
|
||||
|
||||
if (keypress) {
|
||||
SendCommandNG(CMD_BREAK_LOOP, NULL, 0);
|
||||
WaitForResponse(sniff_cmd, &resp);
|
||||
}
|
||||
|
||||
PrintAndLogEx(INFO, "Done!");
|
||||
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf 14a list") "` to view captured tracelog");
|
||||
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("trace save -h") "` to save tracelog for later analysing");
|
||||
} else {
|
||||
PrintAndLogEx(INFO, "Press " _GREEN_("pm3 button") " to abort sniffing");
|
||||
}
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Command table
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
static command_t CommandTable[];
|
||||
|
||||
static int CmdHelp(const char *Cmd) {
|
||||
(void)Cmd;
|
||||
CmdsHelp(CommandTable);
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static command_t CommandTable[] = {
|
||||
{"--------", CmdHelp, AlwaysAvailable, "----------- " _CYAN_("HID Config Card") " -----------"},
|
||||
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
||||
{"sim", CmdHFHIDConfigSim, IfPm3Iso14443a, "Simulate HID iCLASS SE Config Card"},
|
||||
{"sniff", CmdHFHIDConfigSniff, IfPm3Iso14443a, "Sniff reader<->card, jam A0 D4 APDU"},
|
||||
{NULL, NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
int CmdHFHIDConfig(const char *Cmd) {
|
||||
clearCommandBuffer();
|
||||
return CmdsParse(CommandTable, Cmd);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
|
||||
#ifndef CMDHFSECC_H__
|
||||
#define CMDHFSECC_H__
|
||||
|
||||
#include "common.h"
|
||||
|
||||
int CmdHFHIDConfig(const char *Cmd);
|
||||
|
||||
#endif
|
||||
@@ -726,6 +726,8 @@ typedef struct {
|
||||
#define CMD_HF_ISO14443A_SNIFF 0x0383
|
||||
#define CMD_HF_ISO14443A_SIMULATE 0x0384
|
||||
#define CMD_HF_ISO14443A_SIM_AID 0x1420
|
||||
#define CMD_HF_HIDCONFIG_SIM 0x1421
|
||||
#define CMD_HF_HIDCONFIG_SNIFF 0x1422
|
||||
|
||||
#define CMD_HF_ISO14443A_READER 0x0385
|
||||
#define CMD_HF_ISO14443A_EMV_SIMULATE 0x0386
|
||||
|
||||
Reference in New Issue
Block a user