mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2024-11-10 09:32:41 +08:00
found the bug in a call to hex2binarray() fct which overwrote first 16 bytes of keystream. Fixed loops. Crack2 now generates same data as RFIDLer impl.
This commit is contained in:
parent
3d4b5fc413
commit
d9ec99f903
4 changed files with 73 additions and 215 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]
|
||||
- Fixed `lf hitag crack2` - now works. (@iceman1001)
|
||||
- Fixed wrong use of free() in desfire crypto on arm src, thanks @jlitewski! (@iceman1001)
|
||||
- Added `lf em 4x70 calc` - calculate `frn`/`grn` for a given `key` + `rnd`
|
||||
- Fixed `hf 15 dump` memory leaks (@jlitewski)
|
||||
|
|
|
@ -120,7 +120,7 @@ static void hitag2_init(void) {
|
|||
#define HITAG_FRAME_LEN 20
|
||||
#define HITAG_FRAME_BIT_COUNT (8 * HITAG_FRAME_LEN)
|
||||
#define HITAG_T_STOP 36 /* T_EOF should be > 36 */
|
||||
#define HITAG_T_LOW 8 /* T_LOW should be 4..10 */
|
||||
#define HITAG_T_LOW 6 /* T_LOW should be 4..10 */
|
||||
#define HITAG_T_0_MIN 15 /* T[0] should be 18..22 */
|
||||
#define HITAG_T_0 20 /* T[0] should be 18..22 */
|
||||
#define HITAG_T_1_MIN 25 /* T[1] should be 26..30 */
|
||||
|
@ -322,8 +322,6 @@ static void hitag2_handle_reader_command(uint8_t *rx, const size_t rxlen, uint8_
|
|||
// reader/writer
|
||||
// returns how long it took
|
||||
static uint32_t hitag_reader_send_bit(int bit) {
|
||||
uint32_t wait = 0;
|
||||
|
||||
// Binary pulse length modulation (BPLM) is used to encode the data stream
|
||||
// This means that a transmission of a one takes longer than that of a zero
|
||||
|
||||
|
@ -331,8 +329,8 @@ static uint32_t hitag_reader_send_bit(int bit) {
|
|||
lf_modulation(true);
|
||||
|
||||
// Wait for 4-10 times the carrier period
|
||||
lf_wait_periods(8); // wait for 4-10 times the carrier period
|
||||
wait += 8;
|
||||
lf_wait_periods(HITAG_T_LOW); // wait for 4-10 times the carrier period
|
||||
uint32_t wait = HITAG_T_LOW;
|
||||
|
||||
// Disable modulation, just activates the field again
|
||||
lf_modulation(false);
|
||||
|
@ -353,6 +351,7 @@ static uint32_t hitag_reader_send_bit(int bit) {
|
|||
// reader / writer commands
|
||||
// frame_len is in number of bits?
|
||||
static uint32_t hitag_reader_send_frame(const uint8_t *frame, size_t frame_len) {
|
||||
WDT_HIT();
|
||||
|
||||
uint32_t wait = 0;
|
||||
// Send the content of the frame
|
||||
|
@ -360,6 +359,7 @@ static uint32_t hitag_reader_send_frame(const uint8_t *frame, size_t frame_len)
|
|||
wait += hitag_reader_send_bit((frame[i / 8] >> (7 - (i % 8))) & 1);
|
||||
}
|
||||
|
||||
// Send EOF
|
||||
// Enable modulation, which means, drop the field
|
||||
lf_modulation(true);
|
||||
|
||||
|
@ -373,6 +373,7 @@ static uint32_t hitag_reader_send_frame(const uint8_t *frame, size_t frame_len)
|
|||
// t_stop, high field for stop condition (> 36)
|
||||
lf_wait_periods(HITAG_T_STOP);
|
||||
wait += HITAG_T_STOP;
|
||||
WDT_HIT();
|
||||
return wait;
|
||||
}
|
||||
|
||||
|
@ -388,7 +389,7 @@ static uint32_t hitag_reader_send_framebits(const uint8_t *frame, size_t frame_l
|
|||
wait += hitag_reader_send_bit(frame[i]);
|
||||
}
|
||||
|
||||
// EOF
|
||||
// Send EOF
|
||||
// Enable modulation, which means, drop the field
|
||||
// set GPIO_SSC_DOUT to HIGH
|
||||
lf_modulation(true);
|
||||
|
@ -406,7 +407,6 @@ static uint32_t hitag_reader_send_framebits(const uint8_t *frame, size_t frame_l
|
|||
wait += HITAG_T_STOP;
|
||||
|
||||
WDT_HIT();
|
||||
|
||||
return wait;
|
||||
}
|
||||
|
||||
|
@ -2418,7 +2418,7 @@ static void ht2_send(bool turn_on, uint32_t *cmd_start
|
|||
, uint8_t *tx, size_t txlen, bool send_bits) {
|
||||
|
||||
// Tag specific configuration settings (sof, timings, etc.) HITAG2 Settings
|
||||
#define T_WAIT_1_GUARD 8
|
||||
#define T_WAIT_1_GUARD 7
|
||||
|
||||
if (turn_on) {
|
||||
// Wait 50ms with field off to be sure the transponder gets reset
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "cmd.h"
|
||||
#include "lfadc.h"
|
||||
|
||||
// iceman: I have never seen the tag respond with this. Might be something buffer in rfidler.
|
||||
const static uint8_t ERROR_RESPONSE[] = { 0xF4, 0x02, 0x88, 0x9C };
|
||||
|
||||
// #define READP0CMD "1100000111"
|
||||
|
@ -37,8 +38,8 @@ const static uint8_t read_p0_cmd[] = {1, 1, 0, 0, 0, 0, 0, 1, 1, 1};
|
|||
|
||||
// hitag2crack_xor XORs the source with the pad to produce the target.
|
||||
// source, target and pad are binarrays of length len.
|
||||
static void hitag2crack_xor(uint8_t *target, const uint8_t *source, const uint8_t *pad, uint16_t len) {
|
||||
for (uint16_t i = 0; i < len; i++) {
|
||||
static void hitag2crack_xor(uint8_t *target, const uint8_t *source, const uint8_t *pad, size_t len) {
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
target[i] = source[i] ^ pad[i];
|
||||
}
|
||||
}
|
||||
|
@ -168,14 +169,7 @@ static bool hitag2crack_test_e_p0cmd(uint8_t *keybits, uint8_t *nrar, uint8_t *e
|
|||
// send extended encrypted cmd
|
||||
uint8_t resp[4] = {0};
|
||||
if (hitag2crack_send_e_cmd(resp, nrar, e_ext_cmd, 40)) {
|
||||
|
||||
// test if it was valid
|
||||
if (memcmp(resp, ERROR_RESPONSE, 4)) {
|
||||
return true;
|
||||
} else {
|
||||
DbpString("test enc-page0 cmd. got error-response");
|
||||
Dbhexdump(4, resp, false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -296,114 +290,13 @@ static bool hitag2crack_find_valid_e_cmd(uint8_t *e_cmd, uint8_t *nrar) {
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint8_t keybits[2080];
|
||||
uint8_t uid[32];
|
||||
uint8_t nrar[64];
|
||||
uint8_t e_ext_cmd[2080];
|
||||
uint8_t ext_cmd[2080];
|
||||
} PACKED lf_hitag_crack2_t;
|
||||
|
||||
// hitag2crack_consume_keystream sends an extended command (up to 510 bits in
|
||||
// length) to consume keystream.
|
||||
// keybits is the binarray of keystream bits;
|
||||
// kslen is the length of keystream;
|
||||
// ksoffset is a pointer to the current keystream offset (updated by this fn);
|
||||
// nrar is the 64 bit binarray of the nR aR pair.
|
||||
//static bool ht2crack_consume_keystream(uint8_t *keybits, int kslen, int *ksoffset) {
|
||||
/*
|
||||
static bool ht2crack_consume_keystream(lf_hitag_crack2_t *c2, int kslen, int *ksoffset) {
|
||||
|
||||
// calculate the length of keybits to consume with the extended command.
|
||||
// 42 = 32 bit response + 10 bit command reserved for next command. conlen
|
||||
// cannot be longer than 510 bits to fit into the small RWD buffer.
|
||||
int conlen = kslen - *ksoffset - 42;
|
||||
if (conlen < 10) {
|
||||
DbpString("ht2crack_consume_keystream: conlen < 10");
|
||||
return false;
|
||||
}
|
||||
|
||||
// calculate how many repeated commands to send in this extended command.
|
||||
int numcmds = conlen / 10;
|
||||
|
||||
// xor extended cmd with keybits
|
||||
hitag2crack_xor(c2->e_ext_cmd, c2->ext_cmd, c2->keybits + *ksoffset, (numcmds * 10));
|
||||
|
||||
// send encrypted command
|
||||
size_t n = 0;
|
||||
uint8_t resp[4];
|
||||
if (ht2_tx_rx(c2->e_ext_cmd, numcmds * 10, resp, &n, true, true) != PM3_SUCCESS) {
|
||||
Dbprintf("ht2crack_consume_keystream: tx/rx cmd failed, got %zu", n);
|
||||
return false;
|
||||
}
|
||||
|
||||
// test response
|
||||
if (memcmp(resp, ERROR_RESPONSE, 4) == 0) {
|
||||
DbpString("ht2crack_consume_keystream: got error response from card");
|
||||
return false;
|
||||
}
|
||||
|
||||
// dont bother decrypting the response - we already know the keybits
|
||||
|
||||
// update ksoffset with command length and response
|
||||
*ksoffset += (numcmds * 10) + 32;
|
||||
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
// hitag2crack_extend_keystream sends an extended command to retrieve more keybits.
|
||||
// keybits is the binarray of the keystream bits;
|
||||
// kslen is a pointer to the current keybits length;
|
||||
// ksoffset is the offset into the keybits array;
|
||||
// nrar is the 64 bit binarray of the nR aR pair;
|
||||
// uid is the 32 bit binarray of the UID.
|
||||
//static bool ht2crack_extend_keystream(uint8_t *keybits, int *kslen, int ksoffset, uint8_t *nrar, uint8_t *uid) {
|
||||
/*
|
||||
static bool ht2crack_extend_keystream(lf_hitag_crack2_t *c2, int *kslen, int ksoffset) {
|
||||
|
||||
// calc number of command iterations to send
|
||||
int cmdlen = *kslen - ksoffset;
|
||||
if (cmdlen < 10) {
|
||||
DbpString("extend_keystream: cmdlen < 10");
|
||||
return false;
|
||||
}
|
||||
|
||||
int numcmds = cmdlen / 10;
|
||||
|
||||
// xor extended cmd with keybits
|
||||
hitag2crack_xor(c2->e_ext_cmd, c2->ext_cmd, c2->keybits + ksoffset, numcmds * 10);
|
||||
|
||||
// send extended encrypted cmd
|
||||
size_t n = 0;
|
||||
uint8_t resp[4];
|
||||
if (ht2_tx_rx(c2->e_ext_cmd, numcmds * 10, resp, &n, true, true) != PM3_SUCCESS) {
|
||||
DbpString("extend_keystream: tx/rx cmd failed");
|
||||
Dbhexdump(numcmds * 10, c2->e_ext_cmd, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
// test response
|
||||
if (memcmp(resp, ERROR_RESPONSE, 4) == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// convert response to binarray
|
||||
uint8_t e_response[32];
|
||||
hex2binarray((char*)e_response, (char*)resp);
|
||||
|
||||
// recover keystream from encrypted response
|
||||
hitag2crack_xor(c2->keybits + ksoffset + (numcmds * 10), e_response, c2->uid, 32);
|
||||
|
||||
// update kslen
|
||||
*kslen = ksoffset + (numcmds * 10) + 32;
|
||||
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
// hitag2_crack implements the first crack algorithm described in the paper,
|
||||
// Gone In 360 Seconds by Verdult, Garcia and Balasch.
|
||||
// response is a multi-line text response containing the 8 pages of the cracked tag
|
||||
|
@ -468,148 +361,103 @@ out:
|
|||
// nrar_hex is the 32 bit nR and aR in hex
|
||||
void ht2_crack2(uint8_t *nrar_hex) {
|
||||
|
||||
BigBuf_free();
|
||||
|
||||
uint8_t *e_response = BigBuf_calloc(32);
|
||||
lf_hitag_crack2_t *c2 = (lf_hitag_crack2_t *)BigBuf_calloc(sizeof(lf_hitag_crack2_t));
|
||||
lf_hitag_crack_response_t *packet = (lf_hitag_crack_response_t *)BigBuf_calloc(sizeof(lf_hitag_crack_response_t));
|
||||
|
||||
g_logging = false;
|
||||
LEDsoff();
|
||||
set_tracing(false);
|
||||
clear_trace();
|
||||
|
||||
int res = PM3_SUCCESS;
|
||||
|
||||
// find the 'read page 0' command and recover key stream
|
||||
|
||||
// get uid as hexstring
|
||||
uint8_t uid_hex[4];
|
||||
if (ht2_read_uid(uid_hex, false, false, false) != PM3_SUCCESS) {
|
||||
res = PM3_EFAILED;
|
||||
goto out;
|
||||
BigBuf_free();
|
||||
reply_ng(CMD_LF_HITAG2_CRACK_2, PM3_EFAILED, NULL, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
hex2binarray_n((char *)c2->uid, (char *)uid_hex, 4);
|
||||
hex2binarray_n((char *)c2->nrar, (char *)nrar_hex, 8);
|
||||
|
||||
DbpString("looking for encrypted command");
|
||||
|
||||
// find a valid encrypted command
|
||||
uint8_t e_firstcmd[10];
|
||||
if (hitag2crack_find_valid_e_cmd(e_firstcmd, c2->nrar) == false) {
|
||||
res = PM3_EFAILED;
|
||||
goto out;
|
||||
BigBuf_free();
|
||||
reply_ng(CMD_LF_HITAG2_CRACK_2, PM3_EFAILED, NULL, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
DbpString("looking for encrypted page 0");
|
||||
// find encrypted page0 commnd
|
||||
if (hitag2crack_find_e_page0_cmd(c2->keybits, e_firstcmd, c2->nrar, c2->uid) == false) {
|
||||
res = PM3_EFAILED;
|
||||
goto out;
|
||||
BigBuf_free();
|
||||
reply_ng(CMD_LF_HITAG2_CRACK_2, PM3_EFAILED, NULL, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
// Now we got 40 bits of keystream in c2->keybits.
|
||||
|
||||
// We got 42 bits of keystream in c2->keybits.
|
||||
// using the 40 bits of keystream in keybits, sending commands with ever
|
||||
// increasing lengths to acquire 2048 bits of key stream.
|
||||
// increasing lengths to acquire 2048 bits of key stream.
|
||||
int kslen = 40;
|
||||
int res = PM3_SUCCESS;
|
||||
|
||||
// build extended command
|
||||
for (int i = 0; i < 208 ; i++) {
|
||||
memcpy(c2->ext_cmd + (i * 10), read_p0_cmd, 10);
|
||||
}
|
||||
while (kslen < 2048 && BUTTON_PRESS() == false) {
|
||||
|
||||
DbpString("enter main keystream rec");
|
||||
Dbhexdump(160, c2->ext_cmd, false);
|
||||
hitag2crack_xor(c2->e_ext_cmd, read_p0_cmd, c2->keybits, 10);
|
||||
hitag2crack_xor(c2->e_ext_cmd + 10, read_p0_cmd, c2->keybits + 10, 10);
|
||||
hitag2crack_xor(c2->e_ext_cmd + 20, read_p0_cmd, c2->keybits + 20, 10);
|
||||
hitag2crack_xor(c2->e_ext_cmd + 30, read_p0_cmd, c2->keybits + 30, 10);
|
||||
|
||||
DbpString("enter main keystream recover loop");
|
||||
|
||||
while (kslen < 2048) {
|
||||
|
||||
//int ksoffset = 0;
|
||||
Dbprintf("Recovered " _YELLOW_("%i") " bits of keystream", kslen);
|
||||
|
||||
// Get UID
|
||||
if (ht2_read_uid(NULL, true, false, true) != PM3_SUCCESS) {
|
||||
res = PM3_EFAILED;
|
||||
goto out;
|
||||
break;
|
||||
}
|
||||
|
||||
// send nrar and receive (useless) encrypted page 3 value
|
||||
size_t n = 0;
|
||||
if (ht2_tx_rx(c2->nrar, 64, NULL, &n, true, true) != PM3_SUCCESS) {
|
||||
res = PM3_EFAILED;
|
||||
goto out;
|
||||
}
|
||||
|
||||
// while we have at least 52 bits of keystream, consume it with
|
||||
// extended read page 0 commands.
|
||||
// 52 = 10 (min command len) + 32 (response) + 10 (min command len we'll send)
|
||||
/*
|
||||
while ((kslen - ksoffset) >= 52) {
|
||||
// consume the keystream, updating ksoffset as we go
|
||||
//if (ht2crack_consume_keystream(c2->keybits, kslen, &ksoffset, c2->nrar) == false) {
|
||||
if (ht2crack_consume_keystream(c2, kslen, &ksoffset) == false) {
|
||||
DbpString("ht2crack_consume_keystream failed");
|
||||
res = PM3_EFAILED;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
// send an extended command to retrieve more keystream,
|
||||
// updating kslen as we go
|
||||
if (ht2crack_extend_keystream(c2, &kslen, ksoffset) == false) {
|
||||
DbpString("ht2crack_extend_keystream failed");
|
||||
res = PM3_EFAILED;
|
||||
goto out;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
// xor extended cmd with keybits
|
||||
hitag2crack_xor(c2->e_ext_cmd, c2->ext_cmd, c2->keybits, kslen);
|
||||
|
||||
// send extended encrypted cmd
|
||||
uint8_t resp[4];
|
||||
if (ht2_tx_rx(c2->e_ext_cmd, kslen, resp, &n, true, false) != PM3_SUCCESS) {
|
||||
DbpString("extend_keystream: tx/rx cmd failed");
|
||||
break;
|
||||
}
|
||||
|
||||
// test response
|
||||
if (memcmp(resp, ERROR_RESPONSE, 4) == 0) {
|
||||
uint8_t resp[4] = {0};
|
||||
res = ht2_tx_rx(c2->e_ext_cmd, kslen, resp, &n, true, false);
|
||||
if (res != PM3_SUCCESS) {
|
||||
Dbprintf("tx/rx failed, got %zu (res... %i)", n, res);
|
||||
break;
|
||||
}
|
||||
|
||||
// convert response to binarray
|
||||
uint8_t e_response[32];
|
||||
hex2binarray((char *)e_response, (char *)resp);
|
||||
// convert response to binarray
|
||||
hex2binarray_n((char *)e_response, (char *)resp, 4);
|
||||
|
||||
// recover keystream from encrypted response
|
||||
hitag2crack_xor(c2->keybits + kslen + 40, e_response, c2->uid, 32);
|
||||
hitag2crack_xor(c2->keybits + kslen, e_response, c2->uid, 32);
|
||||
|
||||
// update kslen
|
||||
kslen += (40 + 32);
|
||||
|
||||
Dbprintf("Recovered " _YELLOW_("%i") " bits of keystream", kslen);
|
||||
// extented with 30 bits or 3 * 10 read_p0_cmds
|
||||
hitag2crack_xor(c2->e_ext_cmd + kslen, read_p0_cmd, c2->keybits + kslen, 10);
|
||||
kslen += 10;
|
||||
hitag2crack_xor(c2->e_ext_cmd + kslen, read_p0_cmd, c2->keybits + kslen, 10);
|
||||
kslen += 10;
|
||||
hitag2crack_xor(c2->e_ext_cmd + kslen, read_p0_cmd, c2->keybits + kslen, 10);
|
||||
kslen += 10;
|
||||
}
|
||||
|
||||
/*
|
||||
uint8_t *keybitshex = BigBuf_calloc(64);
|
||||
for (int i = 0; i < 2048; i += 256) {
|
||||
binarray2hex(c2->keybits + i, 256, keybitshex);
|
||||
Dbhexdump(256, keybitshex, false);
|
||||
}
|
||||
*/
|
||||
BigBuf_free();
|
||||
lf_hitag_crack_response_t *packet = (lf_hitag_crack_response_t *)BigBuf_calloc(sizeof(lf_hitag_crack_response_t));
|
||||
|
||||
// copy UID since we already have it...
|
||||
memcpy(packet->data, uid_hex, 4);
|
||||
packet->status = 1;
|
||||
|
||||
out:
|
||||
|
||||
/*
|
||||
DbpString("keybits:");
|
||||
Dbhexdump(2080, c2->keybits, false);
|
||||
DbpString("uid:");
|
||||
Dbhexdump(32, c2->uid, false);
|
||||
DbpString("nrar:");
|
||||
Dbhexdump(64, c2->nrar, false);
|
||||
*/
|
||||
binarray2hex(c2->keybits, kslen, packet->data);
|
||||
|
||||
reply_ng(CMD_LF_HITAG2_CRACK_2, res, (uint8_t *)packet, sizeof(lf_hitag_crack_response_t));
|
||||
BigBuf_free();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -2169,7 +2169,7 @@ static int CmdLFHitag2Lookup(const char *Cmd) {
|
|||
|
||||
static int CmdLFHitag2Crack2(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf hitag lookup",
|
||||
CLIParserInit(&ctx, "lf hitag crack2",
|
||||
"This command tries to recover 2048 bits of Hitag2 crypto stream data.\n",
|
||||
"lf hitag crack2 --nrar 73AA5A62EAB8529C"
|
||||
);
|
||||
|
@ -2196,7 +2196,7 @@ static int CmdLFHitag2Crack2(const char *Cmd) {
|
|||
memset(&packet, 0, sizeof(packet));
|
||||
memcpy(packet.NrAr, nrar, sizeof(packet.NrAr));
|
||||
|
||||
PrintAndLogEx(INFO, _YELLOW_("Hitag 2") " - Crack2 (NrAR)");
|
||||
PrintAndLogEx(INFO, _YELLOW_("Hitag 2") " - Nonce replay and length extension attack ( Crack2 )");
|
||||
|
||||
uint64_t t1 = msclock();
|
||||
|
||||
|
@ -2205,23 +2205,32 @@ static int CmdLFHitag2Crack2(const char *Cmd) {
|
|||
SendCommandNG(CMD_LF_HITAG2_CRACK_2, (uint8_t *) &packet, sizeof(packet));
|
||||
|
||||
// loop
|
||||
uint8_t attempt = 30;
|
||||
uint8_t attempt = 50;
|
||||
do {
|
||||
|
||||
PrintAndLogEx(INPLACE, "Attack 2 running...");
|
||||
fflush(stdout);
|
||||
// PrintAndLogEx(INPLACE, "Attack 2 running...");
|
||||
// fflush(stdout);
|
||||
|
||||
if (WaitForResponseTimeout(CMD_LF_HITAG2_CRACK_2, &resp, 1000) == false) {
|
||||
attempt--;
|
||||
continue;
|
||||
}
|
||||
|
||||
// lf_hitag_crack_response_t *payload = (lf_hitag_crack_response_t *)resp.data.asBytes;
|
||||
if (resp.status == PM3_SUCCESS) {
|
||||
PrintAndLogEx(NORMAL, " ( %s )", _GREEN_("ok"));
|
||||
|
||||
PrintAndLogEx(SUCCESS, "--------------------- " _CYAN_("Recovered Keystream") " ----------------------");
|
||||
lf_hitag_crack_response_t *payload = (lf_hitag_crack_response_t *)resp.data.asBytes;
|
||||
|
||||
for (int i = 0; i < 256; i += 32) {
|
||||
PrintAndLogEx(SUCCESS, "%s", sprint_hex_inrow(payload->data + i, 32));
|
||||
}
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(SUCCESS, "Nonce replay and length extension attack ( %s )", _GREEN_("ok"));
|
||||
PrintAndLogEx(HINT, "try running `tools/hitag2crack/crack2/ht2crack2search <FILE_with_above_bytes>");
|
||||
break;
|
||||
} else {
|
||||
PrintAndLogEx(NORMAL, " ( %s )", _RED_("fail"));
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(FAILED, "Nonce replay and length extension attack ( %s )", _RED_("fail"));
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue