- Added initial version of Multiple-Sector Authentication detection based on a full PM3 trace log (used trace1.txt as sample)

- Formatting corrections (all tabs to spaces4)
This commit is contained in:
zveriu@gmail.com
2011-10-04 12:33:16 +00:00
parent 6fde5d8a91
commit eaa9ff8f1a

View File

@@ -981,13 +981,18 @@ int main(int argc, char* argv[])
#define PM3_NR_ENC 2 #define PM3_NR_ENC 2
#define PM3_READER_RESP 3 #define PM3_READER_RESP 3
#define PM3_TAG_RESP 4 #define PM3_TAG_RESP 4
#define PM3_MULTISECT_AUTH 5
uint32_t pm3_full_set_log[5]; // order is: uid, tag_challenge, nr_enc, reader_response, tag_response uint32_t pm3_full_set_log[5]; // order is: uid, tag_challenge, nr_enc, reader_response, tag_response
uint32_t pm3_log_multisect_auth;
uint32_t pm3_ks2; uint32_t pm3_ks2;
uint32_t pm3_ks3; uint32_t pm3_ks3;
struct Crypto1State *pm3_revstate; struct Crypto1State *pm3_revstate = NULL;
struct Crypto1State *pm3_revstate_multisect_auth = NULL;
uint64_t pm3_lfsr; uint64_t pm3_lfsr;
unsigned char* pm3_plfsr = (unsigned char*)&pm3_lfsr; unsigned char* pm3_plfsr = (unsigned char*)&pm3_lfsr;
uint8_t pm3_log_multisect_decrypted[4];
uint8_t pm3_log_multisect_verified[4];
// various related // various related
int i, j, k; int i, j, k;
@@ -1365,7 +1370,7 @@ int main(int argc, char* argv[])
// strtoul failed somewhere. WTF?! strtoul() is not properly setting errno... errrrrggh! // strtoul failed somewhere. WTF?! strtoul() is not properly setting errno... errrrrggh!
if (errno != 0) if (errno != 0)
{ {
WARN("Invalid hex literal %s for option -P", optarg); WARN("Invalid hex literal %s for option -P at position %d", optarg, iter);
} }
iter++; iter++;
@@ -1385,6 +1390,7 @@ int main(int argc, char* argv[])
*/ */
pm3_ks2 = pm3_full_set_log[PM3_READER_RESP] ^ prng_successor(pm3_full_set_log[PM3_TAG_CHAL], 64); pm3_ks2 = pm3_full_set_log[PM3_READER_RESP] ^ prng_successor(pm3_full_set_log[PM3_TAG_CHAL], 64);
pm3_ks3 = pm3_full_set_log[PM3_TAG_RESP] ^ prng_successor(pm3_full_set_log[PM3_TAG_CHAL], 96); pm3_ks3 = pm3_full_set_log[PM3_TAG_RESP] ^ prng_successor(pm3_full_set_log[PM3_TAG_CHAL], 96);
pm3_revstate = lfsr_recovery64(pm3_ks2, pm3_ks3); pm3_revstate = lfsr_recovery64(pm3_ks2, pm3_ks3);
lfsr_rollback_word(pm3_revstate, 0, 0); lfsr_rollback_word(pm3_revstate, 0, 0);
lfsr_rollback_word(pm3_revstate, 0, 0); lfsr_rollback_word(pm3_revstate, 0, 0);
@@ -1393,6 +1399,52 @@ int main(int argc, char* argv[])
crypto1_get_lfsr(pm3_revstate, &pm3_lfsr); crypto1_get_lfsr(pm3_revstate, &pm3_lfsr);
printf("proxmark3 log key: %02x%02x%02x%02x%02x%02x\n", pm3_plfsr[5], pm3_plfsr[4], pm3_plfsr[3], pm3_plfsr[2], pm3_plfsr[1], pm3_plfsr[0]); printf("proxmark3 log key: %02x%02x%02x%02x%02x%02x\n", pm3_plfsr[5], pm3_plfsr[4], pm3_plfsr[3], pm3_plfsr[2], pm3_plfsr[1], pm3_plfsr[0]);
crypto1_destroy(pm3_revstate); crypto1_destroy(pm3_revstate);
// If all minimum required details from the log were parsed and still there are some more hex tokens, it might be a multi-sector authentication test request
if (token)
{
errno = 0;
pm3_log_multisect_auth = strtoul(token, NULL, 16);
// strtoul failed somewhere. WTF?! strtoul() is not properly setting errno... errrrrggh!
if (errno != 0)
{
WARN("Invalid hex literal %s for option -P at position %d", optarg, iter);
}
else
{
// TODO: what if the multi-sect authentication comes not directly after the first successful plain authentication, i.e. several read/write/incr/decr command occur first then multi-sect auth?! how does this affects the crypto stream/state, what should we do? need to simulate with a nfc-multisect-auth program which has tests with interleaved multi-sect authentications
pm3_revstate_multisect_auth = lfsr_recovery64(pm3_ks2, pm3_ks3);
for (i=0; i<4; i++)
{
uint8_t multisect_auth_byte = (pm3_log_multisect_auth >> (8 * (3-i))) & 0xFF;
pm3_log_multisect_decrypted[i] = crypto1_byte(pm3_revstate_multisect_auth,0x00,0) ^ multisect_auth_byte;
pm3_log_multisect_verified[i] = pm3_log_multisect_decrypted[i];
}
if ( (pm3_log_multisect_decrypted[0] == MC_AUTH_A || pm3_log_multisect_decrypted[0] == MC_AUTH_B)
// TODO: This "<= MIFARE_CLASSIC_4K_MAX_BLOCKS" should be properly checked against either MIFARE_CLASSIC_1K_MAX_BLOCKS or MIFARE_CLASSIC_4K_MAX_BLOCKS (depending on card type detected)
&& (pm3_log_multisect_decrypted[1] >= 0x00 && pm3_log_multisect_decrypted[1] <= MIFARE_CLASSIC_4K_MAX_BLOCKS)
)
{
iso14443a_crc_append(pm3_log_multisect_verified, 2);
int multisect_auth_verified = 1;
for (i=0; i<4; i++)
{
if (pm3_log_multisect_verified[i] != pm3_log_multisect_decrypted[i])
{
multisect_auth_verified = 0;
break;
}
}
printf("proxmark3 log multi-sect auth detected: %02X %02X %02X %02X (parity crc %s)\n", pm3_log_multisect_decrypted[0], pm3_log_multisect_decrypted[1], pm3_log_multisect_decrypted[2], pm3_log_multisect_decrypted[3], multisect_auth_verified?"ok":"NOK");
}
crypto1_destroy(pm3_revstate_multisect_auth);
}
}
} }
break; break;
case 'p': case 'p':