This commit is contained in:
merlokk 2022-02-07 23:52:54 +02:00
commit 01761cc273
12 changed files with 1163 additions and 929 deletions

View file

@ -3,6 +3,10 @@ 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]
- Changed `hf_mf_uidbruteforce` - added support for S70, enhance UID length management (@cactuschibre)
- Fixed build issues that may happen from building `mfd_aes_brute` (@linuxgemini)
- Added silicon data parsing logic for NXP chips in `hf mfu info` (@linuxgemini)
- Addes luascript `hf_mf_em_util.lua` - Script for emulator configuration (@nisgola)
- Fixes `hf mf restore` - now takes bin/eml/json as dump files (@iceman1001)
- Fixes `script run some_python_script` segfault on armhf architecture (@doegox)
- Added `trace extract` - extract authentication parts from trace (@iceman1001)

View file

@ -0,0 +1,108 @@
local getopt = require('getopt')
local ansicolors = require('ansicolors')
--Copyright
copyright = ''
author = 'nisgola'
version = 'v1'
-- Script description
desc = [[
This is a script that write Sector Trailers to the emulator memory.
By default, both keys A and B are set to 0xFFFFFFFFFFFF.
The Access Bytes are set to 0xFF0780 and User Bytes to 0x00.
]]
example = [[
-- Use default formatting
1. script run hf_mf_em_util
-- Change keys A and B
2. script run hf_mf_em_util -a 112233445566 -b AABBCCDDEEFF
-- Define access bits and User byte
3. script run hf_mf_em_util -x 00f0ff -u 12
]]
-- Usage info
usage = [[
script run hf_mf_em_util [-h] [-4] [-a <hex>] [-b <hex>] [-x <hex>] [-u <hex>]
]]
-- Arguments
arguments = [[
-h this help
-4 format as 4K card
-a <hex> define key A
-b <hex> define key B
-x <hex> define Access Bytes
-u <hex> define User Byte
]]
-- Help function
local function help()
print(copyright)
print(author)
print(version)
print(desc)
print(ansicolors.cyan..'Usage'..ansicolors.reset)
print(usage)
print(ansicolors.cyan..'Arguments'..ansicolors.reset)
print(arguments)
print(ansicolors.cyan..'Example usage'..ansicolors.reset)
print(example)
end
-- Print error
local function oops(err)
print('ERROR:', err)
return nil,err
end
-- Memory formatting
local function card_format(key_a,key_b,ab,user,s70)
local blocks = {3,7,11,15,19,23,27,31,35,39,43,47,51,55,59,63,67,71,75,79,83,87,91,95,99,103,107,111,115,119,123,127,143,159,175,191,207,223,239,255}
for k,v in ipairs(blocks) do
local cmd = string.format("hf mf esetblk --blk %s -d %s%s%s%s",v,key_a,ab,user,key_b)
core.console(cmd)
print(cmd)
core.clearCommandBuffer()
if s70 == false and k > 15 then
return
end
end
end
local function main(args)
-- Receive parameters
for o, a in getopt.getopt(args, 'ha:b:x:u:4') do
if o == 'h' then return help() end
if o == 'a' then KeyA = a end
if o == 'b' then KeyB = a end
if o == 'x' then Accessbit = a end
if o == 'u' then User = a end
if o == '4' then kkkk = true end
end
local KeyA = KeyA or 'FFFFFFFFFFFF'
if #(KeyA) ~= 12 then
return oops( string.format('Wrong length of the Key A, receveid %d, expected 12', #KeyA))
end
local KeyB = KeyB or 'FFFFFFFFFFFF'
if #(KeyB) ~= 12 then
return oops( string.format('Wrong length of the Key B, received %d, expected 12', #KeyB))
end
local Accessbit = Accessbit or 'FF0780'
if #(Accessbit) ~= 6 then
return oops( string.format('Wrong length of the Access bit, received %d, expected 6', #Accessbit))
end
local User = User or '00'
if #(User) ~= 2 then
return oops( string.format('Wrong lenght for the user defined byte, received %d, expected 2', #User))
end
local kkkk = kkkk or false
-- Call card_format function
card_format(KeyA,KeyB,Accessbit,User,kkkk)
end
main (args)

View file

@ -11,11 +11,11 @@ desc =[[
This script bruteforces 4 or 7 byte UID Mifare classic card numbers.
]]
example =[[
Bruteforce a 4 byte UID Mifare classic card number, starting at 11223344, ending at 11223346.
Bruteforce a 4 bytes UID Mifare classic card number, starting at 11223344, ending at 11223346.
script run hf_mf_uidbruteforce -s 0x11223344 -e 0x11223346 -t 1000 -x mfc
Bruteforce a 7 byte UID Mifare Ultralight card number, starting at 11223344556677, ending at 11223344556679.
Bruteforce a 7 bytes UID Mifare Ultralight card number, starting at 11223344556677, ending at 11223344556679.
script run hf_mf_uidbruteforce -s 0x11223344556677 -e 0x11223344556679 -t 1000 -x mfu
]]
@ -28,8 +28,9 @@ arguments = [[
-e 0-0xFFFFFFFF end id
-t 0-99999, pause timeout (ms) between cards
(use the word 'pause' to wait for user input)
-x mfc, mfu mifare type:
-x mfc, mfc4, mfu mifare type:
mfc for Mifare Classic (default)
mfc4 for Mifare Classic 4K
mfu for Mifare Ultralight EV1
]]
@ -86,23 +87,32 @@ local function main(args)
local start_id = 0
local end_id = 0xFFFFFFFFFFFFFF
local mftype = 'mfc'
local uid_format = '%14x'
for o, a in getopt.getopt(args, 'e:s:t:x:h') do
if o == 's' then start_id = a end
if o == 'e' then end_id = a end
if o == 't' then timeout = a end
if o == 'x' then mftype = a end
if o == 'h' then return print(usage) end
if o == 'h' then return help() end
end
-- template
local command = ''
-- if the end_id is equals or inferior to 0xFFFFFFFF then use the 4 bytes UID format by default
if string.len(end_id) <= 10 then
uid_format = '%08x'
end
if mftype == 'mfc' then
command = 'hf 14a sim -t 1 -u %014x'
command = 'hf 14a sim -t 1 -u ' .. uid_format
msg('Bruteforcing Mifare Classic card numbers')
elseif mftype == 'mfc4' then
command = 'hf 14a sim -t 8 -u ' .. uid_format
msg('Bruteforcing Mifare Classic 4K card numbers')
elseif mftype == 'mfu' then
command = 'hf 14a sim -t 2 -u %014x'
command = 'hf 14a sim -t 2 -u ' .. uid_format
msg('Bruteforcing Mifare Ultralight card numbers')
else
return print(usage)

View file

@ -200,25 +200,30 @@ static int CLIParseCommandParametersEx(CLIParserContext *ctx, size_t keyid, size
uint8_t hdata[250] = {0};
int hdatalen = sizeof(hdata);
if (keyid) {
if (CLIParamHexToBuf(arg_get_str(ctx, keyid), hdata, hdatalen, &hdatalen))
if (CLIParamHexToBuf(arg_get_str(ctx, keyid), hdata, hdatalen, &hdatalen)) {
return PM3_ESOFT;
}
if (hdatalen && hdatalen != 16) {
PrintAndLogEx(ERR, _RED_("ERROR:") " key length for AES128 must be 16 bytes only");
return PM3_EINVARG;
}
if (hdatalen)
memcpy(key, hdata, CIPURSE_AES_KEY_LENGTH);
else
memcpy(key, defaultKey, sizeof(defaultKey));
}
if (useaid)
if (useaid) {
*useaid = false;
}
if (aidid && aid && aidlen) {
hdatalen = sizeof(hdata);
if (CLIParamHexToBuf(arg_get_str(ctx, aidid), hdata, hdatalen, &hdatalen))
if (CLIParamHexToBuf(arg_get_str(ctx, aidid), hdata, hdatalen, &hdatalen)) {
return PM3_ESOFT;
}
if (hdatalen && (hdatalen < 1 || hdatalen > 16)) {
PrintAndLogEx(ERR, _RED_("ERROR:") " application id length must be 1-16 bytes only");
@ -229,16 +234,19 @@ static int CLIParseCommandParametersEx(CLIParserContext *ctx, size_t keyid, size
if (hdatalen) {
memcpy(aid, hdata, hdatalen);
*aidlen = hdatalen;
if (useaid)
if (useaid) {
*useaid = true;
}
} else {
memcpy(aid, defaultAID, defaultAIDLength);
*aidlen = defaultAIDLength;
}
}
if (usefid)
if (usefid) {
*usefid = false;
}
if (fidid && fid) {
hdatalen = sizeof(hdata);
if (CLIParamHexToBuf(arg_get_str(ctx, fidid), hdata, hdatalen, &hdatalen))
@ -337,57 +345,76 @@ static int SelectCommandEx(bool selectDefaultFile, bool useAID, uint8_t *aid, si
int res = 0;
if (verbose && selChildFile)
PrintAndLogEx(INFO, "Select top level application/file");
if (useAID && aidLen > 0) {
res = CIPURSESelectAID(true, true, aid, aidLen, buf, bufSize, len, sw);
if (res != 0 || *sw != 0x9000) {
if (verbose)
if (verbose) {
PrintAndLogEx(ERR, "Cipurse select application " _GREEN_("%s ") _RED_("error") ". Card returns 0x%04x", sprint_hex_inrow(aid, aidLen), *sw);
}
return PM3_ESOFT;
}
if (verbose)
if (verbose) {
PrintAndLogEx(INFO, "Cipurse select application " _CYAN_("%s ") _GREEN_("OK"), sprint_hex_inrow(aid, aidLen));
}
} else if (useFID) {
res = CIPURSESelectFileEx(true, true, fileId, buf, bufSize, len, sw);
if (res != 0 || *sw != 0x9000) {
if (verbose)
if (verbose) {
PrintAndLogEx(ERR, "Cipurse select file 0x%04x " _RED_("error") ". Card returns 0x%04x", fileId, *sw);
}
return PM3_ESOFT;
}
if (verbose)
if (verbose) {
PrintAndLogEx(INFO, "Cipurse select file " _CYAN_("0x%04x ") _GREEN_("OK"), fileId);
}
} else if (selectDefaultFile) {
res = CIPURSESelectMFDefaultFileEx(true, true, buf, bufSize, len, sw);
if (res != 0 || *sw != 0x9000) {
if (verbose)
if (verbose) {
PrintAndLogEx(ERR, "Cipurse select default file " _RED_("error") ". Card returns 0x%04x", *sw);
}
return PM3_ESOFT;
}
if (verbose)
if (verbose) {
PrintAndLogEx(INFO, "Cipurse select default file " _GREEN_("OK"));
}
} else {
res = CIPURSESelect(true, true, buf, bufSize, len, sw);
if (res != 0 || *sw != 0x9000) {
if (verbose)
if (verbose) {
PrintAndLogEx(ERR, "Cipurse select default application " _RED_("error") ". Card returns 0x%04x", *sw);
}
return PM3_ESOFT;
}
if (verbose)
if (verbose) {
PrintAndLogEx(INFO, "Cipurse select default application " _GREEN_("OK"));
}
}
if (selChildFile) {
if (verbose)
if (verbose) {
PrintAndLogEx(INFO, "Select child file");
}
res = CIPURSESelectFileEx(false, true, childFileId, buf, bufSize, len, sw);
if (res != 0 || *sw != 0x9000) {
if (verbose)
if (verbose) {
PrintAndLogEx(ERR, "Select child file 0x%04x " _RED_("error") ". Card returns 0x%04x", childFileId, *sw);
}
return PM3_ESOFT;
}
if (verbose)
if (verbose) {
PrintAndLogEx(INFO, "Select child file " _CYAN_("0x%04x ") _GREEN_("OK"), childFileId);
}
}
return PM3_SUCCESS;
}
@ -408,13 +435,13 @@ static int CmdHFCipurseSelect(const char *Cmd) {
void *argtable[] = {
arg_param_begin,
arg_lit0("a", "apdu", "show APDU requests and responses"),
arg_lit0("v", "verbose", "show technical data"),
arg_lit0("a", "apdu", "Show APDU requests and responses"),
arg_lit0("v", "verbose", "Verbose mode"),
arg_lit0("t", "tlv", "TLV decode returned data"),
arg_str0(NULL, "aid", "<hex 1..16 bytes>", "application ID (AID)"),
arg_str0(NULL, "fid", "<hex 2 bytes>", "top level file (or application) ID (FID)"),
arg_lit0(NULL, "mfd", "select masterfile by empty id"),
arg_str0(NULL, "chfid", "<hex 2 bytes>", "child file ID (EF under application/master file)"),
arg_str0(NULL, "aid", "<hex>", "Application ID (AID) 1..16 bytes"),
arg_str0(NULL, "fid", "<hex>", "Top level file (or application) ID (FID) 2 bytes"),
arg_lit0(NULL, "mfd", "Select masterfile by empty id"),
arg_str0(NULL, "chfid", "<hex>", "Child file ID (EF under application/master file) 2 bytes"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
@ -474,12 +501,12 @@ static int CmdHFCipurseAuth(const char *Cmd) {
void *argtable[] = {
arg_param_begin,
arg_lit0("a", "apdu", "show APDU requests and responses"),
arg_lit0("v", "verbose", "show technical data"),
arg_str0(NULL, "aid", "<hex 1..16 bytes>", "application ID (AID)"),
arg_str0(NULL, "fid", "<hex 2 bytes>", "top file/application ID (FID)"),
arg_lit0(NULL, "mfd", "select masterfile by empty id"),
arg_int0("n", NULL, "<dec>", "key ID"),
arg_lit0("a", "apdu", "Show APDU requests and responses"),
arg_lit0("v", "verbose", "Verbose mode"),
arg_str0(NULL, "aid", "<hex>", "Application ID (AID) ( 1..16 bytes )"),
arg_str0(NULL, "fid", "<hex>", "Top file/application ID (FID) ( 2 bytes )"),
arg_lit0(NULL, "mfd", "Select masterfile by empty id"),
arg_int0("n", NULL, "<dec>", "Key ID"),
arg_str0("k", "key", "<hex>", "Auth key"),
arg_param_end
};
@ -550,16 +577,16 @@ static int CmdHFCipurseReadFile(const char *Cmd) {
void *argtable[] = {
arg_param_begin,
arg_lit0("a", "apdu", "show APDU requests and responses"),
arg_lit0("v", "verbose", "show technical data"),
arg_int0("n", NULL, "<dec>", "key ID"),
arg_lit0("a", "apdu", "Show APDU requests and responses"),
arg_lit0("v", "verbose", "Verbose mode"),
arg_int0("n", NULL, "<dec>", "Key ID"),
arg_str0("k", "key", "<hex>", "Auth key"),
arg_str0(NULL, "aid", "<hex 1..16 bytes>", "application ID (AID)"),
arg_str0(NULL, "fid", "<hex>", "file ID"),
arg_int0("o", "offset", "<dec>", "offset for reading data from file"),
arg_lit0(NULL, "noauth", "read file without authentication"),
arg_str0(NULL, "sreq", "<plain|mac(default)|encode>", "communication reader-PICC security level"),
arg_str0(NULL, "sresp", "<plain|mac(default)|encode>", "communication PICC-reader security level"),
arg_str0(NULL, "aid", "<hex>", "Application ID (AID) ( 1..16 bytes )"),
arg_str0(NULL, "fid", "<hex>", "File ID"),
arg_int0("o", "offset", "<dec>", "Offset for reading data from file"),
arg_lit0(NULL, "noauth", "Read file without authentication"),
arg_str0(NULL, "sreq", "<plain|mac|encode>", "Communication reader-PICC security level (def: mac)"),
arg_str0(NULL, "sresp", "<plain|mac|encode>", "Communication PICC-reader security level (def: mac)"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
@ -660,18 +687,18 @@ static int CmdHFCipurseWriteFile(const char *Cmd) {
void *argtable[] = {
arg_param_begin,
arg_lit0("a", "apdu", "show APDU requests and responses"),
arg_lit0("v", "verbose", "show technical data"),
arg_int0("n", NULL, "<dec>", "key ID"),
arg_lit0("a", "apdu", "Show APDU requests and responses"),
arg_lit0("v", "verbose", "Verbose mode"),
arg_int0("n", NULL, "<dec>", "Key ID"),
arg_str0("k", "key", "<hex>", "Auth key"),
arg_str0(NULL, "aid", "<hex 1..16 bytes>", "application ID (AID)"),
arg_str0(NULL, "fid", "<hex>", "file ID"),
arg_int0("o", "offset", "<dec>", "offset for reading data from file"),
arg_lit0(NULL, "noauth", "read file without authentication"),
arg_str0(NULL, "sreq", "<plain|mac(default)|encode>", "communication reader-PICC security level"),
arg_str0(NULL, "sresp", "<plain|mac(default)|encode>", "communication PICC-reader security level"),
arg_str0("d", "data", "<hex>", "hex data to write to new file"),
arg_lit0(NULL, "commit", "need commit after write"),
arg_str0(NULL, "aid", "<hex>", "Application ID (AID) ( 1..16 bytes )"),
arg_str0(NULL, "fid", "<hex>", "File ID"),
arg_int0("o", "offset", "<dec>", "Offset for reading data from file"),
arg_lit0(NULL, "noauth", "Read file without authentication"),
arg_str0(NULL, "sreq", "<plain|mac|encode>", "communication reader-PICC security level (def: mac)"),
arg_str0(NULL, "sresp", "<plain|mac|encode>", "communication PICC-reader security level (def: mac)"),
arg_str0("d", "data", "<hex>", "Data to write to new file"),
arg_lit0(NULL, "commit", "Commit after write"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
@ -797,17 +824,17 @@ static int CmdHFCipurseReadFileAttr(const char *Cmd) {
void *argtable[] = {
arg_param_begin,
arg_lit0("a", "apdu", "show APDU requests and responses"),
arg_lit0("v", "verbose", "show technical data"),
arg_int0("n", NULL, "<dec>", "key ID"),
arg_lit0("a", "apdu", "Show APDU requests and responses"),
arg_lit0("v", "verbose", "Verbose mode"),
arg_int0("n", NULL, "<dec>", "Key ID"),
arg_str0("k", "key", "<hex>", "Auth key"),
arg_lit0(NULL, "mfd", "show info about master file"),
arg_str0(NULL, "aid", "<hex 1..16 bytes>", "select application ID (AID)"),
arg_str0(NULL, "fid", "<hex>", "file ID"),
arg_str0(NULL, "chfid", "<hex 2 bytes>", "child file ID (EF under application/master file)"),
arg_lit0(NULL, "noauth", "read file attributes without authentication"),
arg_str0(NULL, "sreq", "<plain|mac(default)|encode>", "communication reader-PICC security level"),
arg_str0(NULL, "sresp", "<plain|mac(default)|encode>", "communication PICC-reader security level"),
arg_lit0(NULL, "mfd", "Show info about master file"),
arg_str0(NULL, "aid", "<hex>", "Select application ID (AID) ( 1..16 bytes )"),
arg_str0(NULL, "fid", "<hex>", "File ID"),
arg_str0(NULL, "chfid", "<hex>", "Child file ID (EF under application/master file) ( 2 bytes )"),
arg_lit0(NULL, "noauth", "Read file attributes without authentication"),
arg_str0(NULL, "sreq", "<plain|mac|encode>", "Communication reader-PICC security level (def: mac)"),
arg_str0(NULL, "sresp", "<plain|mac|encode>", "Communication PICC-reader security level (def: mac)"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
@ -916,19 +943,19 @@ static int CmdHFCipurseWriteFileAttr(const char *Cmd) {
void *argtable[] = {
arg_param_begin,
arg_lit0("a", "apdu", "show APDU requests and responses"),
arg_lit0("v", "verbose", "show technical data"),
arg_int0("n", NULL, "<dec>", "key ID"),
arg_lit0("a", "apdu", "Show APDU requests and responses"),
arg_lit0("v", "verbose", "Verbose mode"),
arg_int0("n", NULL, "<dec>", "Key ID"),
arg_str0("k", "key", "<hex>", "Auth key"),
arg_lit0(NULL, "mfd", "show info about master file"),
arg_str0(NULL, "aid", "<hex 1..16 bytes>", "select application ID (AID)"),
arg_str0(NULL, "fid", "<hex>", "file ID"),
arg_str0(NULL, "chfid", "<hex 2 bytes>", "child file ID (EF under application/master file)"),
arg_lit0(NULL, "noauth", "read file attributes without authentication"),
arg_str0(NULL, "sreq", "<plain|mac(default)|encode>", "communication reader-PICC security level"),
arg_str0(NULL, "sresp", "<plain|mac(default)|encode>", "communication PICC-reader security level"),
arg_str0("d", "data", "<hex>", "file attributes"),
arg_lit0(NULL, "commit", "need commit after write"),
arg_lit0(NULL, "mfd", "Show info about master file"),
arg_str0(NULL, "aid", "<hex>", "Select application ID (AID) ( 1..16 bytes )"),
arg_str0(NULL, "fid", "<hex>", "File ID"),
arg_str0(NULL, "chfid", "<hex>", "Child file ID (EF under application/master file) ( 2 bytes )"),
arg_lit0(NULL, "noauth", "Read file attributes without authentication"),
arg_str0(NULL, "sreq", "<plain|mac|encode>", "Communication reader-PICC security level (def: mac)"),
arg_str0(NULL, "sresp", "<plain|mac|encode>", "Communication PICC-reader security level (def: mac)"),
arg_str0("d", "data", "<hex>", "File attributes"),
arg_lit0(NULL, "commit", "Commit after write"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
@ -1053,13 +1080,13 @@ static int CmdHFCipurseFormatAll(const char *Cmd) {
void *argtable[] = {
arg_param_begin,
arg_lit0("a", "apdu", "show APDU requests and responses"),
arg_lit0("v", "verbose", "show technical data"),
arg_int0("n", NULL, "<dec>", "key ID"),
arg_lit0("a", "apdu", "Show APDU requests and responses"),
arg_lit0("v", "verbose", "Verbose mode"),
arg_int0("n", NULL, "<dec>", "Key ID"),
arg_str0("k", "key", "<hex>", "Auth key"),
arg_str0(NULL, "sreq", "<plain|mac(default)|encode>", "communication reader-PICC security level"),
arg_str0(NULL, "sresp", "<plain|mac(default)|encode>", "communication PICC-reader security level"),
arg_lit0(NULL, "no-auth", "execute without authentication"),
arg_str0(NULL, "sreq", "<plain|mac|encode>", "Communication reader-PICC security level (def: mac)"),
arg_str0(NULL, "sresp", "<plain|mac|encode>", "Communication PICC-reader security level (def: mac)"),
arg_lit0(NULL, "no-auth", "Execute without authentication"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
@ -1138,20 +1165,20 @@ static int CmdHFCipurseCreateDGI(const char *Cmd) {
void *argtable[] = {
arg_param_begin,
arg_lit0("a", "apdu", "show APDU requests and responses"),
arg_lit0("v", "verbose", "show technical data"),
arg_int0("n", NULL, "<dec>", "key ID"),
arg_lit0("a", "apdu", "Show APDU requests and responses"),
arg_lit0("v", "verbose", "Verbose mode"),
arg_int0("n", NULL, "<dec>", "Key ID"),
arg_str0("k", "key", "<hex>", "Auth key"),
arg_str0(NULL, "aid", "<hex 1..16 bytes>", "application ID (AID)"),
arg_str0(NULL, "fid", "<hex 2 bytes>", "file ID (FID)"),
arg_lit0(NULL, "mfd", "select masterfile by empty id"),
arg_str0(NULL, "aid", "<hex>", "Application ID (AID) ( 1..16 bytes )"),
arg_str0(NULL, "fid", "<hex>", "file ID (FID) ( 2 bytes )"),
arg_lit0(NULL, "mfd", "Select masterfile by empty id"),
arg_str0("d", "data", "<hex>", "data with DGI for create"),
arg_str0(NULL, "sreq", "<plain|mac(default)|encode>", "communication reader-PICC security level"),
arg_str0(NULL, "sresp", "<plain|mac(default)|encode>", "communication PICC-reader security level"),
arg_lit0(NULL, "no-auth", "execute without authentication"),
arg_lit0(NULL, "commit", "need commit after create"),
arg_str0("d", "data", "<hex>", "Data with DGI for create"),
arg_str0(NULL, "sreq", "<plain|mac|encode>", "Communication reader-PICC security level (def: mac)"),
arg_str0(NULL, "sresp", "<plain|mac|encode>", "Communication PICC-reader security level (def: mac)"),
arg_lit0(NULL, "no-auth", "Execute without authentication"),
arg_lit0(NULL, "commit", "Commit after create"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
@ -1272,17 +1299,17 @@ static int CmdHFCipurseDeleteFile(const char *Cmd) {
void *argtable[] = {
arg_param_begin,
arg_lit0("a", "apdu", "show APDU requests and responses"),
arg_lit0("v", "verbose", "show technical data"),
arg_int0("n", NULL, "<dec>", "key ID"),
arg_lit0("a", "apdu", "Show APDU requests and responses"),
arg_lit0("v", "verbose", "Verbose mode"),
arg_int0("n", NULL, "<dec>", "Key ID"),
arg_str0("k", "key", "<hex>", "Auth key"),
arg_str0(NULL, "fid", "<hex>", "file/application ID under MF for delete"),
arg_str0(NULL, "aid", "<hex 1..16 bytes>", "application ID (AID) for delete"),
arg_str0(NULL, "chfid", "<hex 2 bytes>", "child file ID (EF under application/master file)"),
arg_str0(NULL, "sreq", "<plain|mac(default)|encode>", "communication reader-PICC security level"),
arg_str0(NULL, "sresp", "<plain|mac(default)|encode>", "communication PICC-reader security level"),
arg_lit0(NULL, "no-auth", "execute without authentication"),
arg_lit0(NULL, "commit", "commit "),
arg_str0(NULL, "fid", "<hex>", "File/application ID under MF for delete"),
arg_str0(NULL, "aid", "<hex>", "Application ID (AID) for delete ( 1..16 bytes )"),
arg_str0(NULL, "chfid", "<hex>", "Child file ID (EF under application/master file) ( 2 bytes )"),
arg_str0(NULL, "sreq", "<plain|mac|encode>", "Communication reader-PICC security level (def: mac)"),
arg_str0(NULL, "sresp", "<plain|mac|encode>", "Communication PICC-reader security level (def: mac)"),
arg_lit0(NULL, "no-auth", "Execute without authentication"),
arg_lit0(NULL, "commit", "commit after delete"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
@ -1582,11 +1609,11 @@ static int CmdHFCipurseDefault(const char *Cmd) {
void *argtable[] = {
arg_param_begin,
arg_lit0(NULL, "clear", "resets to defaults"),
arg_lit0(NULL, "clear", "Resets to defaults"),
arg_int0("n", NULL, "<dec>", "Key ID"),
arg_str0("k", "key", "<hex>", "Authentication key"),
arg_str0(NULL, "aid", "<hex 1..16 bytes>", "application ID (AID)"),
arg_str0(NULL, "fid", "<hex 2 bytes>", "File ID"),
arg_str0(NULL, "aid", "<hex>", "Application ID (AID) ( 1..16 bytes )"),
arg_str0(NULL, "fid", "<hex>", "File ID ( 2 bytes )"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);

View file

@ -145,14 +145,14 @@ static int CmdHFFidoRegister(const char *cmd) {
void *argtable[] = {
arg_param_begin,
arg_lit0("a", "apdu", "show APDU requests and responses"),
arg_litn("v", "verbose", 0, 2, "show technical data. vv - show full certificates data"),
arg_lit0("a", "apdu", "Show APDU requests and responses"),
arg_litn("v", "verbose", 0, 2, "Verbose mode. vv - show full certificates data"),
arg_lit0("t", "tlv", "Show DER certificate contents in TLV representation"),
arg_str0("f", "file", "<fn>", "JSON input file name for parameters"),
arg_str0(NULL, "cp", "<ascii>", "challenge parameter (1..16 chars)"),
arg_str0(NULL, "ap", "<ascii>", "application parameter (1..16 chars)"),
arg_str0(NULL, "cpx", "<hex>", "challenge parameter (32 bytes hex)"),
arg_str0(NULL, "apx", "<hex>", "application parameter (32 bytes hex)"),
arg_str0(NULL, "cp", "<str>", "Challenge parameter (1..16 chars)"),
arg_str0(NULL, "ap", "<str>", "Application parameter (1..16 chars)"),
arg_str0(NULL, "cpx", "<hex>", "Challenge parameter (32 bytes hex)"),
arg_str0(NULL, "apx", "<hex>", "Application parameter (32 bytes hex)"),
arg_param_end
};
CLIExecWithReturn(ctx, cmd, argtable, true);
@ -409,18 +409,18 @@ static int CmdHFFidoAuthenticate(const char *cmd) {
void *argtable[] = {
arg_param_begin,
arg_lit0("a", "apdu", "show APDU reqests and responses"),
arg_lit0("v", "verbose", "show technical data"),
arg_lit0("a", "apdu", "Show APDU reqests and responses"),
arg_lit0("v", "verbose", "Verbose mode"),
arg_rem("default mode:", "dont-enforce-user-presence-and-sign"),
arg_lit0("u", "user", "mode: enforce-user-presence-and-sign"),
arg_lit0("c", "check", "mode: check-only"),
arg_str0("f", "file", "<fn>", "JSON input file name for parameters"),
arg_str0("k", "key", "<hex>", "public key to verify signature"),
arg_str0(NULL, "kh", "<hex>", "key handle (var 0..255b)"),
arg_str0(NULL, "cp", "<ascii>", "challenge parameter (1..16 chars)"),
arg_str0(NULL, "ap", "<ascii>", "application parameter (1..16 chars)"),
arg_str0(NULL, "cpx", "<hex>", "challenge parameter (32 bytes hex)"),
arg_str0(NULL, "apx", "<hex>", "application parameter (32 bytes hex)"),
arg_str0("f", "file", "<fn>", "JSON file name for parameters"),
arg_str0("k", "key", "<hex>", "Public key to verify signature"),
arg_str0(NULL, "kh", "<hex>", "Key handle (var 0..255b)"),
arg_str0(NULL, "cp", "<str>", "Challenge parameter (1..16 chars)"),
arg_str0(NULL, "ap", "<str>", "Application parameter (1..16 chars)"),
arg_str0(NULL, "cpx", "<hex>", "Challenge parameter (32 bytes hex)"),
arg_str0(NULL, "apx", "<hex>", "Application parameter (32 bytes hex)"),
arg_param_end
};
CLIExecWithReturn(ctx, cmd, argtable, true);
@ -671,11 +671,11 @@ static int CmdHFFido2MakeCredential(const char *cmd) {
void *argtable[] = {
arg_param_begin,
arg_lit0("a", "apdu", "show APDU reqests and responses"),
arg_litn("v", "verbose", 0, 2, "show technical data. vv - show full certificates data"),
arg_lit0("a", "apdu", "Show APDU reqests and responses"),
arg_litn("v", "verbose", 0, 2, "Verbose mode. vv - show full certificates data"),
arg_lit0("t", "tlv", "Show DER certificate contents in TLV representation"),
arg_lit0("c", "cbor", "show CBOR decoded data"),
arg_str0("f", "file", "<fn>", "parameter JSON file name"),
arg_lit0("c", "cbor", "Show CBOR decoded data"),
arg_str0("f", "file", "<fn>", "Parameter JSON file name"),
arg_param_end
};
CLIExecWithReturn(ctx, cmd, argtable, true);
@ -790,11 +790,11 @@ static int CmdHFFido2GetAssertion(const char *cmd) {
void *argtable[] = {
arg_param_begin,
arg_lit0("a", "apdu", "show APDU reqests and responses"),
arg_litn("v", "verbose", 0, 2, "show technical data. vv - show full certificates data"),
arg_lit0("c", "cbor", "show CBOR decoded data"),
arg_lit0("l", "list", "add CredentialId from json to allowList"),
arg_str0("f", "file", "<fn>", "parameter JSON file name"),
arg_lit0("a", "apdu", "Show APDU reqests and responses"),
arg_litn("v", "verbose", 0, 2, "Verbose mode. vv - show full certificates data"),
arg_lit0("c", "cbor", "Show CBOR decoded data"),
arg_lit0("l", "list", "Add CredentialId from json to allowList"),
arg_str0("f", "file", "<fn>", "Parameter JSON file name"),
arg_param_end
};
CLIExecWithReturn(ctx, cmd, argtable, true);

View file

@ -3008,7 +3008,7 @@ static int CmdHF14AMfChk(const char *Cmd) {
arg_param_begin,
arg_strx0("k", "key", "<hex>", "Key specified as 12 hex symbols"),
arg_int0(NULL, "blk", "<dec>", "Input block number"),
arg_lit0("a", NULL, "Target Key A, if found also check Key B for duplicate"),
arg_lit0("a", NULL, "Target Key A"),
arg_lit0("b", NULL, "Target Key B"),
arg_lit0("*", "all", "Target both key A & B (default)"),
arg_lit0(NULL, "mini", "MIFARE Classic Mini / S20"),
@ -3017,7 +3017,7 @@ static int CmdHF14AMfChk(const char *Cmd) {
arg_lit0(NULL, "4k", "MIFARE Classic 4k / S70"),
arg_lit0(NULL, "emu", "Fill simulator keys from found keys"),
arg_lit0(NULL, "dump", "Dump found keys to binary file"),
arg_str0("f", "file", "<fn>", "filename of dictionary"),
arg_str0("f", "file", "<fn>", "Filename of dictionary"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);

File diff suppressed because it is too large Load diff

View file

@ -461,9 +461,9 @@ static int CmdHFMFPWritePerso(const char *Cmd) {
void *argtable[] = {
arg_param_begin,
arg_lit0("v", "verbose", "show internal data."),
arg_str1(NULL, "ki", "<hex>", " key number, 2 hex bytes"),
arg_str0(NULL, "key", "<hex>", " key, 16 hex bytes"),
arg_lit0("v", "verbose", "Verbose mode"),
arg_str1(NULL, "ki", "<hex>", " Key number, 2 hex bytes"),
arg_str0(NULL, "key", "<hex>", " Key, 16 hex bytes"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
@ -527,8 +527,8 @@ static int CmdHFMFPInitPerso(const char *Cmd) {
void *argtable[] = {
arg_param_begin,
arg_litn("v", "verbose", 0, 2, "show internal data."),
arg_str0("k", "key", "<hex>", "key, 16 hex bytes"),
arg_litn("v", "verbose", 0, 2, "Verbose mode"),
arg_str0("k", "key", "<hex>", "Key, 16 hex bytes"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
@ -602,7 +602,7 @@ static int CmdHFMFPCommitPerso(const char *Cmd) {
void *argtable[] = {
arg_param_begin,
arg_lit0("v", "verbose", "show internal data."),
arg_lit0("v", "verbose", "Verbose mode"),
// arg_int0(NULL, "sl", "<dec>", "SL mode"),
arg_param_end
};
@ -649,9 +649,9 @@ static int CmdHFMFPAuth(const char *Cmd) {
void *argtable[] = {
arg_param_begin,
arg_lit0("v", "verbose", "show internal data."),
arg_str1(NULL, "ki", "<hex>", "key number, 2 hex bytes"),
arg_str1(NULL, "key", "<hex>", "key, 16 hex bytes"),
arg_lit0("v", "verbose", "Verbose mode"),
arg_str1(NULL, "ki", "<hex>", "Key number, 2 hex bytes"),
arg_str1(NULL, "key", "<hex>", "Key, 16 hex bytes"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
@ -683,11 +683,11 @@ static int CmdHFMFPRdbl(const char *Cmd) {
void *argtable[] = {
arg_param_begin,
arg_lit0("v", "verbose", "show internal data"),
arg_int0("n", "count", "<dec>", "blocks count (by default 1)"),
arg_lit0("b", "keyb", "use key B (by default keyA)"),
arg_lit0("p", "plain", "plain communication mode between reader and card"),
arg_int1(NULL, "blk", "<dec>", "block number (0..255)"),
arg_lit0("v", "verbose", "Verbose mode"),
arg_int0("n", "count", "<dec>", "Blocks count (def: 1)"),
arg_lit0("b", "keyb", "Use key B (def: keyA)"),
arg_lit0("p", "plain", "Plain communication mode between reader and card"),
arg_int1(NULL, "blk", "<0..255>", "Block number"),
arg_str0(NULL, "key", "<hex>", "Key, 16 hex bytes"),
arg_param_end
};
@ -790,17 +790,17 @@ static int CmdHFMFPRdbl(const char *Cmd) {
static int CmdHFMFPRdsc(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mfp rdsc",
"Reads one sector from Mifare Plus card",
"Reads one sector from MIFARE Plus card",
"hf mfp rdsc -s 0 --key 000102030405060708090a0b0c0d0e0f -> executes authentication and read sector 0 data\n"
"hf mfp rdsc -s 1 -v -> executes authentication and shows sector 1 data with default key");
void *argtable[] = {
arg_param_begin,
arg_lit0("v", "verbose", "show internal data."),
arg_lit0("b", "keyb", "use key B (by default keyA)."),
arg_lit0("p", "plain", "plain communication mode between reader and card."),
arg_int1("s", "sn", "<dec>", "sector number (0..255)"),
arg_str0("k", "key", "<hex>", "key, 16 hex bytes"),
arg_lit0("v", "verbose", "Verbose mode"),
arg_lit0("b", "keyb", "Use key B (def: keyA)"),
arg_lit0("p", "plain", "Plain communication mode between reader and card"),
arg_int1("s", "sn", "<0..255>", "Sector number"),
arg_str0("k", "key", "<hex>", "Key, 16 hex bytes"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
@ -893,11 +893,11 @@ static int CmdHFMFPWrbl(const char *Cmd) {
void *argtable[] = {
arg_param_begin,
arg_lit0("v", "verbose", "show internal data."),
arg_lit0("b", "keyb", "use key B (by default keyA)."),
arg_int1(NULL, "blk", "<dec>", "block number (0..255)"),
arg_str1("d", "data", "<hex>", "data, 16 hex bytes"),
arg_str0("k", "key", "<hex>", "key, 16 hex bytes"),
arg_lit0("v", "verbose", "Verbose mode"),
arg_lit0("b", "keyb", "Use key B (def: keyA)"),
arg_int1(NULL, "blk", "<0..255>", "Block number"),
arg_str1("d", "data", "<hex>", "Data, 16 hex bytes"),
arg_str0("k", "key", "<hex>", "Key, 16 hex bytes"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
@ -1097,7 +1097,7 @@ static int CmdHFMFPChk(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mfp chk",
"Checks keys with Mifare Plus card.",
"Checks keys on MIFARE Plus card",
"hf mfp chk -k 000102030405060708090a0b0c0d0e0f -> check key on sector 0 as key A and B\n"
"hf mfp chk -s 2 -a -> check default key list on sector 2, key A\n"
"hf mfp chk -d mfp_default_keys -s0 -e6 -> check keys from dictionary against sectors 0-6\n"
@ -1106,17 +1106,17 @@ static int CmdHFMFPChk(const char *Cmd) {
void *argtable[] = {
arg_param_begin,
arg_lit0("a", "keya", "check only key A (by default check all keys)."),
arg_lit0("b", "keyb", "check only key B (by default check all keys)."),
arg_int0("s", "startsec", "Start sector Num (0..255)", NULL),
arg_int0("e", "endsec", "End sector Num (0..255)", NULL),
arg_str0("k", "key", "<Key>", "Key for checking (HEX 16 bytes)"),
arg_str0("d", "dict", "<file>", "file with keys dictionary"),
arg_lit0(NULL, "pattern1b", "check all 1-byte combinations of key (0000...0000, 0101...0101, 0202...0202, ...)"),
arg_lit0(NULL, "pattern2b", "check all 2-byte combinations of key (0000...0000, 0001...0001, 0002...0002, ...)"),
arg_str0(NULL, "startp2b", "<Pattern>", "Start key (2-byte HEX) for 2-byte search (use with `--pattern2b`)"),
arg_str0("j", "json", "<file>", "json file to save keys"),
arg_lit0("v", "verbose", "verbose mode."),
arg_lit0("a", "keya", "Check only key A (def: check all keys)"),
arg_lit0("b", "keyb", "Check only key B (def: check all keys)"),
arg_int0("s", "startsec", "<0..255>", "Start sector number"),
arg_int0("e", "endsec", "<0..255>", "End sector number"),
arg_str0("k", "key", "<hex>", "Key for checking (HEX 16 bytes)"),
arg_str0("d", "dict", "<fn>", "Dictionary file with keys"),
arg_lit0(NULL, "pattern1b", "Check all 1-byte combinations of key (0000...0000, 0101...0101, 0202...0202, ...)"),
arg_lit0(NULL, "pattern2b", "Check all 2-byte combinations of key (0000...0000, 0001...0001, 0002...0002, ...)"),
arg_str0(NULL, "startp2b", "<pattern>", "Start key (2-byte HEX) for 2-byte search (use with `--pattern2b`)"),
arg_str0("j", "json", "<fn>", "Json filename to save keys"),
arg_lit0("v", "verbose", "Verbose mode"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
@ -1339,12 +1339,12 @@ static int CmdHFMFPMAD(const char *Cmd) {
void *argtable[] = {
arg_param_begin,
arg_lit0("v", "verbose", "show technical data"),
arg_str0(NULL, "aid", "<aid>", "print all sectors with aid"),
arg_str0("k", "key", "<key>", "key for printing sectors"),
arg_lit0("b", "keyb", "use key B for access printing sectors (by default: key A)"),
arg_lit0(NULL, "be", "(optional, BigEndian)"),
arg_lit0(NULL, "dch", "decode Card Holder information"),
arg_lit0("v", "verbose", "Show technical data"),
arg_str0(NULL, "aid", "<hex>", "Print all sectors with aid"),
arg_str0("k", "key", "<hex>", "Key for printing sectors"),
arg_lit0("b", "keyb", "Use key B for access printing sectors (def: key A)"),
arg_lit0(NULL, "be", "(optional: BigEndian)"),
arg_lit0(NULL, "dch", "Decode Card Holder information"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);

View file

@ -123,6 +123,39 @@ static char *getProductTypeStr(uint8_t id) {
return buf;
}
static int ul_print_nxp_silicon_info(uint8_t *card_uid) {
if (card_uid[0] != 0x04) {
return PM3_SUCCESS;
}
uint8_t uid[7];
memcpy(&uid, card_uid, 7);
uint16_t waferCoordX = ((uid[6] & 3) << 8) | uid[1];
uint16_t waferCoordY = ((uid[6] & 12) << 6) | uid[2];
uint32_t waferCounter = (
(uid[4] << 5) |
((uid[6] & 0xF0) << 17) |
(uid[5] << 13) |
(uid[3] >> 3)
);
uint8_t testSite = uid[3] & 7;
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(INFO, "--- " _CYAN_("Tag Silicon Information"));
PrintAndLogEx(INFO, " Wafer Counter: %" PRId32 " ( 0x%02" PRIX32 " )", waferCounter, waferCounter);
PrintAndLogEx(INFO, " Wafer Coordinates: x %" PRId16 ", y %" PRId16 " (0x%02" PRIX16 ", 0x%02" PRIX16 ")"
, waferCoordX
, waferCoordY
, waferCoordX
, waferCoordY
);
PrintAndLogEx(INFO, " Test Site: %u", testSite);
return PM3_SUCCESS;
}
/*
The 7 MSBits (=n) code the storage size itself based on 2^n,
the LSBit is set to '0' if the size is exactly 2^n
@ -1644,6 +1677,9 @@ static int CmdHF14AMfUInfo(const char *Cmd) {
}
}
// print silicon info
ul_print_nxp_silicon_info(card.uid);
// Get Version
uint8_t version[10] = {0x00};
status = ulev1_getVersion(version, sizeof(version));

View file

@ -97,6 +97,27 @@ static uint8_t extract_epurse[8] = {0};
#define SKIP_TO_NEXT(a) (TRACELOG_HDR_LEN + (a)->data_len + TRACELOG_PARITY_LEN((a)))
static uint16_t extractChall_ev2(uint16_t tracepos, uint8_t *trace, uint8_t cmdpos, uint8_t long_jmp) {
tracelog_hdr_t *next_hdr = (tracelog_hdr_t *)(trace + tracepos);
if (next_hdr->data_len != 21) {
return 0;
}
tracepos += TRACELOG_HDR_LEN + next_hdr->data_len + TRACELOG_PARITY_LEN(next_hdr);
PrintAndLogEx(INFO, "1499999999 %s " NOLF, sprint_hex_inrow(next_hdr->frame + 1, 16));
next_hdr = (tracelog_hdr_t *)(trace + tracepos);
tracepos += TRACELOG_HDR_LEN + next_hdr->data_len + TRACELOG_PARITY_LEN(next_hdr);
if (next_hdr->frame[cmdpos] == MFDES_ADDITIONAL_FRAME) {
PrintAndLogEx(NORMAL, "%s", sprint_hex_inrow(next_hdr->frame + cmdpos + long_jmp, 32));
} else {
PrintAndLogEx(NORMAL, "");
}
return tracepos;
}
static uint16_t extractChallenges(uint16_t tracepos, uint16_t traceLen, uint8_t *trace) {
// sanity check
@ -270,6 +291,10 @@ static uint16_t extractChallenges(uint16_t tracepos, uint16_t traceLen, uint8_t
return tracepos;
}
if (hdr->isResponse) {
return tracepos;
}
// PCB [CID] [NAD] [INF] CRC CRC
uint8_t pos = calc_pos(frame);
uint8_t long_jmp = (data_len > 6) ? 4 : 1;
@ -279,16 +304,18 @@ static uint16_t extractChallenges(uint16_t tracepos, uint16_t traceLen, uint8_t
switch (frame[pos]) {
case MFDES_AUTHENTICATE: {
// Assume wrapped or unwrapped
PrintAndLogEx(INFO, "AUTH NATIVE (keyNo %d)", frame[pos + long_jmp]);
if (hdr->isResponse == false && next_record_is_response(tracepos, trace)) {
if (next_record_is_response(tracepos, trace) == false) {
break;
}
tracelog_hdr_t *next_hdr = (tracelog_hdr_t *)(trace + tracepos);
tracepos += TRACELOG_HDR_LEN + next_hdr->data_len + TRACELOG_PARITY_LEN(next_hdr);
if (next_hdr->data_len < 7) {
break;
}
tracepos += TRACELOG_HDR_LEN + next_hdr->data_len + TRACELOG_PARITY_LEN(next_hdr);
PrintAndLogEx(INFO, "DES 1499999999 %s " NOLF, sprint_hex_inrow(next_hdr->frame + 1, 8));
@ -297,16 +324,17 @@ static uint16_t extractChallenges(uint16_t tracepos, uint16_t traceLen, uint8_t
if (next_hdr->frame[pos] == MFDES_ADDITIONAL_FRAME) {
PrintAndLogEx(NORMAL, "%s", sprint_hex_inrow(next_hdr->frame + pos + long_jmp, 16));
} else {
PrintAndLogEx(NORMAL, "");
}
return tracepos;
}
break; // AUTHENTICATE_NATIVE
return tracepos; // AUTHENTICATE_NATIVE
}
case MFDES_AUTHENTICATE_ISO: {
// Assume wrapped or unwrapped
PrintAndLogEx(INFO, "AUTH ISO (keyNo %d)", frame[pos + long_jmp]);
if (hdr->isResponse == false && next_record_is_response(tracepos, trace)) {
if (next_record_is_response(tracepos, trace) == false) {
break;
}
tracelog_hdr_t *next_hdr = (tracelog_hdr_t *)(trace + tracepos);
tracepos += TRACELOG_HDR_LEN + next_hdr->data_len + TRACELOG_PARITY_LEN(next_hdr);
@ -327,22 +355,24 @@ static uint16_t extractChallenges(uint16_t tracepos, uint16_t traceLen, uint8_t
if (next_hdr->frame[pos] == MFDES_ADDITIONAL_FRAME) {
PrintAndLogEx(NORMAL, "%s", sprint_hex_inrow(next_hdr->frame + pos + long_jmp, (tdea << 1)));
} else {
PrintAndLogEx(NORMAL, "");
}
return tracepos;
}
break; // AUTHENTICATE_STANDARD
return tracepos; // AUTHENTICATE_STANDARD
}
case MFDES_AUTHENTICATE_AES: {
// Assume wrapped or unwrapped
PrintAndLogEx(INFO, "AUTH AES (keyNo %d)", frame[pos + long_jmp]);
if (hdr->isResponse == false && next_record_is_response(tracepos, trace)) {
if (next_record_is_response(tracepos, trace)) {
break;
}
tracelog_hdr_t *next_hdr = (tracelog_hdr_t *)(trace + tracepos);
tracepos += TRACELOG_HDR_LEN + next_hdr->data_len + TRACELOG_PARITY_LEN(next_hdr);
if (next_hdr->data_len < 7) {
break;
}
PrintAndLogEx(INFO, "AES 1499999999 %s " NOLF, sprint_hex_inrow(next_hdr->frame + 1, 8));
next_hdr = (tracelog_hdr_t *)(trace + tracepos);
@ -350,22 +380,27 @@ static uint16_t extractChallenges(uint16_t tracepos, uint16_t traceLen, uint8_t
if (next_hdr->frame[pos] == MFDES_ADDITIONAL_FRAME) {
PrintAndLogEx(NORMAL, "%s", sprint_hex_inrow(next_hdr->frame + pos + long_jmp, 16));
} else {
PrintAndLogEx(NORMAL, "");
}
return tracepos;
}
break;
}
case MFDES_AUTHENTICATE_EV2F: {
if (hdr->isResponse == false) {
PrintAndLogEx(INFO, "AUTH EV2 First");
}
uint16_t tmp = extractChall_ev2(tracepos, trace, pos, long_jmp);
if (tmp == 0)
break;
else
return tmp;
}
case MFDES_AUTHENTICATE_EV2NF: {
if (hdr->isResponse == false) {
PrintAndLogEx(INFO, "AUTH EV2 Non First");
}
uint16_t tmp = extractChall_ev2(tracepos, trace, pos, long_jmp);
if (tmp == 0)
break;
else
return tmp;
}
}
}

View file

@ -87,11 +87,11 @@ static int CmdEMVSelect(const char *Cmd) {
void *argtable[] = {
arg_param_begin,
arg_lit0("sS", "select", "activate field and select card"),
arg_lit0("kK", "keep", "keep field for next command"),
arg_lit0("aA", "apdu", "show APDU requests and responses"),
arg_lit0("sS", "select", "Activate field and select card"),
arg_lit0("kK", "keep", "Keep field for next command"),
arg_lit0("aA", "apdu", "Show APDU requests and responses"),
arg_lit0("tT", "tlv", "TLV decode results"),
arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. (def: Contactless interface)"),
arg_str1(NULL, NULL, "<hex>", "Applet AID"),
arg_param_end
};
@ -138,11 +138,11 @@ static int CmdEMVSearch(const char *Cmd) {
void *argtable[] = {
arg_param_begin,
arg_lit0("sS", "select", "activate field and select card"),
arg_lit0("kK", "keep", "keep field ON for next command"),
arg_lit0("aA", "apdu", "show APDU reqests and responses"),
arg_lit0("sS", "select", "Activate field and select card"),
arg_lit0("kK", "keep", "Keep field ON for next command"),
arg_lit0("aA", "apdu", "Show APDU reqests and responses"),
arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. (def: Contactless interface)"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
@ -192,13 +192,13 @@ static int CmdEMVPPSE(const char *Cmd) {
void *argtable[] = {
arg_param_begin,
arg_lit0("sS", "select", "activate field and select card"),
arg_lit0("kK", "keep", "keep field ON for next command"),
arg_lit0("1", "pse", "pse (1PAY.SYS.DDF01) mode"),
arg_lit0("2", "ppse", "ppse (2PAY.SYS.DDF01) mode (default mode)"),
arg_lit0("aA", "apdu", "show APDU reqests and responses"),
arg_lit0("sS", "select", "Activate field and select card"),
arg_lit0("kK", "keep", "Keep field ON for next command"),
arg_lit0("1", "pse", "PSE (1PAY.SYS.DDF01) mode"),
arg_lit0("2", "ppse", "PPSE (2PAY.SYS.DDF01) mode (def)"),
arg_lit0("aA", "apdu", "Show APDU reqests and responses"),
arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. (def: Contactless interface)"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
@ -252,12 +252,12 @@ static int CmdEMVGPO(const char *Cmd) {
void *argtable[] = {
arg_param_begin,
arg_lit0("kK", "keep", "keep field ON for next command"),
arg_lit0("pP", "params", "load parameters from `emv_defparams.json` file for PDOLdata making from PDOL and parameters"),
arg_lit0("mM", "make", "make PDOLdata from PDOL (tag 9F38) and parameters (by default uses default parameters)"),
arg_lit0("aA", "apdu", "show APDU reqests and responses"),
arg_lit0("kK", "keep", "Keep field ON for next command"),
arg_lit0("pP", "params", "Load parameters from `emv_defparams.json` file for PDOLdata making from PDOL and parameters"),
arg_lit0("mM", "make", "Make PDOLdata from PDOL (tag 9F38) and parameters (def: uses default parameters)"),
arg_lit0("aA", "apdu", "Show APDU reqests and responses"),
arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. (def: Contactless interface)"),
arg_strx0(NULL, NULL, "<hex>", "PDOLdata/PDOL"),
arg_param_end
};
@ -361,10 +361,10 @@ static int CmdEMVReadRecord(const char *Cmd) {
void *argtable[] = {
arg_param_begin,
arg_lit0("kK", "keep", "keep field ON for next command"),
arg_lit0("aA", "apdu", "show APDU reqests and responses"),
arg_lit0("kK", "keep", "Keep field ON for next command"),
arg_lit0("aA", "apdu", "Show APDU reqests and responses"),
arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. (def: Contactless interface)"),
arg_strx1(NULL, NULL, "<hex>", "<SFI 1 byte><SFIrecord 1 byte"),
arg_param_end
};
@ -421,14 +421,14 @@ static int CmdEMVAC(const char *Cmd) {
void *argtable[] = {
arg_param_begin,
arg_lit0("kK", "keep", "keep field ON for next command"),
arg_lit0("cC", "cda", "executes CDA transaction. Needs to get SDAD in results."),
arg_lit0("kK", "keep", "Keep field ON for next command"),
arg_lit0("cC", "cda", "Executes CDA transaction. Needs to get SDAD in results."),
arg_str0("dD", "decision", "<aac|tc|arqc>", "Terminal decision. aac - declined, tc - approved, arqc - online authorisation requested"),
arg_lit0("pP", "params", "load parameters from `emv_defparams.json` file for CDOLdata making from CDOL and parameters"),
arg_lit0("mM", "make", "make CDOLdata from CDOL (tag 8C and 8D) and parameters (by default uses default parameters)"),
arg_lit0("aA", "apdu", "show APDU reqests and responses"),
arg_lit0("pP", "params", "Load parameters from `emv_defparams.json` file for CDOLdata making from CDOL and parameters"),
arg_lit0("mM", "make", "Make CDOLdata from CDOL (tag 8C and 8D) and parameters (def: use default parameters)"),
arg_lit0("aA", "apdu", "Show APDU reqests and responses"),
arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. (def: Contactless interface)"),
arg_strx1(NULL, NULL, "<hex>", "CDOLdata/CDOL"),
arg_param_end
};
@ -543,9 +543,9 @@ static int CmdEMVGenerateChallenge(const char *Cmd) {
void *argtable[] = {
arg_param_begin,
arg_lit0("kK", "keep", "keep field ON for next command"),
arg_lit0("aA", "apdu", "show APDU reqests and responses"),
arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
arg_lit0("kK", "keep", "Keep field ON for next command"),
arg_lit0("aA", "apdu", "Show APDU reqests and responses"),
arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. (def: Contactless interface)"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
@ -595,12 +595,12 @@ static int CmdEMVInternalAuthenticate(const char *Cmd) {
void *argtable[] = {
arg_param_begin,
arg_lit0("kK", "keep", "keep field ON for next command"),
arg_lit0("pP", "params", "load parameters from `emv_defparams.json` file for DDOLdata making from DDOL and parameters"),
arg_lit0("mM", "make", "make DDOLdata from DDOL (tag 9F49) and parameters (by default uses default parameters)"),
arg_lit0("aA", "apdu", "show APDU reqests and responses"),
arg_lit0("kK", "keep", "Keep field ON for next command"),
arg_lit0("pP", "params", "Load parameters from `emv_defparams.json` file for DDOLdata making from DDOL and parameters"),
arg_lit0("mM", "make", "Make DDOLdata from DDOL (tag 9F49) and parameters (def: use default parameters)"),
arg_lit0("aA", "apdu", "Show APDU reqests and responses"),
arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. (def: Contactless interface)"),
arg_strx1(NULL, NULL, "<hex>", "DDOLdata/DDOL"),
arg_param_end
};
@ -822,17 +822,17 @@ static int CmdEMVExec(const char *Cmd) {
void *argtable[] = {
arg_param_begin,
arg_lit0("sS", "select", "activate field and select card."),
arg_lit0("aA", "apdu", "show APDU reqests and responses."),
arg_lit0("tT", "tlv", "TLV decode results."),
arg_lit0("jJ", "jload", "Load transaction parameters from `emv_defparams.json` file."),
arg_lit0("fF", "forceaid", "Force search AID. Search AID instead of execute PPSE."),
arg_lit0("sS", "select", "Activate field and select card"),
arg_lit0("aA", "apdu", "Show APDU reqests and responses"),
arg_lit0("tT", "tlv", "TLV decode results"),
arg_lit0("jJ", "jload", "Load transaction parameters from `emv_defparams.json` file"),
arg_lit0("fF", "forceaid", "Force search AID. Search AID instead of execute PPSE"),
arg_rem("By default:", "Transaction type - MSD"),
arg_lit0("vV", "qvsdc", "Transaction type - qVSDC or M/Chip."),
arg_lit0("cC", "qvsdccda", "Transaction type - qVSDC or M/Chip plus CDA (SDAD generation)."),
arg_lit0("xX", "vsdc", "Transaction type - VSDC. For test only. Not a standard behavior."),
arg_lit0("gG", "acgpo", "VISA. generate AC from GPO."),
arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
arg_lit0("vV", "qvsdc", "Transaction type - qVSDC or M/Chip"),
arg_lit0("cC", "qvsdccda", "Transaction type - qVSDC or M/Chip plus CDA (SDAD generation)"),
arg_lit0("xX", "vsdc", "Transaction type - VSDC. For test only. Not a standard behavior"),
arg_lit0("gG", "acgpo", "VISA. generate AC from GPO"),
arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. (def: Contactless interface)"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
@ -1448,17 +1448,17 @@ static int CmdEMVScan(const char *Cmd) {
void *argtable[] = {
arg_param_begin,
arg_lit0("aA", "apdu", "show APDU reqests and responses."),
arg_lit0("tT", "tlv", "TLV decode results."),
arg_lit0("aA", "apdu", "Show APDU reqests and responses"),
arg_lit0("tT", "tlv", "TLV decode results"),
arg_lit0("eE", "extract", "Extract TLV elements and fill Application Data"),
arg_lit0("jJ", "jload", "Load transaction parameters from `emv_defparams.json` file."),
arg_lit0("jJ", "jload", "Load transaction parameters from `emv_defparams.json` file"),
arg_rem("By default:", "Transaction type - MSD"),
arg_lit0("vV", "qvsdc", "Transaction type - qVSDC or M/Chip."),
arg_lit0("cC", "qvsdccda", "Transaction type - qVSDC or M/Chip plus CDA (SDAD generation)."),
arg_lit0("xX", "vsdc", "Transaction type - VSDC. For test only. Not a standard behavior."),
arg_lit0("gG", "acgpo", "VISA. generate AC from GPO."),
arg_lit0("vV", "qvsdc", "Transaction type - qVSDC or M/Chip"),
arg_lit0("cC", "qvsdccda", "Transaction type - qVSDC or M/Chip plus CDA (SDAD generation)"),
arg_lit0("xX", "vsdc", "Transaction type - VSDC. For test only. Not a standard behavior"),
arg_lit0("gG", "acgpo", "VISA. generate AC from GPO"),
arg_lit0("mM", "merge", "Merge output file with card's data. (warning: the file may be corrupted!)"),
arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. (def: Contactless interface)"),
arg_str1(NULL, NULL, "<fn>", "JSON output filename"),
arg_param_end
};
@ -1839,8 +1839,8 @@ static int CmdEMVTest(const char *Cmd) {
void *argtable[] = {
arg_param_begin,
arg_lit0("i", "ignore", "ignore timing tests for VM"),
arg_lit0("l", "long", "run long tests too"),
arg_lit0("i", "ignore", "Ignore timing tests for VM"),
arg_lit0("l", "long", "Run long tests too"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
@ -1871,9 +1871,9 @@ static int CmdEMVRoca(const char *Cmd) {
void *argtable[] = {
arg_param_begin,
arg_lit0("tT", "selftest", "self test"),
arg_lit0("aA", "apdu", "show APDU reqests and responses"),
arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default"),
arg_lit0("tT", "selftest", "Self test"),
arg_lit0("aA", "apdu", "Show APDU reqests and responses"),
arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. (def: Contactless interface)"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
@ -2124,17 +2124,17 @@ out:
static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help"},
{"exec", CmdEMVExec, IfPm3Iso14443, "Executes EMV contactless transaction."},
{"pse", CmdEMVPPSE, IfPm3Iso14443, "Execute PPSE. It selects 2PAY.SYS.DDF01 or 1PAY.SYS.DDF01 directory."},
{"search", CmdEMVSearch, IfPm3Iso14443, "Try to select all applets from applets list and print installed applets."},
{"select", CmdEMVSelect, IfPm3Iso14443, "Select applet."},
{"gpo", CmdEMVGPO, IfPm3Iso14443, "Execute GetProcessingOptions."},
{"readrec", CmdEMVReadRecord, IfPm3Iso14443, "Read files from card."},
{"genac", CmdEMVAC, IfPm3Iso14443, "Generate ApplicationCryptogram."},
{"challenge", CmdEMVGenerateChallenge, IfPm3Iso14443, "Generate challenge."},
{"intauth", CmdEMVInternalAuthenticate, IfPm3Iso14443, "Internal authentication."},
{"scan", CmdEMVScan, IfPm3Iso14443, "Scan EMV card and save it contents to json file for emulator."},
{"test", CmdEMVTest, AlwaysAvailable, "Crypto logic test."},
{"exec", CmdEMVExec, IfPm3Iso14443, "Executes EMV contactless transaction"},
{"pse", CmdEMVPPSE, IfPm3Iso14443, "Execute PPSE. It selects 2PAY.SYS.DDF01 or 1PAY.SYS.DDF01 directory"},
{"search", CmdEMVSearch, IfPm3Iso14443, "Try to select all applets from applets list and print installed applets"},
{"select", CmdEMVSelect, IfPm3Iso14443, "Select applet"},
{"gpo", CmdEMVGPO, IfPm3Iso14443, "Execute GetProcessingOptions"},
{"readrec", CmdEMVReadRecord, IfPm3Iso14443, "Read files from card"},
{"genac", CmdEMVAC, IfPm3Iso14443, "Generate ApplicationCryptogram"},
{"challenge", CmdEMVGenerateChallenge, IfPm3Iso14443, "Generate challenge"},
{"intauth", CmdEMVInternalAuthenticate, IfPm3Iso14443, "Internal authentication"},
{"scan", CmdEMVScan, IfPm3Iso14443, "Scan EMV card and save it contents to json file for emulator"},
{"test", CmdEMVTest, AlwaysAvailable, "Crypto logic test"},
/*
{"getrng", CmdEMVGetrng, IfPm3Iso14443, "get random number from terminal"},
{"eload", CmdEmvELoad, IfPm3Iso14443, "load EMV tag into device"},

View file

@ -2252,10 +2252,11 @@ static const DesfireCreateFileCommands_t DesfireFileCommands[] = {
};
const DesfireCreateFileCommands_t *GetDesfireFileCmdRec(uint8_t type) {
for (int i = 0; i < ARRAYLEN(DesfireFileCommands); i++)
if (DesfireFileCommands[i].id == type)
for (int i = 0; i < ARRAYLEN(DesfireFileCommands); i++) {
if (DesfireFileCommands[i].id == type) {
return &DesfireFileCommands[i];
}
}
return NULL;
}
@ -2303,6 +2304,7 @@ const char *GetDesfireAccessRightStr(uint8_t right) {
sprintf(int_access_str, "key 0x%02x", right);
return int_access_str;
}
if (right == 0x0e)
return DesfireFreeStr;
@ -2332,8 +2334,9 @@ const char *AccessRightShortStr[] = {
};
const char *GetDesfireAccessRightShortStr(uint8_t right) {
if (right > 0x0f)
if (right > 0x0F) {
return DesfireNAStr;
}
return AccessRightShortStr[right];
}
@ -2346,23 +2349,20 @@ void DesfireEncodeFileAcessMode(uint8_t *mode, uint8_t r, uint8_t w, uint8_t rw,
void DesfireDecodeFileAcessMode(const uint8_t *mode, uint8_t *r, uint8_t *w, uint8_t *rw, uint8_t *ch) {
// read
if (r)
*r = (mode[1] >> 4) & 0x0f; // hi 2b
*r = (mode[1] >> 4) & 0x0F; // hi 2b
// write
if (w)
*w = mode[1] & 0x0f;
*w = mode[1] & 0x0F;
// read/write
if (rw)
*rw = (mode[0] >> 4) & 0x0f; // low 2b
*rw = (mode[0] >> 4) & 0x0F; // low 2b
// change
if (ch)
*ch = mode[0] & 0x0f;
*ch = mode[0] & 0x0F;
}
void DesfirePrintAccessRight(uint8_t *data) {
uint8_t r = 0;
uint8_t w = 0;
uint8_t rw = 0;
uint8_t ch = 0;
uint8_t r = 0, w = 0, rw = 0, ch = 0;
DesfireDecodeFileAcessMode(data, &r, &w, &rw, &ch);
PrintAndLogEx(SUCCESS, "read : %s", GetDesfireAccessRightStr(r));
PrintAndLogEx(SUCCESS, "write : %s", GetDesfireAccessRightStr(w));