ADD: @go_tus simple bruteforce for t55xx, refactored a bit.
ADD: @pwpiwi 's implementation of Hardnested
This commit is contained in:
@@ -109,6 +109,7 @@ CMDSRCS = nonce2key/crapto1.c\
|
||||
cmdhficlass.c \
|
||||
cmdhfmf.c \
|
||||
cmdhfmfu.c \
|
||||
cmdhfmfhard.c \
|
||||
cmdhfmfdes.c \
|
||||
cmdhftopaz.c \
|
||||
cmdhw.c \
|
||||
|
||||
@@ -1987,7 +1987,11 @@ int getSamples(const char *Cmd, bool silent)
|
||||
GetFromBigBuf(got,n,0);
|
||||
PrintAndLog("Data fetched");
|
||||
UsbCommand response;
|
||||
WaitForResponse(CMD_ACK, &response);
|
||||
if ( !WaitForResponseTimeout(CMD_ACK, &response, 10000) ) {
|
||||
PrintAndLog("timeout while waiting for reply.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t bits_per_sample = 8;
|
||||
|
||||
//Old devices without this feature would send 0 at arg[0]
|
||||
@@ -2030,9 +2034,9 @@ int CmdTuneSamples(const char *Cmd)
|
||||
int timeout = 0;
|
||||
printf("\nMeasuring antenna characteristics, please wait...");
|
||||
|
||||
UsbCommand c = {CMD_MEASURE_ANTENNA_TUNING};
|
||||
UsbCommand c = {CMD_MEASURE_ANTENNA_TUNING, {0,0,0}};
|
||||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
|
||||
UsbCommand resp;
|
||||
while(!WaitForResponseTimeout(CMD_MEASURED_ANTENNA_TUNING,&resp,1000)) {
|
||||
timeout++;
|
||||
@@ -2080,7 +2084,6 @@ int CmdTuneSamples(const char *Cmd)
|
||||
ShowGraphWindow();
|
||||
RepaintGraphWindow();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2096,7 +2099,7 @@ int CmdLoad(const char *Cmd)
|
||||
|
||||
FILE *f = fopen(filename, "r");
|
||||
if (!f) {
|
||||
PrintAndLog("couldn't open '%s'", filename);
|
||||
PrintAndLog("couldn't open '%s'", filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2115,11 +2118,13 @@ int CmdLoad(const char *Cmd)
|
||||
int CmdLtrim(const char *Cmd)
|
||||
{
|
||||
int ds = atoi(Cmd);
|
||||
if (GraphTraceLen<=0) return 0;
|
||||
|
||||
if (GraphTraceLen <= 0) return 0;
|
||||
|
||||
for (int i = ds; i < GraphTraceLen; ++i)
|
||||
GraphBuffer[i-ds] = GraphBuffer[i];
|
||||
GraphTraceLen -= ds;
|
||||
|
||||
GraphTraceLen -= ds;
|
||||
RepaintGraphWindow();
|
||||
return 0;
|
||||
}
|
||||
@@ -2128,9 +2133,7 @@ int CmdLtrim(const char *Cmd)
|
||||
int CmdRtrim(const char *Cmd)
|
||||
{
|
||||
int ds = atoi(Cmd);
|
||||
|
||||
GraphTraceLen = ds;
|
||||
|
||||
RepaintGraphWindow();
|
||||
return 0;
|
||||
}
|
||||
|
||||
100
client/cmdhfmf.c
100
client/cmdhfmf.c
@@ -9,6 +9,7 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "cmdhfmf.h"
|
||||
#include "cmdhfmfhard.h"
|
||||
#include "nonce2key/nonce2key.h"
|
||||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
@@ -791,6 +792,104 @@ int CmdHF14AMfNested(const char *Cmd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int CmdHF14AMfNestedHard(const char *Cmd)
|
||||
{
|
||||
uint8_t blockNo = 0;
|
||||
uint8_t keyType = 0;
|
||||
uint8_t trgBlockNo = 0;
|
||||
uint8_t trgKeyType = 0;
|
||||
uint8_t key[6] = {0, 0, 0, 0, 0, 0};
|
||||
|
||||
char ctmp;
|
||||
ctmp = param_getchar(Cmd, 0);
|
||||
if (ctmp != 'R' && ctmp != 'r' && strlen(Cmd) < 20) {
|
||||
PrintAndLog("Usage:");
|
||||
PrintAndLog(" hf mf hardnested <block number> <key A|B> <key (12 hex symbols)>");
|
||||
PrintAndLog(" <target block number> <target key A|B> [w] [s]");
|
||||
PrintAndLog(" or hf mf hardnested r");
|
||||
PrintAndLog(" ");
|
||||
PrintAndLog("Options: ");
|
||||
PrintAndLog(" w: Acquire nonces and write them to binary file nonces.bin");
|
||||
PrintAndLog(" s: Slower acquisition (required by some non standard cards)");
|
||||
PrintAndLog(" r: Read nonces.bin and start attack");
|
||||
PrintAndLog(" ");
|
||||
PrintAndLog(" sample1: hf mf hardnested 0 A FFFFFFFFFFFF 4 A");
|
||||
PrintAndLog(" sample2: hf mf hardnested 0 A FFFFFFFFFFFF 4 A w");
|
||||
PrintAndLog(" sample3: hf mf hardnested 0 A FFFFFFFFFFFF 4 A w s");
|
||||
PrintAndLog(" sample4: hf mf hardnested r");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool nonce_file_read = false;
|
||||
bool nonce_file_write = false;
|
||||
bool slow = false;
|
||||
|
||||
if (ctmp == 'R' || ctmp == 'r') {
|
||||
|
||||
nonce_file_read = true;
|
||||
|
||||
} else {
|
||||
|
||||
blockNo = param_get8(Cmd, 0);
|
||||
ctmp = param_getchar(Cmd, 1);
|
||||
if (ctmp != 'a' && ctmp != 'A' && ctmp != 'b' && ctmp != 'B') {
|
||||
PrintAndLog("Key type must be A or B");
|
||||
return 1;
|
||||
}
|
||||
if (ctmp != 'A' && ctmp != 'a') {
|
||||
keyType = 1;
|
||||
}
|
||||
|
||||
if (param_gethex(Cmd, 2, key, 12)) {
|
||||
PrintAndLog("Key must include 12 HEX symbols");
|
||||
return 1;
|
||||
}
|
||||
|
||||
trgBlockNo = param_get8(Cmd, 3);
|
||||
ctmp = param_getchar(Cmd, 4);
|
||||
if (ctmp != 'a' && ctmp != 'A' && ctmp != 'b' && ctmp != 'B') {
|
||||
PrintAndLog("Target key type must be A or B");
|
||||
return 1;
|
||||
}
|
||||
if (ctmp != 'A' && ctmp != 'a') {
|
||||
trgKeyType = 1;
|
||||
}
|
||||
|
||||
uint16_t i = 5;
|
||||
while ((ctmp = param_getchar(Cmd, i))) {
|
||||
if (ctmp == 's' || ctmp == 'S') {
|
||||
slow = true;
|
||||
} else if (ctmp == 'w' || ctmp == 'W') {
|
||||
nonce_file_write = true;
|
||||
} else {
|
||||
PrintAndLog("Possible options are w and/or s");
|
||||
return 1;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
PrintAndLog("--target block no:%3d, target key type:%c, file action: %s, Slow: %s ",
|
||||
trgBlockNo,
|
||||
trgKeyType?'B':'A',
|
||||
nonce_file_write?"write":nonce_file_read?"read":"none",
|
||||
slow?"Yes":"No");
|
||||
int16_t isOK = mfnestedhard(blockNo, keyType, key, trgBlockNo, trgKeyType, nonce_file_read, nonce_file_write, slow);
|
||||
if (isOK) {
|
||||
switch (isOK) {
|
||||
case 1 : PrintAndLog("Error: No response from Proxmark.\n"); break;
|
||||
case 2 : PrintAndLog("Button pressed. Aborted.\n"); break;
|
||||
default : break;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int CmdHF14AMfChk(const char *Cmd)
|
||||
{
|
||||
if (strlen(Cmd)<3) {
|
||||
@@ -2017,6 +2116,7 @@ static command_t CommandTable[] =
|
||||
{"chk", CmdHF14AMfChk, 0, "Test block keys"},
|
||||
{"mifare", CmdHF14AMifare, 0, "Read parity error messages."},
|
||||
{"nested", CmdHF14AMfNested, 0, "Test nested authentication"},
|
||||
{"hardnested", CmdHF14AMfNestedHard, 0, "Nested attack for hardened Mifare cards"},
|
||||
{"sniff", CmdHF14AMfSniff, 0, "Sniff card-reader communication"},
|
||||
{"sim", CmdHF14AMf1kSim, 0, "Simulate MIFARE card"},
|
||||
{"eclr", CmdHF14AMfEClear, 0, "Clear simulator memory block"},
|
||||
|
||||
@@ -38,6 +38,7 @@ int CmdHF14AMfUWrBl(const char* cmd);
|
||||
int CmdHF14AMfChk(const char* cmd);
|
||||
int CmdHF14AMifare(const char* cmd);
|
||||
int CmdHF14AMfNested(const char* cmd);
|
||||
int CmdHF14AMfNestedHard(const char *Cmd);
|
||||
int CmdHF14AMfSniff(const char* cmd);
|
||||
int CmdHF14AMf1kSim(const char* cmd);
|
||||
int CmdHF14AMfEClear(const char* cmd);
|
||||
|
||||
@@ -134,7 +134,7 @@ int usage_t55xx_detect(){
|
||||
PrintAndLog("Examples:");
|
||||
PrintAndLog(" lf t55xx detect");
|
||||
PrintAndLog(" lf t55xx detect 1");
|
||||
PrintAndLog(" lf t55xx detect 11223344");
|
||||
PrintAndLog(" lf t55xx detect p 11223344");
|
||||
PrintAndLog("");
|
||||
return 0;
|
||||
}
|
||||
@@ -149,6 +149,14 @@ int usage_t55xx_wakup(){
|
||||
PrintAndLog(" lf t55xx wakeup p 11223344 - send wakeup password");
|
||||
return 0;
|
||||
}
|
||||
int usage_t55xx_bruteforce(){
|
||||
PrintAndLog("Usage: lf t55xx bruteforce <start password> <end password>");
|
||||
PrintAndLog(" password must be 4 bytes (8 hex symbols)");
|
||||
PrintAndLog("Examples:");
|
||||
PrintAndLog(" lf t55xx bruteforce aaaaaaaa bbbbbbbb");
|
||||
PrintAndLog("");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
|
||||
@@ -1307,20 +1315,61 @@ int CmdT55xxWipe(const char *Cmd) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdT55xxBruteForce(const char *Cmd) {
|
||||
uint32_t start_password = 0x00000000; //start password
|
||||
uint32_t end_password = 0xFFFFFFFF; //end password
|
||||
|
||||
bool found = false;
|
||||
char cmdp = param_getchar(Cmd, 0);
|
||||
if (cmdp == 'h' || cmdp == 'H') return usage_t55xx_bruteforce();
|
||||
|
||||
start_password = param_get32ex(Cmd, 0, 0, 16);
|
||||
end_password = param_get32ex(Cmd, 1, 0, 16);
|
||||
|
||||
if ( start_password == end_password ) return usage_t55xx_bruteforce();
|
||||
|
||||
PrintAndLog("Start Password %08x", start_password);
|
||||
PrintAndLog(" End Password %08x", end_password);
|
||||
|
||||
int i = start_password;
|
||||
|
||||
while ((!found) && (i <= end_password)){
|
||||
|
||||
AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, TRUE, i);
|
||||
found = tryDetectModulation();
|
||||
|
||||
if (found)
|
||||
break;
|
||||
|
||||
if ((i % 0x100) == 0) printf("[%08x], ",i);
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
PrintAndLog("");
|
||||
|
||||
if (found)
|
||||
PrintAndLog("Found Password [%08x]", i);
|
||||
else
|
||||
PrintAndLog("NOT Found Last Password [%08x]", i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static command_t CommandTable[] = {
|
||||
{"help", CmdHelp, 1, "This help"},
|
||||
{"config", CmdT55xxSetConfig, 1, "Set/Get T55XX configuration (modulation, inverted, offset, rate)"},
|
||||
{"detect", CmdT55xxDetect, 1, "[1] Try detecting the tag modulation from reading the configuration block."},
|
||||
{"read", CmdT55xxReadBlock, 0, "b <block> p [password] [o] [1] -- Read T55xx block data. Optional [p password], [override], [page1]"},
|
||||
{"resetread",CmdResetRead, 0, "Send Reset Cmd then lf read the stream to attempt to identify the start of it (needs a demod and/or plot after)"},
|
||||
{"write", CmdT55xxWriteBlock,0, "b <block> d <data> p [password] [1] -- Write T55xx block data. Optional [p password], [page1]"},
|
||||
{"trace", CmdT55xxReadTrace, 1, "[1] Show T55x7 traceability data (page 1/ blk 0-1)"},
|
||||
{"info", CmdT55xxInfo, 1, "[1] Show T55x7 configuration data (page 0/ blk 0)"},
|
||||
{"dump", CmdT55xxDump, 0, "[password] [o] Dump T55xx card block 0-7. Optional [password], [override]"},
|
||||
{"special", special, 0, "Show block changes with 64 different offsets"},
|
||||
{"wakeup", CmdT55xxWakeUp, 0, "Send AOR wakeup command"},
|
||||
{"wipe", CmdT55xxWipe, 0, "Wipe a T55xx tag and set defaults (will destroy any data on tag)"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
{"help", CmdHelp, 1, "This help"},
|
||||
{"bruceforce", CmdT55xxBruteForce,0, "Simple bruteforce attack to find password"},
|
||||
{"config", CmdT55xxSetConfig, 1, "Set/Get T55XX configuration (modulation, inverted, offset, rate)"},
|
||||
{"detect", CmdT55xxDetect, 1, "[1] Try detecting the tag modulation from reading the configuration block."},
|
||||
{"dump", CmdT55xxDump, 0, "[password] [o] Dump T55xx card block 0-7. Optional [password], [override]"},
|
||||
{"info", CmdT55xxInfo, 1, "[1] Show T55x7 configuration data (page 0/ blk 0)"},
|
||||
{"read", CmdT55xxReadBlock, 0, "b <block> p [password] [o] [1] -- Read T55xx block data. Optional [p password], [override], [page1]"},
|
||||
{"resetread", CmdResetRead, 0, "Send Reset Cmd then lf read the stream to attempt to identify the start of it (needs a demod and/or plot after)"},
|
||||
{"special", special, 0, "Show block changes with 64 different offsets"},
|
||||
{"trace", CmdT55xxReadTrace, 1, "[1] Show T55x7 traceability data (page 1/ blk 0-1)"},
|
||||
{"wakeup", CmdT55xxWakeUp, 0, "Send AOR wakeup command"},
|
||||
{"wipe", CmdT55xxWipe, 0, "Wipe a T55xx tag and set defaults (will destroy any data on tag)"},
|
||||
{"write", CmdT55xxWriteBlock,0, "b <block> d <data> p [password] [1] -- Write T55xx block data. Optional [p password], [page1]"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
int CmdLFT55XX(const char *Cmd) {
|
||||
|
||||
@@ -75,6 +75,7 @@ int CmdT55xxInfo(const char *Cmd);
|
||||
int CmdT55xxDetect(const char *Cmd);
|
||||
int CmdResetRead(const char *Cmd);
|
||||
int CmdT55xxWipe(const char *Cmd);
|
||||
int CmdT55xxBruteForce(const char *Cmd);
|
||||
|
||||
char * GetBitRateStr(uint32_t id);
|
||||
char * GetSaferStr(uint32_t id);
|
||||
@@ -92,4 +93,5 @@ bool test(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk, bool *Q5)
|
||||
int special(const char *Cmd);
|
||||
int AquireData( uint8_t page, uint8_t block, bool pwdmode, uint32_t password );
|
||||
|
||||
bool detectPassword(int password);
|
||||
#endif
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
|
||||
uint8_t* sample_buf;
|
||||
|
||||
void GetFromBigBuf(uint8_t *dest, int bytes, int start_index)
|
||||
{
|
||||
sample_buf = dest;
|
||||
UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {start_index, bytes, 0}};
|
||||
SendCommand(&c);
|
||||
void GetFromBigBuf(uint8_t *dest, int bytes, int start_index) {
|
||||
sample_buf = dest;
|
||||
UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {start_index, bytes, 0}};
|
||||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
}
|
||||
|
||||
@@ -168,6 +168,8 @@ typedef struct{
|
||||
|
||||
#define CMD_READER_MIFARE 0x0611
|
||||
#define CMD_MIFARE_NESTED 0x0612
|
||||
#define CMD_MIFARE_ACQUIRE_ENCRYPTED_NONCES 0x0613
|
||||
|
||||
|
||||
#define CMD_MIFARE_READBL 0x0620
|
||||
#define CMD_MIFAREU_READBL 0x0720
|
||||
|
||||
@@ -129,6 +129,7 @@ local _commands = {
|
||||
|
||||
CMD_READER_MIFARE = 0x0611,
|
||||
CMD_MIFARE_NESTED = 0x0612,
|
||||
CMD_MIFARE_ACQUIRE_ENCRYPTED_NONCES = 0x0613,
|
||||
|
||||
CMD_MIFARE_READBL = 0x0620,
|
||||
CMD_MIFAREU_READBL = 0x0720,
|
||||
|
||||
Reference in New Issue
Block a user