mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-03-03 19:43:09 +08:00
Merge pull request #1174 from McEloff/trace_list_mf_dict
`trace list -t mf` - now can use external dictionary keys file
This commit is contained in:
commit
375909653d
4 changed files with 56 additions and 13 deletions
|
@ -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 `trace list -t mf` - now can use external dictionary keys file
|
||||
- Added support for bidirectional communication for `lf em 4x50 sim` (@tharexde)
|
||||
- Change `PLATFORM=PM3OTHER` to `PLATFORM=PM3GENERIC` (@iceman1001)
|
||||
- Added `tools/hitag2crack/crack5opencl`, an optimized version of `crack5gpu` (@matrix)
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
#include "commonutil.h" // ARRAYLEN
|
||||
#include "mifare/mifarehost.h"
|
||||
#include "mifare/mifaredefault.h"
|
||||
#include "parity.h" // oddparity
|
||||
#include "ui.h"
|
||||
#include "crc16.h"
|
||||
|
@ -1335,7 +1334,7 @@ void annotateMifare(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, uint8
|
|||
|
||||
}
|
||||
|
||||
bool DecodeMifareData(uint8_t *cmd, uint8_t cmdsize, uint8_t *parity, bool isResponse, uint8_t *mfData, size_t *mfDataLen) {
|
||||
bool DecodeMifareData(uint8_t *cmd, uint8_t cmdsize, uint8_t *parity, bool isResponse, uint8_t *mfData, size_t *mfDataLen, const uint64_t *dicKeys, uint32_t dicKeysCount) {
|
||||
static struct Crypto1State *traceCrypto1;
|
||||
|
||||
*mfDataLen = 0;
|
||||
|
@ -1383,12 +1382,12 @@ bool DecodeMifareData(uint8_t *cmd, uint8_t cmdsize, uint8_t *parity, bool isRes
|
|||
}
|
||||
|
||||
// check default keys
|
||||
if (!traceCrypto1) {
|
||||
for (int i = 0; i < ARRAYLEN(g_mifare_default_keys); i++) {
|
||||
if (NestedCheckKey(g_mifare_default_keys[i], &AuthData, cmd, cmdsize, parity)) {
|
||||
PrintAndLogEx(NORMAL, " | | * |%61s " _GREEN_("%012" PRIX64) "| |", "key", g_mifare_default_keys[i]);
|
||||
if (!traceCrypto1 && dicKeys != NULL && dicKeysCount > 0) {
|
||||
for (int i = 0; i < dicKeysCount; i++) {
|
||||
if (NestedCheckKey(dicKeys[i], &AuthData, cmd, cmdsize, parity)) {
|
||||
PrintAndLogEx(NORMAL, " | | * |%60s " _GREEN_("%012" PRIX64) "| |", "key", dicKeys[i]);
|
||||
|
||||
mfLastKey = g_mifare_default_keys[i];
|
||||
mfLastKey = dicKeys[i];
|
||||
traceCrypto1 = lfsr_recovery64(AuthData.ks2, AuthData.ks3);
|
||||
break;
|
||||
};
|
||||
|
|
|
@ -51,7 +51,7 @@ void annotateMifare(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, uint8
|
|||
void annotateLTO(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize);
|
||||
void annotateCryptoRF(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize);
|
||||
|
||||
bool DecodeMifareData(uint8_t *cmd, uint8_t cmdsize, uint8_t *parity, bool isResponse, uint8_t *mfData, size_t *mfDataLen);
|
||||
bool DecodeMifareData(uint8_t *cmd, uint8_t cmdsize, uint8_t *parity, bool isResponse, uint8_t *mfData, size_t *mfDataLen, const uint64_t *dicKeys, uint32_t dicKeysCount);
|
||||
bool NTParityChk(TAuthData *ad, uint32_t ntx);
|
||||
bool NestedCheckKey(uint64_t key, TAuthData *ad, uint8_t *cmd, uint8_t cmdsize, uint8_t *parity);
|
||||
bool CheckCrypto1Parity(uint8_t *cmd_enc, uint8_t cmdsize, uint8_t *cmd, uint8_t *parity_enc);
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#include "protocols.h"
|
||||
#include "parity.h" // oddparity
|
||||
#include "cmdhflist.h" // annotations
|
||||
#include "commonutil.h" // ARRAYLEN
|
||||
#include "mifare/mifaredefault.h" // mifare default key array
|
||||
#include "comms.h" // for sending cmds to device. GetFromBigBuf
|
||||
#include "fileutils.h" // for saveFile
|
||||
#include "cmdlfhitag.h" // annotate hitag
|
||||
|
@ -131,7 +133,8 @@ static uint16_t printHexLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trac
|
|||
return ret;
|
||||
}
|
||||
|
||||
static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, uint8_t protocol, bool showWaitCycles, bool markCRCBytes, uint32_t *prev_eot, bool use_us) {
|
||||
static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, uint8_t protocol, bool showWaitCycles, bool markCRCBytes, uint32_t *prev_eot, bool use_us,
|
||||
const uint64_t *mfDicKeys, uint32_t mfDicKeysCount) {
|
||||
// sanity check
|
||||
if (is_last_record(tracepos, traceLen)) {
|
||||
PrintAndLogEx(DEBUG, "last record triggered. t-pos: %u t-len %u", tracepos, traceLen);
|
||||
|
@ -428,7 +431,7 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr
|
|||
}
|
||||
|
||||
if (protocol == PROTO_MIFARE) {
|
||||
if (DecodeMifareData(frame, data_len, parityBytes, hdr->isResponse, mfData, &mfDataLen)) {
|
||||
if (DecodeMifareData(frame, data_len, parityBytes, hdr->isResponse, mfData, &mfDataLen, mfDicKeys, mfDicKeysCount)) {
|
||||
memset(explanation, 0x00, sizeof(explanation));
|
||||
if (hdr->isResponse == false) {
|
||||
annotateIso14443a(explanation, sizeof(explanation), mfData, mfDataLen);
|
||||
|
@ -612,8 +615,9 @@ int CmdTraceList(const char *Cmd) {
|
|||
"trace list -t hitags -> interpret as " _YELLOW_("HitagS") " communications\n"
|
||||
"trace list -t lto -> interpret as " _YELLOW_("LTO-CM") " communications\n"
|
||||
"trace list -t cryptorf -> interpret as " _YELLOW_("CryptoRF") " communitcations\n"
|
||||
"trace list -t 14a -f -> show frame delay times\n"
|
||||
"trace list -t 14a -1 -> use trace buffer "
|
||||
"trace list -t mf --dict <mfc_default_keys> -> use dictionary keys file\n"
|
||||
"trace list -t 14a -f -> show frame delay times\n"
|
||||
"trace list -t 14a -1 -> use trace buffer "
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
|
@ -626,6 +630,7 @@ int CmdTraceList(const char *Cmd) {
|
|||
arg_lit0("x", NULL, "show hexdump to convert to pcap(ng)\n"
|
||||
" or to import into Wireshark using encapsulation type \"ISO 14443\""),
|
||||
arg_strx0("t", "type", NULL, "protocol to annotate the trace"),
|
||||
arg_strx0(NULL, "dict", "<file>", "use dictionary keys file"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
@ -642,6 +647,13 @@ int CmdTraceList(const char *Cmd) {
|
|||
CLIParamStrToBuf(arg_get_str(ctx, 7), (uint8_t *)type, sizeof(type), &tlen);
|
||||
str_lower(type);
|
||||
|
||||
int diclen = 0;
|
||||
char dictionary[FILE_PATH_SIZE + 2] = {0};
|
||||
if (CLIParamStrToBuf(arg_get_str(ctx, 8), (uint8_t *)dictionary, FILE_PATH_SIZE, &diclen)) {
|
||||
PrintAndLogEx(FAILED, "Dictionary file name too long or invalid.");
|
||||
diclen = 0;
|
||||
}
|
||||
|
||||
CLIParserFree(ctx);
|
||||
|
||||
clearCommandBuffer();
|
||||
|
@ -742,6 +754,34 @@ int CmdTraceList(const char *Cmd) {
|
|||
}
|
||||
|
||||
|
||||
const uint64_t *dicKeys = NULL;
|
||||
uint32_t dicKeysCount = 0;
|
||||
bool dictionaryLoad = false;
|
||||
|
||||
if (protocol == PROTO_MIFARE) {
|
||||
if (diclen > 0) {
|
||||
uint8_t *keyBlock = NULL;
|
||||
int res = loadFileDICTIONARY_safe(dictionary, (void **) &keyBlock, 6, &dicKeysCount);
|
||||
if (res != PM3_SUCCESS || dicKeysCount == 0 || keyBlock == NULL) {
|
||||
PrintAndLogEx(FAILED, "An error occurred while loading the dictionary! (we will use the default keys now)");
|
||||
} else {
|
||||
dicKeys = calloc(dicKeysCount, sizeof(uint64_t));
|
||||
for (int i = 0; i < dicKeysCount; i++) {
|
||||
uint64_t key = bytes_to_num(keyBlock + i * 6, 6);
|
||||
memcpy((uint8_t *) &dicKeys[i], &key, sizeof(uint64_t));
|
||||
}
|
||||
dictionaryLoad = true;
|
||||
}
|
||||
if (keyBlock != NULL) {
|
||||
free(keyBlock);
|
||||
}
|
||||
}
|
||||
if (dicKeys == NULL) {
|
||||
dicKeys = g_mifare_default_keys;
|
||||
dicKeysCount = ARRAYLEN(g_mifare_default_keys);
|
||||
}
|
||||
}
|
||||
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
if (use_relative) {
|
||||
PrintAndLogEx(NORMAL, " Gap | Duration | Src | Data (! denotes parity error, ' denotes short bytes) | CRC | Annotation");
|
||||
|
@ -761,11 +801,14 @@ int CmdTraceList(const char *Cmd) {
|
|||
}
|
||||
|
||||
while (tracepos < g_traceLen) {
|
||||
tracepos = printTraceLine(tracepos, g_traceLen, g_trace, protocol, show_wait_cycles, mark_crc, prev_EOT, use_us);
|
||||
tracepos = printTraceLine(tracepos, g_traceLen, g_trace, protocol, show_wait_cycles, mark_crc, prev_EOT, use_us, dicKeys, dicKeysCount);
|
||||
|
||||
if (kbd_enter_pressed())
|
||||
break;
|
||||
}
|
||||
|
||||
if (dictionaryLoad)
|
||||
free((void *) dicKeys);
|
||||
}
|
||||
|
||||
if (show_hex)
|
||||
|
|
Loading…
Reference in a new issue