mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 13:53:55 -07:00
Merge branch 'master' into refactor_em4x50
update 210215
This commit is contained in:
commit
84d19bb22d
2 changed files with 200 additions and 81 deletions
|
@ -21,39 +21,108 @@
|
||||||
#include "cmdmain.h"
|
#include "cmdmain.h"
|
||||||
#include "fileutils.h" // convert_mfu..
|
#include "fileutils.h" // convert_mfu..
|
||||||
|
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t typeid;
|
||||||
|
uint8_t figureid;
|
||||||
|
const char figdesc[40];
|
||||||
|
const char typedesc[12];
|
||||||
|
} PACKED jooki_figure_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t uid[7];
|
uint8_t uid[7];
|
||||||
const char b64[17];
|
const char b64[17];
|
||||||
uint8_t tagtype;
|
uint8_t typeid;
|
||||||
} PACKED jooki_t;
|
uint8_t figureid;
|
||||||
|
} PACKED jooki_test_t;
|
||||||
|
|
||||||
// sample set for selftest.
|
// sample set for selftest.
|
||||||
jooki_t jooks[] = {
|
jooki_test_t jooks[] = {
|
||||||
{ {0x04, 0xDA, 0xB7, 0x6A, 0xE7, 0x4C, 0x80}, "ruxow8lnn88uyeX+", 0x00},
|
{ {0x04, 0xDA, 0xB7, 0x6A, 0xE7, 0x4C, 0x80}, "ruxow8lnn88uyeX+", 0x01, 0x00},
|
||||||
{ {0x04, 0xf0, 0x22, 0xc2, 0x33, 0x5e, 0x80}, "\0" , 0x00},
|
{ {0x04, 0xf0, 0x22, 0xc2, 0x33, 0x5e, 0x80}, "\0", 0x01 , 0x00},
|
||||||
{ {0x04, 0x8C, 0xEC, 0xDA, 0xF0, 0x4A, 0x80}, "ONrsVf7jX6IaSNV6", 0x01},
|
{ {0x04, 0x8C, 0xEC, 0xDA, 0xF0, 0x4A, 0x80}, "ONrsVf7jX6IaSNV6", 0x01, 0x01},
|
||||||
{ {0x04, 0x92, 0xA7, 0x6A, 0xE7, 0x4C, 0x81}, "Hjjpcx/mZwuveTF+", 0x02},
|
{ {0x04, 0x92, 0xA7, 0x6A, 0xE7, 0x4C, 0x81}, "Hjjpcx/mZwuveTF+", 0x01, 0x02},
|
||||||
{ {0x04, 0xD0, 0xB0, 0x3A, 0xD3, 0x63, 0x80}, "\0", 0x02},
|
{ {0x04, 0xD0, 0xB0, 0x3A, 0xD3, 0x63, 0x80}, "\0", 0x01, 0x02},
|
||||||
{ {0x04, 0x96, 0x42, 0xDA, 0xF0, 0x4A, 0x80}, "vEWy0WO9wZNEzEok", 0x03},
|
{ {0x04, 0x96, 0x42, 0xDA, 0xF0, 0x4A, 0x80}, "vEWy0WO9wZNEzEok", 0x01, 0x03},
|
||||||
{ {0x04, 0x33, 0xb5, 0x62, 0x39, 0x4d, 0x80}, "\0", 0x03},
|
{ {0x04, 0x33, 0xb5, 0x62, 0x39, 0x4d, 0x80}, "\0", 0x01, 0x03},
|
||||||
{ {0x04, 0x17, 0xB7, 0x3A, 0xD3, 0x63, 0x81}, "f0axEma+g2WnLGAm", 0x05},
|
{ {0x04, 0x17, 0xB7, 0x3A, 0xD3, 0x63, 0x81}, "f0axEma+g2WnLGAm", 0x01, 0x05},
|
||||||
{ {0x04, 0x84, 0x27, 0x6A, 0xE7, 0x4C, 0x80}, "VZB/OLBwOiM5Mpnp", 0x05},
|
{ {0x04, 0x84, 0x27, 0x6A, 0xE7, 0x4C, 0x80}, "VZB/OLBwOiM5Mpnp", 0x01, 0x05},
|
||||||
{ {0x04, 0x28, 0xF4, 0xDA, 0xF0, 0x4A, 0x81}, "7WzlgEzqLgwTnWNy", 0x05},
|
{ {0x04, 0x28, 0xF4, 0xDA, 0xF0, 0x4A, 0x81}, "7WzlgEzqLgwTnWNy", 0x01, 0x05},
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *jooks_figures[] = {"Dragon", "Fox", "Ghost", "Knight", "?", "Whale"};
|
jooki_figure_t jooks_figures[] = {
|
||||||
|
{0x01, 0x00, "Dragon", "Figurine"},
|
||||||
|
{0x01, 0x01, "Fox", "Figurine"},
|
||||||
|
{0x01, 0x02, "Ghost", "Figurine"},
|
||||||
|
{0x01, 0x03, "Knight", "Figurine"},
|
||||||
|
{0x01, 0x04, "ThankYou", "Figurine"},
|
||||||
|
{0x01, 0x05, "Whale", "Figurine"},
|
||||||
|
{0x01, 0x06, "Black Dragon", "Figurine"},
|
||||||
|
{0x01, 0x07, "Black Fox", "Figurine"},
|
||||||
|
{0x01, 0x08, "Black Knight", "Figurine"},
|
||||||
|
{0x01, 0x09, "Black Whale", "Figurine"},
|
||||||
|
{0x01, 0x0A, "White Dragon", "Figurine"},
|
||||||
|
{0x01, 0x0B, "White Fox", "Figurine"},
|
||||||
|
{0x01, 0x0C, "White Knight", "Figurine"},
|
||||||
|
{0x01, 0x0D, "White Whale", "Figurine"},
|
||||||
|
|
||||||
|
{0x02, 0x01, "Generic Flat", "Stone"},
|
||||||
|
|
||||||
|
{0x03, 0x00, "record", "Sys"},
|
||||||
|
{0x03, 0x01, "factory_mode_on", "Sys"},
|
||||||
|
{0x03, 0x02, "factory_mode_off", "Sys"},
|
||||||
|
{0x03, 0x03, "airplane_mode_on", "Sys"},
|
||||||
|
{0x03, 0x04, "airplane_mode_off", "Sys"},
|
||||||
|
{0x03, 0x05, "toy_safe_on", "Sys"},
|
||||||
|
{0x03, 0x06, "toy_safe_off", "Sys"},
|
||||||
|
{0x03, 0x07, "wifi_on", "Sys"},
|
||||||
|
{0x03, 0x08, "bt_on", "Sys"},
|
||||||
|
{0x03, 0x0a, "bt_off", "Sys"},
|
||||||
|
{0x03, 0x0b, "production_finished", "Sys"},
|
||||||
|
|
||||||
|
{0x04, 0x00, "test.0", "Test"},
|
||||||
|
{0x04, 0x01, "test.1", "Test"},
|
||||||
|
{0x04, 0x02, "test.2", "Test"},
|
||||||
|
{0x04, 0x03, "test.3", "Test"},
|
||||||
|
{0x04, 0x04, "test.4", "Test"},
|
||||||
|
{0x04, 0x05, "test.5", "Test"},
|
||||||
|
{0x04, 0x06, "test.6", "Test"},
|
||||||
|
{0x04, 0x07, "test.7", "Test"},
|
||||||
|
{0x04, 0x08, "test.8", "Test"},
|
||||||
|
{0x04, 0x09, "test.9", "Test"},
|
||||||
|
{0x04, 0x10, "test.10", "Test"},
|
||||||
|
{0x04, 0x11, "test.11", "Test"},
|
||||||
|
{0x04, 0x12, "test.12", "Test"},
|
||||||
|
{0x04, 0x13, "test.13", "Test"},
|
||||||
|
{0x04, 0x14, "test.14", "Test"},
|
||||||
|
{0x04, 0x15, "test.15", "Test"},
|
||||||
|
{0x04, 0x16, "test.16", "Test"},
|
||||||
|
{0x04, 0x17, "test.17", "Test"},
|
||||||
|
{0x04, 0x18, "test.18", "Test"},
|
||||||
|
{0x04, 0x19, "test.19", "Test"},
|
||||||
|
{0x04, 0x20, "test.20", "Test"},
|
||||||
|
};
|
||||||
|
|
||||||
|
static int jooki_lookup(uint8_t tid, uint8_t fid) {
|
||||||
|
for (int i=0; i < ARRAYLEN(jooks_figures); i++) {
|
||||||
|
jooki_figure_t tmp = jooks_figures[i];
|
||||||
|
if (tmp.typeid == tid && tmp.figureid == fid) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
const uint8_t jooki_secret[] = {0x20, 0x20, 0x20, 0x6D, 0x24, 0x0B, 0xEB, 0x94, 0x2C, 0x80, 0x45, 0x16};
|
const uint8_t jooki_secret[] = {0x20, 0x20, 0x20, 0x6D, 0x24, 0x0B, 0xEB, 0x94, 0x2C, 0x80, 0x45, 0x16};
|
||||||
const uint8_t NFC_SECRET[] = { 0x03, 0x9c, 0x25, 0x6f, 0xb9, 0x2e, 0xe8, 0x08, 0x09, 0x83, 0xd9, 0x33, 0x56};
|
const uint8_t NFC_SECRET[] = { 0x03, 0x9c, 0x25, 0x6f, 0xb9, 0x2e, 0xe8, 0x08, 0x09, 0x83, 0xd9, 0x33, 0x56};
|
||||||
|
|
||||||
#define JOOKI_UID_LEN 7
|
#define JOOKI_UID_LEN 7
|
||||||
#define JOOKI_IV_LEN 4
|
#define JOOKI_IV_LEN 3
|
||||||
#define JOOKI_B64_LEN (16 + 1)
|
#define JOOKI_B64_LEN (16 + 1)
|
||||||
#define JOOKI_PLAIN_LEN 12
|
#define JOOKI_PLAIN_LEN 12
|
||||||
|
|
||||||
static int jooki_encode(uint8_t *iv, uint8_t tagtype, uint8_t *uid, uint8_t *out) {
|
static int jooki_encode(uint8_t *iv, uint8_t tid, uint8_t fid, uint8_t *uid, uint8_t *out) {
|
||||||
if (out == NULL) {
|
if (out == NULL) {
|
||||||
PrintAndLogEx(ERR, "(encode jooki) base64ndef param is NULL");
|
PrintAndLogEx(ERR, "(encode jooki) base64ndef param is NULL");
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
|
@ -65,7 +134,7 @@ static int jooki_encode(uint8_t *iv, uint8_t tagtype, uint8_t *uid, uint8_t *out
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t d[JOOKI_PLAIN_LEN] = {iv[0], iv[1],iv[2], iv[3], tagtype, uid[0], uid[1], uid[2], uid[3], uid[4], uid[5], uid[6]};
|
uint8_t d[JOOKI_PLAIN_LEN] = {iv[0], iv[1],iv[2], tid, fid, uid[0], uid[1], uid[2], uid[3], uid[4], uid[5], uid[6]};
|
||||||
uint8_t enc[JOOKI_PLAIN_LEN] = {0};
|
uint8_t enc[JOOKI_PLAIN_LEN] = {0};
|
||||||
for (uint8_t i = 0; i < JOOKI_PLAIN_LEN; i++) {
|
for (uint8_t i = 0; i < JOOKI_PLAIN_LEN; i++) {
|
||||||
|
|
||||||
|
@ -118,9 +187,16 @@ static int jooki_create_ndef(uint8_t *b64ndef, uint8_t *ndefrecord) {
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void jooki_printEx(uint8_t *b64, uint8_t *iv, uint8_t tt, uint8_t *uid, bool verbose) {
|
static void jooki_printEx(uint8_t *b64, uint8_t *iv, uint8_t tid, uint8_t fid, uint8_t *uid, bool verbose) {
|
||||||
|
int idx = jooki_lookup(tid, fid);
|
||||||
|
|
||||||
PrintAndLogEx(INFO, "Encoded URL.. %s ( %s )", sprint_hex(b64, 12), b64);
|
PrintAndLogEx(INFO, "Encoded URL.. %s ( %s )", sprint_hex(b64, 12), b64);
|
||||||
PrintAndLogEx(INFO, "Figurine..... %02x - " _GREEN_("%s"), tt, jooks_figures[tt]);
|
PrintAndLogEx(INFO, "Figurine..... %02x %02x - " _GREEN_("%s, %s")
|
||||||
|
, tid
|
||||||
|
, fid
|
||||||
|
, (idx != -1) ? jooks_figures[idx].typedesc : "n/a"
|
||||||
|
, (idx != -1) ? jooks_figures[idx].figdesc : "n/a"
|
||||||
|
);
|
||||||
PrintAndLogEx(INFO, "iv........... %s", sprint_hex(iv, JOOKI_IV_LEN));
|
PrintAndLogEx(INFO, "iv........... %s", sprint_hex(iv, JOOKI_IV_LEN));
|
||||||
PrintAndLogEx(INFO, "uid.......... %s", sprint_hex(uid, JOOKI_UID_LEN));
|
PrintAndLogEx(INFO, "uid.......... %s", sprint_hex(uid, JOOKI_UID_LEN));
|
||||||
|
|
||||||
|
@ -142,11 +218,12 @@ static void jooki_print(uint8_t *b64, uint8_t *result, bool verbose) {
|
||||||
|
|
||||||
uint8_t iv[JOOKI_IV_LEN] = {0};
|
uint8_t iv[JOOKI_IV_LEN] = {0};
|
||||||
uint8_t uid[JOOKI_UID_LEN] = {0};
|
uint8_t uid[JOOKI_UID_LEN] = {0};
|
||||||
memcpy(iv, result, sizeof(iv));
|
memcpy(iv, result, JOOKI_IV_LEN);
|
||||||
uint8_t tt = result[4];
|
uint8_t tid = result[3];
|
||||||
memcpy(uid, result + 5, sizeof(uid));
|
uint8_t fid = result[4];
|
||||||
|
memcpy(uid, result + 5, JOOKI_UID_LEN);
|
||||||
|
|
||||||
jooki_printEx(b64, iv, tt, uid, verbose);
|
jooki_printEx(b64, iv, tid, fid, uid, verbose);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int jooki_selftest(void) {
|
static int jooki_selftest(void) {
|
||||||
|
@ -161,21 +238,26 @@ static int jooki_selftest(void) {
|
||||||
uint8_t result[JOOKI_PLAIN_LEN] = {0};
|
uint8_t result[JOOKI_PLAIN_LEN] = {0};
|
||||||
jooki_decode((uint8_t*)jooks[i].b64, result);
|
jooki_decode((uint8_t*)jooks[i].b64, result);
|
||||||
|
|
||||||
memcpy(iv, result, 4);
|
memcpy(iv, result, JOOKI_IV_LEN);
|
||||||
uint8_t tt = result[4];
|
uint8_t tid = result[3];
|
||||||
|
uint8_t fid = result[4];
|
||||||
memcpy(uid, result + 5, sizeof(uid));
|
memcpy(uid, result + 5, sizeof(uid));
|
||||||
|
|
||||||
bool tt_ok = (tt == jooks[i].tagtype);
|
bool tid_ok = (tid == jooks[i].typeid);
|
||||||
|
bool fid_ok = (fid == jooks[i].figureid);
|
||||||
bool uid_ok = (memcmp(uid, jooks[i].uid, sizeof(uid)) == 0);
|
bool uid_ok = (memcmp(uid, jooks[i].uid, sizeof(uid)) == 0);
|
||||||
|
|
||||||
|
int idx = jooki_lookup(tid, fid);
|
||||||
|
|
||||||
PrintAndLogEx(INFO, "Encoded URL.. %s ( %s )", sprint_hex((const uint8_t*)jooks[i].b64, 12), jooks[i].b64);
|
PrintAndLogEx(INFO, "Encoded URL.. %s ( %s )", sprint_hex((const uint8_t*)jooks[i].b64, 12), jooks[i].b64);
|
||||||
PrintAndLogEx(INFO, "Figurine..... %02x - " _GREEN_("%s") " ( %s )", tt, jooks_figures[tt], tt_ok ? _GREEN_("ok") : _RED_("fail"));
|
PrintAndLogEx(INFO, "Type......... %02x - " _GREEN_("%s") " ( %s )", tid, (idx != -1) ? jooks_figures[idx].typedesc : "n/a", tid_ok ? _GREEN_("ok") : _RED_("fail"));
|
||||||
|
PrintAndLogEx(INFO, "Figurine..... %02x - " _GREEN_("%s") " ( %s )", fid, (idx != -1) ? jooks_figures[idx].figdesc : "n/a", fid_ok ? _GREEN_("ok") : _RED_("fail"));
|
||||||
PrintAndLogEx(INFO, "iv........... %s", sprint_hex(iv, sizeof(iv)));
|
PrintAndLogEx(INFO, "iv........... %s", sprint_hex(iv, sizeof(iv)));
|
||||||
PrintAndLogEx(INFO, "uid.......... %s ( %s )", sprint_hex(uid, sizeof(uid)), uid_ok ? _GREEN_("ok") : _RED_("fail"));
|
PrintAndLogEx(INFO, "uid.......... %s ( %s )", sprint_hex(uid, sizeof(uid)), uid_ok ? _GREEN_("ok") : _RED_("fail"));
|
||||||
|
|
||||||
uint8_t b64[JOOKI_B64_LEN] = {0};
|
uint8_t b64[JOOKI_B64_LEN] = {0};
|
||||||
memset(b64, 0, sizeof(b64));
|
memset(b64, 0, sizeof(b64));
|
||||||
jooki_encode(iv, tt, uid, b64);
|
jooki_encode(iv, tid, fid, uid, b64);
|
||||||
|
|
||||||
uint8_t ndefmsg[52] = {0};
|
uint8_t ndefmsg[52] = {0};
|
||||||
jooki_create_ndef(b64, ndefmsg);
|
jooki_create_ndef(b64, ndefmsg);
|
||||||
|
@ -205,11 +287,19 @@ static int CmdHF14AJookiEncode(const char *Cmd) {
|
||||||
arg_lit0("r", NULL, "read uid from tag instead"),
|
arg_lit0("r", NULL, "read uid from tag instead"),
|
||||||
arg_lit0("t", NULL, "selftest"),
|
arg_lit0("t", NULL, "selftest"),
|
||||||
arg_lit0("v", "verbose", "verbose output"),
|
arg_lit0("v", "verbose", "verbose output"),
|
||||||
arg_lit0(NULL, "dragon", "tag type"),
|
arg_lit0(NULL, "dragon", "figurine type"),
|
||||||
arg_lit0(NULL, "fox", "tag type"),
|
arg_lit0(NULL, "fox", "figurine type"),
|
||||||
arg_lit0(NULL, "ghost", "tag type"),
|
arg_lit0(NULL, "ghost", "figurine type"),
|
||||||
arg_lit0(NULL, "knight", "tag type"),
|
arg_lit0(NULL, "knight", "figurine type"),
|
||||||
arg_lit0(NULL, "whale", "tag type"),
|
arg_lit0(NULL, "whale", "figurine type"),
|
||||||
|
arg_lit0(NULL, "blackdragon", "figurine type"),
|
||||||
|
arg_lit0(NULL, "blackfox", "figurine type"),
|
||||||
|
arg_lit0(NULL, "blackknight", "figurine type"),
|
||||||
|
arg_lit0(NULL, "blackwhale", "figurine type"),
|
||||||
|
arg_lit0(NULL, "whitedragon", "figurine type"),
|
||||||
|
arg_lit0(NULL, "whitefox", "figurine type"),
|
||||||
|
arg_lit0(NULL, "whiteknight", "figurine type"),
|
||||||
|
arg_lit0(NULL, "whitewhale", "figurine type"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
|
@ -225,32 +315,57 @@ static int CmdHF14AJookiEncode(const char *Cmd) {
|
||||||
bool use_tag = arg_get_lit(ctx, 2);
|
bool use_tag = arg_get_lit(ctx, 2);
|
||||||
bool selftest = arg_get_lit(ctx, 3);
|
bool selftest = arg_get_lit(ctx, 3);
|
||||||
bool verbose = arg_get_lit(ctx, 4);
|
bool verbose = arg_get_lit(ctx, 4);
|
||||||
bool tt_dragon = arg_get_lit(ctx, 5);
|
bool t0 = arg_get_lit(ctx, 5);
|
||||||
bool tt_fox = arg_get_lit(ctx, 6);
|
bool t1 = arg_get_lit(ctx, 6);
|
||||||
bool tt_ghost = arg_get_lit(ctx, 7);
|
bool t2 = arg_get_lit(ctx, 7);
|
||||||
bool tt_knight = arg_get_lit(ctx, 8);
|
bool t3 = arg_get_lit(ctx, 8);
|
||||||
bool tt_whale = arg_get_lit(ctx, 9);
|
bool t5 = arg_get_lit(ctx, 9);
|
||||||
|
bool t6 = arg_get_lit(ctx, 10);
|
||||||
|
bool t7 = arg_get_lit(ctx, 11);
|
||||||
|
bool t8 = arg_get_lit(ctx, 12);
|
||||||
|
bool t9 = arg_get_lit(ctx, 13);
|
||||||
|
bool ta = arg_get_lit(ctx, 14);
|
||||||
|
bool tb = arg_get_lit(ctx, 15);
|
||||||
|
bool tc = arg_get_lit(ctx, 16);
|
||||||
|
bool td = arg_get_lit(ctx, 17);
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
if (selftest) {
|
if (selftest) {
|
||||||
return jooki_selftest();
|
return jooki_selftest();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((tt_dragon + tt_fox + tt_ghost + tt_knight + tt_whale) > 1) {
|
if ((t0 + t1 + t2 + t3 + t5 + t6 + t7 + t8 + t9 + ta + tb + tc + td) > 1) {
|
||||||
PrintAndLogEx(ERR, "Select one tag type");
|
PrintAndLogEx(ERR, "Select one tag type");
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
uint8_t tt = 0;
|
uint8_t tid = 0x01;
|
||||||
if (tt_fox)
|
uint8_t fid = 0x00;
|
||||||
tt = 1;
|
if (t1)
|
||||||
if (tt_ghost)
|
fid = 0x01;
|
||||||
tt = 2;
|
if (t2)
|
||||||
if (tt_knight)
|
fid = 0x02;
|
||||||
tt = 3;
|
if (t3)
|
||||||
if (tt_whale)
|
fid = 0x03;
|
||||||
tt = 5;
|
if (t5)
|
||||||
|
fid = 0x05;
|
||||||
|
if (t6)
|
||||||
|
fid = 0x06;
|
||||||
|
if (t7)
|
||||||
|
fid = 0x07;
|
||||||
|
if (t8)
|
||||||
|
fid = 0x08;
|
||||||
|
if (t9)
|
||||||
|
fid = 0x09;
|
||||||
|
if (ta)
|
||||||
|
fid = 0x0a;
|
||||||
|
if (tb)
|
||||||
|
fid = 0x0b;
|
||||||
|
if (tc)
|
||||||
|
fid = 0x0c;
|
||||||
|
if (td)
|
||||||
|
fid = 0x0d;
|
||||||
|
|
||||||
uint8_t iv[JOOKI_IV_LEN] = {0x80, 0x77, 0x51, 1};
|
uint8_t iv[JOOKI_IV_LEN] = {0x80, 0x77, 0x51};
|
||||||
if (use_tag) {
|
if (use_tag) {
|
||||||
res = ul_read_uid(uid);
|
res = ul_read_uid(uid);
|
||||||
if (res != PM3_SUCCESS) {
|
if (res != PM3_SUCCESS) {
|
||||||
|
@ -265,8 +380,8 @@ static int CmdHF14AJookiEncode(const char *Cmd) {
|
||||||
|
|
||||||
uint8_t b64[JOOKI_B64_LEN] = {0};
|
uint8_t b64[JOOKI_B64_LEN] = {0};
|
||||||
memset(b64, 0, sizeof(b64));
|
memset(b64, 0, sizeof(b64));
|
||||||
jooki_encode(iv, tt, uid, b64);
|
jooki_encode(iv, tid, fid, uid, b64);
|
||||||
jooki_printEx(b64, iv, tt, uid, verbose);
|
jooki_printEx(b64, iv, tid, fid, uid, verbose);
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,16 +418,16 @@ static int CmdHF14AJookiSim(const char *Cmd) {
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "hf jooki sim",
|
CLIParserInit(&ctx, "hf jooki sim",
|
||||||
"Simulate a Jooki token. Either `hf mfu eload` before or use `-d` param",
|
"Simulate a Jooki token. Either `hf mfu eload` before or use `-d` param",
|
||||||
"hf jooki sim --> using eload before\n"
|
"hf jooki sim --> use token in emulator memory\n"
|
||||||
"hf jooki sim -d 7WzlgEzqLgwTnWNy"
|
"hf jooki sim -b 7WzlgEzqLgwTnWNy --> using base64 url parameter"
|
||||||
);
|
);
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
arg_str0("d", "data", "<base64>", "base64 url parameter"),
|
arg_str0("b", "b64", "<base64>", "base64 url parameter"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
int dlen = 16;
|
int dlen = 16;
|
||||||
uint8_t b64[JOOKI_B64_LEN] = {0x00};
|
uint8_t b64[JOOKI_B64_LEN] = {0x00};
|
||||||
memset(b64, 0x0, sizeof(b64));
|
memset(b64, 0x0, sizeof(b64));
|
||||||
|
@ -359,8 +474,6 @@ static int CmdHF14AJookiSim(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
mfu_dump_t *mfu_dump = (mfu_dump_t *)data;
|
mfu_dump_t *mfu_dump = (mfu_dump_t *)data;
|
||||||
|
|
||||||
|
|
||||||
memcpy(mfu_dump->version, "\x00\x04\x04\x02\x01\x00\x0F\x03", 8);
|
memcpy(mfu_dump->version, "\x00\x04\x04\x02\x01\x00\x0F\x03", 8);
|
||||||
mfu_dump->counter_tearing[2][3] = 0xBD;
|
mfu_dump->counter_tearing[2][3] = 0xBD;
|
||||||
mfu_dump->pages = 0x2c;
|
mfu_dump->pages = 0x2c;
|
||||||
|
@ -430,35 +543,40 @@ static int CmdHF14AJookiSim(const char *Cmd) {
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int CmdHF14AJookiWrite(const char *Cmd) {
|
static int CmdHF14AJookiClone(const char *Cmd) {
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "hf jooki write",
|
CLIParserInit(&ctx, "hf jooki clone",
|
||||||
"Write a Jooki token to a Ultralight or NTAG tag",
|
"Write a Jooki token to a Ultralight or NTAG tag",
|
||||||
"hf jooki write -d xxxxxxxx -> where x is raw NDEF from encode command"
|
"hf jooki clone -d <hex bytes> --> where hex is raw NDEF"
|
||||||
|
"hf jooki clone --b64 7WzlgEzqLgwTnWNy --> using base64 url parameter"
|
||||||
);
|
);
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
arg_str1("d", "data", "<hex>", "bytes"),
|
arg_str0("b", "b64", "<base64>", "base64 url parameter"),
|
||||||
|
arg_str0("d", "data", "<hex>", "raw NDEF bytes"),
|
||||||
arg_str0("p", "pwd", "<hex>", "password for authentication (EV1/NTAG 4 bytes)"),
|
arg_str0("p", "pwd", "<hex>", "password for authentication (EV1/NTAG 4 bytes)"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
|
int blen = 16;
|
||||||
|
uint8_t b64[JOOKI_B64_LEN] = {0x00};
|
||||||
|
memset(b64, 0x0, sizeof(b64));
|
||||||
|
CLIGetStrWithReturn(ctx, 1, b64, &blen);
|
||||||
|
|
||||||
int dlen = 0;
|
int dlen = 0;
|
||||||
uint8_t data[52] = {0x00};
|
uint8_t data[52] = {0x00};
|
||||||
memset(data, 0x0, sizeof(data));
|
memset(data, 0x0, sizeof(data));
|
||||||
int res = CLIParamHexToBuf(arg_get_str(ctx, 1), data, sizeof(data), &dlen);
|
int res = CLIParamHexToBuf(arg_get_str(ctx, 2), data, sizeof(data), &dlen);
|
||||||
if (res) {
|
if (res) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
PrintAndLogEx(FAILED, "Error parsing bytes");
|
PrintAndLogEx(FAILED, "Error parsing bytes");
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int plen = 0;
|
int plen = 0;
|
||||||
uint8_t pwd[4] = {0x00};
|
uint8_t pwd[4] = {0x00};
|
||||||
CLIGetHexWithReturn(ctx, 2, pwd, &plen);
|
CLIGetHexWithReturn(ctx, 3, pwd, &plen);
|
||||||
|
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
if (dlen != 52) {
|
if (dlen != 52) {
|
||||||
|
@ -498,16 +616,17 @@ static int CmdHF14AJookiWrite(const char *Cmd) {
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PrintAndLogEx(INFO, "Done");
|
||||||
|
PrintAndLogEx(HINT, "Try `" _YELLOW_("hf mfu ndef") "` to view" );
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static command_t CommandTable[] = {
|
static command_t CommandTable[] = {
|
||||||
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
||||||
{"encode", CmdHF14AJookiEncode, AlwaysAvailable, "Encode Jooki token"},
|
{"clone", CmdHF14AJookiClone, IfPm3Iso14443a, "Write a Jooki token"},
|
||||||
{"decode", CmdHF14AJookiDecode, AlwaysAvailable, "Decode Jooki token"},
|
{"decode", CmdHF14AJookiDecode, AlwaysAvailable, "Decode Jooki token"},
|
||||||
|
{"encode", CmdHF14AJookiEncode, AlwaysAvailable, "Encode Jooki token"},
|
||||||
{"sim", CmdHF14AJookiSim, IfPm3Iso14443a, "Simulate Jooki token"},
|
{"sim", CmdHF14AJookiSim, IfPm3Iso14443a, "Simulate Jooki token"},
|
||||||
{"write", CmdHF14AJookiWrite, IfPm3Iso14443a, "Write a Jooki token"},
|
|
||||||
|
|
||||||
{NULL, NULL, NULL, NULL}
|
{NULL, NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1456,27 +1456,27 @@ int CmdLFfind(const char *Cmd) {
|
||||||
//fsk
|
//fsk
|
||||||
if (GetFskClock("", false)) {
|
if (GetFskClock("", false)) {
|
||||||
if (FSKrawDemod(0, 0, 0, 0, true) == PM3_SUCCESS) {
|
if (FSKrawDemod(0, 0, 0, 0, true) == PM3_SUCCESS) {
|
||||||
PrintAndLogEx(NORMAL, "\nUnknown FSK Modulated Tag found!");
|
PrintAndLogEx(INFO, "Unknown FSK Modulated Tag found!");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool st = true;
|
bool st = true;
|
||||||
if (ASKDemod_ext(0, 0, 0, 0, false, true, false, 1, &st) == PM3_SUCCESS) {
|
if (ASKDemod_ext(0, 0, 0, 0, false, true, false, 1, &st) == PM3_SUCCESS) {
|
||||||
PrintAndLogEx(NORMAL, "\nUnknown ASK Modulated and Manchester encoded Tag found!");
|
PrintAndLogEx(INFO, "Unknown ASK Modulated and Manchester encoded Tag found!");
|
||||||
PrintAndLogEx(NORMAL, "if it does not look right it could instead be ASK/Biphase - try " _YELLOW_("'data rawdemod ab'"));
|
PrintAndLogEx(INFO, "if it does not look right it could instead be ASK/Biphase - try " _YELLOW_("'data rawdemod ab'"));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CmdPSK1rawDemod("") == PM3_SUCCESS) {
|
if (CmdPSK1rawDemod("") == PM3_SUCCESS) {
|
||||||
PrintAndLogEx(NORMAL, "Possible unknown PSK1 Modulated Tag found above!");
|
PrintAndLogEx(INFO, "Possible unknown PSK1 Modulated Tag found above!");
|
||||||
PrintAndLogEx(NORMAL, " Could also be PSK2 - try " _YELLOW_("'data rawdemod p2'"));
|
PrintAndLogEx(INFO, " Could also be PSK2 - try " _YELLOW_("'data rawdemod p2'"));
|
||||||
PrintAndLogEx(NORMAL, " Could also be PSK3 - [currently not supported]");
|
PrintAndLogEx(INFO, " Could also be PSK3 - [currently not supported]");
|
||||||
PrintAndLogEx(NORMAL, " Could also be NRZ - try " _YELLOW_("'data rawdemod nr"));
|
PrintAndLogEx(INFO, " Could also be NRZ - try " _YELLOW_("'data rawdemod nr"));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLogEx(FAILED, _RED_("\nNo data found!"));
|
PrintAndLogEx(FAILED, _RED_("No data found!"));
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = PM3_ESOFT;
|
retval = PM3_ESOFT;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue