]> git.zerfleddert.de Git - proxmark3-svn/blob - client/scripts/tnp3.lua
ADD: added identification for Mifare TNP3xxx tags.
[proxmark3-svn] / client / scripts / tnp3.lua
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')
7
8 example =[[
9 1. script run tnp3
10 2. script run tnp3 -k aabbccddeeff
11 ]]
12 author = "Iceman"
13 usage = "script run tnp3 -k <key>"
14 desc =[[
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.
17 Arguments:
18 -h - this help
19 -k <key> - Sector 0 Key A.
20 ]]
21
22 local hashconstant = '20436F707972696768742028432920323031302041637469766973696F6E2E20416C6C205269676874732052657365727665642E20'
23
24 local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
25 local DEBUG = true -- the debug flag
26 local numBlocks = 64
27 local numSectors = 16
28 ---
29 -- A debug printout-function
30 function dbg(args)
31 if not DEBUG then
32 return
33 end
34
35 if type(args) == "table" then
36 local i = 1
37 while result[i] do
38 dbg(result[i])
39 i = i+1
40 end
41 else
42 print("###", args)
43 end
44 end
45 ---
46 -- This is only meant to be used when errors occur
47 function oops(err)
48 print("ERROR: ",err)
49 end
50 ---
51 -- Usage help
52 function help()
53 print(desc)
54 print("Example usage")
55 print(example)
56 end
57 --
58 -- Exit message
59 function ExitMsg(msg)
60 print( string.rep('--',20) )
61 print( string.rep('--',20) )
62 print(msg)
63 print()
64 end
65
66 local function show(data)
67 if DEBUG then
68 local formatString = ("H%d"):format(string.len(data))
69 local _,hexdata = bin.unpack(formatString, data)
70 dbg("Hexdata" , hexdata)
71 end
72 end
73
74 function waitCmd()
75 local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT)
76 if response then
77 local count,cmd,arg0 = bin.unpack('LL',response)
78 if(arg0==1) then
79 local count,arg1,arg2,data = bin.unpack('LLH511',response,count)
80 return data:sub(1,32)
81 else
82 return nil, "Couldn't read block.."
83 end
84 end
85 return nil, "No response from device"
86 end
87
88 local function main(args)
89
90 print( string.rep('--',20) )
91 print( string.rep('--',20) )
92 print()
93
94 local keyA
95 local cmd
96 local err
97 local cmdReadBlockString = 'hf mf rdbl %d A %s'
98
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
103 end
104
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))
109 end
110
111 result, err = lib14a.read1443a(false)
112 if not result then
113 print(err)
114 return
115 end
116 print((" Found tag : %s"):format(result.name))
117
118 core.clearCommandBuffer()
119
120 if 0x01 ~= result.sak then -- NXP MIFARE TNP3xxx
121 print("This is not a TNP3xxx tag. aborting.")
122 return
123 end
124
125 -- Show info
126 print(('Using keyA : %s'):format(keyA))
127 print( string.rep('--',20) )
128
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)
133
134 print('Reading data need to dump data')
135
136 -- Read block 0
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
142
143 -- Read block 1
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
149
150
151 -- Read block 9
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
157
158 -- main loop
159 print('BLOCK MD5 DECRYPTED ASCII' )
160
161 for block=0,numBlocks-1,1 do
162
163 if math.fmod(block,4) then
164
165 end
166
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 )
170
171 local _,hex = bin.unpack(("H%d"):format(16),aestest)
172
173
174 local hexascii = string.gsub(hex, '(%x%x)',
175 function(value)
176 return string.char(tonumber(value, 16))
177 end
178 )
179
180 print( block .. ' :: ' .. md5hash .. ' :: ' .. hex .. ' :: ' .. hexascii )
181
182 -- if core.ukbhit() then
183 -- print("aborted by user")
184 -- break
185 -- end
186 end
187 end
188
189 main(args)
Impressum, Datenschutz