mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2026-05-12 11:18:11 -07:00
lua: fix mix of spaces & tabs
This commit is contained in:
+115
-115
@@ -6,22 +6,22 @@ example = "script run 14araw -x 6000F57b"
|
||||
author = "Martin Holst Swende"
|
||||
desc =
|
||||
[[
|
||||
This is a script to allow raw 1444a commands to be sent and received.
|
||||
This is a script to allow raw 1444a commands to be sent and received.
|
||||
|
||||
Arguments:
|
||||
-o do not connect - use this only if you previously used -p to stay connected
|
||||
-r do not read response
|
||||
-c calculate and append CRC
|
||||
-p stay connected - dont inactivate the field
|
||||
-x <payload> Data to send (NO SPACES!)
|
||||
-d Debug flag
|
||||
-t Topaz mode
|
||||
-3 ISO14443-4 (use RATS)
|
||||
-o do not connect - use this only if you previously used -p to stay connected
|
||||
-r do not read response
|
||||
-c calculate and append CRC
|
||||
-p stay connected - dont inactivate the field
|
||||
-x <payload> Data to send (NO SPACES!)
|
||||
-d Debug flag
|
||||
-t Topaz mode
|
||||
-3 ISO14443-4 (use RATS)
|
||||
|
||||
Examples :
|
||||
Examples :
|
||||
|
||||
# 1. Connect and don't disconnect
|
||||
script run 14araw -p
|
||||
script run 14araw -p
|
||||
# 2. Send mf auth, read response (nonce)
|
||||
script run 14araw -o -x 6000F57b -p
|
||||
# 3. disconnect
|
||||
@@ -33,11 +33,11 @@ script run 14araw -x 6000F57b
|
||||
|
||||
--[[
|
||||
|
||||
This script communicates with
|
||||
/armsrc/iso14443a.c, specifically ReaderIso14443a() at around line 1779 and onwards.
|
||||
This script communicates with
|
||||
/armsrc/iso14443a.c, specifically ReaderIso14443a() at around line 1779 and onwards.
|
||||
|
||||
Check there for details about data format and how commands are interpreted on the
|
||||
device-side.
|
||||
Check there for details about data format and how commands are interpreted on the
|
||||
device-side.
|
||||
]]
|
||||
|
||||
-- Some globals
|
||||
@@ -45,143 +45,143 @@ local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
|
||||
local DEBUG = false -- the debug flag
|
||||
|
||||
-------------------------------
|
||||
-- Some utilities
|
||||
-- Some utilities
|
||||
-------------------------------
|
||||
|
||||
---
|
||||
---
|
||||
-- A debug printout-function
|
||||
local function dbg(args)
|
||||
if DEBUG then
|
||||
print("###", args)
|
||||
end
|
||||
end
|
||||
---
|
||||
if DEBUG then
|
||||
print("###", args)
|
||||
end
|
||||
end
|
||||
---
|
||||
-- This is only meant to be used when errors occur
|
||||
local function oops(err)
|
||||
print("ERROR: ",err)
|
||||
print("ERROR: ",err)
|
||||
end
|
||||
---
|
||||
---
|
||||
-- Usage help
|
||||
local function help()
|
||||
print(desc)
|
||||
print("Example usage")
|
||||
print(example)
|
||||
print(desc)
|
||||
print("Example usage")
|
||||
print(example)
|
||||
end
|
||||
---
|
||||
---
|
||||
-- The main entry point
|
||||
function main(args)
|
||||
|
||||
if args == nil or #args == 0 then return help() end
|
||||
if args == nil or #args == 0 then return help() end
|
||||
|
||||
local ignore_response = false
|
||||
local append_crc = false
|
||||
local stayconnected = false
|
||||
local payload = nil
|
||||
local doconnect = true
|
||||
local topaz_mode = false
|
||||
local no_rats = false
|
||||
|
||||
-- Read the parameters
|
||||
for o, a in getopt.getopt(args, 'orcpx:dt3') do
|
||||
if o == "o" then doconnect = false end
|
||||
if o == "r" then ignore_response = true end
|
||||
if o == "c" then append_crc = true end
|
||||
if o == "p" then stayconnected = true end
|
||||
if o == "x" then payload = a end
|
||||
if o == "d" then DEBUG = true end
|
||||
if o == "t" then topaz_mode = true end
|
||||
if o == "3" then no_rats = true end
|
||||
end
|
||||
local ignore_response = false
|
||||
local append_crc = false
|
||||
local stayconnected = false
|
||||
local payload = nil
|
||||
local doconnect = true
|
||||
local topaz_mode = false
|
||||
local no_rats = false
|
||||
|
||||
-- First of all, connect
|
||||
if doconnect then
|
||||
dbg("doconnect")
|
||||
-- We reuse the connect functionality from a
|
||||
-- common library
|
||||
info, err = lib14a.read(true, no_rats)
|
||||
-- Read the parameters
|
||||
for o, a in getopt.getopt(args, 'orcpx:dt3') do
|
||||
if o == "o" then doconnect = false end
|
||||
if o == "r" then ignore_response = true end
|
||||
if o == "c" then append_crc = true end
|
||||
if o == "p" then stayconnected = true end
|
||||
if o == "x" then payload = a end
|
||||
if o == "d" then DEBUG = true end
|
||||
if o == "t" then topaz_mode = true end
|
||||
if o == "3" then no_rats = true end
|
||||
end
|
||||
|
||||
if err then return oops(err) end
|
||||
print(("Connected to card, uid = %s"):format(info.uid))
|
||||
end
|
||||
-- First of all, connect
|
||||
if doconnect then
|
||||
dbg("doconnect")
|
||||
-- We reuse the connect functionality from a
|
||||
-- common library
|
||||
info, err = lib14a.read(true, no_rats)
|
||||
|
||||
-- The actual raw payload, if any
|
||||
if payload then
|
||||
res,err = sendRaw(payload,{ignore_response = ignore_response, topaz_mode = topaz_mode, append_crc = append_crc})
|
||||
if err then return oops(err) end
|
||||
|
||||
if not ignoreresponse then
|
||||
-- Display the returned data
|
||||
showdata(res)
|
||||
end
|
||||
end
|
||||
-- And, perhaps disconnect?
|
||||
if not stayconnected then
|
||||
disconnect()
|
||||
end
|
||||
if err then return oops(err) end
|
||||
print(("Connected to card, uid = %s"):format(info.uid))
|
||||
end
|
||||
|
||||
-- The actual raw payload, if any
|
||||
if payload then
|
||||
res,err = sendRaw(payload,{ignore_response = ignore_response, topaz_mode = topaz_mode, append_crc = append_crc})
|
||||
if err then return oops(err) end
|
||||
|
||||
if not ignoreresponse then
|
||||
-- Display the returned data
|
||||
showdata(res)
|
||||
end
|
||||
end
|
||||
-- And, perhaps disconnect?
|
||||
if not stayconnected then
|
||||
disconnect()
|
||||
end
|
||||
end
|
||||
|
||||
--- Picks out and displays the data read from a tag
|
||||
-- Specifically, takes a usb packet, converts to a Command
|
||||
-- (as in commands.lua), takes the data-array and
|
||||
-- (as in commands.lua), takes the data-array and
|
||||
-- reads the number of bytes specified in arg1 (arg0 in c-struct)
|
||||
-- and displays the data
|
||||
-- @param usbpacket the data received from the device
|
||||
function showdata(usbpacket)
|
||||
local cmd_response = Command.parse(usbpacket)
|
||||
local len = tonumber(cmd_response.arg1) *2
|
||||
--print("data length:",len)
|
||||
local data = string.sub(tostring(cmd_response.data), 0, len);
|
||||
print("<< ",data)
|
||||
--print("----------------")
|
||||
local cmd_response = Command.parse(usbpacket)
|
||||
local len = tonumber(cmd_response.arg1) *2
|
||||
--print("data length:",len)
|
||||
local data = string.sub(tostring(cmd_response.data), 0, len);
|
||||
print("<< ",data)
|
||||
--print("----------------")
|
||||
end
|
||||
|
||||
function sendRaw(rawdata, options)
|
||||
print(">> ", rawdata)
|
||||
|
||||
local flags = lib14a.ISO14A_COMMAND.ISO14A_NO_DISCONNECT + lib14a.ISO14A_COMMAND.ISO14A_RAW
|
||||
print(">> ", rawdata)
|
||||
|
||||
if options.topaz_mode then
|
||||
flags = flags + lib14a.ISO14A_COMMAND.ISO14A_TOPAZMODE
|
||||
end
|
||||
if options.append_crc then
|
||||
flags = flags + lib14a.ISO14A_COMMAND.ISO14A_APPEND_CRC
|
||||
end
|
||||
|
||||
local command = Command:new{cmd = cmds.CMD_READER_ISO_14443a,
|
||||
arg1 = flags, -- Send raw
|
||||
-- arg2 contains the length, which is half the length
|
||||
-- of the ASCII-string rawdata
|
||||
arg2 = string.len(rawdata)/2,
|
||||
data = rawdata}
|
||||
return lib14a.sendToDevice(command, options.ignore_response)
|
||||
local flags = lib14a.ISO14A_COMMAND.ISO14A_NO_DISCONNECT + lib14a.ISO14A_COMMAND.ISO14A_RAW
|
||||
|
||||
if options.topaz_mode then
|
||||
flags = flags + lib14a.ISO14A_COMMAND.ISO14A_TOPAZMODE
|
||||
end
|
||||
if options.append_crc then
|
||||
flags = flags + lib14a.ISO14A_COMMAND.ISO14A_APPEND_CRC
|
||||
end
|
||||
|
||||
local command = Command:new{cmd = cmds.CMD_READER_ISO_14443a,
|
||||
arg1 = flags, -- Send raw
|
||||
-- arg2 contains the length, which is half the length
|
||||
-- of the ASCII-string rawdata
|
||||
arg2 = string.len(rawdata)/2,
|
||||
data = rawdata}
|
||||
return lib14a.sendToDevice(command, options.ignore_response)
|
||||
end
|
||||
|
||||
-- Sends an instruction to do nothing, only disconnect
|
||||
function disconnect()
|
||||
local command = Command:new{cmd = cmds.CMD_READER_ISO_14443a, arg1 = 0, }
|
||||
-- We can ignore the response here, no ACK is returned for this command
|
||||
-- Check /armsrc/iso14443a.c, ReaderIso14443a() for details
|
||||
return lib14a.sendToDevice(command,true)
|
||||
end
|
||||
local command = Command:new{cmd = cmds.CMD_READER_ISO_14443a, arg1 = 0,}
|
||||
-- We can ignore the response here, no ACK is returned for this command
|
||||
-- Check /armsrc/iso14443a.c, ReaderIso14443a() for details
|
||||
return lib14a.sendToDevice(command,true)
|
||||
end
|
||||
|
||||
-------------------------
|
||||
-- Testing
|
||||
-- Testing
|
||||
-------------------------
|
||||
function selftest()
|
||||
DEBUG = true
|
||||
dbg("Performing test")
|
||||
main()
|
||||
main("-p")
|
||||
main(" -o -x 6000F57b -p")
|
||||
main("-o")
|
||||
main("-x 6000F57b")
|
||||
dbg("Tests done")
|
||||
DEBUG = true
|
||||
dbg("Performing test")
|
||||
main()
|
||||
main("-p")
|
||||
main(" -o -x 6000F57b -p")
|
||||
main("-o")
|
||||
main("-x 6000F57b")
|
||||
dbg("Tests done")
|
||||
end
|
||||
-- Flip the switch here to perform a sanity check.
|
||||
-- Flip the switch here to perform a sanity check.
|
||||
-- It read a nonce in two different ways, as specified in the usage-section
|
||||
if "--test"==args then
|
||||
selftest()
|
||||
else
|
||||
-- Call the main
|
||||
main(args)
|
||||
if "--test"==args then
|
||||
selftest()
|
||||
else
|
||||
-- Call the main
|
||||
main(args)
|
||||
end
|
||||
|
||||
+393
-393
File diff suppressed because it is too large
Load Diff
@@ -88,10 +88,10 @@ local function emulate_amiibo (amiibo_data)
|
||||
local simCmd = Command:new{cmd = cmds.CMD_SIMULATE_TAG_ISO_14443a, arg1 = 7, arg2 = uid_first, arg3 = uid_second}
|
||||
local _, err = reader.sendToDevice(simCmd)
|
||||
if err then
|
||||
print('Failed to start simulator', err)
|
||||
return
|
||||
print('Failed to start simulator', err)
|
||||
return
|
||||
else
|
||||
print('Starting simulator')
|
||||
print('Starting simulator')
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
+207
-207
@@ -21,7 +21,7 @@ desc = [[
|
||||
|
||||
This script uses the proxmark3 implementations of simulation to bruteforce given ranges of id.
|
||||
It uses both LF and HF simulations.
|
||||
|
||||
|
||||
-- Author note
|
||||
-- I wrote this as i was doing a PACS audit. This is far from complete, but is easily expandable.
|
||||
-- The idea was based on proxbrute, but i needed more options, and support for different readers.
|
||||
@@ -38,8 +38,8 @@ usage = [[
|
||||
script run brutesim -r rfid_tag -f facility_code -b base_card_number -c count -t timeout -d direction
|
||||
|
||||
Arguments:
|
||||
-h this help
|
||||
-r *see below RFID Tag: the RFID tag to emulate
|
||||
-h this help
|
||||
-r *see below RFID Tag: the RFID tag to emulate
|
||||
pyramid
|
||||
awid
|
||||
fdx
|
||||
@@ -50,251 +50,251 @@ Arguments:
|
||||
14a
|
||||
hid
|
||||
|
||||
-f 0-999 facility code (dfx: country id, 14a: type)
|
||||
-b 0-65535 base card number to start from
|
||||
-c 1-65536 number of cards to try
|
||||
-t .0-99999, pause timeout between cards (use the word 'pause' to wait for user input)
|
||||
-d up, down direction to move through card numbers
|
||||
-f 0-999 facility code (dfx: country id, 14a: type)
|
||||
-b 0-65535 base card number to start from
|
||||
-c 1-65536 number of cards to try
|
||||
-t .0-99999, pause timeout between cards (use the word 'pause' to wait for user input)
|
||||
-d up, down direction to move through card numbers
|
||||
]]
|
||||
|
||||
local DEBUG = true
|
||||
local bor = bit32.bor
|
||||
local bxor = bit32.bxor
|
||||
local bor = bit32.bor
|
||||
local bxor = bit32.bxor
|
||||
local lshift = bit32.lshift
|
||||
---
|
||||
---
|
||||
-- A debug printout-function
|
||||
local function dbg(args)
|
||||
if type(args) == "table" then
|
||||
local i = 1
|
||||
while args[i] do
|
||||
dbg(args[i])
|
||||
i = i+1
|
||||
end
|
||||
else
|
||||
print("###", args)
|
||||
end
|
||||
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)
|
||||
return nil,err
|
||||
print("ERROR: ",err)
|
||||
return nil,err
|
||||
end
|
||||
---
|
||||
---
|
||||
-- Usage help
|
||||
local function help()
|
||||
print(copyright)
|
||||
print(author)
|
||||
print(version)
|
||||
print(desc)
|
||||
print("Example usage")
|
||||
print(example)
|
||||
print(copyright)
|
||||
print(author)
|
||||
print(version)
|
||||
print(desc)
|
||||
print("Example usage")
|
||||
print(example)
|
||||
end
|
||||
--
|
||||
-- Exit message
|
||||
function exitMsg(msg)
|
||||
print( string.rep('--',20) )
|
||||
print( string.rep('--',20) )
|
||||
print(msg)
|
||||
print()
|
||||
print( string.rep('--',20) )
|
||||
print( string.rep('--',20) )
|
||||
print(msg)
|
||||
print()
|
||||
end
|
||||
--
|
||||
-- Check if a string is empty
|
||||
local function isempty(s)
|
||||
return s == nil or s == ''
|
||||
return s == nil or s == ''
|
||||
end
|
||||
|
||||
-- The code below was blatantly stolen from Brian Redbeard's lf_bulk_program.lua script
|
||||
-- The code below was blatantly stolen from Brian Redbeard's lf_bulk_program.lua script
|
||||
local function toBits(num, bits)
|
||||
bits = bits or math.max(1, select(2, math.frexp(num)))
|
||||
local t = {}
|
||||
for b = bits, 1, -1 do
|
||||
t[b] = math.fmod(num, 2)
|
||||
num = math.floor((num - t[b]) / 2)
|
||||
end
|
||||
return table.concat(t)
|
||||
bits = bits or math.max(1, select(2, math.frexp(num)))
|
||||
local t = {}
|
||||
for b = bits, 1, -1 do
|
||||
t[b] = math.fmod(num, 2)
|
||||
num = math.floor((num - t[b]) / 2)
|
||||
end
|
||||
return table.concat(t)
|
||||
end
|
||||
--
|
||||
-- check for parity in bit-string.
|
||||
-- check for parity in bit-string.
|
||||
local function evenparity(s)
|
||||
local _, count = string.gsub(s, "1", "")
|
||||
local p = count % 2
|
||||
if (p == 0) then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
local _, count = string.gsub(s, "1", "")
|
||||
local p = count % 2
|
||||
if (p == 0) then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
--
|
||||
-- calcs hex for HID
|
||||
-- calcs hex for HID
|
||||
local function cardHex(i, f)
|
||||
fac = lshift(f, 16)
|
||||
id = bor(i, fac)
|
||||
stream = toBits(id, 26)
|
||||
high = evenparity(string.sub(stream, 0, 12)) and 1 or 0
|
||||
low = not evenparity(string.sub(stream, 13)) and 1 or 0
|
||||
bits = bor(lshift(id, 1), low)
|
||||
bits = bor(bits, lshift(high, 25))
|
||||
preamble = bor(0, lshift(1, 5))
|
||||
bits = bor(bits, lshift(1, 26))
|
||||
return ("%04x%08x"):format(preamble, bits)
|
||||
fac = lshift(f, 16)
|
||||
id = bor(i, fac)
|
||||
stream = toBits(id, 26)
|
||||
high = evenparity(string.sub(stream, 0, 12)) and 1 or 0
|
||||
low = not evenparity(string.sub(stream, 13)) and 1 or 0
|
||||
bits = bor(lshift(id, 1), low)
|
||||
bits = bor(bits, lshift(high, 25))
|
||||
preamble = bor(0, lshift(1, 5))
|
||||
bits = bor(bits, lshift(1, 26))
|
||||
return ("%04x%08x"):format(preamble, bits)
|
||||
end
|
||||
--
|
||||
--
|
||||
local function main(args)
|
||||
|
||||
print( string.rep('--',20) )
|
||||
print( string.rep('--',20) )
|
||||
print()
|
||||
|
||||
if #args == 0 then return help() end
|
||||
print( string.rep('--',20) )
|
||||
print( string.rep('--',20) )
|
||||
print()
|
||||
|
||||
for o, a in getopt.getopt(args, 'r:f:b:c:t:d:h') do -- Populate command like arguments
|
||||
if o == 'r' then rfidtag = a end
|
||||
if o == 'f' then facility = a end
|
||||
if o == 'b' then baseid = a end
|
||||
if o == 'c' then count = a end
|
||||
if o == 't' then timeout = a end
|
||||
if o == 'd' then direction = a end
|
||||
if o == 'h' then return print(usage) end
|
||||
end
|
||||
if #args == 0 then return help() end
|
||||
|
||||
-- Check to see if -r argument was passed
|
||||
if isempty(rfidtag) then
|
||||
print("You must supply the flag -r (rfid tag)")
|
||||
print(usage)
|
||||
return
|
||||
end
|
||||
for o, a in getopt.getopt(args, 'r:f:b:c:t:d:h') do -- Populate command like arguments
|
||||
if o == 'r' then rfidtag = a end
|
||||
if o == 'f' then facility = a end
|
||||
if o == 'b' then baseid = a end
|
||||
if o == 'c' then count = a end
|
||||
if o == 't' then timeout = a end
|
||||
if o == 'd' then direction = a end
|
||||
if o == 'h' then return print(usage) end
|
||||
end
|
||||
|
||||
-- Check what RFID Tag we are using
|
||||
if rfidtag == 'pyramid' then
|
||||
consolecommand = 'lf pyramid sim' -- set the console command
|
||||
rfidtagname = 'Farpointe/Pyramid' -- set the display name
|
||||
facilityrequired = 1 -- set if FC is required
|
||||
elseif rfidtag == 'awid' then
|
||||
consolecommand = 'lf awid sim'
|
||||
rfidtagname = 'AWID'
|
||||
facilityrequired = 1
|
||||
elseif rfidtag == 'fdx' then -- I'm not sure why you would need to bruteforce this ¯\_(ツ)_/¯
|
||||
consolecommand = 'lf fdx sim'
|
||||
rfidtagname = 'FDX-B'
|
||||
facilityrequired = 1
|
||||
elseif rfidtag == 'jablotron' then
|
||||
consolecommand = 'lf jablotron sim'
|
||||
rfidtagname = 'Jablotron'
|
||||
facilityrequired = 0
|
||||
elseif rfidtag == 'noralsy' then
|
||||
consolecommand = 'lf noralsy sim'
|
||||
rfidtagname = 'Noralsy'
|
||||
facilityrequired = 0
|
||||
elseif rfidtag == 'presco' then
|
||||
consolecommand = 'lf presco sim d'
|
||||
rfidtagname = 'Presco'
|
||||
facilityrequired = 0
|
||||
elseif rfidtag == 'visa2000' then
|
||||
consolecommand = 'lf visa2000 sim'
|
||||
rfidtagname = 'Visa2000'
|
||||
facilityrequired = 0
|
||||
elseif rfidtag == '14a' then
|
||||
consolecommand = 'hf 14a sim'
|
||||
if facility == "1" then rfidtagname = 'MIFARE Classic' -- Here we use the -f option to read the 14a type instead of the facility code
|
||||
elseif facility == "2" then rfidtagname = 'MIFARE Ultralight'
|
||||
elseif facility == "3" then rfidtagname = 'MIFARE Desfire'
|
||||
elseif facility == "4" then rfidtagname = 'ISO/IEC 14443-4'
|
||||
elseif facility == "5" then rfidtagname = 'MIFARE Tnp3xxx'
|
||||
else
|
||||
print("Invalid 14a type (-f) supplied. Must be 1-5")
|
||||
print(usage)
|
||||
return
|
||||
end
|
||||
facilityrequired = 0 -- Disable the FC required check, as we used it for type instead of FC
|
||||
elseif rfidtag == 'hid' then
|
||||
consolecommand = 'lf hid sim'
|
||||
rfidtagname = 'HID'
|
||||
facilityrequired = 1
|
||||
else -- Display error and exit out if bad RFID tag was supplied
|
||||
print("Invalid rfid tag (-r) supplied")
|
||||
print(usage)
|
||||
return
|
||||
end
|
||||
|
||||
if isempty(baseid) then -- Display error and exit out if no starting id is set
|
||||
print("You must supply the flag -b (base id)")
|
||||
print(usage)
|
||||
return
|
||||
end
|
||||
-- Check to see if -r argument was passed
|
||||
if isempty(rfidtag) then
|
||||
print("You must supply the flag -r (rfid tag)")
|
||||
print(usage)
|
||||
return
|
||||
end
|
||||
|
||||
if isempty(count) then -- Display error and exit out of no count is set
|
||||
print("You must supply the flag -c (count)")
|
||||
print(usage)
|
||||
return
|
||||
end
|
||||
|
||||
if facilityrequired == 1 then -- If FC is required
|
||||
facilitymessage = " - Facility Code: " -- Add FC to status message
|
||||
if isempty(facility) then -- If FC was left blank, display warning and set FC to 0
|
||||
print("Using 0 for the facility code as -f was not supplied")
|
||||
facility = 0
|
||||
end
|
||||
else -- If FC is not required
|
||||
facility = "" -- Clear FC
|
||||
facilitymessage = "" -- Remove FC from status message
|
||||
end
|
||||
|
||||
if isempty(timeout) then -- If timeout was not supplied, show warning and set timeout to 0
|
||||
print("Using 0 for the timeout as -t was not supplied")
|
||||
timeout = 0
|
||||
end
|
||||
|
||||
if isempty(direction) then -- If direction was not supplied, show warning and set direction to down
|
||||
print("Using down for direction as -d was not supplied")
|
||||
direction = 'down'
|
||||
end
|
||||
|
||||
if tonumber(count) < 1 then
|
||||
print("Count -c must be set to 1 or higher")
|
||||
return
|
||||
else
|
||||
count = count -1 -- Make our count accurate by removing 1, because math
|
||||
end
|
||||
|
||||
if direction == 'down' then -- If counting down, set up our for loop to count down
|
||||
endid = baseid - count
|
||||
fordirection = -1
|
||||
elseif direction == 'up' then -- If counting up, set our for loop to count up
|
||||
endid = baseid + count
|
||||
fordirection = 1
|
||||
else -- If invalid direction was set, show warning and set up our for loop to count down
|
||||
print("Invalid direction (-d) supplied, using down")
|
||||
endid = baseid - count
|
||||
fordirection = -1
|
||||
end
|
||||
|
||||
-- Check what RFID Tag we are using
|
||||
if rfidtag == 'pyramid' then
|
||||
consolecommand = 'lf pyramid sim' -- set the console command
|
||||
rfidtagname = 'Farpointe/Pyramid' -- set the display name
|
||||
facilityrequired = 1 -- set if FC is required
|
||||
elseif rfidtag == 'awid' then
|
||||
consolecommand = 'lf awid sim'
|
||||
rfidtagname = 'AWID'
|
||||
facilityrequired = 1
|
||||
elseif rfidtag == 'fdx' then -- I'm not sure why you would need to bruteforce this ¯\_(ツ)_/¯
|
||||
consolecommand = 'lf fdx sim'
|
||||
rfidtagname = 'FDX-B'
|
||||
facilityrequired = 1
|
||||
elseif rfidtag == 'jablotron' then
|
||||
consolecommand = 'lf jablotron sim'
|
||||
rfidtagname = 'Jablotron'
|
||||
facilityrequired = 0
|
||||
elseif rfidtag == 'noralsy' then
|
||||
consolecommand = 'lf noralsy sim'
|
||||
rfidtagname = 'Noralsy'
|
||||
facilityrequired = 0
|
||||
elseif rfidtag == 'presco' then
|
||||
consolecommand = 'lf presco sim d'
|
||||
rfidtagname = 'Presco'
|
||||
facilityrequired = 0
|
||||
elseif rfidtag == 'visa2000' then
|
||||
consolecommand = 'lf visa2000 sim'
|
||||
rfidtagname = 'Visa2000'
|
||||
facilityrequired = 0
|
||||
elseif rfidtag == '14a' then
|
||||
consolecommand = 'hf 14a sim'
|
||||
if facility == "1" then rfidtagname = 'MIFARE Classic' -- Here we use the -f option to read the 14a type instead of the facility code
|
||||
elseif facility == "2" then rfidtagname = 'MIFARE Ultralight'
|
||||
elseif facility == "3" then rfidtagname = 'MIFARE Desfire'
|
||||
elseif facility == "4" then rfidtagname = 'ISO/IEC 14443-4'
|
||||
elseif facility == "5" then rfidtagname = 'MIFARE Tnp3xxx'
|
||||
else
|
||||
print("Invalid 14a type (-f) supplied. Must be 1-5")
|
||||
print(usage)
|
||||
return
|
||||
end
|
||||
facilityrequired = 0 -- Disable the FC required check, as we used it for type instead of FC
|
||||
elseif rfidtag == 'hid' then
|
||||
consolecommand = 'lf hid sim'
|
||||
rfidtagname = 'HID'
|
||||
facilityrequired = 1
|
||||
else -- Display error and exit out if bad RFID tag was supplied
|
||||
print("Invalid rfid tag (-r) supplied")
|
||||
print(usage)
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
-- display status message
|
||||
print("")
|
||||
print("BruteForcing "..rfidtagname..""..facilitymessage..""..facility.." - CardNumber Start: "..baseid.." - CardNumber End: "..endid.." - TimeOut: "..timeout)
|
||||
print("")
|
||||
|
||||
-- loop through for each count (-c)
|
||||
for cardnum = baseid, endid, fordirection do
|
||||
|
||||
-- If rfid tag is set to HID, convert card to HEX using the stolen code above
|
||||
if rfidtag == 'hid' then cardnum = cardHex(cardnum, facility) end
|
||||
|
||||
-- send command to proxmark
|
||||
core.console(consolecommand..' '..facility..' '..cardnum)
|
||||
if isempty(baseid) then -- Display error and exit out if no starting id is set
|
||||
print("You must supply the flag -b (base id)")
|
||||
print(usage)
|
||||
return
|
||||
end
|
||||
|
||||
if timeout == 'pause' then
|
||||
print("Press enter to continue ...")
|
||||
io.read()
|
||||
else
|
||||
os.execute("sleep "..timeout.."")
|
||||
end
|
||||
end
|
||||
|
||||
-- ping the proxmark to stop emulation and see if its still responding
|
||||
core.console('hw ping')
|
||||
if isempty(count) then -- Display error and exit out of no count is set
|
||||
print("You must supply the flag -c (count)")
|
||||
print(usage)
|
||||
return
|
||||
end
|
||||
|
||||
if facilityrequired == 1 then -- If FC is required
|
||||
facilitymessage = " - Facility Code: " -- Add FC to status message
|
||||
if isempty(facility) then -- If FC was left blank, display warning and set FC to 0
|
||||
print("Using 0 for the facility code as -f was not supplied")
|
||||
facility = 0
|
||||
end
|
||||
else -- If FC is not required
|
||||
facility = "" -- Clear FC
|
||||
facilitymessage = "" -- Remove FC from status message
|
||||
end
|
||||
|
||||
if isempty(timeout) then -- If timeout was not supplied, show warning and set timeout to 0
|
||||
print("Using 0 for the timeout as -t was not supplied")
|
||||
timeout = 0
|
||||
end
|
||||
|
||||
if isempty(direction) then -- If direction was not supplied, show warning and set direction to down
|
||||
print("Using down for direction as -d was not supplied")
|
||||
direction = 'down'
|
||||
end
|
||||
|
||||
if tonumber(count) < 1 then
|
||||
print("Count -c must be set to 1 or higher")
|
||||
return
|
||||
else
|
||||
count = count -1 -- Make our count accurate by removing 1, because math
|
||||
end
|
||||
|
||||
if direction == 'down' then -- If counting down, set up our for loop to count down
|
||||
endid = baseid - count
|
||||
fordirection = -1
|
||||
elseif direction == 'up' then -- If counting up, set our for loop to count up
|
||||
endid = baseid + count
|
||||
fordirection = 1
|
||||
else -- If invalid direction was set, show warning and set up our for loop to count down
|
||||
print("Invalid direction (-d) supplied, using down")
|
||||
endid = baseid - count
|
||||
fordirection = -1
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- display status message
|
||||
print("")
|
||||
print("BruteForcing "..rfidtagname..""..facilitymessage..""..facility.." - CardNumber Start: "..baseid.." - CardNumber End: "..endid.." - TimeOut: "..timeout)
|
||||
print("")
|
||||
|
||||
-- loop through for each count (-c)
|
||||
for cardnum = baseid, endid, fordirection do
|
||||
|
||||
-- If rfid tag is set to HID, convert card to HEX using the stolen code above
|
||||
if rfidtag == 'hid' then cardnum = cardHex(cardnum, facility) end
|
||||
|
||||
-- send command to proxmark
|
||||
core.console(consolecommand..' '..facility..' '..cardnum)
|
||||
|
||||
if timeout == 'pause' then
|
||||
print("Press enter to continue ...")
|
||||
io.read()
|
||||
else
|
||||
os.execute("sleep "..timeout.."")
|
||||
end
|
||||
end
|
||||
|
||||
-- ping the proxmark to stop emulation and see if its still responding
|
||||
core.console('hw ping')
|
||||
end
|
||||
|
||||
main(args)
|
||||
+112
-112
@@ -7,170 +7,170 @@ copyright = ''
|
||||
author = "Iceman"
|
||||
version = 'v1.0.0'
|
||||
desc = [[
|
||||
This script calculates mifare keys based on uid diversification for DI.
|
||||
This script calculates mifare keys based on uid diversification for DI.
|
||||
Algo not found by me.
|
||||
]]
|
||||
example = [[
|
||||
-- if called without, it reads tag uid
|
||||
script run calc_di
|
||||
|
||||
--
|
||||
script run calc_di -u 11223344556677
|
||||
-- if called without, it reads tag uid
|
||||
script run calc_di
|
||||
|
||||
--
|
||||
script run calc_di -u 11223344556677
|
||||
]]
|
||||
usage = [[
|
||||
script run calc_di -h -u <uid>
|
||||
|
||||
Arguments:
|
||||
-h : this help
|
||||
-u <UID> : UID
|
||||
-h : this help
|
||||
-u <UID> : UID
|
||||
]]
|
||||
|
||||
local DEBUG = true
|
||||
local BAR = '286329204469736E65792032303133'
|
||||
local MIS = '0A14FD0507FF4BCD026BA83F0A3B89A9'
|
||||
local bxor = bit32.bxor
|
||||
---
|
||||
---
|
||||
-- A debug printout-function
|
||||
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
|
||||
---
|
||||
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)
|
||||
return nil,err
|
||||
print("ERROR: ",err)
|
||||
return nil,err
|
||||
end
|
||||
---
|
||||
---
|
||||
-- Usage help
|
||||
local function help()
|
||||
print(copyright)
|
||||
print(author)
|
||||
print(version)
|
||||
print(desc)
|
||||
print('Example usage')
|
||||
print(example)
|
||||
print(copyright)
|
||||
print(author)
|
||||
print(version)
|
||||
print(desc)
|
||||
print('Example usage')
|
||||
print(example)
|
||||
end
|
||||
---
|
||||
-- Exit message
|
||||
local function exitMsg(msg)
|
||||
print( string.rep('--',20) )
|
||||
print( string.rep('--',20) )
|
||||
print(msg)
|
||||
print()
|
||||
print( string.rep('--',20) )
|
||||
print( string.rep('--',20) )
|
||||
print(msg)
|
||||
print()
|
||||
end
|
||||
---
|
||||
-- dumps all keys to file
|
||||
local function dumptofile(keys)
|
||||
dbg('dumping keys to file')
|
||||
dbg('dumping keys to file')
|
||||
|
||||
if utils.confirm('Do you wish to save the keys to dumpfile?') then
|
||||
local destination = utils.input('Select a filename to store to', 'dumpkeys.bin')
|
||||
local file = io.open(destination, 'wb')
|
||||
if file == nil then
|
||||
print('Could not write to file ', destination)
|
||||
return
|
||||
end
|
||||
if utils.confirm('Do you wish to save the keys to dumpfile?') then
|
||||
local destination = utils.input('Select a filename to store to', 'dumpkeys.bin')
|
||||
local file = io.open(destination, 'wb')
|
||||
if file == nil then
|
||||
print('Could not write to file ', destination)
|
||||
return
|
||||
end
|
||||
|
||||
-- Mifare Mini has 5 sectors,
|
||||
local key_a = ''
|
||||
local key_b = ''
|
||||
|
||||
for sector = 0, #keys do
|
||||
local keyA, keyB = unpack(keys[sector])
|
||||
key_a = key_a .. bin.pack('H', keyA);
|
||||
key_b = key_b .. bin.pack('H', keyB);
|
||||
end
|
||||
file:write(key_a)
|
||||
file:write(key_b)
|
||||
file:close()
|
||||
end
|
||||
-- Mifare Mini has 5 sectors,
|
||||
local key_a = ''
|
||||
local key_b = ''
|
||||
|
||||
for sector = 0, #keys do
|
||||
local keyA, keyB = unpack(keys[sector])
|
||||
key_a = key_a .. bin.pack('H', keyA);
|
||||
key_b = key_b .. bin.pack('H', keyB);
|
||||
end
|
||||
file:write(key_a)
|
||||
file:write(key_b)
|
||||
file:close()
|
||||
end
|
||||
end
|
||||
---
|
||||
-- create key
|
||||
local function keygen(uid)
|
||||
local data = MIS..uid..BAR
|
||||
local hash = utils.ConvertAsciiToBytes(utils.Sha1Hex(data))
|
||||
return string.format("%02X%02X%02X%02X%02X%02X",
|
||||
hash[3+1],
|
||||
hash[2+1],
|
||||
hash[1+1],
|
||||
hash[0+1],
|
||||
hash[7+1],
|
||||
hash[6+1]
|
||||
)
|
||||
local data = MIS..uid..BAR
|
||||
local hash = utils.ConvertAsciiToBytes(utils.Sha1Hex(data))
|
||||
return string.format("%02X%02X%02X%02X%02X%02X",
|
||||
hash[3+1],
|
||||
hash[2+1],
|
||||
hash[1+1],
|
||||
hash[0+1],
|
||||
hash[7+1],
|
||||
hash[6+1]
|
||||
)
|
||||
end
|
||||
---
|
||||
-- print keys
|
||||
local function printKeys(keys)
|
||||
print('|---|----------------|---|----------------|---|')
|
||||
print('|sec|key A |res|key B |res|')
|
||||
print('|---|----------------|---|----------------|---|')
|
||||
for sector = 0, #keys do
|
||||
local keyA, keyB = unpack(keys[sector])
|
||||
print(('|%03d| %s | %s | %s | %s |'):format(sector, keyA, 1, keyB, 1))
|
||||
end
|
||||
print('|---|----------------|---|----------------|---|')
|
||||
print('|---|----------------|---|----------------|---|')
|
||||
print('|sec|key A |res|key B |res|')
|
||||
print('|---|----------------|---|----------------|---|')
|
||||
for sector = 0, #keys do
|
||||
local keyA, keyB = unpack(keys[sector])
|
||||
print(('|%03d| %s | %s | %s | %s |'):format(sector, keyA, 1, keyB, 1))
|
||||
end
|
||||
print('|---|----------------|---|----------------|---|')
|
||||
end
|
||||
---
|
||||
-- createfull set of keys
|
||||
local function createKeys(uid)
|
||||
local key = keygen(uid)
|
||||
local k = {}
|
||||
for i = 0,4 do
|
||||
k[i] = { key, key }
|
||||
end
|
||||
return k
|
||||
local key = keygen(uid)
|
||||
local k = {}
|
||||
for i = 0,4 do
|
||||
k[i] = { key, key }
|
||||
end
|
||||
return k
|
||||
end
|
||||
---
|
||||
-- main
|
||||
local function main(args)
|
||||
|
||||
print( string.rep('==', 30) )
|
||||
print()
|
||||
|
||||
local uid
|
||||
local useUID = false
|
||||
|
||||
-- Arguments for the script
|
||||
for o, a in getopt.getopt(args, 'hu:') do
|
||||
if o == "h" then return help() end
|
||||
if o == "u" then uid = a; useUID = true end
|
||||
end
|
||||
print( string.rep('==', 30) )
|
||||
print()
|
||||
|
||||
if useUID then
|
||||
-- uid string checks if supplied
|
||||
if uid == nil then return oops('empty uid string') end
|
||||
if #uid == 0 then return oops('empty uid string') end
|
||||
if #uid ~= 14 then return oops('uid wrong length. Should be 7 hex bytes') end
|
||||
else
|
||||
-- GET TAG UID
|
||||
local tag, err = lib14a.read(false, true)
|
||||
if not tag then return oops(err) end
|
||||
core.clearCommandBuffer()
|
||||
local uid
|
||||
local useUID = false
|
||||
|
||||
-- simple tag check
|
||||
if 0x09 ~= tag.sak then
|
||||
if 0x4400 ~= tag.atqa then
|
||||
return oops(('[fail] found tag %s :: looking for Mifare Mini 0.3k'):format(tag.name))
|
||||
end
|
||||
end
|
||||
uid = tag.uid
|
||||
end
|
||||
|
||||
print('|UID|', uid)
|
||||
|
||||
local keys, err = createKeys( uid )
|
||||
printKeys( keys )
|
||||
dumptofile( keys )
|
||||
-- Arguments for the script
|
||||
for o, a in getopt.getopt(args, 'hu:') do
|
||||
if o == "h" then return help() end
|
||||
if o == "u" then uid = a; useUID = true end
|
||||
end
|
||||
|
||||
if useUID then
|
||||
-- uid string checks if supplied
|
||||
if uid == nil then return oops('empty uid string') end
|
||||
if #uid == 0 then return oops('empty uid string') end
|
||||
if #uid ~= 14 then return oops('uid wrong length. Should be 7 hex bytes') end
|
||||
else
|
||||
-- GET TAG UID
|
||||
local tag, err = lib14a.read(false, true)
|
||||
if not tag then return oops(err) end
|
||||
core.clearCommandBuffer()
|
||||
|
||||
-- simple tag check
|
||||
if 0x09 ~= tag.sak then
|
||||
if 0x4400 ~= tag.atqa then
|
||||
return oops(('[fail] found tag %s :: looking for Mifare Mini 0.3k'):format(tag.name))
|
||||
end
|
||||
end
|
||||
uid = tag.uid
|
||||
end
|
||||
|
||||
print('|UID|', uid)
|
||||
|
||||
local keys, err = createKeys( uid )
|
||||
printKeys( keys )
|
||||
dumptofile( keys )
|
||||
end
|
||||
|
||||
main(args)
|
||||
+116
-116
@@ -12,167 +12,167 @@ Algo not found by me.
|
||||
]]
|
||||
example =[[
|
||||
-- if called without, it reads tag uid
|
||||
script run calc_ev1_it
|
||||
|
||||
--
|
||||
script run calc_ev1_it -u 11223344556677
|
||||
script run calc_ev1_it
|
||||
|
||||
--
|
||||
script run calc_ev1_it -u 11223344556677
|
||||
]]
|
||||
usage = [[
|
||||
script run calc_ev1_it -h -u <uid> "
|
||||
|
||||
Arguments:
|
||||
-h : this help
|
||||
-u <UID> : UID
|
||||
-h : this help
|
||||
-u <UID> : UID
|
||||
]]
|
||||
|
||||
local DEBUG = true
|
||||
local bxor = bit32.bxor
|
||||
---
|
||||
---
|
||||
-- A debug printout-function
|
||||
local function dbg(args)
|
||||
if not DEBUG then return end
|
||||
|
||||
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
|
||||
---
|
||||
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)
|
||||
return nil,err
|
||||
print("ERROR: ",err)
|
||||
return nil,err
|
||||
end
|
||||
---
|
||||
---
|
||||
-- Usage help
|
||||
local function help()
|
||||
print(copyright)
|
||||
print(author)
|
||||
print(version)
|
||||
print(desc)
|
||||
print("Example usage")
|
||||
print(example)
|
||||
print(copyright)
|
||||
print(author)
|
||||
print(version)
|
||||
print(desc)
|
||||
print("Example usage")
|
||||
print(example)
|
||||
end
|
||||
--
|
||||
-- Exit message
|
||||
function exitMsg(msg)
|
||||
print( string.rep('--',20) )
|
||||
print( string.rep('--',20) )
|
||||
print(msg)
|
||||
print()
|
||||
print( string.rep('--',20) )
|
||||
print( string.rep('--',20) )
|
||||
print(msg)
|
||||
print()
|
||||
end
|
||||
|
||||
local _xortable = {
|
||||
--[[ position, 4byte xor
|
||||
--]]
|
||||
{"00","4f2711c1"},
|
||||
{"01","07D7BB83"},
|
||||
{"02","9636EF07"},
|
||||
{"03","B5F4460E"},
|
||||
{"04","F271141C"},
|
||||
{"05","7D7BB038"},
|
||||
{"06","636EF871"},
|
||||
{"07","5F4468E3"},
|
||||
{"08","271149C7"},
|
||||
{"09","D7BB0B8F"},
|
||||
{"0A","36EF8F1E"},
|
||||
{"0B","F446863D"},
|
||||
{"0C","7114947A"},
|
||||
{"0D","7BB0B0F5"},
|
||||
{"0E","6EF8F9EB"},
|
||||
{"0F","44686BD7"},
|
||||
{"10","11494fAF"},
|
||||
{"11","BB0B075F"},
|
||||
{"12","EF8F96BE"},
|
||||
{"13","4686B57C"},
|
||||
{"14","1494F2F9"},
|
||||
{"15","B0B07DF3"},
|
||||
{"16","F8F963E6"},
|
||||
{"17","686B5FCC"},
|
||||
{"18","494F2799"},
|
||||
{"19","0B07D733"},
|
||||
{"1A","8F963667"},
|
||||
{"1B","86B5F4CE"},
|
||||
{"1C","94F2719C"},
|
||||
{"1D","B07D7B38"},
|
||||
{"1E","F9636E70"},
|
||||
{"1F","6B5F44E0"},
|
||||
{"00","4f2711c1"},
|
||||
{"01","07D7BB83"},
|
||||
{"02","9636EF07"},
|
||||
{"03","B5F4460E"},
|
||||
{"04","F271141C"},
|
||||
{"05","7D7BB038"},
|
||||
{"06","636EF871"},
|
||||
{"07","5F4468E3"},
|
||||
{"08","271149C7"},
|
||||
{"09","D7BB0B8F"},
|
||||
{"0A","36EF8F1E"},
|
||||
{"0B","F446863D"},
|
||||
{"0C","7114947A"},
|
||||
{"0D","7BB0B0F5"},
|
||||
{"0E","6EF8F9EB"},
|
||||
{"0F","44686BD7"},
|
||||
{"10","11494fAF"},
|
||||
{"11","BB0B075F"},
|
||||
{"12","EF8F96BE"},
|
||||
{"13","4686B57C"},
|
||||
{"14","1494F2F9"},
|
||||
{"15","B0B07DF3"},
|
||||
{"16","F8F963E6"},
|
||||
{"17","686B5FCC"},
|
||||
{"18","494F2799"},
|
||||
{"19","0B07D733"},
|
||||
{"1A","8F963667"},
|
||||
{"1B","86B5F4CE"},
|
||||
{"1C","94F2719C"},
|
||||
{"1D","B07D7B38"},
|
||||
{"1E","F9636E70"},
|
||||
{"1F","6B5F44E0"},
|
||||
}
|
||||
|
||||
local function findEntryByUid( uid )
|
||||
|
||||
-- xor UID4,UID5,UID6,UID7
|
||||
-- mod 0x20 (dec 32)
|
||||
local pos = (bxor(uid[4], uid[5], uid[6], uid[7])) % 32
|
||||
-- xor UID4,UID5,UID6,UID7
|
||||
-- mod 0x20 (dec 32)
|
||||
local pos = (bxor(uid[4], uid[5], uid[6], uid[7])) % 32
|
||||
|
||||
-- convert to hexstring
|
||||
pos = string.format('%02X', pos)
|
||||
|
||||
-- convert to hexstring
|
||||
pos = string.format('%02X', pos)
|
||||
|
||||
for k, v in pairs(_xortable) do
|
||||
if ( v[1] == pos ) then
|
||||
return utils.ConvertHexToBytes(v[2])
|
||||
end
|
||||
end
|
||||
return nil
|
||||
if ( v[1] == pos ) then
|
||||
return utils.ConvertHexToBytes(v[2])
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
---
|
||||
-- create pwd
|
||||
local function pwdgen(uid)
|
||||
-- PWD CALC
|
||||
-- PWD0 = T0 xor B xor C xor D
|
||||
-- PWD1 = T1 xor A xor C xor E
|
||||
-- PWD2 = T2 xor A xor B xor F
|
||||
-- PWD3 = T3 xor G
|
||||
local uidbytes = utils.ConvertHexToBytes(uid)
|
||||
-- PWD CALC
|
||||
-- PWD0 = T0 xor B xor C xor D
|
||||
-- PWD1 = T1 xor A xor C xor E
|
||||
-- PWD2 = T2 xor A xor B xor F
|
||||
-- PWD3 = T3 xor G
|
||||
local uidbytes = utils.ConvertHexToBytes(uid)
|
||||
local entry = findEntryByUid(uidbytes)
|
||||
if entry == nil then return nil, "Can't find a xor entry" end
|
||||
if entry == nil then return nil, "Can't find a xor entry" end
|
||||
|
||||
local pwd0 = bxor( entry[1], uidbytes[2], uidbytes[3], uidbytes[4])
|
||||
local pwd1 = bxor( entry[2], uidbytes[1], uidbytes[3], uidbytes[5])
|
||||
local pwd2 = bxor( entry[3], uidbytes[1], uidbytes[2], uidbytes[6])
|
||||
local pwd3 = bxor( entry[4], uidbytes[7])
|
||||
return string.format('%02X%02X%02X%02X', pwd0, pwd1, pwd2, pwd3)
|
||||
local pwd1 = bxor( entry[2], uidbytes[1], uidbytes[3], uidbytes[5])
|
||||
local pwd2 = bxor( entry[3], uidbytes[1], uidbytes[2], uidbytes[6])
|
||||
local pwd3 = bxor( entry[4], uidbytes[7])
|
||||
return string.format('%02X%02X%02X%02X', pwd0, pwd1, pwd2, pwd3)
|
||||
end
|
||||
--
|
||||
-- main
|
||||
local function main(args)
|
||||
|
||||
print( string.rep('--',20) )
|
||||
print( string.rep('--',20) )
|
||||
print()
|
||||
|
||||
local uid = '04111211121110'
|
||||
local useUID = false
|
||||
|
||||
-- Arguments for the script
|
||||
for o, a in getopt.getopt(args, 'hu:') do
|
||||
if o == "h" then return help() end
|
||||
if o == "u" then uid = a; useUID = true end
|
||||
end
|
||||
print( string.rep('--',20) )
|
||||
print( string.rep('--',20) )
|
||||
print()
|
||||
|
||||
if useUID then
|
||||
-- uid string checks
|
||||
if uid == nil then return oops('empty uid string') end
|
||||
if #uid == 0 then return oops('empty uid string') end
|
||||
if #uid ~= 14 then return oops('uid wrong length. Should be 7 hex bytes') end
|
||||
else
|
||||
-- GET TAG UID
|
||||
local tag, err = lib14a.read(false, true)
|
||||
if not tag then return oops(err) end
|
||||
core.clearCommandBuffer()
|
||||
uid = tag.uid
|
||||
end
|
||||
|
||||
print('UID | '..uid)
|
||||
local pwd, err = pwdgen(uid)
|
||||
if not pwd then return ooops(err) end
|
||||
|
||||
print(string.format('PWD | %s', pwd))
|
||||
local uid = '04111211121110'
|
||||
local useUID = false
|
||||
|
||||
-- Arguments for the script
|
||||
for o, a in getopt.getopt(args, 'hu:') do
|
||||
if o == "h" then return help() end
|
||||
if o == "u" then uid = a; useUID = true end
|
||||
end
|
||||
|
||||
if useUID then
|
||||
-- uid string checks
|
||||
if uid == nil then return oops('empty uid string') end
|
||||
if #uid == 0 then return oops('empty uid string') end
|
||||
if #uid ~= 14 then return oops('uid wrong length. Should be 7 hex bytes') end
|
||||
else
|
||||
-- GET TAG UID
|
||||
local tag, err = lib14a.read(false, true)
|
||||
if not tag then return oops(err) end
|
||||
core.clearCommandBuffer()
|
||||
uid = tag.uid
|
||||
end
|
||||
|
||||
print('UID | '..uid)
|
||||
local pwd, err = pwdgen(uid)
|
||||
if not pwd then return ooops(err) end
|
||||
|
||||
print(string.format('PWD | %s', pwd))
|
||||
end
|
||||
|
||||
main(args)
|
||||
+128
-128
@@ -6,192 +6,192 @@ local utils = require('utils')
|
||||
author = 'Iceman'
|
||||
version = 'v1.0.0'
|
||||
desc = [[
|
||||
This script calculates mifare keys based on uid diversification for mizip.
|
||||
This script calculates mifare keys based on uid diversification for mizip.
|
||||
Algo not found by me.
|
||||
]]
|
||||
example = [[
|
||||
-- if called without, it reads tag uid
|
||||
script run calc_mizip
|
||||
|
||||
--
|
||||
script run calc_mizip -u 11223344
|
||||
-- if called without, it reads tag uid
|
||||
script run calc_mizip
|
||||
|
||||
--
|
||||
script run calc_mizip -u 11223344
|
||||
]]
|
||||
usage = [[
|
||||
script run calc_mizip -h -u <uid>
|
||||
|
||||
Arguments:
|
||||
-h : this help
|
||||
-u <UID> : UID
|
||||
-h : this help
|
||||
-u <UID> : UID
|
||||
]]
|
||||
local DEBUG = true
|
||||
local bxor = bit32.bxor
|
||||
local _xortable = {
|
||||
--[[ sector key A/B, 6byte xor
|
||||
--]]
|
||||
{1, "09125a2589e5", "F12C8453D821"},
|
||||
{2, "AB75C937922F", "73E799FE3241"},
|
||||
{3, "E27241AF2C09", "AA4D137656AE"},
|
||||
{4, "317AB72F4490", "B01327272DFD"},
|
||||
{1, "09125a2589e5", "F12C8453D821"},
|
||||
{2, "AB75C937922F", "73E799FE3241"},
|
||||
{3, "E27241AF2C09", "AA4D137656AE"},
|
||||
{4, "317AB72F4490", "B01327272DFD"},
|
||||
}
|
||||
---
|
||||
---
|
||||
-- A debug printout-function
|
||||
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
|
||||
---
|
||||
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)
|
||||
return nil,err
|
||||
print("ERROR: ",err)
|
||||
return nil,err
|
||||
end
|
||||
---
|
||||
---
|
||||
-- Usage help
|
||||
local function help()
|
||||
print(copyright)
|
||||
print(author)
|
||||
print(version)
|
||||
print(desc)
|
||||
print("Example usage")
|
||||
print(example)
|
||||
print(copyright)
|
||||
print(author)
|
||||
print(version)
|
||||
print(desc)
|
||||
print("Example usage")
|
||||
print(example)
|
||||
end
|
||||
--
|
||||
-- Exit message
|
||||
local function exitMsg(msg)
|
||||
print( string.rep('--',20) )
|
||||
print( string.rep('--',20) )
|
||||
print(msg)
|
||||
print()
|
||||
print( string.rep('--',20) )
|
||||
print( string.rep('--',20) )
|
||||
print(msg)
|
||||
print()
|
||||
end
|
||||
--
|
||||
-- dumps all keys to file
|
||||
local function dumptofile(keys)
|
||||
dbg('dumping keys to file')
|
||||
dbg('dumping keys to file')
|
||||
|
||||
if utils.confirm('Do you wish to save the keys to dumpfile?') then
|
||||
local destination = utils.input('Select a filename to store to', 'dumpkeys.bin')
|
||||
local file = io.open(destination, 'wb')
|
||||
if file == nil then
|
||||
print('Could not write to file ', destination)
|
||||
return
|
||||
end
|
||||
if utils.confirm('Do you wish to save the keys to dumpfile?') then
|
||||
local destination = utils.input('Select a filename to store to', 'dumpkeys.bin')
|
||||
local file = io.open(destination, 'wb')
|
||||
if file == nil then
|
||||
print('Could not write to file ', destination)
|
||||
return
|
||||
end
|
||||
|
||||
-- Mifare Mini has 5 sectors,
|
||||
local key_a = ''
|
||||
local key_b = ''
|
||||
|
||||
for sector = 0, #keys do
|
||||
local keyA, keyB = unpack(keys[sector])
|
||||
key_a = key_a .. bin.pack('H', keyA);
|
||||
key_b = key_b .. bin.pack('H', keyB);
|
||||
end
|
||||
file:write(key_a)
|
||||
file:write(key_b)
|
||||
file:close()
|
||||
end
|
||||
-- Mifare Mini has 5 sectors,
|
||||
local key_a = ''
|
||||
local key_b = ''
|
||||
|
||||
for sector = 0, #keys do
|
||||
local keyA, keyB = unpack(keys[sector])
|
||||
key_a = key_a .. bin.pack('H', keyA);
|
||||
key_b = key_b .. bin.pack('H', keyB);
|
||||
end
|
||||
file:write(key_a)
|
||||
file:write(key_b)
|
||||
file:close()
|
||||
end
|
||||
end
|
||||
---
|
||||
-- key bytes to string
|
||||
local function keyStr(p1, p2, p3, p4, p5, p6)
|
||||
return string.format('%02X%02X%02X%02X%02X%02X',p1, p2, p3, p4, p5, p6)
|
||||
return string.format('%02X%02X%02X%02X%02X%02X',p1, p2, p3, p4, p5, p6)
|
||||
end
|
||||
---
|
||||
-- create key
|
||||
local function calckey(uid, xorkey, keytype)
|
||||
local p1,p2,p3,p4,p5,p6
|
||||
if keytype == 'A' then
|
||||
p1 = bxor( uid[1], xorkey[1])
|
||||
p2 = bxor( uid[2], xorkey[2])
|
||||
p3 = bxor( uid[3], xorkey[3])
|
||||
p4 = bxor( uid[4], xorkey[4])
|
||||
p5 = bxor( uid[1], xorkey[5])
|
||||
p6 = bxor( uid[2], xorkey[6])
|
||||
else
|
||||
p1 = bxor( uid[3], xorkey[1])
|
||||
p2 = bxor( uid[4], xorkey[2])
|
||||
p3 = bxor( uid[1], xorkey[3])
|
||||
p4 = bxor( uid[2], xorkey[4])
|
||||
p5 = bxor( uid[3], xorkey[5])
|
||||
p6 = bxor( uid[4], xorkey[6])
|
||||
end
|
||||
return keyStr(p1,p2,p3,p4,p5,p6)
|
||||
end
|
||||
local p1,p2,p3,p4,p5,p6
|
||||
if keytype == 'A' then
|
||||
p1 = bxor( uid[1], xorkey[1])
|
||||
p2 = bxor( uid[2], xorkey[2])
|
||||
p3 = bxor( uid[3], xorkey[3])
|
||||
p4 = bxor( uid[4], xorkey[4])
|
||||
p5 = bxor( uid[1], xorkey[5])
|
||||
p6 = bxor( uid[2], xorkey[6])
|
||||
else
|
||||
p1 = bxor( uid[3], xorkey[1])
|
||||
p2 = bxor( uid[4], xorkey[2])
|
||||
p3 = bxor( uid[1], xorkey[3])
|
||||
p4 = bxor( uid[2], xorkey[4])
|
||||
p5 = bxor( uid[3], xorkey[5])
|
||||
p6 = bxor( uid[4], xorkey[6])
|
||||
end
|
||||
return keyStr(p1,p2,p3,p4,p5,p6)
|
||||
end
|
||||
---
|
||||
-- print keys
|
||||
local function printKeys(keys)
|
||||
print('|---|----------------|---|----------------|---|')
|
||||
print('|sec|key A |res|key B |res|')
|
||||
print('|---|----------------|---|----------------|---|')
|
||||
for sector = 0, #keys do
|
||||
local keyA, keyB = unpack(keys[sector])
|
||||
print(('|%03d| %s | %s | %s | %s |'):format(sector, keyA, 1, keyB, 1))
|
||||
end
|
||||
print('|---|----------------|---|----------------|---|')
|
||||
print('|---|----------------|---|----------------|---|')
|
||||
print('|sec|key A |res|key B |res|')
|
||||
print('|---|----------------|---|----------------|---|')
|
||||
for sector = 0, #keys do
|
||||
local keyA, keyB = unpack(keys[sector])
|
||||
print(('|%03d| %s | %s | %s | %s |'):format(sector, keyA, 1, keyB, 1))
|
||||
end
|
||||
print('|---|----------------|---|----------------|---|')
|
||||
end
|
||||
---
|
||||
-- create a full set of keys
|
||||
local function createKeys(uid)
|
||||
local uidbytes = utils.ConvertHexToBytes(uid)
|
||||
|
||||
local k = {}
|
||||
k[0] = { keyStr(0xA0,0xA1,0xA2,0xA3,0xA4,0xA5), keyStr(0xB4,0xC1,0x32,0x43,0x9e,0xef) }
|
||||
local uidbytes = utils.ConvertHexToBytes(uid)
|
||||
|
||||
local k = {}
|
||||
k[0] = { keyStr(0xA0,0xA1,0xA2,0xA3,0xA4,0xA5), keyStr(0xB4,0xC1,0x32,0x43,0x9e,0xef) }
|
||||
|
||||
for _, v in pairs(_xortable) do
|
||||
local keyA = calckey(uidbytes, utils.ConvertHexToBytes(v[2]), 'A')
|
||||
local keyB = calckey(uidbytes, utils.ConvertHexToBytes(v[3]), 'B')
|
||||
k[v[1]] = { keyA, keyB }
|
||||
end
|
||||
return k
|
||||
local keyA = calckey(uidbytes, utils.ConvertHexToBytes(v[2]), 'A')
|
||||
local keyB = calckey(uidbytes, utils.ConvertHexToBytes(v[3]), 'B')
|
||||
k[v[1]] = { keyA, keyB }
|
||||
end
|
||||
return k
|
||||
end
|
||||
---
|
||||
-- main
|
||||
local function main(args)
|
||||
|
||||
print( string.rep('==', 30) )
|
||||
print()
|
||||
|
||||
local uid = '11223344'
|
||||
local useUID = false
|
||||
|
||||
-- Arguments for the script
|
||||
for o, a in getopt.getopt(args, 'hu:') do
|
||||
if o == "h" then return help() end
|
||||
if o == "u" then uid = a ; useUID = true end
|
||||
end
|
||||
print( string.rep('==', 30) )
|
||||
print()
|
||||
|
||||
if useUID then
|
||||
-- uid string checks
|
||||
if uid == nil then return oops('empty uid string') end
|
||||
if #uid == 0 then return oops('empty uid string') end
|
||||
if #uid ~= 8 then return oops('uid wrong length. Should be 4 hex bytes') end
|
||||
else
|
||||
-- GET TAG UID
|
||||
local tag, err = lib14a.read(false, true)
|
||||
if not tag then return oops(err) end
|
||||
core.clearCommandBuffer()
|
||||
local uid = '11223344'
|
||||
local useUID = false
|
||||
|
||||
-- simple tag check
|
||||
if 0x09 ~= tag.sak then
|
||||
if 0x4400 ~= tag.atqa then
|
||||
return oops(('[fail] found tag %s :: looking for Mifare Mini 0.3k'):format(tag.name))
|
||||
end
|
||||
end
|
||||
uid = tag.uid
|
||||
end
|
||||
|
||||
print('|UID|', uid)
|
||||
|
||||
local keys, err = createKeys( uid )
|
||||
printKeys( keys )
|
||||
dumptofile( keys )
|
||||
-- Arguments for the script
|
||||
for o, a in getopt.getopt(args, 'hu:') do
|
||||
if o == "h" then return help() end
|
||||
if o == "u" then uid = a ; useUID = true end
|
||||
end
|
||||
|
||||
if useUID then
|
||||
-- uid string checks
|
||||
if uid == nil then return oops('empty uid string') end
|
||||
if #uid == 0 then return oops('empty uid string') end
|
||||
if #uid ~= 8 then return oops('uid wrong length. Should be 4 hex bytes') end
|
||||
else
|
||||
-- GET TAG UID
|
||||
local tag, err = lib14a.read(false, true)
|
||||
if not tag then return oops(err) end
|
||||
core.clearCommandBuffer()
|
||||
|
||||
-- simple tag check
|
||||
if 0x09 ~= tag.sak then
|
||||
if 0x4400 ~= tag.atqa then
|
||||
return oops(('[fail] found tag %s :: looking for Mifare Mini 0.3k'):format(tag.name))
|
||||
end
|
||||
end
|
||||
uid = tag.uid
|
||||
end
|
||||
|
||||
print('|UID|', uid)
|
||||
|
||||
local keys, err = createKeys( uid )
|
||||
printKeys( keys )
|
||||
dumptofile( keys )
|
||||
end
|
||||
|
||||
main(args)
|
||||
+153
-153
@@ -11,15 +11,15 @@ desc =
|
||||
This is a script to communicate with a CALYSPO / 14443b tag using the '14b raw' commands
|
||||
|
||||
Arguments:
|
||||
-b 123
|
||||
Examples :
|
||||
script run f -b 11223344
|
||||
script run f
|
||||
-b 123
|
||||
Examples :
|
||||
script run f -b 11223344
|
||||
script run f
|
||||
|
||||
Examples :
|
||||
Examples :
|
||||
|
||||
# 1. Connect and don't disconnect
|
||||
script run f
|
||||
script run f
|
||||
# 2. Send mf auth, read response
|
||||
script run f
|
||||
# 3. disconnect
|
||||
@@ -28,56 +28,56 @@ script run f
|
||||
]]
|
||||
|
||||
--[[
|
||||
This script communicates with /armsrc/iso14443b.c,
|
||||
Check there for details about data format and how commands are interpreted on the
|
||||
device-side.
|
||||
This script communicates with /armsrc/iso14443b.c,
|
||||
Check there for details about data format and how commands are interpreted on the
|
||||
device-side.
|
||||
]]
|
||||
|
||||
---
|
||||
--
|
||||
local function calypso_switch_on_field()
|
||||
local flags = lib14b.ISO14B_COMMAND.ISO14B_CONNECT
|
||||
local c = Command:new{cmd = cmds.CMD_ISO_14443B_COMMAND, arg1 = flags}
|
||||
return lib14b.sendToDevice(c, true)
|
||||
local flags = lib14b.ISO14B_COMMAND.ISO14B_CONNECT
|
||||
local c = Command:new{cmd = cmds.CMD_ISO_14443B_COMMAND, arg1 = flags}
|
||||
return lib14b.sendToDevice(c, true)
|
||||
end
|
||||
---
|
||||
-- Disconnect (poweroff) the antenna forcing a disconnect of a 14b tag.
|
||||
local function calypso_switch_off_field()
|
||||
local flags = lib14b.ISO14B_COMMAND.ISO14B_DISCONNECT
|
||||
local c = Command:new{cmd = cmds.CMD_ISO_14443B_COMMAND, arg1 = flags}
|
||||
return lib14b.sendToDevice(c, true)
|
||||
local flags = lib14b.ISO14B_COMMAND.ISO14B_DISCONNECT
|
||||
local c = Command:new{cmd = cmds.CMD_ISO_14443B_COMMAND, arg1 = flags}
|
||||
return lib14b.sendToDevice(c, true)
|
||||
end
|
||||
|
||||
local function calypso_parse(result)
|
||||
local r = Command.parse(result)
|
||||
local len = r.arg2 * 2
|
||||
r.data = string.sub(r.data, 0, len);
|
||||
print('GOT:', r.data)
|
||||
if r.arg1 == 0 then
|
||||
return r, nil
|
||||
end
|
||||
return nil,nil
|
||||
local r = Command.parse(result)
|
||||
local len = r.arg2 * 2
|
||||
r.data = string.sub(r.data, 0, len);
|
||||
print('GOT:', r.data)
|
||||
if r.arg1 == 0 then
|
||||
return r, nil
|
||||
end
|
||||
return nil,nil
|
||||
end
|
||||
---
|
||||
---
|
||||
-- A debug printout-function
|
||||
local function dbg(args)
|
||||
if DEBUG then
|
||||
print("###", args)
|
||||
end
|
||||
end
|
||||
---
|
||||
if DEBUG then
|
||||
print("###", args)
|
||||
end
|
||||
end
|
||||
---
|
||||
-- This is only meant to be used when errors occur
|
||||
local function oops(err)
|
||||
print("ERROR: ", err)
|
||||
calypso_switch_off_field()
|
||||
return nil, err
|
||||
print("ERROR: ", err)
|
||||
calypso_switch_off_field()
|
||||
return nil, err
|
||||
end
|
||||
---
|
||||
---
|
||||
-- Usage help
|
||||
local function help()
|
||||
print(desc)
|
||||
print("Example usage")
|
||||
print(example)
|
||||
print(desc)
|
||||
print("Example usage")
|
||||
print(example)
|
||||
end
|
||||
--
|
||||
-- helper function, give current count of items in lua-table.
|
||||
@@ -87,7 +87,7 @@ local function tablelen(T)
|
||||
return count
|
||||
end
|
||||
---
|
||||
-- helper function, gives a sorted table from table t,
|
||||
-- helper function, gives a sorted table from table t,
|
||||
-- order can be a seperate sorting-order function.
|
||||
local function spairs(t, order)
|
||||
-- collect the keys
|
||||
@@ -95,7 +95,7 @@ local function spairs(t, order)
|
||||
for k in pairs(t) do keys[#keys+1] = k end
|
||||
|
||||
-- if order function given, sort by it by passing the table and keys a, b,
|
||||
-- otherwise just sort the keys
|
||||
-- otherwise just sort the keys
|
||||
if order then
|
||||
table.sort(keys, function(a,b) return order(t, a, b) end)
|
||||
else
|
||||
@@ -112,54 +112,54 @@ local function spairs(t, order)
|
||||
end
|
||||
end
|
||||
---
|
||||
-- Sends a usbpackage , "hf 14b raw"
|
||||
-- Sends a usbpackage , "hf 14b raw"
|
||||
-- if it reads the response, it converts it to a lua object "Command" first and the Data is cut to correct length.
|
||||
local function calypso_send_cmd_raw(data, ignoreresponse )
|
||||
|
||||
local command, flags, result, err
|
||||
flags = lib14b.ISO14B_COMMAND.ISO14B_RAW +
|
||||
lib14b.ISO14B_COMMAND.ISO14B_APPEND_CRC
|
||||
local command, flags, result, err
|
||||
flags = lib14b.ISO14B_COMMAND.ISO14B_RAW +
|
||||
lib14b.ISO14B_COMMAND.ISO14B_APPEND_CRC
|
||||
|
||||
data = data or "00"
|
||||
data = data or "00"
|
||||
|
||||
command = Command:new{cmd = cmds.CMD_ISO_14443B_COMMAND,
|
||||
arg1 = flags,
|
||||
arg2 = #data/2, -- LEN of data, half the length of the ASCII-string hex string
|
||||
arg3 = 0,
|
||||
data = data} -- data bytes (commands etc)
|
||||
result, err = lib14b.sendToDevice(command, false)
|
||||
|
||||
if ignoreresponse then return response, err end
|
||||
|
||||
if result then
|
||||
local r = calypso_parse(result)
|
||||
return r, nil
|
||||
end
|
||||
return respone, err
|
||||
command = Command:new{cmd = cmds.CMD_ISO_14443B_COMMAND,
|
||||
arg1 = flags,
|
||||
arg2 = #data/2, -- LEN of data, half the length of the ASCII-string hex string
|
||||
arg3 = 0,
|
||||
data = data} -- data bytes (commands etc)
|
||||
result, err = lib14b.sendToDevice(command, false)
|
||||
|
||||
if ignoreresponse then return response, err end
|
||||
|
||||
if result then
|
||||
local r = calypso_parse(result)
|
||||
return r, nil
|
||||
end
|
||||
return respone, err
|
||||
end
|
||||
---
|
||||
-- calypso_card_num : Reads card number from ATR and
|
||||
-- writes it in the tree in decimal format.
|
||||
local function calypso_card_num(card)
|
||||
if not card then return end
|
||||
local card_num = tonumber( card.uid:sub(1,8),16 )
|
||||
print('Card UID', card.uid)
|
||||
print('Card Number', card_num)
|
||||
if not card then return end
|
||||
local card_num = tonumber( card.uid:sub(1,8),16 )
|
||||
print('Card UID', card.uid)
|
||||
print('Card Number', card_num)
|
||||
end
|
||||
---
|
||||
-- analyse CALYPSO apdu status bytes.
|
||||
local function calypso_apdu_status(apdu)
|
||||
-- last two is CRC
|
||||
-- next two is APDU status bytes.
|
||||
local status = false
|
||||
local mess = 'FAIL'
|
||||
local sw = apdu:sub( #apdu-7, #apdu-4)
|
||||
desc, err = iso7816.tostring(sw)
|
||||
print ('SW', sw, desc, err )
|
||||
-- last two is CRC
|
||||
-- next two is APDU status bytes.
|
||||
local status = false
|
||||
local mess = 'FAIL'
|
||||
local sw = apdu:sub( #apdu-7, #apdu-4)
|
||||
desc, err = iso7816.tostring(sw)
|
||||
print ('SW', sw, desc, err )
|
||||
|
||||
status = ( sw == '9000' )
|
||||
|
||||
return status
|
||||
status = ( sw == '9000' )
|
||||
|
||||
return status
|
||||
end
|
||||
|
||||
local _calypso_cmds = {
|
||||
@@ -167,16 +167,16 @@ local _calypso_cmds = {
|
||||
-- Break down of command bytes:
|
||||
-- A4 = select
|
||||
-- Master File 3F00
|
||||
-- 0x3F = master file
|
||||
-- 0x3F = master file
|
||||
-- 0x00 = master file id, is constant to 0x00.
|
||||
|
||||
-- DF Dedicated File 38nn
|
||||
-- can be seen as directories
|
||||
-- 0x38
|
||||
-- 0x38
|
||||
-- 0xNN id
|
||||
-- ["01.Select ICC file"] = '0294 a4 080004 3f00 0002',
|
||||
-- ["01.Select ICC file"] = '0294 a4 080004 3f00 0002',
|
||||
|
||||
-- EF Elementary File
|
||||
-- EF Elementary File
|
||||
-- EF1 Pin file
|
||||
-- EF2 Key file
|
||||
-- Grey Lock file
|
||||
@@ -184,93 +184,93 @@ local _calypso_cmds = {
|
||||
-- Electronic Purse file
|
||||
-- Electronic Transaction log file
|
||||
|
||||
|
||||
--["01.Select ICC file"] = '0294 a4 00 0002 3f00',
|
||||
["01.Select ICC file"] = '0294 a4 080004 3f00 0002',
|
||||
["02.ICC"] = '0394 b2 01 041d',
|
||||
["03.Select EnvHol file"] = '0294 a4 080004 2000 2001',
|
||||
["04.EnvHol1"] = '0394 b2 01 041d',
|
||||
["05.Select EvLog file"] = '0294 a4 080004 2000 2010',
|
||||
["06.EvLog1"] = '0394 b2 01 041d',
|
||||
["07.EvLog2"] = '0294 b2 02 041d',
|
||||
["08.EvLog3"] = '0394 b2 03 041d',
|
||||
["09.Select ConList file"] ='0294 a4 080004 2000 2050',
|
||||
["10.ConList"] = '0394 b2 01 041d',
|
||||
["11.Select Contra file"] = '0294 a4 080004 2000 2020',
|
||||
["12.Contra1"] = '0394 b2 01 041d',
|
||||
["13.Contra2"] = '0294 b2 02 041d',
|
||||
["14.Contra3"] = '0394 b2 03 041d',
|
||||
["15.Contra4"] = '0294 b2 04 041d',
|
||||
["16.Select Counter file"]= '0394 a4 080004 2000 2069',
|
||||
["17.Counter"] = '0294 b2 01 041d',
|
||||
["18.Select SpecEv file"]= '0394 a4 080004 2000 2040',
|
||||
["19.SpecEv1"] = '0294 b2 01 041d',
|
||||
|
||||
--["01.Select ICC file"] = '0294 a4 00 0002 3f00',
|
||||
["01.Select ICC file"] = '0294 a4 080004 3f00 0002',
|
||||
["02.ICC"] = '0394 b2 01 041d',
|
||||
["03.Select EnvHol file"] = '0294 a4 080004 2000 2001',
|
||||
["04.EnvHol1"] = '0394 b2 01 041d',
|
||||
["05.Select EvLog file"] = '0294 a4 080004 2000 2010',
|
||||
["06.EvLog1"] = '0394 b2 01 041d',
|
||||
["07.EvLog2"] = '0294 b2 02 041d',
|
||||
["08.EvLog3"] = '0394 b2 03 041d',
|
||||
["09.Select ConList file"]= '0294 a4 080004 2000 2050',
|
||||
["10.ConList"] = '0394 b2 01 041d',
|
||||
["11.Select Contra file"] = '0294 a4 080004 2000 2020',
|
||||
["12.Contra1"] = '0394 b2 01 041d',
|
||||
["13.Contra2"] = '0294 b2 02 041d',
|
||||
["14.Contra3"] = '0394 b2 03 041d',
|
||||
["15.Contra4"] = '0294 b2 04 041d',
|
||||
["16.Select Counter file"]= '0394 a4 080004 2000 2069',
|
||||
["17.Counter"] = '0294 b2 01 041d',
|
||||
["18.Select SpecEv file"] = '0394 a4 080004 2000 2040',
|
||||
["19.SpecEv1"] = '0294 b2 01 041d',
|
||||
}
|
||||
|
||||
---
|
||||
---
|
||||
-- The main entry point
|
||||
function main(args)
|
||||
|
||||
print( string.rep('--',20) )
|
||||
print( string.rep('--',20) )
|
||||
print()
|
||||
|
||||
local data, apdu, flags, uid, cid, result, err, card
|
||||
-- Read the parameters
|
||||
for o, a in getopt.getopt(args, 'h') do
|
||||
if o == "h" then return help() end
|
||||
end
|
||||
|
||||
calypso_switch_on_field()
|
||||
|
||||
-- Select 14b tag.
|
||||
card, err = lib14b.waitFor14443b()
|
||||
if not card then return oops(err) end
|
||||
|
||||
calypso_card_num(card)
|
||||
cid = card.cid
|
||||
print( string.rep('--',20) )
|
||||
print( string.rep('--',20) )
|
||||
print()
|
||||
|
||||
--[[
|
||||
NAME VALUE APDU_POS
|
||||
PCB 0x0A 0
|
||||
CID 0x00 1
|
||||
CLA 0x94 2
|
||||
SELECT FILE 0xA4 3
|
||||
READ FILE 0xB2 3
|
||||
P1 4
|
||||
P2 5
|
||||
LEN_
|
||||
0 1 2 3 4 5 6 7
|
||||
apdu = '02 94 a4 08 00 04 3f 00 00 02' --select ICC file
|
||||
DF_NAME = "1TIC.ICA"
|
||||
--]]
|
||||
--for i = 1,10 do
|
||||
--result, err = calypso_send_cmd_raw('0294a40800043f000002',false) --select ICC file
|
||||
for i, apdu in spairs(_calypso_cmds) do
|
||||
print('>>', i )
|
||||
apdu = apdu:gsub("%s+","")
|
||||
result, err = calypso_send_cmd_raw(apdu , false)
|
||||
if result then
|
||||
calypso_apdu_status(result.data)
|
||||
print('<<', result.data )
|
||||
else
|
||||
print('<< no answer')
|
||||
end
|
||||
end
|
||||
calypso_switch_off_field()
|
||||
local data, apdu, flags, uid, cid, result, err, card
|
||||
-- Read the parameters
|
||||
for o, a in getopt.getopt(args, 'h') do
|
||||
if o == "h" then return help() end
|
||||
end
|
||||
|
||||
calypso_switch_on_field()
|
||||
|
||||
-- Select 14b tag.
|
||||
card, err = lib14b.waitFor14443b()
|
||||
if not card then return oops(err) end
|
||||
|
||||
calypso_card_num(card)
|
||||
cid = card.cid
|
||||
|
||||
--[[
|
||||
NAME VALUE APDU_POS
|
||||
PCB 0x0A 0
|
||||
CID 0x00 1
|
||||
CLA 0x94 2
|
||||
SELECT FILE 0xA4 3
|
||||
READ FILE 0xB2 3
|
||||
P1 4
|
||||
P2 5
|
||||
LEN_
|
||||
0 1 2 3 4 5 6 7
|
||||
apdu = '02 94 a4 08 00 04 3f 00 00 02' --select ICC file
|
||||
DF_NAME = "1TIC.ICA"
|
||||
--]]
|
||||
--for i = 1,10 do
|
||||
--result, err = calypso_send_cmd_raw('0294a40800043f000002',false) --select ICC file
|
||||
for i, apdu in spairs(_calypso_cmds) do
|
||||
print('>>', i )
|
||||
apdu = apdu:gsub("%s+","")
|
||||
result, err = calypso_send_cmd_raw(apdu , false)
|
||||
if result then
|
||||
calypso_apdu_status(result.data)
|
||||
print('<<', result.data )
|
||||
else
|
||||
print('<< no answer')
|
||||
end
|
||||
end
|
||||
calypso_switch_off_field()
|
||||
end
|
||||
---
|
||||
-- a simple selftest function, tries to convert
|
||||
-- a simple selftest function, tries to convert
|
||||
function selftest()
|
||||
DEBUG = true
|
||||
dbg("Performing test")
|
||||
dbg("Tests done")
|
||||
DEBUG = true
|
||||
dbg("Performing test")
|
||||
dbg("Tests done")
|
||||
end
|
||||
-- Flip the switch here to perform a sanity check.
|
||||
-- Flip the switch here to perform a sanity check.
|
||||
-- It read a nonce in two different ways, as specified in the usage-section
|
||||
if "--test"==args then
|
||||
selftest()
|
||||
else
|
||||
-- Call the main
|
||||
main(args)
|
||||
if "--test"==args then
|
||||
selftest()
|
||||
else
|
||||
-- Call the main
|
||||
main(args)
|
||||
end
|
||||
@@ -1,12 +1,12 @@
|
||||
print("This is how a cmd-line interface could be implemented\nPrint 'exit' to exit.\n")
|
||||
local answer
|
||||
repeat
|
||||
io.write("$>")
|
||||
io.flush()
|
||||
answer=io.read()
|
||||
if answer ~= 'exit' then
|
||||
local func = assert(loadstring("return " .. answer))
|
||||
io.write("\n"..tostring(func() or "").."\n");
|
||||
end--]]
|
||||
until answer=="exit"
|
||||
io.write("$>")
|
||||
io.flush()
|
||||
answer=io.read()
|
||||
if answer ~= 'exit' then
|
||||
local func = assert(loadstring("return " .. answer))
|
||||
io.write("\n"..tostring(func() or "").."\n");
|
||||
end--]]
|
||||
until answer=="exit"
|
||||
print("Bye\n");
|
||||
|
||||
+221
-221
File diff suppressed because it is too large
Load Diff
@@ -13,120 +13,120 @@ This script takes a dumpfile from 'hf mfu dump' and converts it to a format that
|
||||
by the emulator
|
||||
|
||||
Arguments:
|
||||
-h This help
|
||||
-i <file> Specifies the dump-file (input). If omitted, 'dumpdata.bin' is used
|
||||
-o <filename> Specifies the output file. If omitted, <uid>.eml is used.
|
||||
-h This help
|
||||
-i <file> Specifies the dump-file (input). If omitted, 'dumpdata.bin' is used
|
||||
-o <filename> Specifies the output file. If omitted, <uid>.eml is used.
|
||||
|
||||
]]
|
||||
local DEBUG = false
|
||||
|
||||
---
|
||||
---
|
||||
-- A debug printout-function
|
||||
local function dbg(args)
|
||||
if not DEBUG then return end
|
||||
|
||||
if type(args) == 'table' then
|
||||
local i = 1
|
||||
while result[i] do
|
||||
dbg(result[i])
|
||||
i = i+1
|
||||
end
|
||||
else
|
||||
print('###', args)
|
||||
end
|
||||
end
|
||||
---
|
||||
if not DEBUG then return end
|
||||
|
||||
if type(args) == 'table' then
|
||||
local i = 1
|
||||
while result[i] do
|
||||
dbg(result[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)
|
||||
return nil,err
|
||||
print('ERROR: ',err)
|
||||
return nil,err
|
||||
end
|
||||
---
|
||||
---
|
||||
-- Usage help
|
||||
function help()
|
||||
print(desc)
|
||||
print(author)
|
||||
print("Example usage")
|
||||
print(example)
|
||||
print(desc)
|
||||
print(author)
|
||||
print("Example usage")
|
||||
print(example)
|
||||
end
|
||||
|
||||
local function convert_to_ascii(hexdata)
|
||||
if string.len(hexdata) % 8 ~= 0 then
|
||||
return oops(("Bad data, length should be a multiple of 8 (was %d)"):format(string.len(hexdata)))
|
||||
end
|
||||
if string.len(hexdata) % 8 ~= 0 then
|
||||
return oops(("Bad data, length should be a multiple of 8 (was %d)"):format(string.len(hexdata)))
|
||||
end
|
||||
|
||||
local js,i = "[";
|
||||
for i = 1, string.len(hexdata),8 do
|
||||
js = js .."'" ..string.sub(hexdata,i,i+7).."',\n"
|
||||
end
|
||||
js = js .. "]"
|
||||
return js
|
||||
local js,i = "[";
|
||||
for i = 1, string.len(hexdata),8 do
|
||||
js = js .."'" ..string.sub(hexdata,i,i+7).."',\n"
|
||||
end
|
||||
js = js .. "]"
|
||||
return js
|
||||
end
|
||||
|
||||
local function readdump(infile)
|
||||
t = infile:read("*all")
|
||||
len = string.len(t)
|
||||
local len,hex = bin.unpack(("H%d"):format(len),t)
|
||||
return hex
|
||||
t = infile:read("*all")
|
||||
len = string.len(t)
|
||||
local len,hex = bin.unpack(("H%d"):format(len),t)
|
||||
return hex
|
||||
end
|
||||
|
||||
local function convert_to_emulform(hexdata)
|
||||
if string.len(hexdata) % 8 ~= 0 then
|
||||
return oops(("Bad data, length should be a multiple of 8 (was %d)"):format(string.len(hexdata)))
|
||||
end
|
||||
local ascii,i = "";
|
||||
for i = 1, string.len(hexdata), 8 do
|
||||
ascii = ascii..string.sub(hexdata, i, i+7).."\n"
|
||||
end
|
||||
return string.sub(ascii, 1, -2)
|
||||
if string.len(hexdata) % 8 ~= 0 then
|
||||
return oops(("Bad data, length should be a multiple of 8 (was %d)"):format(string.len(hexdata)))
|
||||
end
|
||||
local ascii,i = "";
|
||||
for i = 1, string.len(hexdata), 8 do
|
||||
ascii = ascii..string.sub(hexdata, i, i+7).."\n"
|
||||
end
|
||||
return string.sub(ascii, 1, -2)
|
||||
end
|
||||
|
||||
local function main(args)
|
||||
|
||||
local input = "dumpdata.bin"
|
||||
local output
|
||||
local input = "dumpdata.bin"
|
||||
local output
|
||||
|
||||
for o, a in getopt.getopt(args, 'i:o:h') do
|
||||
if o == "h" then return help() end
|
||||
if o == "i" then input = a end
|
||||
if o == "o" then output = a end
|
||||
end
|
||||
-- Validate the parameters
|
||||
|
||||
local infile = io.open(input, "rb")
|
||||
if infile == nil then
|
||||
return oops("Could not read file ", input)
|
||||
end
|
||||
local dumpdata = readdump(infile)
|
||||
-- The hex-data is now in ascii-format,
|
||||
for o, a in getopt.getopt(args, 'i:o:h') do
|
||||
if o == "h" then return help() end
|
||||
if o == "i" then input = a end
|
||||
if o == "o" then output = a end
|
||||
end
|
||||
-- Validate the parameters
|
||||
|
||||
-- But first, check the uid
|
||||
-- lua uses start index and endindex, not count.
|
||||
-- UID is 3three skip bcc0 then 4bytes.
|
||||
-- 1 lua is one-index.
|
||||
-- 1 + 96 (48*2) new dump format has version/signature/counter data here
|
||||
-- 97,98,99,100,101,102 UID first three bytes
|
||||
-- 103,104 bcc0
|
||||
-- 105--- UID last four bytes
|
||||
local uid = string.sub(dumpdata, 97, 97+5)..string.sub(dumpdata, 97+8, 97+8+7)
|
||||
output = output or (uid .. ".eml")
|
||||
local infile = io.open(input, "rb")
|
||||
if infile == nil then
|
||||
return oops("Could not read file ", input)
|
||||
end
|
||||
local dumpdata = readdump(infile)
|
||||
-- The hex-data is now in ascii-format,
|
||||
|
||||
-- Format some linebreaks
|
||||
dumpdata = convert_to_emulform(dumpdata)
|
||||
-- But first, check the uid
|
||||
-- lua uses start index and endindex, not count.
|
||||
-- UID is 3three skip bcc0 then 4bytes.
|
||||
-- 1 lua is one-index.
|
||||
-- 1 + 96 (48*2) new dump format has version/signature/counter data here
|
||||
-- 97,98,99,100,101,102 UID first three bytes
|
||||
-- 103,104 bcc0
|
||||
-- 105--- UID last four bytes
|
||||
local uid = string.sub(dumpdata, 97, 97+5)..string.sub(dumpdata, 97+8, 97+8+7)
|
||||
output = output or (uid .. ".eml")
|
||||
|
||||
local outfile = io.open(output, "w")
|
||||
if outfile == nil then
|
||||
return oops("Could not write to file ", output)
|
||||
end
|
||||
|
||||
outfile:write(dumpdata:lower())
|
||||
io.close(outfile)
|
||||
print(("Wrote an emulator-dump to the file %s"):format(output))
|
||||
-- Format some linebreaks
|
||||
dumpdata = convert_to_emulform(dumpdata)
|
||||
|
||||
local outfile = io.open(output, "w")
|
||||
if outfile == nil then
|
||||
return oops("Could not write to file ", output)
|
||||
end
|
||||
|
||||
outfile:write(dumpdata:lower())
|
||||
io.close(outfile)
|
||||
print(("Wrote an emulator-dump to the file %s"):format(output))
|
||||
end
|
||||
|
||||
--[[
|
||||
In the future, we may implement so that scripts are invoked directly
|
||||
In the future, we may implement so that scripts are invoked directly
|
||||
into a 'main' function, instead of being executed blindly. For future
|
||||
compatibility, I have done so, but I invoke my main from here.
|
||||
compatibility, I have done so, but I invoke my main from here.
|
||||
--]]
|
||||
main(args)
|
||||
|
||||
@@ -11,117 +11,117 @@ This script takes a dumpfile from 'hf mf dump' and converts it to a format that
|
||||
by the emulator
|
||||
|
||||
Arguments:
|
||||
-h This help
|
||||
-i <file> Specifies the dump-file (input). If omitted, 'dumpdata.bin' is used
|
||||
-o <filename> Specifies the output file. If omitted, <uid>.eml is used.
|
||||
-h This help
|
||||
-i <file> Specifies the dump-file (input). If omitted, 'dumpdata.bin' is used
|
||||
-o <filename> Specifies the output file. If omitted, <uid>.eml is used.
|
||||
|
||||
]]
|
||||
local DEBUG = false
|
||||
-------------------------------
|
||||
-- Some utilities
|
||||
-- Some utilities
|
||||
-------------------------------
|
||||
|
||||
---
|
||||
---
|
||||
-- A debug printout-function
|
||||
local function dbg(args)
|
||||
if not DEBUG then return end
|
||||
|
||||
if type(args) == 'table' then
|
||||
local i = 1
|
||||
while result[i] do
|
||||
dbg(result[i])
|
||||
i = i+1
|
||||
end
|
||||
else
|
||||
print('###', args)
|
||||
end
|
||||
end
|
||||
---
|
||||
if not DEBUG then return end
|
||||
|
||||
if type(args) == 'table' then
|
||||
local i = 1
|
||||
while result[i] do
|
||||
dbg(result[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)
|
||||
return nil,err
|
||||
print('ERROR: ',err)
|
||||
return nil,err
|
||||
end
|
||||
---
|
||||
---
|
||||
-- Usage help
|
||||
function help()
|
||||
print(desc)
|
||||
print(author)
|
||||
print("Example usage")
|
||||
print(example)
|
||||
print(desc)
|
||||
print(author)
|
||||
print("Example usage")
|
||||
print(example)
|
||||
end
|
||||
|
||||
local function convert_to_ascii(hexdata)
|
||||
if string.len(hexdata) % 32 ~= 0 then
|
||||
return oops(("Bad data, length should be a multiple of 32 (was %d)"):format(string.len(hexdata)))
|
||||
end
|
||||
if string.len(hexdata) % 32 ~= 0 then
|
||||
return oops(("Bad data, length should be a multiple of 32 (was %d)"):format(string.len(hexdata)))
|
||||
end
|
||||
|
||||
local js,i = "[";
|
||||
for i = 1, string.len(hexdata),32 do
|
||||
js = js .."'" ..string.sub(hexdata,i,i+31).."',\n"
|
||||
end
|
||||
js = js .. "]"
|
||||
return js
|
||||
local js,i = "[";
|
||||
for i = 1, string.len(hexdata),32 do
|
||||
js = js .."'" ..string.sub(hexdata,i,i+31).."',\n"
|
||||
end
|
||||
js = js .. "]"
|
||||
return js
|
||||
end
|
||||
|
||||
local function readdump(infile)
|
||||
t = infile:read("*all")
|
||||
len = string.len(t)
|
||||
local len,hex = bin.unpack(("H%d"):format(len),t)
|
||||
return hex
|
||||
t = infile:read("*all")
|
||||
len = string.len(t)
|
||||
local len,hex = bin.unpack(("H%d"):format(len),t)
|
||||
return hex
|
||||
end
|
||||
|
||||
local function convert_to_emulform(hexdata)
|
||||
if string.len(hexdata) % 32 ~= 0 then
|
||||
return oops(("Bad data, length should be a multiple of 32 (was %d)"):format(string.len(hexdata)))
|
||||
end
|
||||
local ascii,i = "";
|
||||
for i = 1, string.len(hexdata),32 do
|
||||
ascii = ascii..string.sub(hexdata,i,i+31).."\n"
|
||||
end
|
||||
return string.sub(ascii, 1, -2)
|
||||
if string.len(hexdata) % 32 ~= 0 then
|
||||
return oops(("Bad data, length should be a multiple of 32 (was %d)"):format(string.len(hexdata)))
|
||||
end
|
||||
local ascii,i = "";
|
||||
for i = 1, string.len(hexdata),32 do
|
||||
ascii = ascii..string.sub(hexdata,i,i+31).."\n"
|
||||
end
|
||||
return string.sub(ascii, 1, -2)
|
||||
end
|
||||
|
||||
local function main(args)
|
||||
|
||||
local input = "dumpdata.bin"
|
||||
local output
|
||||
local input = "dumpdata.bin"
|
||||
local output
|
||||
|
||||
for o, a in getopt.getopt(args, 'i:o:h') do
|
||||
if o == "h" then return help() end
|
||||
if o == "i" then input = a end
|
||||
if o == "o" then output = a end
|
||||
end
|
||||
-- Validate the parameters
|
||||
|
||||
local infile = io.open(input, "rb")
|
||||
if infile == nil then
|
||||
return oops("Could not read file ", input)
|
||||
end
|
||||
local dumpdata = readdump(infile)
|
||||
-- The hex-data is now in ascii-format,
|
||||
for o, a in getopt.getopt(args, 'i:o:h') do
|
||||
if o == "h" then return help() end
|
||||
if o == "i" then input = a end
|
||||
if o == "o" then output = a end
|
||||
end
|
||||
-- Validate the parameters
|
||||
|
||||
-- But first, check the uid
|
||||
local uid = string.sub(dumpdata,1,8)
|
||||
output = output or (uid .. ".eml")
|
||||
local infile = io.open(input, "rb")
|
||||
if infile == nil then
|
||||
return oops("Could not read file ", input)
|
||||
end
|
||||
local dumpdata = readdump(infile)
|
||||
-- The hex-data is now in ascii-format,
|
||||
|
||||
-- Format some linebreaks
|
||||
dumpdata = convert_to_emulform(dumpdata)
|
||||
-- But first, check the uid
|
||||
local uid = string.sub(dumpdata,1,8)
|
||||
output = output or (uid .. ".eml")
|
||||
|
||||
local outfile = io.open(output, "w")
|
||||
if outfile == nil then
|
||||
return oops("Could not write to file ", output)
|
||||
end
|
||||
|
||||
outfile:write(dumpdata:lower())
|
||||
io.close(outfile)
|
||||
print(("Wrote an emulator-dump to the file %s"):format(output))
|
||||
-- Format some linebreaks
|
||||
dumpdata = convert_to_emulform(dumpdata)
|
||||
|
||||
local outfile = io.open(output, "w")
|
||||
if outfile == nil then
|
||||
return oops("Could not write to file ", output)
|
||||
end
|
||||
|
||||
outfile:write(dumpdata:lower())
|
||||
io.close(outfile)
|
||||
print(("Wrote an emulator-dump to the file %s"):format(output))
|
||||
end
|
||||
|
||||
|
||||
--[[
|
||||
In the future, we may implement so that scripts are invoked directly
|
||||
In the future, we may implement so that scripts are invoked directly
|
||||
into a 'main' function, instead of being executed blindly. For future
|
||||
compatibility, I have done so, but I invoke my main from here.
|
||||
compatibility, I have done so, but I invoke my main from here.
|
||||
--]]
|
||||
main(args)
|
||||
|
||||
+50
-50
@@ -5,73 +5,73 @@ example = "script calculates many different checksums (CRC) over the provided he
|
||||
author = "Iceman"
|
||||
desc =
|
||||
[[
|
||||
This script calculates many checksums (CRC) over the provided hex input.
|
||||
This script calculates many checksums (CRC) over the provided hex input.
|
||||
|
||||
Arguments:
|
||||
-b data in hex
|
||||
-w bitwidth of the CRC family of algorithm. <optional> defaults to all known CRC presets.
|
||||
Examples :
|
||||
script run e -b 010203040506070809
|
||||
script run e -b 010203040506070809 -w 16
|
||||
-b data in hex
|
||||
-w bitwidth of the CRC family of algorithm. <optional> defaults to all known CRC presets.
|
||||
Examples :
|
||||
script run e -b 010203040506070809
|
||||
script run e -b 010203040506070809 -w 16
|
||||
]]
|
||||
|
||||
---
|
||||
---
|
||||
-- A debug printout-function
|
||||
function dbg(args)
|
||||
if DEBUG then
|
||||
print("###", args)
|
||||
end
|
||||
end
|
||||
---
|
||||
if DEBUG then
|
||||
print("###", args)
|
||||
end
|
||||
end
|
||||
---
|
||||
-- This is only meant to be used when errors occur
|
||||
function oops(err)
|
||||
print("[!] ERROR: ",err)
|
||||
return nil,err
|
||||
print("[!] ERROR: ",err)
|
||||
return nil,err
|
||||
end
|
||||
---
|
||||
---
|
||||
-- Usage help
|
||||
function help()
|
||||
print(desc)
|
||||
print("Example usage")
|
||||
print(example)
|
||||
print(desc)
|
||||
print("Example usage")
|
||||
print(example)
|
||||
end
|
||||
---
|
||||
---
|
||||
-- The main entry point
|
||||
function main(args)
|
||||
|
||||
local data
|
||||
local width = 0
|
||||
local data
|
||||
local width = 0
|
||||
|
||||
-- Read the parameters
|
||||
for o, a in getopt.getopt(args, 'hb:w:') do
|
||||
if o == "h" then return help() end
|
||||
if o == "b" then data = a end
|
||||
if o == "w" then width = a end
|
||||
end
|
||||
-- Read the parameters
|
||||
for o, a in getopt.getopt(args, 'hb:w:') do
|
||||
if o == "h" then return help() end
|
||||
if o == "b" then data = a end
|
||||
if o == "w" then width = a end
|
||||
end
|
||||
|
||||
data = data or '01020304'
|
||||
width = width or 0
|
||||
|
||||
print( string.rep('-',60) )
|
||||
print('Bit width of CRC | '..width)
|
||||
print('Bytes | '..data)
|
||||
print('')
|
||||
print( ('%-20s| %-16s| %s'):format('Model','CRC', 'CRC reverse','bigEnd', 'bigEnd','little','little'))
|
||||
print( string.rep('-',60) )
|
||||
local lists, err = core.reveng_models(width)
|
||||
if lists == nil then return oops(err) end
|
||||
|
||||
for _,i in pairs(lists) do
|
||||
if string.len(i) > 1 then
|
||||
local a1 = core.reveng_runmodel(i, data, false, '0')
|
||||
local a2 = core.reveng_runmodel(i, data, true, '0')
|
||||
local a3 = core.reveng_runmodel(i, data, false, 'b')
|
||||
local a4 = core.reveng_runmodel(i, data, false, 'B')
|
||||
local a5 = core.reveng_runmodel(i, data, false, 'l')
|
||||
local a6 = core.reveng_runmodel(i, data, false, 'L')
|
||||
print( ('%-20s| %-16s| %-16s| %-16s| %-16s| %-16s| %-16s'):format(i, a1:upper(), a2:upper(),a3:upper(),a4:upper(),a5:upper(),a6:upper() ) )
|
||||
end
|
||||
end
|
||||
data = data or '01020304'
|
||||
width = width or 0
|
||||
|
||||
print( string.rep('-',60) )
|
||||
print('Bit width of CRC | '..width)
|
||||
print('Bytes | '..data)
|
||||
print('')
|
||||
print( ('%-20s| %-16s| %s'):format('Model','CRC', 'CRC reverse','bigEnd', 'bigEnd','little','little'))
|
||||
print( string.rep('-',60) )
|
||||
local lists, err = core.reveng_models(width)
|
||||
if lists == nil then return oops(err) end
|
||||
|
||||
for _,i in pairs(lists) do
|
||||
if string.len(i) > 1 then
|
||||
local a1 = core.reveng_runmodel(i, data, false, '0')
|
||||
local a2 = core.reveng_runmodel(i, data, true, '0')
|
||||
local a3 = core.reveng_runmodel(i, data, false, 'b')
|
||||
local a4 = core.reveng_runmodel(i, data, false, 'B')
|
||||
local a5 = core.reveng_runmodel(i, data, false, 'l')
|
||||
local a6 = core.reveng_runmodel(i, data, false, 'L')
|
||||
print( ('%-20s| %-16s| %-16s| %-16s| %-16s| %-16s| %-16s'):format(i, a1:upper(), a2:upper(),a3:upper(),a4:upper(),a5:upper(),a6:upper() ) )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
main(args)
|
||||
@@ -1,60 +1,60 @@
|
||||
local getopt = require('getopt')
|
||||
local bin = require('bin')
|
||||
local dumplib = require('html_dumplib')
|
||||
|
||||
example =[[
|
||||
1. script run emul2dump
|
||||
2. script run emul2dump -i myfile.eml
|
||||
3. script run emul2dump -i myfile.eml -o myfile.bin
|
||||
]]
|
||||
author = "Iceman"
|
||||
usage = "script run emul2dump [-i <file>] [-o <file>]"
|
||||
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"
|
||||
|
||||
Arguments:
|
||||
-h This help
|
||||
-i <filename> Specifies the dump-file (input). If omitted, 'dumpdata.eml' is used
|
||||
-o <filename> Specifies the output file. If omitted, <currdate>.bin is used.
|
||||
]]
|
||||
|
||||
---
|
||||
-- This is only meant to be used when errors occur
|
||||
function oops(err)
|
||||
print("ERROR: ",err)
|
||||
end
|
||||
---
|
||||
-- Usage help
|
||||
function help()
|
||||
print(desc)
|
||||
print("Example usage")
|
||||
print(example)
|
||||
end
|
||||
--
|
||||
-- Exit message
|
||||
function ExitMsg(msg)
|
||||
print( string.rep('--',20) )
|
||||
print( string.rep('--',20) )
|
||||
print(msg)
|
||||
print()
|
||||
end
|
||||
|
||||
local function main(args)
|
||||
|
||||
local input = "dumpdata.eml"
|
||||
local output = os.date("%Y-%m-%d_%H%M%S.bin");
|
||||
|
||||
-- Arguments for the script
|
||||
for o, a in getopt.getopt(args, 'hi:o:') do
|
||||
if o == "h" then return help() end
|
||||
if o == "i" then input = a end
|
||||
if o == "o" then output = a end
|
||||
end
|
||||
|
||||
local filename, err = dumplib.convert_eml_to_bin(input,output)
|
||||
if err then return oops(err) end
|
||||
|
||||
ExitMsg(("Wrote a BIN dump to the file %s"):format(filename))
|
||||
end
|
||||
|
||||
local getopt = require('getopt')
|
||||
local bin = require('bin')
|
||||
local dumplib = require('html_dumplib')
|
||||
|
||||
example =[[
|
||||
1. script run emul2dump
|
||||
2. script run emul2dump -i myfile.eml
|
||||
3. script run emul2dump -i myfile.eml -o myfile.bin
|
||||
]]
|
||||
author = "Iceman"
|
||||
usage = "script run emul2dump [-i <file>] [-o <file>]"
|
||||
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"
|
||||
|
||||
Arguments:
|
||||
-h This help
|
||||
-i <filename> Specifies the dump-file (input). If omitted, 'dumpdata.eml' is used
|
||||
-o <filename> Specifies the output file. If omitted, <currdate>.bin is used.
|
||||
]]
|
||||
|
||||
---
|
||||
-- This is only meant to be used when errors occur
|
||||
function oops(err)
|
||||
print("ERROR: ",err)
|
||||
end
|
||||
---
|
||||
-- Usage help
|
||||
function help()
|
||||
print(desc)
|
||||
print("Example usage")
|
||||
print(example)
|
||||
end
|
||||
--
|
||||
-- Exit message
|
||||
function ExitMsg(msg)
|
||||
print( string.rep('--',20) )
|
||||
print( string.rep('--',20) )
|
||||
print(msg)
|
||||
print()
|
||||
end
|
||||
|
||||
local function main(args)
|
||||
|
||||
local input = "dumpdata.eml"
|
||||
local output = os.date("%Y-%m-%d_%H%M%S.bin");
|
||||
|
||||
-- Arguments for the script
|
||||
for o, a in getopt.getopt(args, 'hi:o:') do
|
||||
if o == "h" then return help() end
|
||||
if o == "i" then input = a end
|
||||
if o == "o" then output = a end
|
||||
end
|
||||
|
||||
local filename, err = dumplib.convert_eml_to_bin(input,output)
|
||||
if err then return oops(err) end
|
||||
|
||||
ExitMsg(("Wrote a BIN dump to the file %s"):format(filename))
|
||||
end
|
||||
|
||||
main(args)
|
||||
@@ -8,60 +8,60 @@ example = "script run emul2html -o dumpdata.eml "
|
||||
author = "Martin Holst Swende"
|
||||
usage = "script run htmldump [-i <file>] [-o <file>]"
|
||||
desc =[[
|
||||
This script takes a dumpfile on EML (ASCII) format and produces a html based dump, which is a
|
||||
bit more easily analyzed.
|
||||
This script takes a dumpfile on EML (ASCII) format and produces a html based dump, which is a
|
||||
bit more easily analyzed.
|
||||
|
||||
Arguments:
|
||||
-h This help
|
||||
-i <file> Specifies the dump-file (input). If omitted, 'dumpdata.eml' is used
|
||||
-o <filename> Speciies the output file. If omitted, <curdate>.html is used.
|
||||
-h This help
|
||||
-i <file> Specifies the dump-file (input). If omitted, 'dumpdata.eml' is used
|
||||
-o <filename> Speciies the output file. If omitted, <curdate>.html is used.
|
||||
|
||||
]]
|
||||
|
||||
-------------------------------
|
||||
-- Some utilities
|
||||
-- Some utilities
|
||||
-------------------------------
|
||||
|
||||
---
|
||||
---
|
||||
-- A debug printout-function
|
||||
function dbg(args)
|
||||
if DEBUG then
|
||||
print("###", args)
|
||||
end
|
||||
end
|
||||
---
|
||||
if DEBUG then
|
||||
print("###", args)
|
||||
end
|
||||
end
|
||||
---
|
||||
-- This is only meant to be used when errors occur
|
||||
function oops(err)
|
||||
print("ERROR: ",err)
|
||||
print("ERROR: ",err)
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
---
|
||||
-- Usage help
|
||||
function help()
|
||||
print(desc)
|
||||
print("Example usage")
|
||||
print(example)
|
||||
print(desc)
|
||||
print("Example usage")
|
||||
print(example)
|
||||
end
|
||||
|
||||
local function main(args)
|
||||
|
||||
local input = "dumpdata.eml"
|
||||
local output = os.date("%Y-%m-%d_%H%M%S.html");
|
||||
for o, a in getopt.getopt(args, 'i:o:h') do
|
||||
if o == "h" then return help() end
|
||||
if o == "i" then input = a end
|
||||
if o == "o" then output = a end
|
||||
end
|
||||
local filename, err = dumplib.convert_eml_to_html(input,output)
|
||||
if err then return oops(err) end
|
||||
local input = "dumpdata.eml"
|
||||
local output = os.date("%Y-%m-%d_%H%M%S.html");
|
||||
for o, a in getopt.getopt(args, 'i:o:h') do
|
||||
if o == "h" then return help() end
|
||||
if o == "i" then input = a end
|
||||
if o == "o" then output = a end
|
||||
end
|
||||
local filename, err = dumplib.convert_eml_to_html(input,output)
|
||||
if err then return oops(err) end
|
||||
|
||||
print(("Wrote a HTML dump to the file %s"):format(filename))
|
||||
print(("Wrote a HTML dump to the file %s"):format(filename))
|
||||
end
|
||||
|
||||
--[[
|
||||
In the future, we may implement so that scripts are invoked directly
|
||||
In the future, we may implement so that scripts are invoked directly
|
||||
into a 'main' function, instead of being executed blindly. For future
|
||||
compatibility, I have done so, but I invoke my main from here.
|
||||
compatibility, I have done so, but I invoke my main from here.
|
||||
--]]
|
||||
main(args)
|
||||
+215
-215
@@ -1,216 +1,216 @@
|
||||
local cmds = require('commands')
|
||||
local getopt = require('getopt')
|
||||
local bin = require('bin')
|
||||
local lib14a = require('read14a')
|
||||
local utils = require('utils')
|
||||
|
||||
example = [[
|
||||
-- generate commands
|
||||
1. script run formatMifare
|
||||
|
||||
-- generate command, replacing key with new key.
|
||||
2. script run formatMifare -k aabbccddeeff -n 112233445566 -a FF0780
|
||||
|
||||
-- generate commands and excute them against card.
|
||||
3. script run formatMifare -x
|
||||
]]
|
||||
copyright = ''
|
||||
version = ''
|
||||
author = 'Iceman'
|
||||
usage = [[
|
||||
script run formatMifare -k <key> -n <key> -a <access> -x
|
||||
]]
|
||||
desc = [[
|
||||
This script will generate 'hf mf wrbl' commands for each block to format a Mifare card.
|
||||
|
||||
Alla datablocks gets 0x00
|
||||
As default the script sets the keys A/B to 0xFFFFFFFFFFFF
|
||||
and the access bytes will become 0x78,0x77,0x88
|
||||
The GDB will become 0x00
|
||||
|
||||
The script will skip the manufactoring block 0.
|
||||
|
||||
|
||||
Arguments:
|
||||
-h - this help
|
||||
-k <key> - the current six byte key with write access
|
||||
-n <key> - the new key that will be written to the card
|
||||
-a <access> - the new access bytes that will be written to the card
|
||||
-x - execute the commands aswell.
|
||||
]]
|
||||
local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
|
||||
local DEBUG = true -- the debug flag
|
||||
local CmdString = 'hf mf wrbl %d B %s %s'
|
||||
local numBlocks = 64
|
||||
local numSectors = 16
|
||||
---
|
||||
-- A debug printout-function
|
||||
function dbg(args)
|
||||
if not DEBUG then
|
||||
return
|
||||
end
|
||||
|
||||
if type(args) == "table" then
|
||||
local i = 1
|
||||
while result[i] do
|
||||
dbg(result[i])
|
||||
i = i+1
|
||||
end
|
||||
else
|
||||
print("###", args)
|
||||
end
|
||||
end
|
||||
---
|
||||
-- This is only meant to be used when errors occur
|
||||
function oops(err)
|
||||
print("ERROR: ",err)
|
||||
end
|
||||
---
|
||||
-- Usage help
|
||||
function help()
|
||||
print(copyright)
|
||||
print(author)
|
||||
print(version)
|
||||
print(desc)
|
||||
print("Example usage")
|
||||
print(example)
|
||||
end
|
||||
--
|
||||
-- Exit message
|
||||
function ExitMsg(msg)
|
||||
print( string.rep('--',20) )
|
||||
print( string.rep('--',20) )
|
||||
print(msg)
|
||||
print()
|
||||
end
|
||||
--
|
||||
-- Read information from a card
|
||||
function GetCardInfo()
|
||||
result, err = lib14a.read(false, true)
|
||||
if not result then
|
||||
print(err)
|
||||
return
|
||||
end
|
||||
print(("Found: %s"):format(result.name))
|
||||
|
||||
core.clearCommandBuffer()
|
||||
|
||||
if 0x18 == result.sak then -- NXP MIFARE Classic 4k | Plus 4k
|
||||
-- IFARE Classic 4K offers 4096 bytes split into forty sectors,
|
||||
-- of which 32 are same size as in the 1K with eight more that are quadruple size sectors.
|
||||
numSectors = 40
|
||||
elseif 0x08 == result.sak then -- NXP MIFARE CLASSIC 1k | Plus 2k
|
||||
-- 1K offers 1024 bytes of data storage, split into 16 sector
|
||||
numSectors = 16
|
||||
elseif 0x09 == result.sak then -- NXP MIFARE Mini 0.3k
|
||||
-- MIFARE Classic mini offers 320 bytes split into five sectors.
|
||||
numSectors = 5
|
||||
elseif 0x10 == result.sak then -- NXP MIFARE Plus 2k
|
||||
numSectors = 32
|
||||
elseif 0x01 == result.sak then -- NXP MIFARE TNP3xxx 1K
|
||||
numSectors = 16
|
||||
else
|
||||
print("I don't know how many sectors there are on this type of card, defaulting to 16")
|
||||
end
|
||||
--[[
|
||||
The mifare Classic 1k card has 16 sectors of 4 data blocks each.
|
||||
The first 32 sectors of a mifare Classic 4k card consists of 4 data blocks and the remaining
|
||||
8 sectors consist of 16 data blocks.
|
||||
--]]
|
||||
|
||||
-- Defaults to 16 * 4 = 64 - 1 = 63
|
||||
numBlocks = numSectors * 4 - 1
|
||||
|
||||
if numSectors > 32 then
|
||||
numBlocks = 32*4+ (numSectors-32)*16 -1
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local function main(args)
|
||||
|
||||
print( string.rep('--',20) )
|
||||
print( string.rep('--',20) )
|
||||
print()
|
||||
|
||||
local OldKey, NewKey, Accessbytes
|
||||
local x = false
|
||||
|
||||
-- Arguments for the script
|
||||
for o, a in getopt.getopt(args, 'hk:n:a:x') do
|
||||
if o == "h" then return help() end
|
||||
if o == "k" then OldKey = a end
|
||||
if o == "n" then NewKey = a end
|
||||
if o == "a" then Accessbytes = a end
|
||||
if o == "x" then x = true end
|
||||
end
|
||||
|
||||
-- validate input args.
|
||||
OldKey = OldKey or 'FFFFFFFFFFFF'
|
||||
if #(OldKey) ~= 12 then
|
||||
return oops( string.format('Wrong length of write key (was %d) expected 12', #OldKey))
|
||||
end
|
||||
|
||||
NewKey = NewKey or 'FFFFFFFFFFFF'
|
||||
if #(NewKey) ~= 12 then
|
||||
return oops( string.format('Wrong length of new key (was %d) expected 12', #NewKey))
|
||||
end
|
||||
|
||||
--Accessbytes = Accessbytes or '787788'
|
||||
Accessbytes = Accessbytes or 'FF0780'
|
||||
if #(Accessbytes) ~= 6 then
|
||||
return oops( string.format('Wrong length of accessbytes (was %d) expected 12', #Accessbytes))
|
||||
end
|
||||
|
||||
GetCardInfo()
|
||||
|
||||
-- Show info
|
||||
print( string.format('Estimating number of blocks: %d', numBlocks))
|
||||
print( string.format('Old key: %s', OldKey))
|
||||
print( string.format('New key: %s', NewKey))
|
||||
print( string.format('New Access: %s', Accessbytes))
|
||||
print( string.rep('--',20) )
|
||||
|
||||
-- Set new block data
|
||||
local EMPTY_BL = string.rep('00',16)
|
||||
local EMPTY_SECTORTRAIL = string.format('%s%s%s%s',NewKey,Accessbytes,'00',NewKey)
|
||||
|
||||
dbg( string.format('New sector-trailer : %s',EMPTY_SECTORTRAIL))
|
||||
dbg( string.format('New emptyblock: %s',EMPTY_BL))
|
||||
dbg('')
|
||||
|
||||
if x then
|
||||
print('[Warning] you have used the EXECUTE parameter, which means this will run these commands against card.')
|
||||
end
|
||||
-- Ask
|
||||
local dialogResult = utils.confirm("Do you want to erase this card")
|
||||
if dialogResult == false then
|
||||
return ExitMsg('Quiting it is then. Your wish is my command...')
|
||||
end
|
||||
|
||||
print( string.rep('--',20) )
|
||||
|
||||
-- main loop
|
||||
for block=0,numBlocks,1 do
|
||||
|
||||
local reminder = (block+1) % 4
|
||||
local cmd
|
||||
if reminder == 0 then
|
||||
cmd = CmdString:format(block, OldKey , EMPTY_SECTORTRAIL)
|
||||
else
|
||||
cmd = CmdString:format(block, OldKey , EMPTY_BL)
|
||||
end
|
||||
|
||||
if block ~= 0 then
|
||||
print(cmd)
|
||||
if x then core.console(cmd) end
|
||||
end
|
||||
|
||||
if core.ukbhit() then
|
||||
print("aborted by user")
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local cmds = require('commands')
|
||||
local getopt = require('getopt')
|
||||
local bin = require('bin')
|
||||
local lib14a = require('read14a')
|
||||
local utils = require('utils')
|
||||
|
||||
example = [[
|
||||
-- generate commands
|
||||
1. script run formatMifare
|
||||
|
||||
-- generate command, replacing key with new key.
|
||||
2. script run formatMifare -k aabbccddeeff -n 112233445566 -a FF0780
|
||||
|
||||
-- generate commands and excute them against card.
|
||||
3. script run formatMifare -x
|
||||
]]
|
||||
copyright = ''
|
||||
version = ''
|
||||
author = 'Iceman'
|
||||
usage = [[
|
||||
script run formatMifare -k <key> -n <key> -a <access> -x
|
||||
]]
|
||||
desc = [[
|
||||
This script will generate 'hf mf wrbl' commands for each block to format a Mifare card.
|
||||
|
||||
Alla datablocks gets 0x00
|
||||
As default the script sets the keys A/B to 0xFFFFFFFFFFFF
|
||||
and the access bytes will become 0x78,0x77,0x88
|
||||
The GDB will become 0x00
|
||||
|
||||
The script will skip the manufactoring block 0.
|
||||
|
||||
|
||||
Arguments:
|
||||
-h - this help
|
||||
-k <key> - the current six byte key with write access
|
||||
-n <key> - the new key that will be written to the card
|
||||
-a <access> - the new access bytes that will be written to the card
|
||||
-x - execute the commands aswell.
|
||||
]]
|
||||
local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
|
||||
local DEBUG = true -- the debug flag
|
||||
local CmdString = 'hf mf wrbl %d B %s %s'
|
||||
local numBlocks = 64
|
||||
local numSectors = 16
|
||||
---
|
||||
-- A debug printout-function
|
||||
function dbg(args)
|
||||
if not DEBUG then
|
||||
return
|
||||
end
|
||||
|
||||
if type(args) == "table" then
|
||||
local i = 1
|
||||
while result[i] do
|
||||
dbg(result[i])
|
||||
i = i+1
|
||||
end
|
||||
else
|
||||
print("###", args)
|
||||
end
|
||||
end
|
||||
---
|
||||
-- This is only meant to be used when errors occur
|
||||
function oops(err)
|
||||
print("ERROR: ",err)
|
||||
end
|
||||
---
|
||||
-- Usage help
|
||||
function help()
|
||||
print(copyright)
|
||||
print(author)
|
||||
print(version)
|
||||
print(desc)
|
||||
print("Example usage")
|
||||
print(example)
|
||||
end
|
||||
--
|
||||
-- Exit message
|
||||
function ExitMsg(msg)
|
||||
print( string.rep('--',20) )
|
||||
print( string.rep('--',20) )
|
||||
print(msg)
|
||||
print()
|
||||
end
|
||||
--
|
||||
-- Read information from a card
|
||||
function GetCardInfo()
|
||||
result, err = lib14a.read(false, true)
|
||||
if not result then
|
||||
print(err)
|
||||
return
|
||||
end
|
||||
print(("Found: %s"):format(result.name))
|
||||
|
||||
core.clearCommandBuffer()
|
||||
|
||||
if 0x18 == result.sak then -- NXP MIFARE Classic 4k | Plus 4k
|
||||
-- IFARE Classic 4K offers 4096 bytes split into forty sectors,
|
||||
-- of which 32 are same size as in the 1K with eight more that are quadruple size sectors.
|
||||
numSectors = 40
|
||||
elseif 0x08 == result.sak then -- NXP MIFARE CLASSIC 1k | Plus 2k
|
||||
-- 1K offers 1024 bytes of data storage, split into 16 sector
|
||||
numSectors = 16
|
||||
elseif 0x09 == result.sak then -- NXP MIFARE Mini 0.3k
|
||||
-- MIFARE Classic mini offers 320 bytes split into five sectors.
|
||||
numSectors = 5
|
||||
elseif 0x10 == result.sak then -- NXP MIFARE Plus 2k
|
||||
numSectors = 32
|
||||
elseif 0x01 == result.sak then -- NXP MIFARE TNP3xxx 1K
|
||||
numSectors = 16
|
||||
else
|
||||
print("I don't know how many sectors there are on this type of card, defaulting to 16")
|
||||
end
|
||||
--[[
|
||||
The mifare Classic 1k card has 16 sectors of 4 data blocks each.
|
||||
The first 32 sectors of a mifare Classic 4k card consists of 4 data blocks and the remaining
|
||||
8 sectors consist of 16 data blocks.
|
||||
--]]
|
||||
|
||||
-- Defaults to 16 * 4 = 64 - 1 = 63
|
||||
numBlocks = numSectors * 4 - 1
|
||||
|
||||
if numSectors > 32 then
|
||||
numBlocks = 32*4+ (numSectors-32)*16 -1
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local function main(args)
|
||||
|
||||
print( string.rep('--',20) )
|
||||
print( string.rep('--',20) )
|
||||
print()
|
||||
|
||||
local OldKey, NewKey, Accessbytes
|
||||
local x = false
|
||||
|
||||
-- Arguments for the script
|
||||
for o, a in getopt.getopt(args, 'hk:n:a:x') do
|
||||
if o == "h" then return help() end
|
||||
if o == "k" then OldKey = a end
|
||||
if o == "n" then NewKey = a end
|
||||
if o == "a" then Accessbytes = a end
|
||||
if o == "x" then x = true end
|
||||
end
|
||||
|
||||
-- validate input args.
|
||||
OldKey = OldKey or 'FFFFFFFFFFFF'
|
||||
if #(OldKey) ~= 12 then
|
||||
return oops( string.format('Wrong length of write key (was %d) expected 12', #OldKey))
|
||||
end
|
||||
|
||||
NewKey = NewKey or 'FFFFFFFFFFFF'
|
||||
if #(NewKey) ~= 12 then
|
||||
return oops( string.format('Wrong length of new key (was %d) expected 12', #NewKey))
|
||||
end
|
||||
|
||||
--Accessbytes = Accessbytes or '787788'
|
||||
Accessbytes = Accessbytes or 'FF0780'
|
||||
if #(Accessbytes) ~= 6 then
|
||||
return oops( string.format('Wrong length of accessbytes (was %d) expected 12', #Accessbytes))
|
||||
end
|
||||
|
||||
GetCardInfo()
|
||||
|
||||
-- Show info
|
||||
print( string.format('Estimating number of blocks: %d', numBlocks))
|
||||
print( string.format('Old key: %s', OldKey))
|
||||
print( string.format('New key: %s', NewKey))
|
||||
print( string.format('New Access: %s', Accessbytes))
|
||||
print( string.rep('--',20) )
|
||||
|
||||
-- Set new block data
|
||||
local EMPTY_BL = string.rep('00',16)
|
||||
local EMPTY_SECTORTRAIL = string.format('%s%s%s%s',NewKey,Accessbytes,'00',NewKey)
|
||||
|
||||
dbg( string.format('New sector-trailer : %s',EMPTY_SECTORTRAIL))
|
||||
dbg( string.format('New emptyblock: %s',EMPTY_BL))
|
||||
dbg('')
|
||||
|
||||
if x then
|
||||
print('[Warning] you have used the EXECUTE parameter, which means this will run these commands against card.')
|
||||
end
|
||||
-- Ask
|
||||
local dialogResult = utils.confirm("Do you want to erase this card")
|
||||
if dialogResult == false then
|
||||
return ExitMsg('Quiting it is then. Your wish is my command...')
|
||||
end
|
||||
|
||||
print( string.rep('--',20) )
|
||||
|
||||
-- main loop
|
||||
for block=0,numBlocks,1 do
|
||||
|
||||
local reminder = (block+1) % 4
|
||||
local cmd
|
||||
if reminder == 0 then
|
||||
cmd = CmdString:format(block, OldKey , EMPTY_SECTORTRAIL)
|
||||
else
|
||||
cmd = CmdString:format(block, OldKey , EMPTY_BL)
|
||||
end
|
||||
|
||||
if block ~= 0 then
|
||||
print(cmd)
|
||||
if x then core.console(cmd) end
|
||||
end
|
||||
|
||||
if core.ukbhit() then
|
||||
print("aborted by user")
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
main(args)
|
||||
+12
-12
@@ -1,18 +1,18 @@
|
||||
local reader = require('hf_reader')
|
||||
|
||||
local function main(args)
|
||||
print("WORK IN PROGRESS - not expected to be functional yet")
|
||||
info, err = reader.waitForTag()
|
||||
print("WORK IN PROGRESS - not expected to be functional yet")
|
||||
info, err = reader.waitForTag()
|
||||
|
||||
if err then
|
||||
print(err)
|
||||
return
|
||||
end
|
||||
local k,v
|
||||
print("Tag info")
|
||||
for k,v in pairs(info) do
|
||||
print(string.format(" %s : %s", tostring(k), tostring(v)))
|
||||
end
|
||||
return
|
||||
if err then
|
||||
print(err)
|
||||
return
|
||||
end
|
||||
local k,v
|
||||
print("Tag info")
|
||||
for k,v in pairs(info) do
|
||||
print(string.format(" %s : %s", tostring(k), tostring(v)))
|
||||
end
|
||||
return
|
||||
end
|
||||
main(args)
|
||||
+29
-29
@@ -8,58 +8,58 @@ example = "script run htmldump -o mifarecard_foo.html"
|
||||
author = "Martin Holst Swende"
|
||||
usage = "script run htmldump [-i <file>] [-o <file>]"
|
||||
desc =[[
|
||||
This script takes a dumpfile and produces a html based dump, which is a
|
||||
bit more easily analyzed.
|
||||
This script takes a dumpfile and produces a html based dump, which is a
|
||||
bit more easily analyzed.
|
||||
|
||||
Arguments:
|
||||
-h This help
|
||||
-i <file> Specifies the dump-file (input). If omitted, 'dumpdata.bin' is used
|
||||
-o <filename> Speciies the output file. If omitted, <curtime>.html is used.
|
||||
-h This help
|
||||
-i <file> Specifies the dump-file (input). If omitted, 'dumpdata.bin' is used
|
||||
-o <filename> Speciies the output file. If omitted, <curtime>.html is used.
|
||||
|
||||
]]
|
||||
|
||||
-------------------------------
|
||||
-- Some utilities
|
||||
-- Some utilities
|
||||
-------------------------------
|
||||
|
||||
---
|
||||
---
|
||||
-- A debug printout-function
|
||||
function dbg(args)
|
||||
if DEBUG then
|
||||
print("###", args)
|
||||
end
|
||||
end
|
||||
---
|
||||
if DEBUG then
|
||||
print("###", args)
|
||||
end
|
||||
end
|
||||
---
|
||||
-- This is only meant to be used when errors occur
|
||||
function oops(err)
|
||||
print("ERROR: ",err)
|
||||
print("ERROR: ",err)
|
||||
end
|
||||
---
|
||||
---
|
||||
-- Usage help
|
||||
function help()
|
||||
print(desc)
|
||||
print("Example usage")
|
||||
print(example)
|
||||
print(desc)
|
||||
print("Example usage")
|
||||
print(example)
|
||||
end
|
||||
|
||||
local function main(args)
|
||||
|
||||
local input = "dumpdata.bin"
|
||||
local output = os.date("%Y-%m-%d_%H%M%S.html");
|
||||
for o, a in getopt.getopt(args, 'i:o:h') do
|
||||
if o == "h" then return help() end
|
||||
if o == "i" then input = a end
|
||||
if o == "o" then output = a end
|
||||
end
|
||||
local filename, err = dumplib.convert_bin_to_html(input,output,16)
|
||||
if err then return oops(err) end
|
||||
local input = "dumpdata.bin"
|
||||
local output = os.date("%Y-%m-%d_%H%M%S.html");
|
||||
for o, a in getopt.getopt(args, 'i:o:h') do
|
||||
if o == "h" then return help() end
|
||||
if o == "i" then input = a end
|
||||
if o == "o" then output = a end
|
||||
end
|
||||
local filename, err = dumplib.convert_bin_to_html(input,output,16)
|
||||
if err then return oops(err) end
|
||||
|
||||
print(("Wrote a HTML dump to the file %s"):format(filename))
|
||||
print(("Wrote a HTML dump to the file %s"):format(filename))
|
||||
end
|
||||
|
||||
--[[
|
||||
In the future, we may implement so that scripts are invoked directly
|
||||
In the future, we may implement so that scripts are invoked directly
|
||||
into a 'main' function, instead of being executed blindly. For future
|
||||
compatibility, I have done so, but I invoke my main from here.
|
||||
compatibility, I have done so, but I invoke my main from here.
|
||||
--]]
|
||||
main(args)
|
||||
@@ -7,112 +7,112 @@ copyright = 'Copyright (c) 2018 IceSQL AB. All rights reserved.'
|
||||
author = 'Christian Herrmann'
|
||||
version = 'v1.0.4'
|
||||
desc = [[
|
||||
This script tries to set UID on a IS15693 SLIX magic card
|
||||
This script tries to set UID on a IS15693 SLIX magic card
|
||||
Remember the UID ->MUST<- start with 0xE0
|
||||
]]
|
||||
example = [[
|
||||
|
||||
-- ISO15693 slix magic tag
|
||||
-- ISO15693 slix magic tag
|
||||
|
||||
script run iso15_magic -u E004013344556677
|
||||
|
||||
script run iso15_magic -u E004013344556677 -a
|
||||
script run iso15_magic -u E004013344556677
|
||||
|
||||
script run iso15_magic -u E004013344556677 -a
|
||||
]]
|
||||
usage = [[
|
||||
script run iso15_magic -h -u <uid>
|
||||
|
||||
Arguments:
|
||||
-h : this help
|
||||
-u <UID> : UID (16 hexsymbols)
|
||||
-a : use offical pm3 repo ISO15 commands instead of iceman fork.
|
||||
-h : this help
|
||||
-u <UID> : UID (16 hexsymbols)
|
||||
-a : use offical pm3 repo ISO15 commands instead of iceman fork.
|
||||
]]
|
||||
|
||||
local DEBUG = true
|
||||
---
|
||||
---
|
||||
-- A debug printout-function
|
||||
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
|
||||
---
|
||||
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)
|
||||
return nil, err
|
||||
print("ERROR: ",err)
|
||||
return nil, err
|
||||
end
|
||||
---
|
||||
---
|
||||
-- Usage help
|
||||
local function help()
|
||||
print(copyright)
|
||||
print(author)
|
||||
print(version)
|
||||
print(desc)
|
||||
print('Example usage')
|
||||
print(example)
|
||||
print(copyright)
|
||||
print(author)
|
||||
print(version)
|
||||
print(desc)
|
||||
print('Example usage')
|
||||
print(example)
|
||||
end
|
||||
--
|
||||
--- Set UID on magic command enabled on a ICEMAN based REPO
|
||||
local function magicUID_iceman(b0, b1)
|
||||
print('Using backdoor Magic tag function')
|
||||
core.console("hf 15 raw -2 -c 02213E00000000")
|
||||
core.console("hf 15 raw -2 -c 02213F69960000")
|
||||
core.console("hf 15 raw -2 -c 022138"..b1)
|
||||
core.console("hf 15 raw -2 -c 022139"..b0)
|
||||
print('Using backdoor Magic tag function')
|
||||
core.console("hf 15 raw -2 -c 02213E00000000")
|
||||
core.console("hf 15 raw -2 -c 02213F69960000")
|
||||
core.console("hf 15 raw -2 -c 022138"..b1)
|
||||
core.console("hf 15 raw -2 -c 022139"..b0)
|
||||
end
|
||||
--
|
||||
--- Set UID on magic command enabled, OFFICAL REPO
|
||||
local function magicUID_offical(b0, b1)
|
||||
print('Using backdoor Magic tag function OFFICAL REPO')
|
||||
core.console("hf 15 cmd raw -c 02213E00000000")
|
||||
core.console("hf 15 cmd raw -c 02213F69960000")
|
||||
core.console("hf 15 cmd raw -c 022138"..b1)
|
||||
core.console("hf 15 cmd raw -c 022139"..b0)
|
||||
print('Using backdoor Magic tag function OFFICAL REPO')
|
||||
core.console("hf 15 cmd raw -c 02213E00000000")
|
||||
core.console("hf 15 cmd raw -c 02213F69960000")
|
||||
core.console("hf 15 cmd raw -c 022138"..b1)
|
||||
core.console("hf 15 cmd raw -c 022139"..b0)
|
||||
end
|
||||
---
|
||||
---
|
||||
-- The main entry point
|
||||
function main(args)
|
||||
|
||||
print( string.rep('--',20) )
|
||||
print( string.rep('--',20) )
|
||||
print()
|
||||
print( string.rep('--',20) )
|
||||
print( string.rep('--',20) )
|
||||
print()
|
||||
|
||||
local uid = 'E004013344556677'
|
||||
local use_iceman = true
|
||||
|
||||
-- Read the parameters
|
||||
for o, a in getopt.getopt(args, 'hu:a') do
|
||||
if o == "h" then return help() end
|
||||
if o == "u" then uid = a end
|
||||
if o == "a" then use_iceman = false end
|
||||
end
|
||||
|
||||
-- uid string checks
|
||||
if uid == nil then return oops('empty uid string') end
|
||||
if #uid == 0 then return oops('empty uid string') end
|
||||
if #uid ~= 16 then return oops('uid wrong length. Should be 8 hex bytes') end
|
||||
local uid = 'E004013344556677'
|
||||
local use_iceman = true
|
||||
|
||||
local bytes = utils.ConvertHexToBytes(uid)
|
||||
|
||||
local block0 = string.format('%02X%02X%02X%02X', bytes[4], bytes[3], bytes[2], bytes[1])
|
||||
local block1 = string.format('%02X%02X%02X%02X', bytes[8], bytes[7], bytes[6], bytes[5])
|
||||
|
||||
print('new UID | '..uid)
|
||||
|
||||
core.clearCommandBuffer()
|
||||
|
||||
if use_iceman then
|
||||
magicUID_iceman(block0, block1)
|
||||
else
|
||||
magicUID_offical(block0, block1)
|
||||
end
|
||||
-- Read the parameters
|
||||
for o, a in getopt.getopt(args, 'hu:a') do
|
||||
if o == "h" then return help() end
|
||||
if o == "u" then uid = a end
|
||||
if o == "a" then use_iceman = false end
|
||||
end
|
||||
|
||||
-- uid string checks
|
||||
if uid == nil then return oops('empty uid string') end
|
||||
if #uid == 0 then return oops('empty uid string') end
|
||||
if #uid ~= 16 then return oops('uid wrong length. Should be 8 hex bytes') end
|
||||
|
||||
local bytes = utils.ConvertHexToBytes(uid)
|
||||
|
||||
local block0 = string.format('%02X%02X%02X%02X', bytes[4], bytes[3], bytes[2], bytes[1])
|
||||
local block1 = string.format('%02X%02X%02X%02X', bytes[8], bytes[7], bytes[6], bytes[5])
|
||||
|
||||
print('new UID | '..uid)
|
||||
|
||||
core.clearCommandBuffer()
|
||||
|
||||
if use_iceman then
|
||||
magicUID_iceman(block0, block1)
|
||||
else
|
||||
magicUID_offical(block0, block1)
|
||||
end
|
||||
end
|
||||
|
||||
main(args)
|
||||
|
||||
+353
-353
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user