text
[RRG-proxmark3.git] / client / luascripts / hf_mf_ultimatecard.lua
blob09040eea5353c0ccdbad069aeadacffe1b26d05f
1 local cmds = require('commands')
2 local getopt = require('getopt')
3 local lib14a = require('read14a')
4 local utils = require('utils')
5 local ansicolors = require('ansicolors')
7 -- global
8 local DEBUG = false -- the debug flag
9 local bxor = bit32.bxor
10 local _ntagpassword = nil
11 local _key = '00000000' -- default UMC key
12 local err_lock = 'use -k or change cfg0 block'
13 local _print = 0
14 copyright = ''
15 author = 'Nathan Glaser'
16 version = 'v1.0.5'
17 date = 'Created - Jan 2022'
18 desc = 'This script enables easy programming of an Ultimate Mifare Magic card'
19 example = [[
20 -- read magic tag configuration
21 ]]..ansicolors.yellow..[[script run hf_mf_ultimatecard -c ]]..ansicolors.reset..[[
23 -- set uid
24 ]]..ansicolors.yellow..[[script run hf_mf_ultimatecard -u 04E10CDA993C80 ]]..ansicolors.reset..[[
26 -- set NTAG pwd / pack
27 ]]..ansicolors.yellow..[[script run hf_mf_ultimatecard -p 11223344 -a 8080 ]]..ansicolors.reset..[[
29 -- set version to NTAG213
30 ]]..ansicolors.yellow..[[script run hf_mf_ultimatecard -v 0004040201000f03 ]]..ansicolors.reset..[[
32 -- set ATQA/SAK to [00 44] [08]
33 ]]..ansicolors.yellow..[[script run hf_mf_ultimatecard -q 004408 ]]..ansicolors.reset..[[
35 -- wipe tag with a NTAG213 or Mifare 1k S50 4 byte
36 ]]..ansicolors.yellow..[[script run hf_mf_ultimatecard -w 1]]..ansicolors.reset..[[
38 -- use a non default UMC key. Only use this if the default key for the MAGIC CARD was changed.
39 ]]..ansicolors.yellow..[[script run hf_mf_ultimatecard -k ffffffff -w 1]]..ansicolors.reset..[[
41 -- Wipe tag, turn into NTAG215, set sig, version, NTAG pwd/pak, and OTP.
42 ]]..ansicolors.yellow..[[script run hf_mf_ultimatecard -w 1 -t 18 -u 04E10CDA993C80 -s 8B76052EE42F5567BEB53238B3E3F9950707C0DCC956B5C5EFCFDB709B2D82B3 -p FFFFFFFF -a 8080 -o 11111111]]..ansicolors.reset..[[
45 usage = [[
46 script run hf_mf_ultimatecard -h -k <passwd> -c -w <type> -u <uid> -t <type> -p <passwd> -a <pack> -s <signature> -o <otp> -v <version> -q <atqa/sak> -g <gtu> -z <ats> -m <ul-mode> -n <ul-protocol>
48 arguments = [[
49 -h this help
50 -c read magic configuration
51 -u UID (8-20 hexsymbols), set UID on tag
52 -t tag type to impersonate
53 1 = Mifare Mini S20 4-byte
54 2 = Mifare Mini S20 7-byte 15 = NTAG 210
55 3 = Mifare Mini S20 10-byte 16 = NTAG 212
56 4 = Mifare 1k S50 4-byte 17 = NTAG 213
57 5 = Mifare 1k S50 7-byte 18 = NTAG 215
58 6 = Mifare 1k S50 10-byte 19 = NTAG 216
59 7 = Mifare 4k S70 4-byte 20 = NTAG I2C 1K
60 8 = Mifare 4k S70 7-byte 21 = NTAG I2C 2K
61 9 = Mifare 4k S70 10-byte 22 = NTAG I2C 1K PLUS
62 *** 10 = UL - NOT WORKING FULLY 23 = NTAG I2C 2K PLUS
63 *** 11 = UL-C - NOT WORKING FULLY 24 = NTAG 213F
64 12 = UL EV1 48b 25 = NTAG 216F
65 13 = UL EV1 128b
66 *** 14 = UL Plus - NOT WORKING YET
68 -p NTAG password (8 hexsymbols), set NTAG password on tag.
69 -a NTAG pack ( 4 hexsymbols), set NTAG pack on tag.
70 -s Signature data (64 hexsymbols), set signature data on tag.
71 -o OTP data (8 hexsymbols), set `One-Time Programmable` data on tag.
72 -v Version data (16 hexsymbols), set version data on tag.
73 -q ATQA/SAK (<2b ATQA><1b SAK> hexsymbols), set ATQA/SAK on tag.
74 -g GTU Mode (1 hexsymbol), set GTU shadow mode.
75 -z ATS (<1b length><0-16 ATS> hexsymbols), Configure ATS. Length set to 00 will disable ATS.
76 -w Wipe tag. 0 for Mifare or 1 for UL. Fills tag with zeros and put default values for type selected.
77 -m Ultralight mode (00 UL EV1, 01 NTAG, 02 UL-C, 03 UL) Set type of UL.
78 -n Ultralight protocol (00 MFC, 01 UL), switches between UL and MFC mode
79 -k Ultimate Magic Card Key (IF DIFFERENT THAN DEFAULT 00000000)
81 ---
82 -- A debug printout-function
83 local function dbg(args)
84 if not DEBUG then return end
85 if type(args) == 'table' then
86 local i = 1
87 while result[i] do
88 dbg(result[i])
89 i = i+1
90 end
91 else
92 print('###', args)
93 end
94 end
95 -- This is only meant to be used when errors occur
96 local function oops(err)
97 print("ERROR: ",err)
98 core.clearCommandBuffer()
99 return nil, err
102 -- Usage help
103 local function help()
104 print(copyright)
105 print(author)
106 print(version)
107 print(date)
108 print(desc)
109 print(ansicolors.cyan..'Usage'..ansicolors.reset)
110 print(usage)
111 print(ansicolors.cyan..'Arguments'..ansicolors.reset)
112 print(arguments)
113 print(ansicolors.cyan..'Example usage'..ansicolors.reset)
114 print(example)
117 -- set the global password variable
118 local function set_ntagpassword(pwd)
119 if pwd == nil then _ntagpassword = nil; return true, 'Ok' end
120 if #pwd ~= 8 then return nil, 'password wrong length. Must be 4 hex bytes' end
121 if #pwd == 0 then _ntagpassword = nil end
122 _ntagpassword = pwd
123 return true, 'Ok'
125 -- set the global UMC key variable
126 local function set_key(key)
127 print('Key:'..key)
128 if key == nil then _key = '00000000'; return true, 'Ok' end
129 if #key ~= 8 then return nil, 'UMC key is wrong the length. Must be 4 hex bytes' end
130 if #key == 0 then _key = nil end
131 _key = key
132 return true, 'Ok'
134 --- Picks out and displays the data read from a tag
135 -- Specifically, takes a usb packet, converts to a Command
136 -- (as in commands.lua), takes the data-array and
137 -- reads the number of bytes specified in arg1 (arg0 in c-struct)
138 -- @param usbpacket the data received from the device
139 local function getResponseData(usbpacket)
140 local resp = Command.parse(usbpacket)
141 local len = tonumber(resp.arg1) * 2
142 return string.sub(tostring(resp.data), 0, len);
145 local function sendRaw(rawdata, options)
146 local flags = lib14a.ISO14A_COMMAND.ISO14A_NO_DISCONNECT
147 + lib14a.ISO14A_COMMAND.ISO14A_RAW
148 + lib14a.ISO14A_COMMAND.ISO14A_APPEND_CRC
149 local c = Command:newMIX{cmd = cmds.CMD_HF_ISO14443A_READER,
150 arg1 = flags,
151 arg2 = string.len(rawdata)/2,
152 data = rawdata}
153 return c:sendMIX(options.ignore_response)
156 local function send(payload)
157 local usb, err = sendRaw(payload,{ignore_response = false})
158 if err then return oops(err) end
159 return getResponseData(usb)
162 local function connect()
163 core.clearCommandBuffer()
164 -- First of all, connect
165 info, err = lib14a.read(true, true)
166 if err then
167 lib14a.disconnect()
168 return oops(err)
170 core.clearCommandBuffer()
171 --authenticate if needed using global variable
172 if _ntagpassword then
173 send('1B'.._ntagpassword)
175 return true
178 -- Read magic configuration
179 local function read_config()
180 local info = connect()
181 if not info then return false, "Can't select card" end
182 -- read Ultimate Magic Card CONFIG
183 if magicconfig == nil then
184 magicconfig = send("CF".._key.."C6")
185 else print('No Config')
187 -- extract data from CONFIG - based on CONFIG in https://github.com/RfidResearchGroup/proxmark3/blob/master/doc/magic_cards_notes.md#gen-4-gtu
188 ulprotocol, uidlength, readpass, gtumode, ats, atqa1, atqa2, sak, ulmode = magicconfig:sub(1,2), magicconfig:sub(3,4), magicconfig:sub(5,12), magicconfig:sub(13,14), magicconfig:sub(15,48), magicconfig:sub(51,52), magicconfig:sub(49,50), magicconfig:sub(53,54), magicconfig:sub(55,56)
189 atqaf = atqa1..' '..atqa2
190 cardtype, cardprotocol, gtustr, atsstr = 'unknown', 'unknown', 'unknown', 'unknown'
191 if magicconfig == nil then lib14a.disconnect(); return nil, "can't read configuration, "..err_lock end
192 if #magicconfig ~= 64 and #magicconfig ~= 68 then lib14a.disconnect(); return nil, "partial read of configuration, "..err_lock end
193 if gtumode == '00' then gtustr = 'Pre-write/Shadow Mode'
194 elseif gtumode == '01' or gtumode == '04' then gtustr = 'Restore Mode'
195 elseif gtumode == '02' then gtustr = 'Disabled'
196 elseif gtumode == '03' then gtustr = 'Disabled, high speed R/W mode for Ultralight'
198 if ats:sub(1,2) == '00' then atsstr = 'Disabled'
199 else atsstr = (string.sub(ats, 3))
201 if ulprotocol == '00' then
202 cardprotocol = 'MIFARE Classic Protocol'
203 ultype = 'Disabled'
204 if uidlength == '00' then
205 uid = send("CF".._key.."CE00"):sub(1,8)
206 if atqaf == '00 04' and sak == '09' then cardtype = 'MIFARE Mini S20 4-byte UID'
207 elseif atqaf == '00 04' and sak == '08' then cardtype = 'MIFARE 1k S50 4-byte UID'
208 elseif atqaf == '00 02' and sak == '18' then cardtype = 'MIFARE 4k S70 4-byte UID'
210 elseif uidlength == '01' then
211 uid = send("CF".._key.."CE00"):sub(1,14)
212 if atqaf == '00 44' and sak == '09' then cardtype = 'MIFARE Mini S20 7-byte UID'
213 elseif atqaf == '00 44' and sak == '08' then cardtype = 'MIFARE 1k S50 7-byte UID'
214 elseif atqaf == '00 42' and sak == '18' then cardtype = 'MIFARE 4k S70 7-byte UID'
216 elseif uidlength == '02' then
217 uid = send("CF".._key.."CE00"):sub(1,20)
218 if atqaf == '00 84' and sak == '09' then cardtype = 'MIFARE Mini S20 10-byte UID'
219 elseif atqaf == '00 84' and sak == '08' then cardtype = 'MIFARE 1k S50 10-byte UID'
220 elseif atqaf == '00 82' and sak == '18' then cardtype = 'MIFARE 4k S70 10-byte UID'
223 elseif ulprotocol == '01' then
224 -- Read Ultralight config only if UL protocol is enabled
225 cardprotocol = 'MIFARE Ultralight/NTAG'
226 block0 = send("3000")
227 uid0 = block0:sub(1,6)
228 uid = uid0..block0:sub(9,16)
229 if ulmode == '00' then ultype = 'Ultralight EV1'
230 elseif ulmode == '01' then ultype = 'NTAG21x'
231 elseif ulmode == '02' then ultype = 'Ultralight-C'
232 elseif ulmode == '03' then ultype = 'Ultralight'
234 -- read VERSION
235 cversion = send('30FA'):sub(1,16)
236 -- pwdblock must be set since the 30F1 and 30F2 special commands don't work on the ntag21x part of the UMC
237 if ulmode == '03' then versionstr = 'Ultralight'
238 elseif ulmode == '02' then versionstr = 'Ultralight-C'
239 elseif cversion == '0004030101000B03' then versionstr = 'UL EV1 48b'
240 elseif cversion == '0004030101000E03' then versionstr = 'UL EV1 128b'
241 elseif cversion == '0004040101000B03' then versionstr = 'NTAG 210'
242 elseif cversion == '0004040101000E03' then versionstr = 'NTAG 212'
243 elseif cversion == '0004040201000F03' then versionstr = 'NTAG 213'
244 elseif cversion == '0004040201001103' then versionstr = 'NTAG 215'
245 elseif cversion == '0004040201001303' then versionstr = 'NTAG 216'
246 elseif cversion == '0004040502011303' then versionstr = 'NTAG I2C 1K'
247 elseif cversion == '0004040502011503' then versionstr = 'NTAG I2C 2K'
248 elseif cversion == '0004040502021303' then versionstr = 'NTAG I2C 1K PLUS'
249 elseif cversion == '0004040502021503' then versionstr = 'NTAG I2C 2K PLUS'
250 elseif cversion == '0004040401000F03' then versionstr = 'NTAG 213F'
251 elseif cversion == '0004040401001303' then versionstr = 'NTAG 216F'
253 -- read PWD
254 cpwd = send("30F0"):sub(1,8)
255 pwd = send("30E5"):sub(1,8)
256 -- 04 response indicates that blocks has been locked down.
257 if pwd == '04' then lib14a.disconnect(); return nil, "can't read configuration, "..err_lock end
258 -- read PACK
259 cpack = send("30F1"):sub(1,4)
260 pack = send("30E6"):sub(1,4)
261 -- read SIGNATURE
262 signature1 = send('30F2'):sub(1,32)
263 signature2 = send('30F6'):sub(1,32)
264 lib14a.disconnect()
266 if _print < 1 then
267 print(string.rep('=', 88))
268 print('\t\t\tUltimate Magic Card Configuration')
269 print(string.rep('=', 88))
270 print(' - Raw Config ', string.sub(magicconfig, 1, -9))
271 print(' - Card Protocol ', cardprotocol)
272 print(' - Ultralight Mode ', ultype)
273 print(' - ULM Backdoor Key ', readpass)
274 print(' - GTU Mode ', gtustr)
275 if ulprotocol == '01' then
276 print(' - Card Type ', versionstr)
277 else
278 print(' - Card Type ', cardtype)
280 print(' - UID ', uid)
281 print(' - ATQA ', atqaf)
282 print(' - SAK ', sak)
283 if ulprotocol == '01' then
284 print('')
285 print(string.rep('=', 88))
286 print('\t\t\tMagic UL/NTAG 21* Configuration')
287 print(string.rep('=', 88))
288 print(' - ATS ', atsstr)
289 print(' - Password ', '[0xE5] '..pwd, '[0xF0] '..cpwd)
290 print(' - Pack ', '[0xE6] '..pack, '[0xF1] '..cpack)
291 print(' - Version ', cversion)
292 print(' - Signature ', signature1..signature2)
295 lib14a.disconnect()
296 return true, 'Ok'
299 -- calculate block0
300 local function calculate_block0(useruid)
301 local uidbytes = utils.ConvertHexToBytes(useruid)
302 local i = 1
303 local bcc = bxor(uidbytes[i], uidbytes[i+1]);
304 local length = #useruid / 2;
306 -- bcc
307 for i = 3, length, 1 do bcc = bxor(bcc, uidbytes[i]) end
309 -- block0
310 local block0 = ""
311 for i = 1, length, 1 do block0 = block0..string.format('%02X', uidbytes[i]) end
313 return block0..string.format('%02X', bcc)
316 -- Writes a UID for MFC and MFUL/NTAG cards
317 local function write_uid(useruid)
318 -- read CONFIG
319 if not magicconfig then
320 _print = 1
321 read_config()
323 local info = connect()
324 if not info then return false, "Can't select card" end
325 -- Writes a MFC UID with GEN4 magic commands.
326 if ulprotocol == '00' then
327 -- uid string checks
328 if useruid == nil then return nil, 'empty uid string' end
329 if #useruid == 0 then return nil, 'empty uid string' end
330 if (#useruid ~= 8) and (#useruid ~= 14) and (#useruid ~= 20) then return nil, 'UID wrong length. Should be 4, 7 or 10 hex bytes' end
331 print('Writing new UID ', useruid)
332 local block0 = calculate_block0(useruid)
333 print('Calculated block0 ', block0)
334 local resp = send('CF'.._key..'CD00'..block0)
335 -- Writes a MFUL UID with bcc1, bcc2 using NTAG21xx commands.
336 elseif ulprotocol == '01' then
337 -- uid string checks
338 if useruid == nil then return nil, 'empty uid string' end
339 if #useruid == 0 then return nil, 'empty uid string' end
340 if #useruid ~= 14 then return nil, 'uid wrong length. Should be 7 hex bytes' end
341 print('Writing new UID ', useruid)
342 local uidbytes = utils.ConvertHexToBytes(useruid)
343 local bcc1 = bxor(bxor(bxor(uidbytes[1], uidbytes[2]), uidbytes[3]), 0x88)
344 local bcc2 = bxor(bxor(bxor(uidbytes[4], uidbytes[5]), uidbytes[6]), uidbytes[7])
345 local block0 = string.format('%02X%02X%02X%02X', uidbytes[1], uidbytes[2], uidbytes[3], bcc1)
346 local block1 = string.format('%02X%02X%02X%02X', uidbytes[4], uidbytes[5], uidbytes[6], uidbytes[7])
347 local block2 = string.format('%02X%02X%02X%02X', bcc2, 0x48, 0x00, 0x00)
348 local resp
349 resp = send('A200'..block0)
350 resp = send('A201'..block1)
351 resp = send('A202'..block2)
352 else
353 print('Incorrect ul')
355 lib14a.disconnect()
356 if resp ~= nil then
357 return nil, oops('Failed to write UID')
358 else
359 return true, 'Ok'
363 -- Write ATQA/SAK
364 local function write_atqasak(atqasak)
365 -- read CONFIG
366 if not magicconfig then
367 _print = 1
368 read_config()
370 if atqasak == nil then return nil, 'Empty ATQA/SAK string' end
371 if #atqasak == 0 then return nil, 'Empty ATQA/SAK string' end
372 if #atqasak ~= 6 then return nil, 'ATQA/SAK wrong length. Should be 6 hex bytes. I.E. 004408 ATQA(0044) SAK(08)' end
373 local atqauser1 = atqasak:sub(1,2)
374 local atqauser2 = atqasak:sub(3,4)
375 local atqauserf = atqauser2..atqauser1
376 local sakuser = atqasak:sub(5,6)
377 if sakuser == '04' then
378 print('Never set SAK bit 3 (e.g. SAK=04), it indicates an extra cascade level is required')
379 return nil
380 elseif (sakuser == '20' or sakuser == '28') and atslen == '00' then
381 print('When SAK equals 20 or 28, ATS must be turned on')
382 return nil
383 elseif atqauser2 == '40' then
384 print('ATQA of [00 40] will cause the card to not answer.')
385 return nil
386 else
387 local info = connect()
388 if not info then return false, "Can't select card" end
389 print('New ATQA: '..atqauser1..' '..atqauser2..' New SAK: '..sakuser)
390 local resp = send("CF".._key.."35"..atqauserf..sakuser)
391 lib14a.disconnect()
392 if resp == nil then
393 return nil, oops('Failed to write ATQA/SAK')
394 else
395 return true, 'Ok'
400 -- Write NTAG PWD
401 local function write_ntagpwd(ntagpwd)
402 -- read CONFIG
403 if not magicconfig then
404 _print = 1
405 read_config()
407 if ulprotocol == '00' then return nil, 'Magic Card is not using the Ultralight Protocol' end
408 -- PWD string checks
409 if ntagpwd == nil then return nil, 'empty NTAG PWD string' end
410 if #ntagpwd == 0 then return nil, 'empty NTAG PWD string' end
411 if #ntagpwd ~= 8 then return nil, 'NTAG PWD wrong length. Should be 4 hex bytes' end
412 local info = connect()
413 if not info then return false, "Can't select card" end
414 print('Writing new NTAG PWD ', ntagpwd)
415 local resp = send('A2E5'..ntagpwd) -- must add both for password to be read by the reader command B1
416 local resp = send('A2F0'..ntagpwd)
417 lib14a.disconnect()
418 if resp == nil then
419 return nil, 'Failed to write password'
420 else
421 return true, 'Ok'
425 -- Write PACK
426 local function write_pack(userpack)
427 -- read CONFIG
428 if not magicconfig then
429 _print = 1
430 read_config()
432 if ulprotocol == 0 then return nil, 'Magic Card is not using the Ultralight Protocol' end
433 -- PACK string checks
434 if userpack == nil then return nil, 'empty PACK string' end
435 if #userpack == 0 then return nil, 'empty PACK string' end
436 if #userpack ~= 4 then return nil, 'PACK wrong length. Should be 4 hex bytes' end
437 local info = connect()
438 if not info then return false, "Can't select card" end
439 print('Writing new PACK', userpack)
440 send('A2E6'..userpack..'0000')
441 send('A2F1'..userpack..'0000')
442 lib14a.disconnect()
443 return true, 'Ok'
446 -- Write OTP block
447 local function write_otp(block3)
448 -- OTP string checks
449 if block3 == nil then return nil, 'empty OTP string' end
450 if #block3 == 0 then return nil, 'empty OTP string' end
451 if #block3 ~= 8 then return nil, 'OTP wrong length. Should be 4 hex bytes' end
452 -- read CONFIG
453 if not magicconfig then
454 _print = 1
455 read_config()
457 if ulprotocol == '00' then return nil, 'Magic Card is not using the Ultralight Protocol' end
458 local info = connect()
459 if not info then return false, "Can't select card" end
460 print('Writing new OTP ', block3)
461 local resp = send('A203'..block3)
462 lib14a.disconnect()
463 if resp ~= '0A' then return false, oops('Failed to write OTP')
464 else
465 return true, 'Ok'
469 -- Write VERSION data,
470 -- make sure you have correct version data
471 local function write_version(data)
472 -- Version string checks
473 if data == nil then return nil, 'empty version string' end
474 if #data == 0 then return nil, 'empty version string' end
475 if #data ~= 16 then return nil, 'version wrong length. Should be 8 hex bytes' end
476 -- read CONFIG
477 if not magicconfig then
478 _print = 1
479 read_config()
481 if ulprotocol == '00' then return nil, 'Magic Card is not using the Ultralight Protocol' end
482 print('Writing new version', data)
483 local b1 = data:sub(1,8)
484 local b2 = data:sub(9,16)
485 local info = connect()
486 if not info then return false, "Can't select card" end
487 local resp
488 -- set maximum read/write blocks to 251; version is stored in blocks 250-251
489 send("CF".._key.."6B".."FB")
490 resp = send('A2FA'..b1)
491 resp = send('A2FB'..b2)
492 lib14a.disconnect()
493 if resp ~= '0A' then return nil, oops('Failed to write version')
494 else
495 return true, 'Ok'
500 -- Write SIGNATURE data
501 local function write_signature(data)
502 -- Signature string checks
503 if data == nil then return nil, 'empty data string' end
504 if #data == 0 then return nil, 'empty data string' end
505 if #data ~= 64 then return nil, 'data wrong length. Should be 32 hex bytes' end
506 -- read CONFIG
507 if not magicconfig then
508 _print = 1
509 read_config()
511 local info = connect()
512 if not info then return false, "Can't select card" end
513 if ulprotocol == '00' then
514 print('Writing new MFC signature',data)
515 send('CF'.._key..'6B48')
516 lib14a.disconnect()
517 connect() -- not 100% sure why it's needed, but without this blocks aren't actually written
518 local sig1 = data:sub(1, 32)
519 local sig2 = data:sub(33, 64)
521 send('CF'.._key..'CD45'..sig1)
522 send('CF'.._key..'CD46'..sig2)
523 send('CF'.._key..'CD475C8FF9990DA270F0F8694B791BEA7BCC')
524 else
525 print('Writing new MFUL signature',data)
526 local b,c
527 local cmd = 'A2F%d%s'
528 local j = 2
529 -- set maximum read/write blocks to 251; signature is stored in blocks 242-249
530 send("CF".._key.."6B".."FB")
531 lib14a.disconnect()
532 connect() -- not 100% sure why it's needed, but without this blocks aren't actually written
533 for i = 1, #data, 8 do
534 b = data:sub(i,i+7)
535 c = cmd:format(j,b)
536 local resp = send(c)
537 if resp ~= '0A' then lib14a.disconnect(); return nil, oops('Failed to write signature') end
538 j = j + 1
541 lib14a.disconnect()
542 return true, 'Ok'
545 -- Enable/Disable GTU Mode
546 -- 00: pre-write, 01: restore mode, 02: disabled, 03: disabled, high speed R/W mode for Ultralight
547 local function write_gtu(gtu)
548 if gtu == nil then return nil, 'empty GTU string' end
549 if #gtu == 0 then return nil, 'empty GTU string' end
550 if #gtu ~= 2 then return nil, 'type wrong length. Should be 1 hex byte' end
551 local info = connect()
552 if not info then return false, "Can't select card" end
553 if gtu == '00' then
554 print('Enabling GTU Pre-Write')
555 send('CF'.._key..'32'..gtu)
556 elseif gtu == '01' or gtu == '04' then
557 print('Enabling GTU Restore Mode')
558 send('CF'.._key..'32'..gtu)
559 elseif gtu == '02' then
560 print('Disabled GTU')
561 send('CF'.._key..'32'..gtu)
562 elseif gtu == '03' then
563 print('Disabled GTU, high speed R/W mode for Ultralight')
564 send('CF'.._key..'32'..gtu)
565 else
566 print('Failed to set GTU mode')
568 lib14a.disconnect()
569 return true, 'Ok'
572 -- Write ATS
573 -- First hexbyte is length. 00 to disable ATS. 16 hexbytes for ATS
574 local function write_ats(atsuser)
575 if atsuser == nil then return nil, 'empty ATS string' end
576 if #atsuser == 0 then return nil, 'empty ATS string' end
577 if #atsuser > 34 then return nil, 'type wrong length. Should be <1b length><0-16b ATS> hex byte' end
578 local atscardlen = atsuser:sub(1,2)
579 local atscardlendecimal = tonumber(atscardlen, 16)
580 local atsf = string.sub(atsuser, 3)
581 if (#atsf / 2) ~= atscardlendecimal then
582 oops('Given length of ATS ('..atscardlendecimal..') does not match the ATS_length ('..(#atsf / 2)..')')
583 return true, 'Ok'
584 else
585 local info = connect()
586 if not info then return false, "Can't select card" end
587 print('Writing '..atscardlendecimal..' ATS bytes of '..atsf)
588 send("CF".._key.."34"..atsuser)
590 lib14a.disconnect()
591 return true, 'Ok'
594 -- Change UL/MFC protocol
595 local function write_ulp(ulp)
596 if ulp == nil then return nil, 'empty ULP string' end
597 if #ulp == 0 then return nil, 'empty ULP string' end
598 if #ulp > 2 then return nil, 'type wrong length. Should be 1 hex byte' end
599 local info = connect()
600 if not info then return false, "Can't select card" end
601 if ulp == '00' then
602 print('Changing card to Mifare Classic Protocol')
603 send("CF".._key.."69"..ulp)
604 elseif ulp == '01' then
605 print('Changing card to Ultralight Protocol')
606 send("CF".._key.."69"..ulp)
607 else
608 oops('Protocol needs to be either 00 or 01')
610 lib14a.disconnect()
611 return true, 'Ok'
614 -- Change UL Mode Type
615 local function write_ulm(ulm)
616 if ulm == nil then return nil, 'empty ULM string' end
617 if #ulm == 0 then return nil, 'empty ULM string' end
618 if #ulm > 2 then return nil, 'type wrong length. Should be 1 hex byte' end
619 local info = connect()
620 if not info then return false, "Can't select card" end
621 if ulm == '00' then
622 print('Changing card UL mode to Ultralight EV1')
623 send("CF".._key.."6A"..ulm)
624 elseif ulm == '01' then
625 print('Changing card UL mode to NTAG')
626 send("CF".._key.."6A"..ulm)
627 elseif ulm == '02' then
628 print('Changing card UL mode to Ultralight-C')
629 send("CF".._key.."6A"..ulm)
630 elseif ulm == '03' then
631 print('Changing card UL mode to Ultralight')
632 send("CF".._key.."6A"..ulm)
633 else
634 oops('UL mode needs to be either 00, 01, 02, 03')
636 lib14a.disconnect()
637 return true, 'Ok'
640 -- Set type for magic card presets.
641 local function set_type(tagtype)
642 -- tagtype checks
643 if type(tagtype) == 'string' then tagtype = tonumber(tagtype, 10) end
644 if tagtype == nil then return nil, oops('empty tagtype') end
645 -- Setting Mifare mini S20 4-byte
646 if tagtype == 1 then
647 print('Setting: Ultimate Magic card to Mifare mini S20 4-byte')
648 connect()
649 send("CF".._key.."F000000000000002000978009102DABC19101011121314151604000900")
650 lib14a.disconnect()
651 write_uid('04112233')
652 -- Setting Mifare mini S20 7-byte
653 elseif tagtype == 2 then
654 print('Setting: Ultimate Magic card to Mifare mini S20 7-byte')
655 connect()
656 send("CF".._key.."F000010000000002000978009102DABC19101011121314151644000900")
657 lib14a.disconnect()
658 write_uid('04112233445566')
659 -- Setting Mifare mini S20 10-byte
660 elseif tagtype == 3 then
661 print('Setting: Ultimate Magic card to Mifare mini S20 10-byte')
662 connect()
663 send("CF".._key.."F000020000000002000978009102DABC19101011121314151684000900")
664 lib14a.disconnect()
665 write_uid('04112233445566778899')
666 -- Setting Mifare 1k S50 4--byte
667 elseif tagtype == 4 then
668 print('Setting: Ultimate Magic card to Mifare 1k S50 4-byte')
669 connect()
670 send("CF".._key.."F000000000000002000978009102DABC19101011121314151604000800")
671 lib14a.disconnect()
672 write_uid('04112233')
673 -- Setting Mifare 1k S50 7-byte
674 elseif tagtype == 5 then
675 print('Setting: Ultimate Magic card to Mifare 1k S50 7-byte')
676 connect()
677 send("CF".._key.."F000010000000002000978009102DABC19101011121314151644000800")
678 lib14a.disconnect()
679 write_uid('04112233445566')
680 -- Setting Mifare 1k S50 10-byte
681 elseif tagtype == 6 then
682 print('Setting: Ultimate Magic card to Mifare 1k S50 10-byte')
683 connect()
684 send("CF".._key.."F000020000000002000978009102DABC19101011121314151684000800")
685 lib14a.disconnect()
686 write_uid('04112233445566778899')
687 -- Setting Mifare 4k S70 4-byte
688 elseif tagtype == 7 then
689 print('Setting: Ultimate Magic card to Mifare 4k S70 4-byte')
690 connect()
691 send("CF".._key.."F000000000000002000978009102DABC19101011121314151602001800")
692 lib14a.disconnect()
693 write_uid('04112233')
694 -- Setting Mifare 4k S70 7-byte
695 elseif tagtype == 8 then
696 print('Setting: Ultimate Magic card to Mifare 4k S70 7-byte')
697 connect()
698 send("CF".._key.."F000010000000002000978009102DABC19101011121314151642001800")
699 lib14a.disconnect()
700 write_uid('04112233445566')
701 -- Setting Mifare 4k S70 10-byte
702 elseif tagtype == 9 then
703 print('Setting: Ultimate Magic card to Mifare 4k S70 10-byte')
704 connect()
705 send("CF".._key.."F000020000000002000978009102DABC19101011121314151682001800")
706 lib14a.disconnect()
707 write_uid('04112233445566778899')
708 -- Setting UL
709 elseif tagtype == 10 then
710 print('Setting: Ultimate Magic card to UL')
711 connect()
712 send("CF".._key.."F0010100000000030A0A78008102DBA0C119402AB5BA4D321A44000003")
713 lib14a.disconnect()
714 write_uid('04112233445566')
715 write_otp('00000000') -- Setting OTP to default 00 00 00 00
716 write_version('0000000000000000') -- UL-C does not have a version
717 -- Setting UL-C
718 elseif tagtype == 11 then
719 print('Setting: Ultimate Magic card to UL-C')
720 connect()
721 send("CF".._key.."F0010100000000030A0A78008102DBA0C119402AB5BA4D321A44000002")
722 print('Setting default permissions and 3des key')
723 send('A22A30000000') -- Auth0 page 48/0x30 and above need authentication
724 send('A22B80000000') -- Auth1 read and write access restricted
725 send('A22C42524541') -- Default 3des key
726 send('A22D4B4D4549')
727 send('A22E46594F55')
728 send('A22F43414E21')
729 lib14a.disconnect()
730 write_uid('04112233445566')
731 write_otp('00000000') -- Setting OTP to default 00 00 00 00
732 write_version('0000000000000000') -- UL-C does not have a version
733 elseif tagtype == 12 then
734 print('Setting: Ultimate Magic card to UL-EV1 48')
735 connect()
736 send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000000")
737 -- Setting UL-Ev1 default config bl 16,17
738 send('a2E5FFFFFFFF') -- A2F0 block does not align correctly to actual pwd block
739 send('a2E6FFFFFFFF') -- A2F1 block does not align correctly to actual pack block
740 send('a210000000FF')
741 send('a21100050000')
742 lib14a.disconnect()
743 write_uid('04112233445566')
744 write_otp('00000000') -- Setting OTP to default 00 00 00 00
745 write_version('0004030101000b03') -- UL-EV1 (48) 00 04 03 01 01 00 0b 03
746 elseif tagtype == 13 then
747 print('Setting: Ultimate Magic card to UL-EV1 128')
748 connect()
749 send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000000")
750 -- Setting UL-Ev1 default config bl 37,38
751 send('a2E5FFFFFFFF') -- A2F0 block does not align correctly to actual pwd block
752 send('a2E6FFFFFFFF') -- A2F1 block does not align correctly to actual pack block
753 send('a225000000FF')
754 send('a22600050000')
755 lib14a.disconnect()
756 write_uid('04112233445566')
757 write_otp('00000000') -- Setting OTP to default 00 00 00 00
758 write_version('0004030101000e03') -- UL-EV1 (128) 00 04 03 01 01 00 0e 03
759 elseif tagtype == 15 then
760 print('Setting: Ultimate Magic card to NTAG 210')
761 connect()
762 send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
763 -- Setting NTAG210 default CC block456
764 send('a203e1100600')
765 send('a2040300fe00')
766 send('a20500000000')
767 -- Setting cfg1/cfg2
768 send('a210000000FF')
769 send('a21100050000')
770 lib14a.disconnect()
771 write_uid('04E10CDA993C80')
772 write_version('0004040101000b03') -- NTAG210 00 04 04 01 01 00 0b 03
773 elseif tagtype == 16 then
774 print('Setting: Ultimate Magic card to NTAG 212')
775 connect()
776 send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
777 -- Setting NTAG212 default CC block456
778 send('a203e1101000')
779 send('a2040103900a')
780 send('a205340300fe')
781 -- Setting cfg1/cfg2
782 send('a225000000FF')
783 send('a22600050000')
784 lib14a.disconnect()
785 write_uid('04E10CDA993C80')
786 write_version('0004040101000E03') -- NTAG212 00 04 04 01 01 00 0E 03
787 elseif tagtype == 17 then
788 print('Setting: Ultimate Magic card to NTAG 213')
789 connect()
790 send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
791 -- Setting NTAG213 default CC block456
792 send('a203e1101200')
793 send('a2040103a00c')
794 send('a205340300fe')
795 -- setting cfg1/cfg2
796 send('a229000000ff')
797 send('a22a00050000')
798 lib14a.disconnect()
799 write_uid('04E10CDA993C80')
800 write_version('0004040201000F03') -- NTAG213 00 04 04 02 01 00 0f 03
801 elseif tagtype == 18 then
802 print('Setting: Ultimate Magic card to NTAG 215')
803 connect()
804 send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
805 -- Setting NTAG215 default CC block456
806 send('a203e1103e00')
807 send('a2040300fe00')
808 send('a20500000000')
809 -- setting cfg1/cfg2
810 send('a283000000ff')
811 send('a28400050000')
812 lib14a.disconnect()
813 write_uid('04E10CDA993C80')
814 write_version('0004040201001103') -- NTAG215 00 04 04 02 01 00 11 03
815 elseif tagtype == 19 then
816 print('Setting: Ultimate Magic card to NTAG 216')
817 connect()
818 send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
819 -- Setting NTAG216 default CC block456
820 send('a203e1106d00')
821 send('a2040300fe00')
822 send('a20500000000')
823 -- setting cfg1/cfg2
824 send('a2e3000000ff')
825 send('a2e400050000')
826 lib14a.disconnect()
827 write_uid('04E10CDA993C80')
828 write_version('0004040201001303') -- NTAG216 00 04 04 02 01 00 13 03
829 elseif tagtype == 20 then
830 print('Setting: Ultimate Magic card to NTAG I2C 1K')
831 connect()
832 send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
833 -- Setting NTAG I2C 1K default CC block456
834 send('a203e1106D00')
835 send('a2040300fe00')
836 send('a20500000000')
837 lib14a.disconnect()
838 write_uid('04E10CDA993C80')
839 write_version('0004040502011303') -- NTAG_I2C_1K 00 04 04 05 02 01 13 03
840 elseif tagtype == 21 then
841 print('Setting: Ultimate Magic card to NTAG I2C 2K')
842 connect()
843 send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
844 -- Setting NTAG I2C 2K default CC block456
845 send('a203e110EA00')
846 send('a2040300fe00')
847 send('a20500000000')
848 lib14a.disconnect()
849 write_uid('04E10CDA993C80')
850 write_version('0004040502011503') -- NTAG_I2C_2K 00 04 04 05 02 01 15 03
851 elseif tagtype == 22 then
852 print('Setting: Ultimate Magic card to NTAG I2C plus 1K')
853 connect()
854 send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
855 -- Setting NTAG I2C 1K default CC block456
856 send('a203e1106D00')
857 send('a2040300fe00')
858 send('a20500000000')
859 lib14a.disconnect()
860 write_uid('04E10CDA993C80')
861 write_version('0004040502021303') -- NTAG_I2C_1K 00 04 04 05 02 02 13 03
862 elseif tagtype == 23 then
863 print('Setting: Ultimate Magic card to NTAG I2C plus 2K')
864 connect()
865 send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
866 -- Setting NTAG I2C 2K default CC block456
867 send('a203e1106D00')
868 send('a2040300fe00')
869 send('a20500000000')
870 write_uid('04E10CDA993C80')
871 write_version('0004040502021503') -- NTAG_I2C_2K 00 04 04 05 02 02 15 03
872 elseif tagtype == 24 then
873 print('Setting: Ultimate Magic card to NTAG 213F')
874 connect()
875 send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
876 -- Setting NTAG213 default CC block456
877 send('a203e1101200')
878 send('a2040103a00c')
879 send('a205340300fe')
880 -- setting cfg1/cfg2
881 send('a229000000ff')
882 send('a22a00050000')
883 lib14a.disconnect()
884 write_uid('04E10CDA993C80')
885 write_version('0004040401000F03') -- NTAG213F 00 04 04 04 01 00 0f 03
886 elseif tagtype == 25 then
887 print('Setting: Ultimate Magic card to NTAG 216F')
888 connect()
889 send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
890 -- Setting NTAG216 default CC block456
891 send('a203e1106d00')
892 send('a2040300fe00')
893 send('a20500000000')
894 -- setting cfg1/cfg2
895 send('a2e3000000ff')
896 send('a2e400050000')
897 lib14a.disconnect()
898 write_uid('04E10CDA993C80')
899 write_version('0004040401001303') -- NTAG216F 00 04 04 04 01 00 13 03
900 else
901 oops('No matching tag types')
903 lib14a.disconnect()
904 if resp == '04' then
905 return nil, 'Failed to set type'
906 else
907 return true, 'Ok'
911 -- returns true if b is the index of a sector trailer
912 local function mfIsSectorTrailer(b)
913 n=b+1
914 if (n < 32*4 ) then
915 if (n % 4 == 0) then return true
916 else return false
920 if (n % 16 == 0) then return true
923 return false
926 -- wipe tag
927 local function wipe(wtype)
928 local info = connect()
929 if not info then return false, "Can't select card" end
930 if wtype == '0' then
931 print('Starting Mifare Wipe')
932 send("CF".._key.."F000000000000002000978009102DABC19101011121314151604000800")
933 send("CF".._key.."CD000102030404080400000000000000BEAF")
934 local err, msg, resp
935 local cmd_empty = 'CF'.._key..'CD%02X00000000000000000000000000000000'
936 local cmd_trail = 'CF'.._key..'CD%02XFFFFFFFFFFFFFF078069FFFFFFFFFFFF'
937 for b = 1, 0xFF do
938 if mfIsSectorTrailer(b) then
939 local cmd = (cmd_trail):format(b)
940 resp = send(cmd)
941 else
942 local cmd = (cmd_empty):format(b)
943 resp = send(cmd)
945 if resp == nil then
946 io.write('\nwrote block '..b, ' failed\n')
947 err = true
948 else
949 io.write('.')
951 io.flush()
953 print('\n')
954 err, msg = set_type(4)
955 if err == nil then return err, msg end
956 lib14a.disconnect()
957 return true, 'Ok'
958 elseif wtype == '1' then
959 print('Starting Ultralight Wipe')
960 local err, msg, resp
961 local cmd_empty = 'A2%02X00000000'
962 local cmd_cfg1 = 'A2%02X000000FF'
963 local cmd_cfg2 = 'A2%02X00050000'
964 print('Wiping tag')
965 local info = connect()
966 if not info then return false, "Can't select card" end
967 send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001FB")
968 for b = 3, 0xFB do
969 --configuration block 0
970 if b == 0x29 or b == 0x83 or b == 0xe3 then
971 local cmd = (cmd_cfg1):format(b)
972 resp = send(cmd)
973 --configuration block 1
974 elseif b == 0x2a or b == 0x84 or b == 0xe4 then
975 local cmd = (cmd_cfg2):format(b)
976 resp = send(cmd)
977 else
978 resp = send(cmd_empty:format(b))
980 if resp == '04' or #resp == 0 then
981 io.write('\nwrote block '..b, ' failed\n')
982 err = true
983 else
984 io.write('.')
986 io.flush()
988 io.write('\r\n')
989 lib14a.disconnect()
990 print('\n')
991 if err then return nil, "Tag locked down or misconfigured maximum read/write blocks, "..err_lock end
992 -- set NTAG213 default values
993 err, msg = set_type(17)
994 if err == nil then return err, msg end
995 --set UID
996 err, msg = write_uid('04E10CDA993C80')
997 if err == nil then return err, msg end
998 --set NTAG pwd
999 err, msg = write_ntagpwd('FFFFFFFF')
1000 if err == nil then return err, msg end
1001 --set pack
1002 err, msg = write_pack('0000')
1003 if err == nil then return err, msg end
1004 --set signature
1005 err, msg = write_signature('8B76052EE42F5567BEB53238B3E3F9950707C0DCC956B5C5EFCFDB709B2D82B3')
1006 if err == nil then return err, msg end
1007 lib14a.disconnect()
1008 return true, 'Ok'
1009 else oops('Use 0 for Mifare wipe or 1 for Ultralight wipe')
1013 -- The main entry point
1014 function main(args)
1015 print()
1016 local err, msg
1017 if #args == 0 then return help() end
1018 -- Read the parameters
1019 for o, a in getopt.getopt(args, 'hck:u:t:p:a:s:o:v:q:g:z:n:m:w:') do
1020 -- help
1021 if o == "h" then return help() end
1022 -- set Ultimate Magic Card Key for read write
1023 if o == "k" then err, msg = set_key(a) end
1024 -- configuration
1025 if o == "c" then err, msg = read_config() end
1026 -- wipe tag
1027 if o == "w" then err, msg = wipe(a) end
1028 -- write uid
1029 if o == "u" then err, msg = write_uid(a) end
1030 -- write type/version
1031 if o == "t" then err, msg = set_type(a) end
1032 -- write NTAG pwd
1033 if o == "p" then err, msg = write_ntagpwd(a) end
1034 -- write pack
1035 if o == "a" then err, msg = write_pack(a) end
1036 -- write signature
1037 if o == "s" then err, msg = write_signature(a) end
1038 -- write otp
1039 if o == "o" then err, msg = write_otp(a) end
1040 -- write version
1041 if o == "v" then err, msg = write_version(a) end
1042 -- write atqa/sak
1043 if o == "q" then err, msg = write_atqasak(a) end
1044 -- write gtu mode
1045 if o == "g" then err, msg = write_gtu(a) end
1046 -- write ats
1047 if o == "z" then err, msg = write_ats(a) end
1048 -- write UL mode
1049 if o == "m" then err, msg = write_ulm(a) end
1050 -- write UL protocol
1051 if o == "n" then err, msg = write_ulp(a) end
1052 if err == nil then return oops(msg) end
1055 main(args)