From 2010f8db038f5841abce8265d246dd0151127869 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 5 Apr 2020 12:28:49 +0200 Subject: [PATCH 01/12] colors --- client/luascripts/Legic_clone.lua | 24 +++++----- client/luascripts/formatMifare.lua | 14 +++--- client/luascripts/hf_bruteforce.lua | 51 +++++++++++---------- client/luascripts/hf_read.lua | 60 +++++++++++++++++++++++++ client/luascripts/htmldump.lua | 14 +++--- client/luascripts/init_rdv4.lua | 15 ++++--- client/luascripts/iso15_magic.lua | 14 +++--- client/luascripts/legic_buffer2card.lua | 14 +++--- client/luascripts/lf_bulk.lua | 14 +++--- client/luascripts/lto_dump.lua | 14 +++--- 10 files changed, 164 insertions(+), 70 deletions(-) diff --git a/client/luascripts/Legic_clone.lua b/client/luascripts/Legic_clone.lua index 982b17aec..191f9f9e0 100644 --- a/client/luascripts/Legic_clone.lua +++ b/client/luascripts/Legic_clone.lua @@ -1,3 +1,6 @@ +local utils = require('utils') +local getopt = require('getopt') +local ansicolors = require('ansicolors') --[[ script to create a clone-dump with new crc Author: mosci @@ -86,7 +89,7 @@ copyright = '' author = 'Mosci' -version = 'v1.0.1' +version = 'v1.0.2' desc = [[ This is a script which creates a clone-dump of a dump from a Legic Prime Tag (MIM256 or MIM1024) (created with 'hf legic save my_dump.hex') @@ -97,11 +100,12 @@ example = [[ ]] usage = [[ script run legic_clone -h -i -o -c -d -s -w - -required arguments: +]] +arguments = [[ +required : -i (file to read data from) -optional arguments : +optional : -h - Help text -o - requires option -c to be given -c - requires option -o to be given @@ -112,8 +116,7 @@ optional arguments : e.g.: hint: using the CRC '00' will result in a plain dump ( -c 00 ) ]] -local utils = require('utils') -local getopt = require('getopt') + local bxor = bit32.bxor -- we need always 2 digits @@ -128,7 +131,6 @@ local function prepend_zero(s) end end end - --- -- This is only meant to be used when errors occur local function oops(err) @@ -136,7 +138,6 @@ local function oops(err) core.clearCommandBuffer() return nil, err end - --- -- Usage help local function help() @@ -144,9 +145,12 @@ local function help() print(author) print(version) print(desc) - print('Example usage') - print(example) + 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 -- Check availability of file diff --git a/client/luascripts/formatMifare.lua b/client/luascripts/formatMifare.lua index 7c6fd92c0..30ab20535 100644 --- a/client/luascripts/formatMifare.lua +++ b/client/luascripts/formatMifare.lua @@ -3,10 +3,11 @@ local getopt = require('getopt') local bin = require('bin') local lib14a = require('read14a') local utils = require('utils') +local ansicolors = require('ansicolors') copyright = '' author = 'Iceman' -version = 'v1.0.1' +version = 'v1.0.2' desc = [[ This script will generate 'hf mf wrbl' commands for each block to format a Mifare card. @@ -29,8 +30,8 @@ example = [[ ]] usage = [[ script run formatMifare -k -n -a -x - -Arguments: +]] +arguments = [[ -h - this help -k - the current six byte key with write access -n - the new key that will be written to the card @@ -71,9 +72,12 @@ local function help() print(author) print(version) print(desc) - print('Example usage') - print(example) + 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 -- -- Exit message diff --git a/client/luascripts/hf_bruteforce.lua b/client/luascripts/hf_bruteforce.lua index 485d72809..a1ba34fad 100644 --- a/client/luascripts/hf_bruteforce.lua +++ b/client/luascripts/hf_bruteforce.lua @@ -2,38 +2,38 @@ -- Run me like this (connected via Blueshark addon): ./client/proxmark3 /dev/rfcomm0 -l ./hf_bruteforce.lua local getopt = require('getopt') +local ansicolors = require('ansicolors') copyright = '' author = 'Daniel Underhay (updated), Keld Norman(original)' -version = 'v2.0.0' -usage = [[ - -pm3 --> script run hf_bruteforce -s start_id -e end_id -t timeout -x mifare_card_type - -Arguments: - -h this help - -s 0-0xFFFFFFFF start id - -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: mfc for Mifare Classic (default) or mfu for Mifare Ultralight EV1 - - -Example: - -pm3 --> script run hf_bruteforce -s 0x11223344 -e 0x11223346 -t 1000 -x mfc - +version = 'v2.0.1' +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. - - -pm3 --> script run hf_bruteforce -s 0x11223344556677 -e 0x11223344556679 -t 1000 -x mfu + + script run hf_bruteforce -s 0x11223344 -e 0x11223346 -t 1000 -x mfc Bruteforce a 7 byte UID Mifare Ultralight card number, starting at 11223344556677, ending at 11223344556679. + script run hf_bruteforce -s 0x11223344556677 -e 0x11223344556679 -t 1000 -x mfu +]] +usage = [[ +script run hf_bruteforce [-s ] [-e ] [-t ] [-x ] +]] +arguments = [[ + -h this help + -s 0-0xFFFFFFFF start id + -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: + mfc for Mifare Classic (default) + mfu for Mifare Ultralight EV1 ]] - local DEBUG = true - --- -- Debug print function local function dbg(args) @@ -62,9 +62,12 @@ local function help() print(author) print(version) print(desc) - print('Example usage') - print(example) + 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 user message diff --git a/client/luascripts/hf_read.lua b/client/luascripts/hf_read.lua index 00238a67c..e416cdd2e 100644 --- a/client/luascripts/hf_read.lua +++ b/client/luascripts/hf_read.lua @@ -1,6 +1,65 @@ local reader = require('hf_reader') +local getopt = require('getopt') +local ansicolors = require('ansicolors') +copyright = '' +author = '' +version = 'v1.0.1' +desc = [[ +This script tries to detect a HF card. Just like 'hf search' does but this is experimental +]] +example = [[ + 1. script run hf_read +]] +usage = [[ +script run hf_read +]] +arguments = [[ + -h - this help +]] +--- +-- This is only meant to be used when errors occur +local function dbg(err) + if not DEBUG then return end + if type(args) == 'table' then + local i = 1 + while args[i] do + dbg(args[i]) + i = i+1 + end + else + print('###', args) + end +end +--- +-- This is only meant to be used when errors occur +local function oops(err) + print('ERROR:', err) + core.clearCommandBuffer() + return nil, err +end +--- +-- Usage help +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 +--- +-- local function main(args) + -- Arguments for the script + for o, a in getopt.getopt(args, 'h') do + if o == 'h' then return help() end + end + print("WORK IN PROGRESS - not expected to be functional yet") info, err = reader.waitForTag() @@ -15,4 +74,5 @@ local function main(args) end return end + main(args) diff --git a/client/luascripts/htmldump.lua b/client/luascripts/htmldump.lua index 0101c14a8..2853d343b 100644 --- a/client/luascripts/htmldump.lua +++ b/client/luascripts/htmldump.lua @@ -3,10 +3,11 @@ getopt = require('getopt') bin = require('bin') dumplib = require('html_dumplib') +local ansicolors = require('ansicolors') copyright = '' author = 'Martin Holst Swende' -version = 'v1.0.1' +version = 'v1.0.2' desc =[[ This script takes a dumpfile and produces a html based dump, which is a bit more easily analyzed. @@ -16,8 +17,8 @@ example = [[ ]] usage = [[ script run htmldump [-i ] [-o ] - -Arguments: +]] +arguments = [[ -h This help -i Specifies the dump-file (input). If omitted, 'dumpdata.bin' is used -o Speciies the output file. If omitted, .html is used. @@ -55,9 +56,12 @@ local function help() print(author) print(version) print(desc) - print('Example usage') - print(example) + 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 local function main(args) diff --git a/client/luascripts/init_rdv4.lua b/client/luascripts/init_rdv4.lua index d2dd03e24..bc18dc0a9 100644 --- a/client/luascripts/init_rdv4.lua +++ b/client/luascripts/init_rdv4.lua @@ -1,21 +1,21 @@ local getopt = require('getopt') +local ansicolors = require('ansicolors') copyright = 'Copyright (c) 2019 IceSQL AB. All rights reserved.' author = 'Christian Herrmann' -version = 'v1.0.0' +version = 'v1.0.1' desc = [[ This script initialize a Proxmark3 RDV4.0 with - uploading dictionary files to flashmem - configuring the LF T55X7 device settings ]] example = [[ - script run init_rdv4 ]] usage = [[ script run init_rdv4 -h - -Arguments: +]] +arguments = [[ -h : this help ]] @@ -48,9 +48,12 @@ local function help() print(author) print(version) print(desc) - print('Example usage') - print(example) + 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 --- -- The main entry point diff --git a/client/luascripts/iso15_magic.lua b/client/luascripts/iso15_magic.lua index ba94465e4..94f1d8f97 100644 --- a/client/luascripts/iso15_magic.lua +++ b/client/luascripts/iso15_magic.lua @@ -2,10 +2,11 @@ local cmds = require('commands') local lib15 = require('read15') local getopt = require('getopt') local utils = require('utils') +local ansicolors = require('ansicolors') copyright = 'Copyright (c) 2018 IceSQL AB. All rights reserved.' author = 'Christian Herrmann' -version = 'v1.0.5' +version = 'v1.0.6' desc = [[ This script tries to set UID on a IS15693 SLIX magic card Remember the UID ->MUST<- start with 0xE0 @@ -20,8 +21,8 @@ example = [[ ]] usage = [[ script run iso15_magic -h -u - -Arguments: +]] +arguments = [[ -h : this help -u : UID (16 hexsymbols) -a : use offical pm3 repo ISO15 commands instead of iceman fork. @@ -56,9 +57,12 @@ local function help() print(author) print(version) print(desc) - print('Example usage') - print(example) + 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 -- --- Set UID on magic command enabled on a ICEMAN based REPO diff --git a/client/luascripts/legic_buffer2card.lua b/client/luascripts/legic_buffer2card.lua index 462880ce5..d0a018d83 100644 --- a/client/luascripts/legic_buffer2card.lua +++ b/client/luascripts/legic_buffer2card.lua @@ -1,10 +1,11 @@ local utils = require('utils') local getopt = require('getopt') +local ansicolors = require('ansicolors') -- this script writes bytes 8 to 256 on the Legic MIM256 copyright = '' author = 'Mosci' -version = 'v1.0.1' +version = 'v1.0.2' desc = [[ This is a script which writes value 0x01 to bytes from position 0x07 until 0xFF on a Legic Prime Tag (MIM256 or MIM1024) -- (created with 'hf legic save my_dump.hex') -- @@ -14,8 +15,8 @@ example = [[ ]] usage = [[ script run legic_buffer2card -h - -Arguments +]] +arguments = [[ -h - Help text ]] @@ -33,9 +34,12 @@ local function help() print(author) print(version) print(desc) - print('Example usage') - print(example) + 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 -- -- simple loop-write from 0x07 to 0xff diff --git a/client/luascripts/lf_bulk.lua b/client/luascripts/lf_bulk.lua index 54c60fb89..709c992a4 100644 --- a/client/luascripts/lf_bulk.lua +++ b/client/luascripts/lf_bulk.lua @@ -3,10 +3,11 @@ -- Updated 2017-04-18 -- Updated 2018-02-20 iceman local getopt = require('getopt') +local ansicolors = require('ansicolors') copyright = '' author = "Brian Redbeard" -version = 'v1.0.1' +version = 'v1.0.2' desc = [[ Perform bulk enrollment of 26 bit H10301 style RFID Tags For more info, check the comments in the code @@ -17,8 +18,8 @@ example = [[ ]] usage = [[ script run lf_bulk.lua -f facility -b base_id_num -c count - -Arguments: +]] +arguments = [[ -h : this help -f : facility id -b : starting card id @@ -56,9 +57,12 @@ local function help() print(author) print(version) print(desc) - print('Example usage') - print(example) + 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 --- -- Exit message diff --git a/client/luascripts/lto_dump.lua b/client/luascripts/lto_dump.lua index a384a4f9b..d2dd87762 100644 --- a/client/luascripts/lto_dump.lua +++ b/client/luascripts/lto_dump.lua @@ -2,10 +2,11 @@ local cmds = require('commands') local getopt = require('getopt') local lib14a = require('read14a') local utils = require('utils') +local ansicolors = require('ansicolors') copyright = '' author = 'Kevin' -version = 'v1.0.1' +version = 'v1.0.2' desc = [[ This is a script that reads LTO-CM ISO14443a tags. It starts from block 0 and ends at default block 254. @@ -19,8 +20,8 @@ example = [[ ]] usage = [[ script run lto_dump -h -s -e - -Arguments: +]] +arguments = [[ h this helptext s start block in decimal e end block in decimal @@ -58,9 +59,12 @@ local function help() print(author) print(version) print(desc) - print('Example usage') - print(example) + 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 local function sendRaw(rawdata, options) From 95bc1230d7516abbfbc1f964fb63760963885f69 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 5 Apr 2020 12:41:38 +0200 Subject: [PATCH 02/12] colors --- client/luascripts/emul2dump.lua | 2 +- client/luascripts/luxeodump.lua | 59 +++++++++++++++++++--------- client/luascripts/mfckeys.lua | 18 ++++++--- client/luascripts/mfu_magic.lua | 21 +++++----- client/luascripts/mifare_access.lua | 16 +++++--- client/luascripts/mifare_autopwn.lua | 16 +++++--- client/luascripts/mifareplus.lua | 22 ++++++----- client/luascripts/ndef_dump.lua | 16 +++++--- client/luascripts/ntag_3d.lua | 16 +++++--- 9 files changed, 118 insertions(+), 68 deletions(-) diff --git a/client/luascripts/emul2dump.lua b/client/luascripts/emul2dump.lua index 9249dd5c0..cf6900bff 100644 --- a/client/luascripts/emul2dump.lua +++ b/client/luascripts/emul2dump.lua @@ -1,7 +1,7 @@ local getopt = require('getopt') local bin = require('bin') local dumplib = require('html_dumplib') -local ansicolors = require('ansicolors') +local ansicolors = require('ansicolors') copyright = '' author = 'Iceman' diff --git a/client/luascripts/luxeodump.lua b/client/luascripts/luxeodump.lua index 6b7254801..3efc8e7c0 100644 --- a/client/luascripts/luxeodump.lua +++ b/client/luascripts/luxeodump.lua @@ -12,9 +12,9 @@ local ansicolors = require('ansicolors') copyright = '' author = '0xdrrb' -version = 'v0.1.0' +version = 'v0.1.1' desc = [[ -This is a script to dump and decrypt the data of a specific type of Mifare laundromat token. +This is a script that tries to dump and decrypt the data of a specific type of Mifare laundromat token. OBS! Tag must be on the antenna. ]] example = [[ script run luxeodump @@ -22,7 +22,9 @@ example = [[ usage = [[ script run luxeodump ]] - +arguments = [[ + -h This help +]] local PM3_SUCCESS = 0 -- Some shortcuts @@ -48,7 +50,22 @@ local function oops(err) core.clearCommandBuffer() return nil, err end - +--- +-- Usage help +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 +--- +-- local function setdevicedebug( status ) local c = 'hw dbg ' if status then @@ -72,8 +89,8 @@ local function xteaCrypt(num_rounds, v, key) -- v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3]); v1 = band(bxor(bxor(lsh(v0,4), rsh(v0,5)) + v0, sum + key[band(rsh(sum,11),3)]) + v1, 0xFFFFFFFF) end - v[0]=v0 - v[1]=v1 + v[0] = v0 + v[1] = v1 end local function xteaDecrypt(num_rounds, v, key) @@ -89,8 +106,8 @@ local function xteaDecrypt(num_rounds, v, key) -- v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]); v0 = band(v0 - bxor(bxor(lsh(v1,4), rsh(v1,5)) + v1, sum + key[band(sum,3)]), 0xFFFFFFFF) end - v[0]=v0 - v[1]=v1 + v[0] = v0 + v[1] = v1 end local function createxteakey(mfuid) @@ -150,7 +167,7 @@ local function readtag(mfkey,xteakey) -- Read 4 sectors and build table for sect = 8, 11 do - for blockn = sect*4, (sect*4)+2 do + for blockn = sect * 4, (sect * 4) + 2 do local blockdata = readblock(blockn, mfkey) if not blockdata then return oops('[!] failed reading block') end table.insert(tagdata, blockdata) @@ -160,17 +177,17 @@ local function readtag(mfkey,xteakey) -- Decrypt data and build clear table for key,value in ipairs(tagdata) do local clearblockdata - v[0]=utils.SwapEndianness(value:sub(1,8),32) - v[1]=utils.SwapEndianness(value:sub(9,16),32) + v[0] = utils.SwapEndianness(value:sub(1, 8), 32) + v[1] = utils.SwapEndianness(value:sub(9, 16), 32) xteaDecrypt(16, v, xteakey) - vv[0]=utils.SwapEndianness(value:sub(17,24),32) - vv[1]=utils.SwapEndianness(value:sub(25,32),32) + vv[0] = utils.SwapEndianness(value:sub(17, 24), 32) + vv[1] = utils.SwapEndianness(value:sub(25, 32), 32) xteaDecrypt(16, vv, xteakey) clearblockdata=string.format("%08X%08X%08X%08X", - utils.SwapEndianness(string.format("%08X", v[0]),32), - utils.SwapEndianness(string.format("%08X", v[1]),32), - utils.SwapEndianness(string.format("%08X", vv[0]),32), - utils.SwapEndianness(string.format("%08X", vv[1]),32)) + utils.SwapEndianness(string.format("%08X", v[0]), 32), + utils.SwapEndianness(string.format("%08X", v[1]), 32), + utils.SwapEndianness(string.format("%08X", vv[0]), 32), + utils.SwapEndianness(string.format("%08X", vv[1]), 32)) table.insert(cleardata, clearblockdata) end @@ -180,6 +197,12 @@ end local function main(args) + + -- Arguments for the script + for o, a in getopt.getopt(args, 'h') do + if o == 'h' then return help() end + end + local xteakey = {} -- local v = {} local edata = {} @@ -207,7 +230,7 @@ local function main(args) print(acblue.."UID: "..tag.uid..acoff) print(acblue..string.format("XTEA key: %08X %08X %08X %08X", xteakey[0], xteakey[1], xteakey[2], xteakey[3])..acoff) - edata, cdata = readtag("415A54454B4D",xteakey) + edata, cdata = readtag("415A54454B4D", xteakey) if edata == nil or cdata == nil then print("ERROR Reading tag!") diff --git a/client/luascripts/mfckeys.lua b/client/luascripts/mfckeys.lua index 32808b62d..bf0cccb45 100644 --- a/client/luascripts/mfckeys.lua +++ b/client/luascripts/mfckeys.lua @@ -13,10 +13,11 @@ local keylist = require('mfc_default_keys') local lib14a = require('read14a') local getopt = require('getopt') local utils = require('utils') +local ansicolors = require('ansicolors') copyright = '' author = "Holiman" -version = 'v1.0.1' +version = 'v1.0.2' desc = ("This script implements Mifare check keys.\ It utilises a large list of default keys (currently %d keys).\ If you want to add more, just put them inside /lualibs/mfc_default_keys.lua\n"):format(#keylist) @@ -24,7 +25,9 @@ example = [[ 1. script run mfckeys ]] usage = [[ -Arguments: +script run mfckeys [-p] +]] +arguments = [[ -h : this help -p : print keys ]] @@ -46,9 +49,12 @@ local function help() print(author) print(version) print(desc) - print('Example usage') - print(example) + 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 -- -- waits for answer from pm3 device @@ -269,8 +275,6 @@ end -- The main entry point local function main(args) - local numSectors = 16 - -- Arguments for the script for o, a in getopt.getopt(args, 'hp') do if o == 'h' then return help() end @@ -280,6 +284,8 @@ local function main(args) tag, err = lib14a.read(false, true) if not tag then return oops(err) end + local numSectors = 16 + -- detect sectors and print taginfo numsectors = taginfo(tag) diff --git a/client/luascripts/mfu_magic.lua b/client/luascripts/mfu_magic.lua index badc691c5..d921a9fb2 100644 --- a/client/luascripts/mfu_magic.lua +++ b/client/luascripts/mfu_magic.lua @@ -2,6 +2,7 @@ local cmds = require('commands') local getopt = require('getopt') local lib14a = require('read14a') local utils = require('utils') +local ansicolors = require('ansicolors') -- global local DEBUG = false -- the debug flag @@ -11,10 +12,9 @@ local err_lock = 'use -k or change cfg0 block' copyright = 'Copyright (c) 2017 IceSQL AB. All rights reserved.' author = 'Christian Herrmann' -version = 'v1.1.2' +version = 'v1.1.3' desc = 'This script enables easy programming of a MAGIC NTAG 21* card' -example = -[[ +example = [[ -- wipe tag script run mfu_magic -w @@ -36,12 +36,10 @@ example = -- set signature script run mfu_magic -s 1122334455667788990011223344556677889900112233445566778899001122 ]] -usage = -[[ -Usage: +usage = [[ script run mfu_magic -h -k -c -w -u -t -p -a -s -o -v - -Arguments: +]] +arguments = [[ -h this help -c read magic configuration -u UID (14 hexsymbols), set UID on tag @@ -94,9 +92,12 @@ local function help() print(author) print(version) print(desc) - print('Example usage') - print(example) + 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 --- -- set the global password variable diff --git a/client/luascripts/mifare_access.lua b/client/luascripts/mifare_access.lua index 1c38576e7..4c416e8d6 100644 --- a/client/luascripts/mifare_access.lua +++ b/client/luascripts/mifare_access.lua @@ -1,8 +1,9 @@ local getopt = require('getopt') +local ansicolors = require('ansicolors') copyright = '' author = "Neuromancer" -version = 'v1.0.1' +version = 'v1.0.2' desc = [[ This script tries to decode Mifare Classic Access bytes ]] @@ -10,9 +11,9 @@ example = [[ 1. script run mifare_access -a 7F0F0869 ]] usage = [[ -script run mifare_access -h -a - -Arguments: +script run mifare_access [-h] [-a ] +]] +arguments = [[ -h : this help -a : 4 bytes ACCESS CONDITIONS ]] @@ -50,9 +51,12 @@ local function help() print(author) print(version) print(desc) - print('Example usage') - print(example) + 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 local access_condition_sector_trailer = {} diff --git a/client/luascripts/mifare_autopwn.lua b/client/luascripts/mifare_autopwn.lua index bc7582760..6ff40a70d 100644 --- a/client/luascripts/mifare_autopwn.lua +++ b/client/luascripts/mifare_autopwn.lua @@ -2,20 +2,23 @@ local getopt = require('getopt') local lib14a = require('read14a') local cmds = require('commands') local utils = require('utils') +local ansicolors = require('ansicolors') copyright = '' author = "Martin Holst Swende" -version = 'v1.0.2' +version = 'v1.0.3' desc = [[ This is a script which automates cracking and dumping mifare classic cards. It sets itself into 'listening'-mode, after which it cracks and dumps any mifare classic card that you place by the device. ]] example = [[ -script run mifare_autopwn + 1. script run mifare_autopwn ]] usage = [[ -Arguments: +script run mifare_autopwn [-h] [-d] [-k ] +]] +arguments = [[ -h this help -d debug logging on -k known key for Sector 0 , keytype A @@ -61,9 +64,12 @@ local function help() print(author) print(version) print(desc) - print('Example usage') - print(example) + 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 --- -- Waits for a mifare card to be placed within the vicinity of the reader. diff --git a/client/luascripts/mifareplus.lua b/client/luascripts/mifareplus.lua index f49ad95e5..a30f24f8b 100644 --- a/client/luascripts/mifareplus.lua +++ b/client/luascripts/mifareplus.lua @@ -1,12 +1,12 @@ local cmds = require('commands') local lib14a = require('read14a') local getopt = require('getopt') +local ansicolors = require('ansicolors') copyright = '' author = 'Dominic Celiano' -version = 'v1.0.1' -desc = -[[ +version = 'v1.0.2' +desc = [[ Purpose: Lua script to communicate with the Mifare Plus EV1, including personalization (setting the keys) and proximity check. Manually edit the file to add to the commands you can send the card. Please read the NXP manual before running this script to prevent making irreversible changes. Also note: - The Mifare Plus must start in SL0 for personalization. Card can then be moved to SL1 or SL3. @@ -15,13 +15,12 @@ Please read the NXP manual before running this script to prevent making irrevers Small changes can be to made this script to communicate with the Mifare Plus S, X, or SE. ]] example = [[ - -- default - script run mifareplus + 1. script run mifareplus ]] usage = [[ -script run mifareplus -h - -Arguments: +script run mifareplus [-h] +]] +arguments = [[ -h : this help ]] @@ -57,9 +56,12 @@ local function help() print(author) print(version) print(desc) - print('Example usage') - print(example) + 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 --- -- Used to send raw data to the firmware to subsequently forward the data to the card. diff --git a/client/luascripts/ndef_dump.lua b/client/luascripts/ndef_dump.lua index a4cbdf655..672beda1c 100644 --- a/client/luascripts/ndef_dump.lua +++ b/client/luascripts/ndef_dump.lua @@ -2,11 +2,12 @@ local getopt = require('getopt') local cmds = require('commands') local lib14a = require('read14a') local utils = require('utils') +local ansicolors = require('ansicolors') -- -- Refactored iceman, 2019 copyright = '' author = 'Martin Holst Swende & Asper' -version = 'v1.0.1' +version = 'v1.0.2' desc = [[ This script will automatically recognize and dump full content of a NFC NDEF Initialized tag; non-initialized tags will be ignored. @@ -23,9 +24,9 @@ example = [[ 1. script run ndef_dump ]] usage = [[ -script run ndef_dump - -Arguments: +script run ndef_dump [-h] [-d] [-v] +]] +arguments = [[ -h this help -d debug logging on -v verbose output (from ndef parsing) @@ -63,9 +64,12 @@ local function help() print(author) print(version) print(desc) - print('Example usage') - print(example) + 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 -- -- Sends an instruction to do nothing, only disconnect diff --git a/client/luascripts/ntag_3d.lua b/client/luascripts/ntag_3d.lua index 869590cf2..d986923ba 100644 --- a/client/luascripts/ntag_3d.lua +++ b/client/luascripts/ntag_3d.lua @@ -1,10 +1,11 @@ local getopt = require('getopt') local lib14a = require('read14a') local utils = require('utils') +local ansicolors = require('ansicolors') copyright = 'Copyright (c) 2017 IceSQL AB. All rights reserved.' author = "Christian Herrmann" -version = 'v1.0.4' +version = 'v1.0.5' desc = [[ This script writes a empty template for 3D printing system onto a empty NTAG213 or MAGIC NTAG21* @@ -21,9 +22,9 @@ example =[[ script run ntag_3d -u 11223344556677 -c 46 -m 50 -p 5448 -s 4555 -l 200 -1 ]] usage = [[ -script run ntag_3d -h -t -u -c -m -p -s -l - -Arguments: +script run ntag_3d [-h] [-t] [-u ] [-c ] [-m ] [-p ] [-s ] [-l ] +]] +arguments = [[ -h : this help -t : selftest -u : UID @@ -168,9 +169,12 @@ local function help() print(author) print(version) print(desc) - print('Example usage') - print(example) + 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 -- -- Exit message From 2474385ab09a246898cecf44673d6aa3e3fd64b3 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 5 Apr 2020 12:49:25 +0200 Subject: [PATCH 03/12] colors --- client/luascripts/parameters.lua | 23 ++++++++++++++++---- client/luascripts/read_pwd_mem.lua | 26 +++++++++++------------ client/luascripts/read_pwd_mem_spiffs.lua | 26 +++++++++++------------ client/luascripts/remagic.lua | 19 ++++++++++------- client/luascripts/test_t55x7.lua | 17 +++++++++------ 5 files changed, 66 insertions(+), 45 deletions(-) diff --git a/client/luascripts/parameters.lua b/client/luascripts/parameters.lua index d68b7b06a..dce215eb7 100644 --- a/client/luascripts/parameters.lua +++ b/client/luascripts/parameters.lua @@ -1,19 +1,31 @@ -- The getopt-functionality is loaded from pm3/getopt.lua -- Have a look there for further details -getopt = require('getopt') +local getopt = require('getopt') +local ansicolors = require('ansicolors') copyright = '' usage = 'script run parameters.lua -a 1 -blala -c -de' author = 'Martin Holst Swende' -version = 'v1.0.1' +version = 'v1.0.2' desc = [[ This is an example script to demonstrate handle parameters in scripts. For more info, check the comments in the code ]] example = [[ + 1. script run parameters -a mytestparam_input -c ]] usage = [[ +script run parameters [-h] [-a ] [-b ] [-c] [-d] [-e] ]] +arguments = [[ + -h This help + -a text + -b text + -c test param w/o input + -d test param w/o input + -e test param w/o input +]] + --- -- Usage help local function help() @@ -21,9 +33,12 @@ local function help() print(author) print(version) print(desc) - print('Example usage') - print(example) + 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 local function main(args) diff --git a/client/luascripts/read_pwd_mem.lua b/client/luascripts/read_pwd_mem.lua index ffc00a998..0c786f6f9 100644 --- a/client/luascripts/read_pwd_mem.lua +++ b/client/luascripts/read_pwd_mem.lua @@ -1,11 +1,11 @@ local getopt = require('getopt') local bin = require('bin') +local ansicolors = require('ansicolors') copyright = 'Copyright (c) 2018 Bogito. All rights reserved.' author = 'Bogito' -version = 'v1.0.3' -desc = -[[ +version = 'v1.0.4' +desc = [[ This script will read the flash memory of RDV4 and print the stored passwords/keys. It was meant to be used as a help tool after using the BogRun standalone mode before SPIFFS. @@ -13,8 +13,7 @@ You should now use read_pwd_mem_spiffs instead after the updated BogRun standalo (Iceman) script adapted to read and print keys in the default dictionary flashmemory sections. ]] -example = -[[ +example = [[ -- This will scan the first 256 bytes of flash memory for stored passwords script run read_pwd_mem @@ -33,12 +32,10 @@ example = -- This will print the stored iClass dictionary keys script run read_pwd_mem -i ]] -usage = -[[ -Usage: - script run read_pwd_mem -h -o -l -k - -Arguments: +usage = [[ + script run read_pwd_mem [-h] [-o ] [-l ] [-k ] [-m] [-t] [-i] +]] +arguments = [[ -h : this help -o : memory offset, default is 0 -l : length in bytes, default is 256 @@ -61,9 +58,12 @@ local function help() print(author) print(version) print(desc) - print('Example usage') - print(example) + 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 --- -- The main entry point diff --git a/client/luascripts/read_pwd_mem_spiffs.lua b/client/luascripts/read_pwd_mem_spiffs.lua index 89ef64e6d..ae2f0ba99 100644 --- a/client/luascripts/read_pwd_mem_spiffs.lua +++ b/client/luascripts/read_pwd_mem_spiffs.lua @@ -1,16 +1,15 @@ local getopt = require('getopt') local bin = require('bin') +local ansicolors = require('ansicolors') copyright = 'Copyright (c) 2019 Bogito. All rights reserved.' author = 'Bogito' -version = 'v1.1.1' -desc = -[[ +version = 'v1.1.2' +desc = [[ This script will read the flash memory of RDV4 using SPIFFS and print the stored passwords. It was meant to be used as a help tool after using the BogRun standalone mode. ]] -example = -[[ +example = [[ -- This will read the hf_bog.log file in SPIFFS and print the stored passwords script run read_pwd_mem_spiffs @@ -20,12 +19,10 @@ example = -- This will delete the hf_bog.log file from SPIFFS script run read_pwd_mem_spiffs -r ]] -usage = -[[ -Usage: - script run read_pwd_mem_spiffs -h -f -r - -Arguments: +usage = [[ + script run read_pwd_mem_spiffs [-h] [-f ] [-r] +]] +arguments = [[ -h : this help -f : filename in SPIFFS -r : delete filename from SPIFFS @@ -44,9 +41,12 @@ local function help() print(author) print(version) print(desc) - print('Example usage') - print(example) + 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 --- -- The main entry point diff --git a/client/luascripts/remagic.lua b/client/luascripts/remagic.lua index 096fcfa27..51aa0be40 100644 --- a/client/luascripts/remagic.lua +++ b/client/luascripts/remagic.lua @@ -1,10 +1,10 @@ local getopt = require('getopt') +local ansicolors = require('ansicolors') copyright = '' author = 'Iceman' -version = 'v1.0.1' -desc = -[[ +version = 'v1.0.2' +desc = [[ This is a script that tries to bring back a chinese magic card (1k generation1) from the dead when it's block 0 has been written with bad values. or mifare Ultralight magic card which answers to chinese backdoor commands @@ -15,9 +15,9 @@ example = [[ ]] usage = [[ -script run remagic - -Arguments: +script run remagic [-h] [-u] +]] +arguments = [[ -h this help -u remagic a Ultralight tag w 7 bytes UID. ]] @@ -49,9 +49,12 @@ local function help() print(author) print(version) print(desc) - print('Example usage') - print(example) + 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 local function cmdUltralight() diff --git a/client/luascripts/test_t55x7.lua b/client/luascripts/test_t55x7.lua index 0fc112ea7..b92375520 100644 --- a/client/luascripts/test_t55x7.lua +++ b/client/luascripts/test_t55x7.lua @@ -2,13 +2,14 @@ local cmds = require('commands') local getopt = require('getopt') local bin = require('bin') local utils = require('utils') +local ansicolors = require('ansicolors') local format = string.format local floor = math.floor copyright = '' author = "Iceman" -version = 'v1.0.1' +version = 'v1.0.2' desc =[[ This script will program a T55x7 TAG with a configuration and four blocks of data. It will then try to detect and read back those block data and compare if read data matches the expected data. @@ -32,10 +33,9 @@ example = [[ 1. script run test_t55x7 ]] usage = [[ - -script run test_t55x7 - -Arguments: +script run test_t55x7 [-h] +]] +arguments = [[ -h this help ]] @@ -79,9 +79,12 @@ local function help() print(author) print(version) print(desc) - print("Example usage") - print(example) + 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 --- -- Exit message From 175a5718b03e01a0a1e1adacb168da69c6f29642 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 5 Apr 2020 12:56:35 +0200 Subject: [PATCH 04/12] colors --- client/luascripts/test_t55x7_ask.lua | 18 +++++++++++------- client/luascripts/test_t55x7_bi.lua | 16 ++++++++++------ client/luascripts/test_t55x7_fsk.lua | 16 ++++++++++------ client/luascripts/test_t55x7_psk.lua | 16 ++++++++++------ client/luascripts/tnp3clone.lua | 20 ++++++++++++-------- client/luascripts/tnp3dump.lua | 18 +++++++++++------- client/luascripts/tnp3sim.lua | 20 ++++++++++++-------- client/luascripts/tracetest.lua | 22 +++++++++++++--------- client/luascripts/ufodump.lua | 20 ++++++++++++-------- client/luascripts/ul_uid.lua | 16 ++++++++++------ 10 files changed, 111 insertions(+), 71 deletions(-) diff --git a/client/luascripts/test_t55x7_ask.lua b/client/luascripts/test_t55x7_ask.lua index bb232a6fd..adfaf1eeb 100644 --- a/client/luascripts/test_t55x7_ask.lua +++ b/client/luascripts/test_t55x7_ask.lua @@ -2,14 +2,15 @@ local cmds = require('commands') local getopt = require('getopt') local bin = require('bin') local utils = require('utils') +local ansicolors = require('ansicolors') local format=string.format local floor=math.floor copyright = '' author = 'Iceman' -version = 'v1.0.1' -desc =[[ +version = 'v1.0.2' +desc = [[ This script will program a T55x7 TAG with the configuration: block 0x00 data 0x000100 The outlined procedure is as following: @@ -41,9 +42,9 @@ example =[[ 1. script run test_t55x7_ask ]] usage = [[ -script run test_t55x7_ask - -Arguments: +script run test_t55x7_ask [-h] +]] +arguments = [[ -h : this help ]] @@ -87,9 +88,12 @@ local function help() print(author) print(version) print(desc) - print('Example usage') - print(example) + 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 -- -- Exit message diff --git a/client/luascripts/test_t55x7_bi.lua b/client/luascripts/test_t55x7_bi.lua index 49ee4882a..4b897b367 100644 --- a/client/luascripts/test_t55x7_bi.lua +++ b/client/luascripts/test_t55x7_bi.lua @@ -2,10 +2,11 @@ local cmds = require('commands') local getopt = require('getopt') local bin = require('bin') local utils = require('utils') +local ansicolors = require('ansicolors') copyright = '' author = 'Iceman' -version = 'v1.0.1' +version = 'v1.0.2' desc = [[ This script will program a T55x7 TAG with the configuration: block 0x00 data 0x00010040 The outlined procedure is as following: @@ -35,9 +36,9 @@ example = [[ 1. script run test_t55x7_bi ]] usage = [[ -script run test_t55x7_bi - -Arguments: +script run test_t55x7_bi [-h] +]] +arguments = [[ -h : this help ]] @@ -81,9 +82,12 @@ local function help() print(author) print(version) print(desc) - print('Example usage') - print(example) + 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 -- -- Exit message diff --git a/client/luascripts/test_t55x7_fsk.lua b/client/luascripts/test_t55x7_fsk.lua index c755042b1..7a8d724a0 100644 --- a/client/luascripts/test_t55x7_fsk.lua +++ b/client/luascripts/test_t55x7_fsk.lua @@ -2,10 +2,11 @@ local cmds = require('commands') local getopt = require('getopt') local bin = require('bin') local utils = require('utils') +local ansicolors = require('ansicolors') copyright = '' author = 'Iceman' -version = 'v1.0.1' +version = 'v1.0.2' desc = [[ This script will program a T55x7 TAG with the configuration: block 0x00 data 0x000100 The outlined procedure is as following: @@ -37,9 +38,9 @@ example = [[ 1. script run test_t55x7_fsk ]] usage = [[ -script run test_t55x7_fsk - -Arguments: +script run test_t55x7_fsk [-h] +]] +arguments = [[ -h : this help ]] @@ -83,9 +84,12 @@ local function help() print(author) print(version) print(desc) - print('Example usage') - print(example) + 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 -- -- Exit message diff --git a/client/luascripts/test_t55x7_psk.lua b/client/luascripts/test_t55x7_psk.lua index 10fecd549..0c991dcb0 100644 --- a/client/luascripts/test_t55x7_psk.lua +++ b/client/luascripts/test_t55x7_psk.lua @@ -2,10 +2,11 @@ local cmds = require('commands') local getopt = require('getopt') local bin = require('bin') local utils = require('utils') +local ansicolors = require('ansicolors') copyright = '' author = 'Iceman' -version = 'v1.0.1' +version = 'v1.0.2' desc = [[ This script will program a T55x7 TAG with the configuration: block 0x00 data 0x00088040 The outlined procedure is as following: @@ -33,9 +34,9 @@ example = [[ 2. script run test_t55x7_psk -o ]] usage = [[ -script run test_t55x7_psk - -Arguments: +script run test_t55x7_psk [-h] +]] +arguments = [[ -h : this help ]] @@ -82,9 +83,12 @@ local function help() print(author) print(version) print(desc) - print('Example usage') - print(example) + 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 -- -- Exit message diff --git a/client/luascripts/tnp3clone.lua b/client/luascripts/tnp3clone.lua index 58bb5d338..056e7021b 100644 --- a/client/luascripts/tnp3clone.lua +++ b/client/luascripts/tnp3clone.lua @@ -4,6 +4,7 @@ local lib14a = require('read14a') local utils = require('utils') local pre = require('precalc') local toys = require('default_toys') +local ansicolors = require('ansicolors') local lsh = bit32.lshift local rsh = bit32.rshift @@ -12,11 +13,11 @@ local band = bit32.band copyright = '' author = "Iceman" -version = 'v1.0.1' -desc =[[ +version = 'v1.0.2' +desc = [[ This script will try making a barebone clone of a tnp3 tag on to a magic generation1 card. ]] -example =[[ +example = [[ script run tnp3clone script run tnp3clone -h script run tnp3clone -l @@ -24,9 +25,9 @@ example =[[ ]] usage = [[ -script run tnp3clone -t -s - -Arguments: +script run tnp3clone [-h] [-t ] [-s ] +]] +arguments = [[ -h : this help -l : list all known toy tokens -t : toytype id, 4hex symbols @@ -56,9 +57,12 @@ local function help() print(author) print(version) print(desc) - print('Example usage') - print(example) + 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 --- -- decode response and get the blockdata from a normal mifare read command diff --git a/client/luascripts/tnp3dump.lua b/client/luascripts/tnp3dump.lua index 9a7a9bc8f..0dea0a01a 100644 --- a/client/luascripts/tnp3dump.lua +++ b/client/luascripts/tnp3dump.lua @@ -6,11 +6,12 @@ local utils = require('utils') local md5 = require('md5') local dumplib = require('html_dumplib') local toys = require('default_toys') +local ansicolors = require('ansicolors') copyright = '' author = 'Iceman' -version = 'v1.0.1' -desc =[[ +version = 'v1.0.2' +desc = [[ This script will try to dump the contents of a Mifare TNP3xxx card. It will need a valid KeyA in order to find the other keys and decode the card. ]] @@ -26,9 +27,9 @@ example = [[ script run tnp3dump -k aabbccddeeff -n -o myfile ]] usage = [[ -script run tnp3dump -k -n -p -o - -Arguments: +script run tnp3dump [-h] [-k ] [-n] [-p] [-o ] +]] +arguments = [[ -h : this help -k : Sector 0 Key A. -n : Use the nested cmd to find all keys @@ -69,9 +70,12 @@ local function help() print(author) print(version) print(desc) - print('Example usage') - print(example) + 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 -- -- Exit message diff --git a/client/luascripts/tnp3sim.lua b/client/luascripts/tnp3sim.lua index 014474416..069bbfe08 100644 --- a/client/luascripts/tnp3sim.lua +++ b/client/luascripts/tnp3sim.lua @@ -6,25 +6,26 @@ local utils = require('utils') local md5 = require('md5') local toys = require('default_toys') local pre = require('precalc') +local ansicolors = require('ansicolors') copyright = '' author = 'Iceman' -version = 'v1.0.1' -desc =[[ +version = 'v1.0.2' +desc = [[ This script will try to load a binary datadump of a Mifare TNP3xxx card. It vill try to validate all checksums and view some information stored in the dump For an experimental mode, it tries to manipulate some data. At last it sends all data to the PM3 device memory where it can be used in the command "hf mf sim" ]] -example =[[ +example = [[ 1. script run tnp3sim 2. script run tnp3sim -m 3. script run tnp3sim -m -i myfile ]] usage = [[ -script run tnp3sim -h -m -i - -Arguments: +script run tnp3sim [-h] [-m] [-i ] +]] +arguments = [[ -h : this help -m : Maxed out items (experimental) -i : filename for the datadump to read (bin) @@ -70,9 +71,12 @@ local function help() print(author) print(version) print(desc) - print('Example usage') - print(example) + 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 -- -- Exit message diff --git a/client/luascripts/tracetest.lua b/client/luascripts/tracetest.lua index 44cd66b58..c1917b401 100644 --- a/client/luascripts/tracetest.lua +++ b/client/luascripts/tracetest.lua @@ -3,11 +3,12 @@ local getopt = require('getopt') local bin = require('bin') local utils = require('utils') local dumplib = require('html_dumplib') +local ansicolors = require('ansicolors') copyright = '' author = 'Iceman' -version = 'v1.0.1' -desc =[[ +version = 'v1.0.2' +desc = [[ This script will load several traces files in ../traces/ folder and do "data load" "lf search 1 u" @@ -16,13 +17,13 @@ The following tracefiles will be loaded: em*.pm3 m*.pm3 ]] -example =[[ - script run tracetest +example = [[ + 1. script run tracetest ]] usage = [[ -script run tracetest -h - -Arguments: +script run tracetest [-h] +]] +arguments = [[ -h : this help ]] local DEBUG = true -- the debug flag @@ -54,9 +55,12 @@ local function help() print(author) print(version) print(desc) - print('Example usage') - print(example) + 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 -- -- Exit message diff --git a/client/luascripts/ufodump.lua b/client/luascripts/ufodump.lua index ccf20f6b4..d9a8faa68 100644 --- a/client/luascripts/ufodump.lua +++ b/client/luascripts/ufodump.lua @@ -2,10 +2,11 @@ local cmds = require('commands') local getopt = require('getopt') local lib14a = require('read14a') local utils = require('utils') +local ansicolors = require('ansicolors') copyright = '' author = 'Iceman' -version = 'v1.0.1' +version = 'v1.0.2' desc = [[ This is a script that reads AZTEK ISO14443a tags. It starts from block 0 and ends at default block 20. Use 'b' to say different endblock. @@ -19,11 +20,11 @@ example = [[ script run ufodump -b 10 ]] usage = [[ -script run ufudump -h -b - -Arguments: - h this helptext - b endblock in decimal (1-255, default 20) +script run ufudump [-h] [-b] +]] +arguments = [[ + -h This help + -b endblock in decimal (1-255, default 20) ]] -- Some globals @@ -56,9 +57,12 @@ local function help() print(author) print(version) print(desc) - print('Example usage') - print(example) + 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 -- --- Picks out and displays the data read from a tag diff --git a/client/luascripts/ul_uid.lua b/client/luascripts/ul_uid.lua index 9ac89c211..ece368ce5 100644 --- a/client/luascripts/ul_uid.lua +++ b/client/luascripts/ul_uid.lua @@ -1,9 +1,10 @@ local getopt = require('getopt') local utils = require('utils') +local ansicolors = require('ansicolors') copyright = '' author = "Iceman" -version = 'v1.0.1' +version = 'v1.0.2' desc = [[ This script tries to set UID on a mifare Ultralight magic card which either - answers to chinese backdoor commands @@ -17,9 +18,9 @@ example = [[ script run ul_uid -b -u 11223344556677 ]] usage = [[ -script run ul_uid -h -b -u - -Arguments: +script run ul_uid [-h] [-b] [-u ] +]] +arguments = [[ -h : this help -u : UID (14 hexsymbols) -b : write to brickable magic tag @@ -55,9 +56,12 @@ local function help() print(author) print(version) print(desc) - print('Example usage') - print(example) + 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 -- --- Set UID on magic command enabled From 06afb795a0c78d213fb69af4cb899e9a4cf2849c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 5 Apr 2020 13:02:50 +0200 Subject: [PATCH 05/12] text --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 95d7ce2e6..946b7c541 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,12 @@ 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] + - Updated helptext layout in all luascripts (@iceman1001) + - Change `hf mfdes info` - output and logging (@brkeler) + - Updated texts in legic commands (@ikarus23) + - Fix timing bug inside 40x5 (@mwalker33) + - Refactored all Hitag2 attacks (@doegox) + - Added two new Hitag2 attacks (@doegox) - Change `hf search` - now continue to search in case of dual tech cards (@iceman1001) Thanks to @ikarus23 for the suggestion! - Added `hf topas info` - old reader command, now also prints NDEF (@iceman1001) - Change `hf topaz reader` - now only prints lighter info, like UID. (@iceman1001) From 16b14aa0e670b488906f8bf43ed2d123b8056090 Mon Sep 17 00:00:00 2001 From: Uli Heilmeier Date: Sun, 5 Apr 2020 12:56:00 +0200 Subject: [PATCH 06/12] Legic_clone.lua: Refactor to work with current command set Refactored to work with current command set and MIM256 and MIM1024 tags --- client/luascripts/Legic_clone.lua | 119 +++++++++++++----------------- 1 file changed, 52 insertions(+), 67 deletions(-) diff --git a/client/luascripts/Legic_clone.lua b/client/luascripts/Legic_clone.lua index 191f9f9e0..a0a8e590d 100644 --- a/client/luascripts/Legic_clone.lua +++ b/client/luascripts/Legic_clone.lua @@ -1,4 +1,5 @@ local utils = require('utils') +local cmds = require('commands') local getopt = require('getopt') local ansicolors = require('ansicolors') --[[ @@ -16,10 +17,10 @@ local ansicolors = require('ansicolors') simplest usage: read a valid legic tag with 'hf legic reader' - save the dump with 'hf legic save orig.hex' - place your 'empty' tag on the reader and run 'script run Legic_clone -i orig.hex -w' + save the dump with 'hf legic dump o orig' + place your 'empty' tag on the reader and run 'script run Legic_clone -i orig.bin -w' you will see some output like: - read 1024 bytes from legic_dumps/j_0000.hex + read 1024 bytes from orig.bin place your empty tag onto the PM3 to read and display the MCD & MSN0..2 the values will be shown below @@ -92,18 +93,18 @@ author = 'Mosci' version = 'v1.0.2' desc = [[ This is a script which creates a clone-dump of a dump from a Legic Prime Tag (MIM256 or MIM1024) -(created with 'hf legic save my_dump.hex') +(created with 'hf legic dump o my_dump') ]] example = [[ - script run legic_clone -i my_dump.hex -o my_clone.hex -c f8 - script run legic_clone -i my_dump.hex -d -s + script run legic_clone -i my_dump.bin -o my_clone.bin -c f8 + script run legic_clone -i my_dump.bin -d -s ]] usage = [[ script run legic_clone -h -i -o -c -d -s -w ]] arguments = [[ required : - -i (file to read data from) + -i (file to read data from, must be in binary format (*.bin)) optional : -h - Help text @@ -111,7 +112,7 @@ optional : -c - requires option -o to be given -d - Display content of found Segments -s - Display summary at the end - -w - write directly to Tag - a file myLegicClone.hex wille be generated also + -w - write directly to Tag - a file myLegicClone.bin will be generated also e.g.: hint: using the CRC '00' will result in a plain dump ( -c 00 ) @@ -138,6 +139,23 @@ local function oops(err) core.clearCommandBuffer() return nil, err end + +-- read LEGIC data +local function readlegicdata( offset, length, iv ) + -- Read data + local command = Command:newMIX{ + cmd = cmds.CMD_HF_LEGIC_READER + , arg1 = offset + , arg2 = length + , arg3 = iv + , data = nil + } + local result, err = command:sendMIX() + if not result then return oops(err) end + -- result is a packed data structure, data starts at offset 33 + return result +end + --- -- Usage help local function help() @@ -179,16 +197,12 @@ local function getInputBytes(infile) local line local bytes = {} - local fhi,err = io.open(infile) + local fhi,err = io.open(infile,"rb") if err then print("OOps ... faild to read from file ".. infile); return false; end - while true do - line = fhi:read() - if line == nil then break end - - for byte in line:gmatch("%w+") do - table.insert(bytes, byte) - end + str = fhi:read("*all") + for c in (str or ''):gmatch'.' do + bytes[#bytes+1] = ('%02x'):format(c:byte()) end fhi:close() @@ -199,25 +213,11 @@ end -- write to file local function writeOutputBytes(bytes, outfile) - local line - local bcnt = 0 - local fho,err = io.open(outfile,"w") + local fho,err = io.open(outfile,"wb") if err then print("OOps ... faild to open output-file ".. outfile); return false; end for i = 1, #bytes do - if (bcnt == 0) then - line = bytes[i] - elseif (bcnt <= 7) then - line = line.." "..bytes[i] - end - if (bcnt == 7) then - -- write line to new file - fho:write(line.."\n") - -- reset counter & line - bcnt = -1 - line = "" - end - bcnt = bcnt + 1 + fho:write(string.char(tonumber(bytes[i],16))) end fho:close() print("\nwrote ".. #bytes .." bytes to " .. outfile) @@ -322,7 +322,7 @@ function getSegmentCrcBytes(bytes) return crcbytes end --- print segment-data (hf legic decode like) +-- print segment-data (hf legic info like) function displaySegments(bytes) --display segment header(s) start = 23 @@ -389,23 +389,25 @@ end -- write clone-data to tag function writeToTag(plainBytes) local SegCrcs = {} - if(utils.confirm("\nplace your empty tag onto the PM3 to read and display the MCD & MSN0..2\nthe values will be shown below\n confirm when ready") == false) then + local output + local readbytes + if(utils.confirm("\nplace your empty tag onto the PM3 to restore the data of the input file\nthe CRCs will be calculated as needed\n confirm when ready") == false) then return end + readbytes = readlegicdata(0, 4, 0x55) -- gather MCD & MSN from new Tag - this must be enterd manually - cmd = 'hf legic read 0x00 0x04' - core.console(cmd) print("\nthese are the MCD MSN0 MSN1 MSN2 from the Tag that has being read:") - cmd = 'data hexsamples 4' - core.console(cmd) - print("^^ use this values as input for the following answers (one 2-digit-value per question/answer):") - -- enter MCD & MSN (in hex) - MCD = utils.input("type in MCD as 2-digit value - e.g.: 00", plainBytes[1]) - MSN0 = utils.input("type in MSN0 as 2-digit value - e.g.: 01", plainBytes[2]) - MSN1 = utils.input("type in MSN1 as 2-digit value - e.g.: 02", plainBytes[3]) - MSN2 = utils.input("type in MSN2 as 2-digit value - e.g.: 03", plainBytes[4]) + plainBytes[1] = ('%02x'):format(readbytes:byte(33)) + plainBytes[2] = ('%02x'):format(readbytes:byte(34)) + plainBytes[3] = ('%02x'):format(readbytes:byte(35)) + plainBytes[4] = ('%02x'):format(readbytes:byte(36)) + + MCD = plainBytes[1] + MSN0 = plainBytes[2] + MSN1 = plainBytes[3] + MSN2 = plainBytes[4] -- calculate crc8 over MCD & MSN cmd = MCD..MSN0..MSN1..MSN2 MCC = ("%02x"):format(utils.Crc8Legic(cmd)) @@ -437,27 +439,10 @@ function writeToTag(plainBytes) bytes = xorBytes(plainBytes, MCC) -- write data to file - if (writeOutputBytes(bytes, "myLegicClone.hex")) then - WriteBytes = utils.input("enter number of bytes to write?", SegCrcs[#SegCrcs]) - - -- load file into pm3-buffer - cmd = 'hf legic eload myLegicClone.hex' - core.console(cmd) - + if (writeOutputBytes(bytes, "myLegicClone.bin")) then -- write pm3-buffer to Tag - for i=0, WriteBytes do - if ( i<5 or i>6) then - cmd = ('hf legic write o %02x d 01'):format(i) - core.console(cmd) - elseif (i == 6) then - -- write DCF in reverse order (requires 'mosci-patch') - cmd = 'hf legic write o 05 d 02' - core.console(cmd) - else - print("skipping byte 0x05 - will be written next step") - end - utils.Sleep(0.2) - end + cmd = ('hf legic restore i myLegicClone') + core.console(cmd) end end @@ -495,7 +480,7 @@ function main(args) end -- new crc if o == 'c' then - newcrc = a + newcrc = a:lower() ncs = true end -- display segments switch @@ -535,7 +520,7 @@ function main(args) res = res .."\nafter writing this dump to a tag!" res = res .."\n\na segmentCRC gets calculated over MCD,MSN0..3,Segment-Header0..3" res = res .."\ne.g. (based on Segment00 of the data from "..infile.."):" - res = res .."\nhf legic crc8 "..bytes[1]..bytes[2]..bytes[3]..bytes[4]..bytes[23]..bytes[24]..bytes[25]..bytes[26] + res = res .."\nhf legic crc d "..bytes[1]..bytes[2]..bytes[3]..bytes[4]..bytes[23]..bytes[24]..bytes[25]..bytes[26].." u "..newcrc.." c 8" -- this can not be calculated without knowing the new MCD, MSN0..2 print(res) end @@ -549,7 +534,7 @@ function main(args) end end -- write to tag - if (ws and #bytes == 1024) then + if (ws and ( #bytes == 1024 or #bytes == 256)) then writeToTag(bytes) end end From eac19be4142010d537588e89220f3da5958de705 Mon Sep 17 00:00:00 2001 From: Uli Heilmeier Date: Sun, 5 Apr 2020 13:16:14 +0200 Subject: [PATCH 07/12] Legic_clone.lua: Adopt last command changes --- client/luascripts/Legic_clone.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/luascripts/Legic_clone.lua b/client/luascripts/Legic_clone.lua index a0a8e590d..00834c98b 100644 --- a/client/luascripts/Legic_clone.lua +++ b/client/luascripts/Legic_clone.lua @@ -93,7 +93,7 @@ author = 'Mosci' version = 'v1.0.2' desc = [[ This is a script which creates a clone-dump of a dump from a Legic Prime Tag (MIM256 or MIM1024) -(created with 'hf legic dump o my_dump') +(created with 'hf legic dump f my_dump') ]] example = [[ script run legic_clone -i my_dump.bin -o my_clone.bin -c f8 @@ -441,7 +441,7 @@ function writeToTag(plainBytes) -- write data to file if (writeOutputBytes(bytes, "myLegicClone.bin")) then -- write pm3-buffer to Tag - cmd = ('hf legic restore i myLegicClone') + cmd = ('hf legic restore f myLegicClone') core.console(cmd) end end @@ -515,7 +515,7 @@ function main(args) res = "\n+-------------------------------------------- Summary -------------------------------------------+" res = res .."\ncreated clone_dump from\n\t"..infile.." crc: "..oldcrc.."\ndump_file:" res = res .."\n\t"..outfile.." crc: "..string.sub(newcrc,-2) - res = res .."\nyou may load the new file with: hf legic load "..outfile + res = res .."\nyou may load the new file with: hf legic eload "..outfile res = res .."\n\nif you don't write to tag immediately ('-w' switch) you will need to recalculate each segmentCRC" res = res .."\nafter writing this dump to a tag!" res = res .."\n\na segmentCRC gets calculated over MCD,MSN0..3,Segment-Header0..3" From acfe18e7e97218cc8c47bef31023f851e8fd297c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 5 Apr 2020 14:18:07 +0200 Subject: [PATCH 08/12] rename to lower --- client/luascripts/legic_clone.lua | 543 ++++++++++++++++++++++++++++++ 1 file changed, 543 insertions(+) create mode 100644 client/luascripts/legic_clone.lua diff --git a/client/luascripts/legic_clone.lua b/client/luascripts/legic_clone.lua new file mode 100644 index 000000000..00834c98b --- /dev/null +++ b/client/luascripts/legic_clone.lua @@ -0,0 +1,543 @@ +local utils = require('utils') +local cmds = require('commands') +local getopt = require('getopt') +local ansicolors = require('ansicolors') +--[[ + script to create a clone-dump with new crc + Author: mosci + my Fork: https://github.com/icsom/proxmark3.git + Upstream: https://github.com/Proxmark/proxmark3.git + + 1. read tag-dump, xor byte 22..end with byte 0x05 of the inputfile + 2. write to outfile + 3. set byte 0x05 to newcrc + 4. until byte 0x21 plain like in inputfile + 5. from 0x22..end xored with newcrc + 6. calculate new crc on each segment (needs to know the new MCD & MSN0..2) + + simplest usage: + read a valid legic tag with 'hf legic reader' + save the dump with 'hf legic dump o orig' + place your 'empty' tag on the reader and run 'script run Legic_clone -i orig.bin -w' + you will see some output like: + read 1024 bytes from orig.bin + + place your empty tag onto the PM3 to read and display the MCD & MSN0..2 + the values will be shown below + confirm when ready [y/n] ?y + #db# setting up legic card + #db# MIM 256 card found, reading card ... + #db# Card read, use 'hf legic decode' or + #db# 'data hexsamples 8' to view results + 0b ad c0 de <- !! here you'll see the MCD & MSN of your empty tag, which has to be typed in manually as seen below !! + type in MCD as 2-digit value - e.g.: 00 (default: 79 ) + > 0b + type in MSN0 as 2-digit value - e.g.: 01 (default: 28 ) + > ad + type in MSN1 as 2-digit value - e.g.: 02 (default: d1 ) + > c0 + type in MSN2 as 2-digit value - e.g.: 03 (default: 43 ) + > de + MCD:0b, MSN:ad c0 de, MCC:79 <- this crc is calculated from the MCD & MSN and must match the one on yout empty tag + + wrote 1024 bytes to myLegicClone.hex + enter number of bytes to write? (default: 86 ) + + loaded 1024 samples + #db# setting up legic card + #db# MIM 256 card found, writing 0x00 - 0x01 ... + #db# write successful + ... + #db# setting up legic card + #db# MIM 256 card found, writing 0x56 - 0x01 ... + #db# write successful + proxmark3> + + the default value (number of bytes to write) is calculated over all valid segments and should be ok - just hit enter, wait until write has finished + and your clone should be ready (except there has to be a additional KGH-CRC to be calculated - which credentials are unknown until yet) + + the '-w' switch will only work with my fork - it needs the binary legic_crc8 which is not part of the proxmark3-master-branch + also the ability to write DCF is not possible with the proxmark3-master-branch + but creating dumpfile-clone files will be possible (without valid segment-crc - this has to done manually with) + + + (example) Legic-Prime Layout with 'Kaba Group Header' + +----+----+----+----+----+----+----+----+ + 0x00|MCD |MSN0|MSN1|MSN2|MCC | 60 | ea | 9f | + +----+----+----+----+----+----+----+----+ + 0x08| ff | 00 | 00 | 00 | 11 |Bck0|Bck1|Bck2| + +----+----+----+----+----+----+----+----+ + 0x10|Bck3|Bck4|Bck5|BCC | 00 | 00 |Seg0|Seg1| + +----+----+----+----+----+----+----+----+ + 0x18|Seg2|Seg3|SegC|Stp0|Stp1|Stp2|Stp3|UID0| + +----+----+----+----+----+----+----+----+ + 0x20|UID1|UID2|kghC| + +----+----+----+ + + MCD= ManufacturerID (1 Byte) + MSN0..2= ManufactureSerialNumber (3 Byte) + MCC= CRC (1 Byte) calculated over MCD,MSN0..2 + DCF= DecrementalField (2 Byte) 'credential' (enduser-Tag) seems to have always DCF-low=0x60 DCF-high=0xea + Bck0..5= Backup (6 Byte) Bck0 'dirty-flag', Bck1..5 SegmentHeader-Backup + BCC= BackupCRC (1 Byte) CRC calculated over Bck1..5 + Seg0..3= SegmentHeader (on MIM 4 Byte ) + SegC= SegmentCRC (1 Byte) calculated over MCD,MSN0..2,Seg0..3 + Stp0..n= Stamp0... (variable length) length = Segment-Len - UserData - 1 + UID0..n= UserDater (variable length - with KGH hex 0x00-0x63 / dec 0-99) length = Segment-Len - WRP - WRC - 1 + kghC= KabaGroupHeader (1 Byte + addr 0x0c must be 0x11) + as seen on this example: addr 0x05..0x08 & 0x0c must have been set to this values - otherwise kghCRC will not be created by a official reader (not accepted) +--]] + +copyright = '' +author = 'Mosci' +version = 'v1.0.2' +desc = [[ +This is a script which creates a clone-dump of a dump from a Legic Prime Tag (MIM256 or MIM1024) +(created with 'hf legic dump f my_dump') +]] +example = [[ + script run legic_clone -i my_dump.bin -o my_clone.bin -c f8 + script run legic_clone -i my_dump.bin -d -s +]] +usage = [[ +script run legic_clone -h -i -o -c -d -s -w +]] +arguments = [[ +required : + -i (file to read data from, must be in binary format (*.bin)) + +optional : + -h - Help text + -o - requires option -c to be given + -c - requires option -o to be given + -d - Display content of found Segments + -s - Display summary at the end + -w - write directly to Tag - a file myLegicClone.bin will be generated also + + e.g.: + hint: using the CRC '00' will result in a plain dump ( -c 00 ) +]] + +local bxor = bit32.bxor + +-- we need always 2 digits +local function prepend_zero(s) + if (string.len(s) == 1) then + return '0' .. s + else + if (string.len(s) == 0) then + return '00' + else + return s + end + end +end +--- +-- This is only meant to be used when errors occur +local function oops(err) + print('ERROR:', err) + core.clearCommandBuffer() + return nil, err +end + +-- read LEGIC data +local function readlegicdata( offset, length, iv ) + -- Read data + local command = Command:newMIX{ + cmd = cmds.CMD_HF_LEGIC_READER + , arg1 = offset + , arg2 = length + , arg3 = iv + , data = nil + } + local result, err = command:sendMIX() + if not result then return oops(err) end + -- result is a packed data structure, data starts at offset 33 + return result +end + +--- +-- Usage help +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 + +-- Check availability of file +local function file_check(file_name) + local file_found = io.open(file_name, "r") + if not file_found then + file_found = false + else + file_found = true + end + return file_found +end + +--- xor-wrapper +-- xor all from addr 0x22 (start counting from 1 => 23) +local function xorme(hex, xor, index) + if ( index >= 23 ) then + return ('%02x'):format(bxor( tonumber(hex,16) , tonumber(xor,16) )) + else + return hex + end +end + +-- read input-file into array +local function getInputBytes(infile) + local line + local bytes = {} + + local fhi,err = io.open(infile,"rb") + if err then print("OOps ... faild to read from file ".. infile); return false; end + + str = fhi:read("*all") + for c in (str or ''):gmatch'.' do + bytes[#bytes+1] = ('%02x'):format(c:byte()) + end + + fhi:close() + + print("\nread ".. #bytes .." bytes from ".. infile) + return bytes +end + +-- write to file +local function writeOutputBytes(bytes, outfile) + local fho,err = io.open(outfile,"wb") + if err then print("OOps ... faild to open output-file ".. outfile); return false; end + + for i = 1, #bytes do + fho:write(string.char(tonumber(bytes[i],16))) + end + fho:close() + print("\nwrote ".. #bytes .." bytes to " .. outfile) + return true +end + +-- xore certain bytes +local function xorBytes(inBytes, crc) + local bytes = {} + for index = 1, #inBytes do + bytes[index] = xorme(inBytes[index], crc, index) + end + if (#inBytes == #bytes) then + -- replace crc + bytes[5] = string.sub(crc,-2) + return bytes + else + print("error: byte-count missmatch") + return false + end +end + +-- get raw segment-data +function getSegmentData(bytes, start, index) + local raw, len, valid, last, wrp, wrc, rd, crc + local segment = {} + segment[0] = bytes[start]..' '..bytes[start+1]..' '..bytes[start+2]..' '..bytes[start+3] + -- flag = high nibble of byte 1 + segment[1] = string.sub(bytes[start+1],0,1) + + -- valid = bit 6 of byte 1 + segment[2] = tonumber(bit32.extract('0x'..bytes[start+1],6,1),16) + + -- last = bit 7 of byte 1 + segment[3] = tonumber(bit32.extract('0x'..bytes[start+1],7,1),16) + + -- len = (byte 0)+(bit0-3 of byte 1) + segment[4] = tonumber(('%03x'):format(tonumber(bit32.extract('0x'..bytes[start+1],0,3),16)..tonumber(bytes[start],16)),16) + + -- wrp (write proteted) = byte 2 + segment[5] = tonumber(bytes[start+2]) + + -- wrc (write control) - bit 4-6 of byte 3 + segment[6] = tonumber(bit32.extract('0x'..bytes[start+3],4,3),16) + + -- rd (read disabled) - bit 7 of byte 3 + segment[7] = tonumber(bit32.extract('0x'..bytes[start+3],7,1),16) + + -- crc byte 4 + segment[8] = bytes[start+4] + + -- segment index + segment[9] = index + + -- # crc-byte + segment[10] = start+4 + return segment +end + +--- Kaba Group Header +-- checks if a segment does have a kghCRC +-- returns boolean false if no kgh has being detected or the kghCRC if a kgh was detected +function CheckKgh(bytes, segStart, segEnd) + if (bytes[8]=='9f' and bytes[9]=='ff' and bytes[13]=='11') then + local i + local data = {} + segStart = tonumber(segStart, 10) + segEnd = tonumber(segEnd, 10) + local dataLen = segEnd-segStart-5 + --- gather creadentials for verify + local WRP = bytes[(segStart+2)] + local WRC = ("%02x"):format(tonumber(bit32.extract("0x"..bytes[segStart+3],4,3),16)) + local RD = ("%02x"):format(tonumber(bit32.extract("0x"..bytes[segStart+3],7,1),16)) + local XX = "00" + cmd = bytes[1]..bytes[2]..bytes[3]..bytes[4]..WRP..WRC..RD..XX + for i = (segStart+5), (segStart+5+dataLen-2) do + cmd = cmd..bytes[i] + end + local KGH = ("%02x"):format(utils.Crc8Legic(cmd)) + if (KGH == bytes[segEnd-1]) then + return KGH + else + return false + end + else + return false + end +end + +-- get only the addresses of segemnt-crc's and the length of bytes +function getSegmentCrcBytes(bytes) + local start = 23 + local index = 0 + local crcbytes = {} + repeat + seg = getSegmentData(bytes,start,index) + crcbytes[index] = seg[10] + start = start + seg[4] + index = index + 1 + until (seg[3] == 1 or tonumber(seg[9]) == 126 ) + crcbytes[index] = start + return crcbytes +end + +-- print segment-data (hf legic info like) +function displaySegments(bytes) + --display segment header(s) + start = 23 + index = '00' + + --repeat until last-flag ist set to 1 or segment-index has reached 126 + repeat + wrc = '' + wrp = '' + pld = '' + Seg = getSegmentData(bytes, start, index) + KGH = CheckKgh(bytes, start, (start+tonumber(Seg[4],10))) + printSegment(Seg) + + -- wrc + if (Seg[6] > 0) then + print("WRC protected area:") + -- length of wrc = wrc + for i=1, Seg[6] do + -- starts at (segment-start + segment-header + segment-crc)-1 + wrc = wrc..bytes[(start+4+1+i)-1]..' ' + end + print(wrc) + elseif (Seg[5] > 0) then + print("Remaining write protected area:") + -- length of wrp = (wrp-wrc) + for i=1, (Seg[5]-Seg[6]) do + -- starts at (segment-start + segment-header + segment-crc + wrc)-1 + wrp = wrp..bytes[(start+4+1+Seg[6]+i)-1]..' ' + end + print(wrp) + end + + -- payload + print("Remaining segment payload:") + --length of payload = segment-len - segment-header - segment-crc - wrp -wrc + for i=1, (Seg[4]-4-1-Seg[5]-Seg[6]) do + -- starts at (segment-start + segment-header + segment-crc + segment-wrp + segemnt-wrc)-1 + pld = pld..bytes[(start+4+1+Seg[5]+Seg[6]+i)-1]..' ' + end + print(pld) + if (KGH) then + print("'Kaba Group Header' detected") + end + start = start+Seg[4] + index = prepend_zero(tonumber(Seg[9])+1) + + until (Seg[3] == 1 or tonumber(Seg[9]) == 126 ) +end + +-- print Segment values +function printSegment(SegmentData) + res = "\nSegment "..SegmentData[9]..": " + res = res.. "raw header="..SegmentData[0]..", " + res = res.. "flag="..SegmentData[1].." (valid="..SegmentData[2].." last="..SegmentData[3].."), " + res = res.. "len="..("%04d"):format(SegmentData[4])..", " + res = res.. "WRP="..prepend_zero(SegmentData[5])..", " + res = res.. "WRC="..prepend_zero(SegmentData[6])..", " + res = res.. "RD="..SegmentData[7]..", " + res = res.. "crc="..SegmentData[8] + print(res) +end + +-- write clone-data to tag +function writeToTag(plainBytes) + local SegCrcs = {} + local output + local readbytes + if(utils.confirm("\nplace your empty tag onto the PM3 to restore the data of the input file\nthe CRCs will be calculated as needed\n confirm when ready") == false) then + return + end + + readbytes = readlegicdata(0, 4, 0x55) + -- gather MCD & MSN from new Tag - this must be enterd manually + print("\nthese are the MCD MSN0 MSN1 MSN2 from the Tag that has being read:") + + plainBytes[1] = ('%02x'):format(readbytes:byte(33)) + plainBytes[2] = ('%02x'):format(readbytes:byte(34)) + plainBytes[3] = ('%02x'):format(readbytes:byte(35)) + plainBytes[4] = ('%02x'):format(readbytes:byte(36)) + + MCD = plainBytes[1] + MSN0 = plainBytes[2] + MSN1 = plainBytes[3] + MSN2 = plainBytes[4] + -- calculate crc8 over MCD & MSN + cmd = MCD..MSN0..MSN1..MSN2 + MCC = ("%02x"):format(utils.Crc8Legic(cmd)) + print("MCD:"..MCD..", MSN:"..MSN0.." "..MSN1.." "..MSN2..", MCC:"..MCC) + + -- calculate new Segment-CRC for each valid segment + SegCrcs = getSegmentCrcBytes(plainBytes) + for i=0, (#SegCrcs-1) do + -- SegCrcs[i]-4 = address of first byte of segmentHeader (low byte segment-length) + segLen = tonumber(("%1x"):format(tonumber(bit32.extract("0x"..plainBytes[(SegCrcs[i]-3)],0,3),16))..("%02x"):format(tonumber(plainBytes[SegCrcs[i]-4],16)),16) + segStart = (SegCrcs[i]-4) + segEnd = (SegCrcs[i]-4+segLen) + KGH = CheckKgh(plainBytes,segStart,segEnd) + if (KGH) then + print("'Kaba Group Header' detected - re-calculate...") + end + cmd = MCD..MSN0..MSN1..MSN2..plainBytes[SegCrcs[i]-4]..plainBytes[SegCrcs[i]-3]..plainBytes[SegCrcs[i]-2]..plainBytes[SegCrcs[i]-1] + plainBytes[SegCrcs[i]] = ("%02x"):format(utils.Crc8Legic(cmd)) + end + + -- apply MCD & MSN to plain data + plainBytes[1] = MCD + plainBytes[2] = MSN0 + plainBytes[3] = MSN1 + plainBytes[4] = MSN2 + plainBytes[5] = MCC + + -- prepare plainBytes for writing (xor plain data with new MCC) + bytes = xorBytes(plainBytes, MCC) + + -- write data to file + if (writeOutputBytes(bytes, "myLegicClone.bin")) then + -- write pm3-buffer to Tag + cmd = ('hf legic restore f myLegicClone') + core.console(cmd) + end +end + +-- main function +function main(args) + -- some variables + local i = 0 + local oldcrc, newcrc, infile, outfile + local bytes = {} + local segments = {} + + -- parse arguments for the script + for o, a in getopt.getopt(args, 'hwsdc:i:o:') do + -- output file + if o == 'o' then + outfile = a + ofs = true + if (file_check(a)) then + local answer = utils.confirm('\nthe output-file '..a..' already exists!\nthis will delete the previous content!\ncontinue?') + if (answer==false) then return oops('quiting') end + end + end + -- input file + if o == 'i' then + infile = a + if (file_check(infile)==false) then + return oops('input file: '..infile..' not found') + else + bytes = getInputBytes(infile) + oldcrc = bytes[5] + ifs = true + if (bytes == false) then return oops('couldnt get input bytes') end + end + i = i+1 + end + -- new crc + if o == 'c' then + newcrc = a:lower() + ncs = true + end + -- display segments switch + if o == 'd' then ds = true; end + -- display summary switch + if o == 's' then ss = true; end + -- write to tag switch + if o == 'w' then ws = true; end + -- help + if o == 'h' then return help() end + end + + if (not ifs) then return oops('option -i is required but missing') end + + -- bytes to plain + bytes = xorBytes(bytes, oldcrc) + + -- show segments (works only on plain bytes) + if (ds) then + print("+------------------------------------------- Segments -------------------------------------------+") + displaySegments(bytes); + end + + if (ofs and ncs) then + -- xor bytes with new crc + newBytes = xorBytes(bytes, newcrc) + -- write output + if (writeOutputBytes(newBytes, outfile)) then + -- show summary if requested + if (ss) then + -- information + res = "\n+-------------------------------------------- Summary -------------------------------------------+" + res = res .."\ncreated clone_dump from\n\t"..infile.." crc: "..oldcrc.."\ndump_file:" + res = res .."\n\t"..outfile.." crc: "..string.sub(newcrc,-2) + res = res .."\nyou may load the new file with: hf legic eload "..outfile + res = res .."\n\nif you don't write to tag immediately ('-w' switch) you will need to recalculate each segmentCRC" + res = res .."\nafter writing this dump to a tag!" + res = res .."\n\na segmentCRC gets calculated over MCD,MSN0..3,Segment-Header0..3" + res = res .."\ne.g. (based on Segment00 of the data from "..infile.."):" + res = res .."\nhf legic crc d "..bytes[1]..bytes[2]..bytes[3]..bytes[4]..bytes[23]..bytes[24]..bytes[25]..bytes[26].." u "..newcrc.." c 8" + -- this can not be calculated without knowing the new MCD, MSN0..2 + print(res) + end + end + else + if (ss) then + -- show why the output-file was not written + print("\nnew file not written - some arguments are missing ..") + print("output file: ".. (ofs and outfile or "not given")) + print("new crc: ".. (ncs and newcrc or "not given")) + end + end + -- write to tag + if (ws and ( #bytes == 1024 or #bytes == 256)) then + writeToTag(bytes) + end +end + +-- call main with arguments +main(args) From 3a2723ac63f9eed70c08fb1daefabaa7a54f604f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 5 Apr 2020 14:53:32 +0200 Subject: [PATCH 09/12] style --- client/luascripts/legic_clone.lua | 204 +++++++++++++++--------------- 1 file changed, 101 insertions(+), 103 deletions(-) diff --git a/client/luascripts/legic_clone.lua b/client/luascripts/legic_clone.lua index 00834c98b..29a43a184 100644 --- a/client/luascripts/legic_clone.lua +++ b/client/luascripts/legic_clone.lua @@ -2,6 +2,7 @@ local utils = require('utils') local cmds = require('commands') local getopt = require('getopt') local ansicolors = require('ansicolors') + --[[ script to create a clone-dump with new crc Author: mosci @@ -17,18 +18,15 @@ local ansicolors = require('ansicolors') simplest usage: read a valid legic tag with 'hf legic reader' - save the dump with 'hf legic dump o orig' - place your 'empty' tag on the reader and run 'script run Legic_clone -i orig.bin -w' + save the dump with 'hf legic dump f orig' + place your 'empty' tag on the reader and run 'script run legic_clone -i orig.bin -w' you will see some output like: read 1024 bytes from orig.bin place your empty tag onto the PM3 to read and display the MCD & MSN0..2 the values will be shown below confirm when ready [y/n] ?y - #db# setting up legic card - #db# MIM 256 card found, reading card ... - #db# Card read, use 'hf legic decode' or - #db# 'data hexsamples 8' to view results + 0b ad c0 de <- !! here you'll see the MCD & MSN of your empty tag, which has to be typed in manually as seen below !! type in MCD as 2-digit value - e.g.: 00 (default: 79 ) > 0b @@ -93,18 +91,18 @@ author = 'Mosci' version = 'v1.0.2' desc = [[ This is a script which creates a clone-dump of a dump from a Legic Prime Tag (MIM256 or MIM1024) -(created with 'hf legic dump f my_dump') +Create a dump by running 'hf legic dump'. ]] example = [[ script run legic_clone -i my_dump.bin -o my_clone.bin -c f8 script run legic_clone -i my_dump.bin -d -s ]] usage = [[ -script run legic_clone -h -i -o -c -d -s -w +script run legic_clone [-h] [-i ] [-o ] [-c ] [-d] [-s] [-w] ]] arguments = [[ required : - -i (file to read data from, must be in binary format (*.bin)) + -i - file to read data from, must be in binary format (*.bin) optional : -h - Help text @@ -112,7 +110,7 @@ optional : -c - requires option -o to be given -d - Display content of found Segments -s - Display summary at the end - -w - write directly to Tag - a file myLegicClone.bin will be generated also + -w - write directly to tag - a file hf-legic-UID-dump.bin will also be generated e.g.: hint: using the CRC '00' will result in a plain dump ( -c 00 ) @@ -139,23 +137,6 @@ local function oops(err) core.clearCommandBuffer() return nil, err end - --- read LEGIC data -local function readlegicdata( offset, length, iv ) - -- Read data - local command = Command:newMIX{ - cmd = cmds.CMD_HF_LEGIC_READER - , arg1 = offset - , arg2 = length - , arg3 = iv - , data = nil - } - local result, err = command:sendMIX() - if not result then return oops(err) end - -- result is a packed data structure, data starts at offset 33 - return result -end - --- -- Usage help local function help() @@ -170,23 +151,38 @@ local function help() print(ansicolors.cyan..'Example usage'..ansicolors.reset) print(example) end +-- read LEGIC data +local function readlegicdata(offset, length, iv) + -- Read data + local command = Command:newMIX{ + cmd = cmds.CMD_HF_LEGIC_READER + , arg1 = offset + , arg2 = length + , arg3 = iv + , data = nil + } + local result, err = command:sendMIX() + if not result then return oops(err) end + -- result is a packed data structure, data starts at offset 33 + return result +end -- Check availability of file local function file_check(file_name) - local file_found = io.open(file_name, "r") - if not file_found then - file_found = false + local exists = io.open(file_name, "r") + if not exists then + exists = false else - file_found = true + exists = true end - return file_found + return exists end --- xor-wrapper -- xor all from addr 0x22 (start counting from 1 => 23) local function xorme(hex, xor, index) if ( index >= 23 ) then - return ('%02x'):format(bxor( tonumber(hex,16) , tonumber(xor,16) )) + return ('%02x'):format(bxor( tonumber(hex, 16) , tonumber(xor, 16) )) else return hex end @@ -197,12 +193,12 @@ local function getInputBytes(infile) local line local bytes = {} - local fhi,err = io.open(infile,"rb") + local fhi,err = io.open(infile, "rb") if err then print("OOps ... faild to read from file ".. infile); return false; end str = fhi:read("*all") for c in (str or ''):gmatch'.' do - bytes[#bytes+1] = ('%02x'):format(c:byte()) + bytes[#bytes + 1] = ('%02x'):format(c:byte()) end fhi:close() @@ -213,11 +209,11 @@ end -- write to file local function writeOutputBytes(bytes, outfile) - local fho,err = io.open(outfile,"wb") + local fho,err = io.open(outfile, "wb") if err then print("OOps ... faild to open output-file ".. outfile); return false; end for i = 1, #bytes do - fho:write(string.char(tonumber(bytes[i],16))) + fho:write(string.char(tonumber(bytes[i], 16))) end fho:close() print("\nwrote ".. #bytes .." bytes to " .. outfile) @@ -232,7 +228,7 @@ local function xorBytes(inBytes, crc) end if (#inBytes == #bytes) then -- replace crc - bytes[5] = string.sub(crc,-2) + bytes[5] = string.sub(crc, -2) return bytes else print("error: byte-count missmatch") @@ -241,63 +237,63 @@ local function xorBytes(inBytes, crc) end -- get raw segment-data -function getSegmentData(bytes, start, index) +local function getSegmentData(bytes, start, index) local raw, len, valid, last, wrp, wrc, rd, crc local segment = {} - segment[0] = bytes[start]..' '..bytes[start+1]..' '..bytes[start+2]..' '..bytes[start+3] + segment[0] = bytes[start]..' '..bytes[start + 1]..' '..bytes[start + 2]..' '..bytes[start + 3] -- flag = high nibble of byte 1 - segment[1] = string.sub(bytes[start+1],0,1) + segment[1] = string.sub(bytes[start + 1], 0, 1) -- valid = bit 6 of byte 1 - segment[2] = tonumber(bit32.extract('0x'..bytes[start+1],6,1),16) + segment[2] = tonumber(bit32.extract('0x'..bytes[start + 1], 6, 1), 16) -- last = bit 7 of byte 1 - segment[3] = tonumber(bit32.extract('0x'..bytes[start+1],7,1),16) + segment[3] = tonumber(bit32.extract('0x'..bytes[start + 1], 7, 1), 16) -- len = (byte 0)+(bit0-3 of byte 1) - segment[4] = tonumber(('%03x'):format(tonumber(bit32.extract('0x'..bytes[start+1],0,3),16)..tonumber(bytes[start],16)),16) + segment[4] = tonumber(('%03x'):format(tonumber(bit32.extract('0x'..bytes[start + 1], 0, 3), 16)..tonumber(bytes[start], 16)), 16) -- wrp (write proteted) = byte 2 - segment[5] = tonumber(bytes[start+2]) + segment[5] = tonumber(bytes[start + 2]) -- wrc (write control) - bit 4-6 of byte 3 - segment[6] = tonumber(bit32.extract('0x'..bytes[start+3],4,3),16) + segment[6] = tonumber(bit32.extract('0x'..bytes[start + 3], 4, 3), 16) -- rd (read disabled) - bit 7 of byte 3 - segment[7] = tonumber(bit32.extract('0x'..bytes[start+3],7,1),16) + segment[7] = tonumber(bit32.extract('0x'..bytes[start + 3], 7, 1), 16) -- crc byte 4 - segment[8] = bytes[start+4] + segment[8] = bytes[start + 4] -- segment index segment[9] = index -- # crc-byte - segment[10] = start+4 + segment[10] = start + 4 return segment end --- Kaba Group Header -- checks if a segment does have a kghCRC -- returns boolean false if no kgh has being detected or the kghCRC if a kgh was detected -function CheckKgh(bytes, segStart, segEnd) - if (bytes[8]=='9f' and bytes[9]=='ff' and bytes[13]=='11') then +local function CheckKgh(bytes, segStart, segEnd) + if (bytes[8] == '9f' and bytes[9] == 'ff' and bytes[13] == '11') then local i local data = {} segStart = tonumber(segStart, 10) segEnd = tonumber(segEnd, 10) - local dataLen = segEnd-segStart-5 + local dataLen = segEnd - segStart - 5 --- gather creadentials for verify - local WRP = bytes[(segStart+2)] - local WRC = ("%02x"):format(tonumber(bit32.extract("0x"..bytes[segStart+3],4,3),16)) - local RD = ("%02x"):format(tonumber(bit32.extract("0x"..bytes[segStart+3],7,1),16)) + local WRP = bytes[(segStart + 2)] + local WRC = ("%02x"):format(tonumber(bit32.extract("0x"..bytes[segStart+3], 4, 3), 16)) + local RD = ("%02x"):format(tonumber(bit32.extract("0x"..bytes[segStart+3], 7, 1), 16)) local XX = "00" cmd = bytes[1]..bytes[2]..bytes[3]..bytes[4]..WRP..WRC..RD..XX - for i = (segStart+5), (segStart+5+dataLen-2) do + for i = (segStart + 5), (segStart + 5 + dataLen - 2) do cmd = cmd..bytes[i] end local KGH = ("%02x"):format(utils.Crc8Legic(cmd)) - if (KGH == bytes[segEnd-1]) then + if (KGH == bytes[segEnd - 1]) then return KGH else return false @@ -308,12 +304,12 @@ function CheckKgh(bytes, segStart, segEnd) end -- get only the addresses of segemnt-crc's and the length of bytes -function getSegmentCrcBytes(bytes) +local function getSegmentCrcBytes(bytes) local start = 23 local index = 0 local crcbytes = {} repeat - seg = getSegmentData(bytes,start,index) + seg = getSegmentData(bytes, start, index) crcbytes[index] = seg[10] start = start + seg[4] index = index + 1 @@ -323,7 +319,7 @@ function getSegmentCrcBytes(bytes) end -- print segment-data (hf legic info like) -function displaySegments(bytes) +local function displaySegments(bytes) --display segment header(s) start = 23 index = '00' @@ -334,24 +330,24 @@ function displaySegments(bytes) wrp = '' pld = '' Seg = getSegmentData(bytes, start, index) - KGH = CheckKgh(bytes, start, (start+tonumber(Seg[4],10))) + KGH = CheckKgh(bytes, start, (start + tonumber(Seg[4], 10))) printSegment(Seg) -- wrc if (Seg[6] > 0) then print("WRC protected area:") -- length of wrc = wrc - for i=1, Seg[6] do + for i = 1, Seg[6] do -- starts at (segment-start + segment-header + segment-crc)-1 - wrc = wrc..bytes[(start+4+1+i)-1]..' ' + wrc = wrc..bytes[(start + 4 + 1 + i) - 1]..' ' end print(wrc) elseif (Seg[5] > 0) then print("Remaining write protected area:") -- length of wrp = (wrp-wrc) - for i=1, (Seg[5]-Seg[6]) do + for i = 1, (Seg[5] - Seg[6]) do -- starts at (segment-start + segment-header + segment-crc + wrc)-1 - wrp = wrp..bytes[(start+4+1+Seg[6]+i)-1]..' ' + wrp = wrp..bytes[(start + 4 + 1 + Seg[6] + i) - 1]..' ' end print(wrp) end @@ -359,22 +355,22 @@ function displaySegments(bytes) -- payload print("Remaining segment payload:") --length of payload = segment-len - segment-header - segment-crc - wrp -wrc - for i=1, (Seg[4]-4-1-Seg[5]-Seg[6]) do + for i = 1, (Seg[4] - 4 - 1 - Seg[5] - Seg[6]) do -- starts at (segment-start + segment-header + segment-crc + segment-wrp + segemnt-wrc)-1 - pld = pld..bytes[(start+4+1+Seg[5]+Seg[6]+i)-1]..' ' + pld = pld..bytes[(start + 4 + 1 + Seg[5] + Seg[6] + i) - 1]..' ' end print(pld) if (KGH) then - print("'Kaba Group Header' detected") + print(ansicolors.yellow.."'Kaba Group Header' detected"..ansicolors.reset) end - start = start+Seg[4] - index = prepend_zero(tonumber(Seg[9])+1) + start = start + Seg[4] + index = prepend_zero(tonumber(Seg[9]) + 1) until (Seg[3] == 1 or tonumber(Seg[9]) == 126 ) end -- print Segment values -function printSegment(SegmentData) +local function printSegment(SegmentData) res = "\nSegment "..SegmentData[9]..": " res = res.. "raw header="..SegmentData[0]..", " res = res.. "flag="..SegmentData[1].." (valid="..SegmentData[2].." last="..SegmentData[3].."), " @@ -387,18 +383,19 @@ function printSegment(SegmentData) end -- write clone-data to tag -function writeToTag(plainBytes) +local function writeToTag(plainBytes) local SegCrcs = {} local output local readbytes - if(utils.confirm("\nplace your empty tag onto the PM3 to restore the data of the input file\nthe CRCs will be calculated as needed\n confirm when ready") == false) then - return - end + if (utils.confirm("\nplace your empty tag onto the PM3 to restore the data of the input file\nthe CRCs will be calculated as needed\n confirm when ready") == false) then + return + end readbytes = readlegicdata(0, 4, 0x55) -- gather MCD & MSN from new Tag - this must be enterd manually print("\nthese are the MCD MSN0 MSN1 MSN2 from the Tag that has being read:") + -- readbytes is a usbcommandOLD package, hence 32 bytes offset until data. plainBytes[1] = ('%02x'):format(readbytes:byte(33)) plainBytes[2] = ('%02x'):format(readbytes:byte(34)) plainBytes[3] = ('%02x'):format(readbytes:byte(35)) @@ -411,19 +408,19 @@ function writeToTag(plainBytes) -- calculate crc8 over MCD & MSN cmd = MCD..MSN0..MSN1..MSN2 MCC = ("%02x"):format(utils.Crc8Legic(cmd)) - print("MCD:"..MCD..", MSN:"..MSN0.." "..MSN1.." "..MSN2..", MCC:"..MCC) + print("MCD:"..ansicolors.green..MCD..ansicolors.reset..", MSN:"..ansicolors.green..MSN0.." "..MSN1.." "..MSN2..ansicolors.reset..", MCC:"..MCC) -- calculate new Segment-CRC for each valid segment SegCrcs = getSegmentCrcBytes(plainBytes) - for i=0, (#SegCrcs-1) do - -- SegCrcs[i]-4 = address of first byte of segmentHeader (low byte segment-length) - segLen = tonumber(("%1x"):format(tonumber(bit32.extract("0x"..plainBytes[(SegCrcs[i]-3)],0,3),16))..("%02x"):format(tonumber(plainBytes[SegCrcs[i]-4],16)),16) - segStart = (SegCrcs[i]-4) - segEnd = (SegCrcs[i]-4+segLen) - KGH = CheckKgh(plainBytes,segStart,segEnd) - if (KGH) then - print("'Kaba Group Header' detected - re-calculate...") - end + for i = 0, (#SegCrcs - 1) do + -- SegCrcs[i]-4 = address of first byte of segmentHeader (low byte segment-length) + segLen = tonumber(("%1x"):format(tonumber(bit32.extract("0x"..plainBytes[(SegCrcs[i] - 3)], 0, 3), 16))..("%02x"):format(tonumber(plainBytes[SegCrcs[i] - 4], 16)), 16) + segStart = (SegCrcs[i] - 4) + segEnd = (SegCrcs[i] - 4 + segLen) + KGH = CheckKgh(plainBytes, segStart, segEnd) + if (KGH) then + print("'Kaba Group Header' detected - re-calculate...") + end cmd = MCD..MSN0..MSN1..MSN2..plainBytes[SegCrcs[i]-4]..plainBytes[SegCrcs[i]-3]..plainBytes[SegCrcs[i]-2]..plainBytes[SegCrcs[i]-1] plainBytes[SegCrcs[i]] = ("%02x"):format(utils.Crc8Legic(cmd)) end @@ -439,15 +436,15 @@ function writeToTag(plainBytes) bytes = xorBytes(plainBytes, MCC) -- write data to file - if (writeOutputBytes(bytes, "myLegicClone.bin")) then + if (writeOutputBytes(bytes, "hf-legic-UID-dump.bin")) then -- write pm3-buffer to Tag - cmd = ('hf legic restore f myLegicClone') + cmd = ('hf legic restore f hf-legic-UID-dump') core.console(cmd) end end -- main function -function main(args) +local function main(args) -- some variables local i = 0 local oldcrc, newcrc, infile, outfile @@ -462,21 +459,20 @@ function main(args) ofs = true if (file_check(a)) then local answer = utils.confirm('\nthe output-file '..a..' already exists!\nthis will delete the previous content!\ncontinue?') - if (answer==false) then return oops('quiting') end + if (answer == false) then return oops('quiting') end end end -- input file if o == 'i' then infile = a - if (file_check(infile)==false) then - return oops('input file: '..infile..' not found') - else - bytes = getInputBytes(infile) - oldcrc = bytes[5] - ifs = true - if (bytes == false) then return oops('couldnt get input bytes') end - end - i = i+1 + if (file_check(infile) == false) then return oops('input file: '..infile..' not found') end + + bytes = getInputBytes(infile) + oldcrc = bytes[5] + ifs = true + if (bytes == false) then return oops('couldnt get input bytes') end + + i = i + 1 end -- new crc if o == 'c' then @@ -514,13 +510,15 @@ function main(args) -- information res = "\n+-------------------------------------------- Summary -------------------------------------------+" res = res .."\ncreated clone_dump from\n\t"..infile.." crc: "..oldcrc.."\ndump_file:" - res = res .."\n\t"..outfile.." crc: "..string.sub(newcrc,-2) - res = res .."\nyou may load the new file with: hf legic eload "..outfile + res = res .."\n\t"..outfile.." crc: "..string.sub(newcrc, -2) + res = res .."\nyou may load the new file with:" + res = res ..ansicolors.yellow.."hf legic eload f "..outfile..ansicolors.reset res = res .."\n\nif you don't write to tag immediately ('-w' switch) you will need to recalculate each segmentCRC" res = res .."\nafter writing this dump to a tag!" - res = res .."\n\na segmentCRC gets calculated over MCD,MSN0..3,Segment-Header0..3" + res = res .."\n\na segmentCRC gets calculated over MCD,MSN0..3, Segment-Header0..3" res = res .."\ne.g. (based on Segment00 of the data from "..infile.."):" - res = res .."\nhf legic crc d "..bytes[1]..bytes[2]..bytes[3]..bytes[4]..bytes[23]..bytes[24]..bytes[25]..bytes[26].." u "..newcrc.." c 8" + res = res .."\n" + res = res ..ansicolors.yellow.."hf legic crc d "..bytes[1]..bytes[2]..bytes[3]..bytes[4]..bytes[23]..bytes[24]..bytes[25]..bytes[26].." u "..newcrc.." c 8"..ansicolors.reset -- this can not be calculated without knowing the new MCD, MSN0..2 print(res) end @@ -535,7 +533,7 @@ function main(args) end -- write to tag if (ws and ( #bytes == 1024 or #bytes == 256)) then - writeToTag(bytes) + writeToTag(bytes) end end From 214bb46e9c073c7e7479c34372c516fca121d58a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 5 Apr 2020 16:59:14 +0200 Subject: [PATCH 10/12] fix: hf mfu ndef - ul ev1 48 bytes with a NDEF otp. e1101200, max size mismatch. Now it will select smallest --- client/cmdhfmfu.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index 1f97c6b36..7c204f861 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -2781,7 +2781,20 @@ static int CmdHF14MfuNDEF(const char *Cmd) { // max datasize; maxsize = ndef_get_maxsize(data + 12); } - + + // iceman: maybe always take MIN of tag identified size vs NDEF reported size? + // fix: UL_EV1 48bytes != NDEF reported size + for (uint8_t i = 0; i < ARRAYLEN(UL_TYPES_ARRAY); i++) { + if (tagtype & UL_TYPES_ARRAY[i]) { + + if (maxsize != (UL_MEMORY_ARRAY[i] * 4) ) { + PrintAndLogEx(INFO, "Tag reported size vs NDEF reported size mismatch. Using smallest value"); + } + maxsize = MIN(maxsize, (UL_MEMORY_ARRAY[i] * 4)); + break; + } + } + // allocate mem uint8_t *records = calloc(maxsize, sizeof(uint8_t)); if (records == NULL) { From 0263273ec3788beeaa818640b9f2b8b613b4ef73 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 5 Apr 2020 17:00:16 +0200 Subject: [PATCH 11/12] fix: wrong paramname --- client/luascripts/emul2dump.lua | 4 ++-- client/luascripts/hf_read.lua | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client/luascripts/emul2dump.lua b/client/luascripts/emul2dump.lua index cf6900bff..e0286e625 100644 --- a/client/luascripts/emul2dump.lua +++ b/client/luascripts/emul2dump.lua @@ -7,7 +7,7 @@ copyright = '' author = 'Iceman' version = 'v1.0.2' desc =[[ -This script takes an dumpfile on EML (ASCII) format and converts it to the PM3 dumpbin file to be used with `hf mf restore` +This script takes an dumpfile in EML (ASCII) format and converts it to the PM3 dumpbin file to be used with `hf mf restore` ]] example =[[ 1. script run emul2dump @@ -25,7 +25,7 @@ arguments = [[ ]] --- -- This is only meant to be used when errors occur -local function dbg(err) +local function dbg(args) if not DEBUG then return end if type(args) == 'table' then local i = 1 diff --git a/client/luascripts/hf_read.lua b/client/luascripts/hf_read.lua index e416cdd2e..22234e116 100644 --- a/client/luascripts/hf_read.lua +++ b/client/luascripts/hf_read.lua @@ -19,7 +19,7 @@ arguments = [[ ]] --- -- This is only meant to be used when errors occur -local function dbg(err) +local function dbg(args) if not DEBUG then return end if type(args) == 'table' then local i = 1 From 0029f6fceb22fdae2ee10115a359affed34b1196 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 5 Apr 2020 17:02:41 +0200 Subject: [PATCH 12/12] minor fixes. wrong params, helptext --- client/luascripts/legic_clone.lua | 90 ++++++++++++++++++------------- 1 file changed, 54 insertions(+), 36 deletions(-) diff --git a/client/luascripts/legic_clone.lua b/client/luascripts/legic_clone.lua index 29a43a184..c27da3c08 100644 --- a/client/luascripts/legic_clone.lua +++ b/client/luascripts/legic_clone.lua @@ -4,10 +4,9 @@ local getopt = require('getopt') local ansicolors = require('ansicolors') --[[ - script to create a clone-dump with new crc + script to create a clone-dump with new crc Author: mosci - my Fork: https://github.com/icsom/proxmark3.git - Upstream: https://github.com/Proxmark/proxmark3.git + my Fork: https://github.com/icsom/proxmark3.git 1. read tag-dump, xor byte 22..end with byte 0x05 of the inputfile 2. write to outfile @@ -16,11 +15,13 @@ local ansicolors = require('ansicolors') 5. from 0x22..end xored with newcrc 6. calculate new crc on each segment (needs to know the new MCD & MSN0..2) - simplest usage: - read a valid legic tag with 'hf legic reader' - save the dump with 'hf legic dump f orig' - place your 'empty' tag on the reader and run 'script run legic_clone -i orig.bin -w' - you will see some output like: + simplest usage: + Dump a legic tag with 'hf legic dump' + place your 'empty' tag on the reader and run + 'script run legic_clone -i orig.bin -w' + + you will see some output like: + read 1024 bytes from orig.bin place your empty tag onto the PM3 to read and display the MCD & MSN0..2 @@ -90,8 +91,8 @@ copyright = '' author = 'Mosci' version = 'v1.0.2' desc = [[ -This is a script which creates a clone-dump of a dump from a Legic Prime Tag (MIM256 or MIM1024) -Create a dump by running 'hf legic dump'. +This is a script which creates a clone-dump of a dump from a LEGIC Prime Tag (MIM256 or MIM1024) +Create a dump by running `hf legic dump`. ]] example = [[ script run legic_clone -i my_dump.bin -o my_clone.bin -c f8 @@ -115,15 +116,30 @@ optional : e.g.: hint: using the CRC '00' will result in a plain dump ( -c 00 ) ]] - +local DEBUG = true local bxor = bit32.bxor - +--- +-- This is only meant to be used when errors occur +local function dbg(args) + if not DEBUG then return end + if type(args) == 'table' then + local i = 1 + while args[i] do + dbg(args[i]) + i = i+1 + end + else + print('###', args) + end +end -- we need always 2 digits local function prepend_zero(s) - if (string.len(s) == 1) then + if s == nil then return '..' end + + if (#s == 1) then return '0' .. s else - if (string.len(s) == 0) then + if (#s == 0) then return '00' else return s @@ -190,20 +206,18 @@ end -- read input-file into array local function getInputBytes(infile) - local line local bytes = {} + local f = io.open(infile, "rb") + if f == nil then print("OOps ... failed to read from file ".. infile); return false; end - local fhi,err = io.open(infile, "rb") - if err then print("OOps ... faild to read from file ".. infile); return false; end + local str = f:read("*all") + f:close() - str = fhi:read("*all") for c in (str or ''):gmatch'.' do bytes[#bytes + 1] = ('%02x'):format(c:byte()) end - fhi:close() - - print("\nread ".. #bytes .." bytes from ".. infile) + print("\nread ".. #bytes .." bytes from "..ansicolors.yellow..infile..ansicolors.reset) return bytes end @@ -318,8 +332,22 @@ local function getSegmentCrcBytes(bytes) return crcbytes end +-- print Segment values +local function printSegment(SegmentData) + res = "\nSegment "..SegmentData[9]..": " + res = res.. "raw header="..SegmentData[0]..", " + res = res.. "flag="..SegmentData[1].." (valid="..SegmentData[2].." last="..SegmentData[3].."), " + res = res.. "len="..("%04d"):format(SegmentData[4])..", " + res = res.. "WRP="..prepend_zero(SegmentData[5])..", " + res = res.. "WRC="..prepend_zero(SegmentData[6])..", " + res = res.. "RD="..SegmentData[7]..", " + res = res.. "crc="..SegmentData[8] + print(res) +end + -- print segment-data (hf legic info like) local function displaySegments(bytes) + --display segment header(s) start = 23 index = '00' @@ -330,7 +358,10 @@ local function displaySegments(bytes) wrp = '' pld = '' Seg = getSegmentData(bytes, start, index) + if Seg == nil then return OOps("segment is nil") end + KGH = CheckKgh(bytes, start, (start + tonumber(Seg[4], 10))) + printSegment(Seg) -- wrc @@ -369,19 +400,6 @@ local function displaySegments(bytes) until (Seg[3] == 1 or tonumber(Seg[9]) == 126 ) end --- print Segment values -local function printSegment(SegmentData) - res = "\nSegment "..SegmentData[9]..": " - res = res.. "raw header="..SegmentData[0]..", " - res = res.. "flag="..SegmentData[1].." (valid="..SegmentData[2].." last="..SegmentData[3].."), " - res = res.. "len="..("%04d"):format(SegmentData[4])..", " - res = res.. "WRP="..prepend_zero(SegmentData[5])..", " - res = res.. "WRC="..prepend_zero(SegmentData[6])..", " - res = res.. "RD="..SegmentData[7]..", " - res = res.. "crc="..SegmentData[8] - print(res) -end - -- write clone-data to tag local function writeToTag(plainBytes) local SegCrcs = {} @@ -470,7 +488,7 @@ local function main(args) bytes = getInputBytes(infile) oldcrc = bytes[5] ifs = true - if (bytes == false) then return oops('couldnt get input bytes') end + if (bytes == false) then return oops('couldnt read file') end i = i + 1 end @@ -489,7 +507,7 @@ local function main(args) if o == 'h' then return help() end end - if (not ifs) then return oops('option -i is required but missing') end + if (not ifs) then return oops('option -i is required') end -- bytes to plain bytes = xorBytes(bytes, oldcrc)