proxmark3/client/luascripts/lf_em4100_bulk.lua
iceman1001 9028c05539 style
2021-05-04 16:45:25 +02:00

212 lines
5.9 KiB
Lua

local getopt = require('getopt')
local utils = require('utils')
local ac = require('ansicolors')
copyright = ''
author = "Christian Herrmann"
version = 'v1.0.2'
desc = [[
Perform bulk EM410x enrollment of T5577 RFID tags. It keeps track of last card id used.
If called with -s, this value resets "session".
if press <enter> it defaults to Y, which writes a ID.
Any other input char will exit the script.
You can supply a password, which will set the config block / block 7 on the T5577.
The verify option will issue a 'lf em 410x reader' command, so you can manually verify
that the write worked.
]]
example = [[
-- resets and start enrolling EM410x id 11CC334455
script run lf_em4100_bulk.lua -s 11CC334455
-- continue enrolling from where last iteration
script run lf_em4100_bulk.lua -c
-- reset and start enrolling from 11223344,
-- protecting the tag with password 010203
-- and verify the em id write.
script run lf_em4100_bulk.lua -s 1122334455 -p 01020304 -v
]]
usage = [[
script run lf_en4100_bulk.lua [-h] [-c] [-p password] [-s <start cn>] [-v]
]]
arguments = [[
-h : this help
-c : continue from last card number used
-p : Password protecting the T5577.
-s : starting card number
-v : verify write by executing a `lf em 410x reader`
]]
-- Some globals
local DEBUG = false
local ENROLL_STATUS_FN = 'lf_em4100_status.txt'
---
-- 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
---
-- This is only meant to be used when errors occur
local function oops(err)
print('ERROR:', err)
core.clearCommandBuffer()
return nil, errr
end
---
-- Usage help
local function help()
print(copyright)
print(author)
print(version)
print(desc)
print(ac.cyan..'Usage'..ac.reset)
print(usage)
print(ac.cyan..'Arguments'..ac.reset)
print(arguments)
print(ac.cyan..'Example usage'..ac.reset)
print(example)
end
---
-- Exit message
local function exitMsg(msg)
print( string.rep('--',20) )
print( string.rep('--',20) )
print(msg)
print()
end
---
--
local function readfile()
local f = io.open(ENROLL_STATUS_FN, "r")
if f == nil then
return nil, string.format("Could not read file %s", ENROLL_STATUS_FN)
end
local t = f:read("*all")
f:close()
local cn_hi = tonumber(t:sub(1, 2), 16)
local cn_low = tonumber(t:sub(3, 10), 16)
print(('Using EM4100 ID '..ac.green..'%02X%08X'..ac.reset..' from `'..ac.yellow..'%s'..ac.reset..'`'):format(cn_hi, cn_low, ENROLL_STATUS_FN))
return cn_hi, cn_low
end
---
--
local function writefile(cn_hi, cn_low)
local f = io.open(ENROLL_STATUS_FN, "w")
if f == nil then
return nil, string.format("Could not write to file %s", ENROLL_STATUS_FN)
end
f:write(("%02X%08X\n"):format(cn_hi, cn_low))
f:close()
print(('Wrote EM4100 ID '..ac.green..'%02X%08X'..ac.reset..' to `'..ac.yellow..'%s'..ac.reset..'`'):format(cn_hi, cn_low, ENROLL_STATUS_FN))
return true, 'Ok'
end
---
-- main
local function main(args)
print( string.rep('--',20) )
print( string.rep('--',20) )
print()
if #args == 0 then return help() end
local shall_verify = false
local shall_continue = false
local got_pwd = false
local startid = ''
local ipwd = ''
for o, a in getopt.getopt(args, 'cp:s:hv') do
if o == 'h' then return help() end
if o == 'c' then shall_continue = true end
if o == 's' then startid = a end
if o == 'p' then
ipwd = a
got_pwd = true
end
if o == 'v' then shall_verify = true end
end
-- if reset/start over, check -s
if not shall_continue then
if startid == nil then return oops('empty card number string') end
if #startid == 0 then return oops('empty card number string') end
if #startid ~= 10 then return oops('card number wrong length. Must be 5 hex bytes') end
end
if got_pwd then
if ipwd == nil then return oops('empty password') end
if #ipwd == 0 then return oops('empty password') end
if #ipwd ~= 8 then return oops('password wrong length. Must be 4 hex bytes') end
end
core.console('clear')
print(ac.red..'disable hints for less output'..ac.reset)
core.console('pref set hint --off')
print('')
local hi = tonumber(startid:sub(1, 2), 16)
local low = tonumber(startid:sub(3, 10), 16)
local pwd = tonumber(ipwd, 16)
if got_pwd then
print(('Will protect T5577 with password '..ac.green..'%08X'..ac.reset):format(pwd))
end
if shall_verify then
print('Will verify write afterwards')
end
if shall_continue then
print('Continue enrolling from last save')
hi, low = readfile()
else
print('reset & starting enrolling from refresh')
end
local template = 'EM4100 ID '..ac.green..'%02X%08X'..ac.reset
for i = low, low + 10000, 1 do
print('')
print( string.rep('--',20) )
local msg = (template):format(hi, i)
local ans = utils.input(msg, 'y'):lower()
if ans == 'y' then
core.console( ('lf em 410x clone --id %02X%08X'):format(hi, i) )
-- print ( ('lf em 410x clone --id %02X%08X'):format(hi, i) )
if got_pwd then
core.console('lf t55 detect')
core.console(('lf t55 protect -n %08x'):format(pwd))
end
if shall_verify then
core.console('lf em 410x reader')
end
else
print(ac.red..'User aborted'..ac.reset)
low = i
break
end
end
writefile(hi, low)
print('enabling hints again')
core.console('pref set hint --on')
end
main(args)