]> git.zerfleddert.de Git - proxmark3-svn/blame - client/scripts/tnp3.lua
fixing scripts/tnp3.lua
[proxmark3-svn] / client / scripts / tnp3.lua
CommitLineData
c15d2bdc 1local cmds = require('commands')
2local getopt = require('getopt')
3local bin = require('bin')
4local lib14a = require('read14a')
5local utils = require('utils')
6local md5 = require('md5')
7
8example =[[
9 1. script run tnp3
10 2. script run tnp3 -k aabbccddeeff
11]]
12author = "Iceman"
13usage = "script run tnp3 -k <key>"
14desc =[[
15This script will try to dump the contents of a Mifare TNP3xxx card.
16It will need a valid KeyA in order to find the other keys and decode the card.
17Arguments:
18 -h - this help
19 -k <key> - Sector 0 Key A.
20]]
21
22local hashconstant = '20436F707972696768742028432920323031302041637469766973696F6E2E20416C6C205269676874732052657365727665642E20'
23
24local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
25local DEBUG = true -- the debug flag
26local numBlocks = 64
27local numSectors = 16
28---
29-- A debug printout-function
30function 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
44end
45---
46-- This is only meant to be used when errors occur
47function oops(err)
48 print("ERROR: ",err)
49end
50---
51-- Usage help
52function help()
53 print(desc)
54 print("Example usage")
55 print(example)
56end
57--
58-- Exit message
59function ExitMsg(msg)
60 print( string.rep('--',20) )
61 print( string.rep('--',20) )
62 print(msg)
63 print()
64end
65
66local 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
72end
73
c70cef97 74local function readdumpkeys(infile)
75 t = infile:read("*all")
76 len = string.len(t)
77 local len,hex = bin.unpack(("H%d"):format(len),t)
78 --print(len,hex)
79 return hex
80end
81
82local function waitCmd()
c15d2bdc 83 local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT)
84 if response then
85 local count,cmd,arg0 = bin.unpack('LL',response)
86 if(arg0==1) then
87 local count,arg1,arg2,data = bin.unpack('LLH511',response,count)
88 return data:sub(1,32)
89 else
90 return nil, "Couldn't read block.."
91 end
92 end
93 return nil, "No response from device"
94end
95
96local function main(args)
97
98 print( string.rep('--',20) )
99 print( string.rep('--',20) )
100 print()
101
102 local keyA
103 local cmd
104 local err
105 local cmdReadBlockString = 'hf mf rdbl %d A %s'
c70cef97 106 local input = "dumpkeys.bin"
c15d2bdc 107
108 -- Arguments for the script
109 for o, a in getopt.getopt(args, 'hk:') do
110 if o == "h" then return help() end
111 if o == "k" then keyA = a end
112 end
113
114 -- validate input args.
115 keyA = keyA or '4b0b20107ccb'
116 if #(keyA) ~= 12 then
117 return oops( string.format('Wrong length of write key (was %d) expected 12', #keyA))
118 end
119
120 result, err = lib14a.read1443a(false)
121 if not result then
122 print(err)
123 return
124 end
c70cef97 125 print((' Found tag : %s'):format(result.name))
c15d2bdc 126
127 core.clearCommandBuffer()
128
129 if 0x01 ~= result.sak then -- NXP MIFARE TNP3xxx
c70cef97 130 print('This is not a TNP3xxx tag. aborting.')
c15d2bdc 131 return
132 end
133
134 -- Show info
135 print(('Using keyA : %s'):format(keyA))
136 print( string.rep('--',20) )
137
c70cef97 138 print('Trying to find other keys. ')
139 --core.console( ('hf mf nested 1 0 A %s d'):format(keyA) )
140
141 -- Reading found keys file
142 local infile = io.open(input, "rb")
143 if infile == nil then
144 return oops('Could not read file ', input)
145 end
146 local akeys = readdumpkeys(infile):sub(0,12*16)
c15d2bdc 147
c70cef97 148 --print( ('KEYS: %s'):format(akeys))
149
c15d2bdc 150 print('Reading data need to dump data')
151
152 -- Read block 0
153 cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = 0,arg2 = 0,arg3 = 0, data = keyA}
154 err = core.SendCommand(cmd:getBytes())
155 if err then return oops(err) end
156 local block0, err = waitCmd()
157 if err then return oops(err) end
158
159 -- Read block 1
160 cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = 1,arg2 = 0,arg3 = 0, data = keyA}
161 local err = core.SendCommand(cmd:getBytes())
162 if err then return oops(err) end
163 local block1, err = waitCmd()
164 if err then return oops(err) end
165
c70cef97 166 print('Dumping data')
c15d2bdc 167
c15d2bdc 168 -- main loop
169 print('BLOCK MD5 DECRYPTED ASCII' )
c70cef97 170
171 local key
172 local keyPosStart = 0
173 local block
174 for block = 0, numBlocks-1, 1 do
175 local b = (block+1)%4
176 if b ~= 0 then
177 keyPosStart = (math.floor( block / 4 ) * 12)+1
178 key = akeys:sub(keyPosStart, keyPosStart + 12 )
179 --print( ('%02d %s'):format(block, key))
c15d2bdc 180
c70cef97 181 cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = block ,arg2 = 0,arg3 = 0, data = key}
182 local err = core.SendCommand(cmd:getBytes())
183 if err then return oops(err) end
184 local blockdata, err = waitCmd()
185 if err then return oops(err) end
c15d2bdc 186
c70cef97 187 local base = ('%s%s%02d%s'):format(block0, block1, block, hashconstant)
188 local md5hash = md5.sumhexa(base)
189 local aestest = core.aes(md5hash, blockdata)
c15d2bdc 190
c70cef97 191 local _,hex = bin.unpack(("H%d"):format(16),aestest)
c15d2bdc 192
c70cef97 193 local hexascii = string.gsub(hex, '(%x%x)',
c15d2bdc 194 function(value)
195 return string.char(tonumber(value, 16))
196 end
197 )
198
c70cef97 199 print( ('%02d :: %s :: %s :: %s :: %s'):format(block,key,md5hash,hex,hexascii) )
c15d2bdc 200
c70cef97 201 if core.ukbhit() then
202 print("aborted by user")
203 break
204 end
205 end
c15d2bdc 206 end
207end
208
209main(args)
Impressum, Datenschutz