1 local cmds = require('commands')
2 local getopt = require('getopt')
3 local bin = require('bin')
4 local lib14a = require('read14a')
5 local utils = require('utils')
6 local md5 = require('md5')
10 2. script run tnp3 -k aabbccddeeff
13 usage = "script run tnp3 -k <key>"
15 This script will try to dump the contents of a Mifare TNP3xxx card.
16 It will need a valid KeyA in order to find the other keys and decode the card.
19 -k <key> - Sector 0 Key A.
22 local hashconstant = '20436F707972696768742028432920323031302041637469766973696F6E2E20416C6C205269676874732052657365727665642E20'
24 local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
25 local DEBUG = true -- the debug flag
29 -- A debug printout-function
35 if type(args) == "table" then
46 -- This is only meant to be used when errors occur
54 print("Example usage")
60 print( string.rep('--',20) )
61 print( string.rep('--',20) )
66 local function show(data)
68 local formatString = ("H%d"):format(string.len(data))
69 local _,hexdata = bin.unpack(formatString, data)
70 dbg("Hexdata" , hexdata)
75 local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT)
77 local count,cmd,arg0 = bin.unpack('LL',response)
79 local count,arg1,arg2,data = bin.unpack('LLH511',response,count)
82 return nil, "Couldn't read block.."
85 return nil, "No response from device"
88 local function main(args)
90 print( string.rep('--',20) )
91 print( string.rep('--',20) )
97 local cmdReadBlockString = 'hf mf rdbl %d A %s'
99 -- Arguments for the script
100 for o, a in getopt.getopt(args, 'hk:') do
101 if o == "h" then return help() end
102 if o == "k" then keyA = a end
105 -- validate input args.
106 keyA = keyA or '4b0b20107ccb'
107 if #(keyA) ~= 12 then
108 return oops( string.format('Wrong length of write key (was %d) expected 12', #keyA))
111 result, err = lib14a.read1443a(false)
116 print((" Found tag : %s"):format(result.name))
118 core.clearCommandBuffer()
120 if 0x01 ~= result.sak then -- NXP MIFARE TNP3xxx
121 print("This is not a TNP3xxx tag. aborting.")
126 print(('Using keyA : %s'):format(keyA))
127 print( string.rep('--',20) )
129 local cmdNestedString = 'hf mf nested 1 0 A %s d'
130 local cmdDumpString = 'hf mf dump'
131 --core.console(cmdNestedString.format(keyA) )
132 --core.console(cmdDumpString)
134 print('Reading data need to dump data')
137 cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = 0,arg2 = 0,arg3 = 0, data = keyA}
138 err = core.SendCommand(cmd:getBytes())
139 if err then return oops(err) end
140 local block0, err = waitCmd()
141 if err then return oops(err) end
144 cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = 1,arg2 = 0,arg3 = 0, data = keyA}
145 local err = core.SendCommand(cmd:getBytes())
146 if err then return oops(err) end
147 local block1, err = waitCmd()
148 if err then return oops(err) end
152 cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = 9,arg2 = 0,arg3 = 0, data = '56f6313550f9'}
153 local err = core.SendCommand(cmd:getBytes())
154 if err then return oops(err) end
155 local block9, err = waitCmd()
156 if err then return oops(err) end
159 print('BLOCK MD5 DECRYPTED ASCII' )
161 for block=0,numBlocks-1,1 do
163 if math.fmod(block,4) then
167 local base = ('%s%s%02d%s'):format(block0, block1, block, hashconstant)
168 local md5hash = md5.sumhexa(base)
169 local aestest = core.aes(md5hash, block9 )
171 local _,hex = bin.unpack(("H%d"):format(16),aestest)
174 local hexascii = string.gsub(hex, '(%x%x)',
176 return string.char(tonumber(value, 16))
180 print( block .. ' :: ' .. md5hash .. ' :: ' .. hex .. ' :: ' .. hexascii )
182 -- if core.ukbhit() then
183 -- print("aborted by user")