2020-03-17 18:37:38 +08:00
local utils = require ( ' utils ' )
2020-03-19 17:29:39 +08:00
local getopt = require ( ' getopt ' )
2020-03-17 18:37:38 +08:00
local read14a = require ( ' read14a ' )
2020-03-21 17:04:03 +08:00
2020-03-21 19:34:58 +08:00
--[[
2020-03-21 17:04:03 +08:00
---Suggestions of improvement:
--- Add support another types of dumps: BIN, JSON
--- Maybe it will be not only as `mfc_gen3_writer`, like a universal dump manager.
--- Add undependence from the operation system. At the moment code not working in Linux.
--- Add more chinesse backdoors RAW commands for UID changing (find RAW for the 4 byte familiar chinese card, from native it soft: http://bit.ly/39VIDsU)
--- Hide system messages when you writing a dumps, replace it to some of like [#####----------] 40%
-- iceman notes:
-- doesn't take consideration filepaths for dump files.
-- doesn't allow A keys for authenticating when writing
-- doesn't verify that card is magic gen3.
2020-03-21 19:34:58 +08:00
-- doesn't take several versions of same dump ( -1, -2, -3 ) styles.
2020-03-21 17:04:03 +08:00
--]]
2020-03-17 18:37:38 +08:00
2020-03-18 18:39:10 +08:00
copyright = ' '
author = ' Winds '
version = ' v1.0.0 '
desc = [ [
2020-03-21 17:04:03 +08:00
The script gives you a easy way to write your * . eml dumps onto normal MFC and magic Gen3 cards .
Works with both 4 and 7 bytes NXP MIFARE Classic 1 K cards .
The script also has the possibility to change UID and permanent lock uid on magic Gen3 cards .
2020-03-18 18:39:10 +08:00
2020-03-21 17:04:03 +08:00
It supports the following functionality .
2020-03-18 18:39:10 +08:00
2020-03-21 17:04:03 +08:00
1. Write it to the same of current card UID .
2. Write it to magic Gen3 card .
3. Change uid to match dump on magic Gen3 card .
4. Permanent lock UID on magic Gen3 card .
5. Erase all data at the card and set the FF FF FF FF FF FF keys , and Access Conditions to 78778800.
Script works in a wizard styled way .
2020-03-18 18:39:10 +08:00
] ]
example = [ [
2020-03-21 17:04:03 +08:00
1. script run mfc_gen3_writer
2020-03-18 18:39:10 +08:00
] ]
usage = [ [
2020-03-21 17:04:03 +08:00
Select your * . eml dump from list to write to the card .
2020-03-18 18:39:10 +08:00
] ]
2020-03-21 19:34:58 +08:00
-- Some globals
local DEBUG = false -- the debug flag
-------------------------------
-- Some utilities
-------------------------------
---
-- 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 , err
end
2020-03-19 17:29:39 +08:00
---
-- Usage help
local function help ( )
print ( copyright )
print ( author )
print ( version )
print ( desc )
2020-03-21 19:34:58 +08:00
print ( ' Example usage ' )
2020-03-19 17:29:39 +08:00
print ( example )
print ( usage )
end
2020-03-21 17:04:03 +08:00
---
-- GetUID
local function GetUID ( )
return read14a.read ( true , true ) . uid
2020-03-17 18:37:38 +08:00
end
2020-03-21 17:04:03 +08:00
---
--
local function dropfield ( )
2020-03-17 18:37:38 +08:00
read14a.disconnect ( )
core.clearCommandBuffer ( )
end
2020-03-21 17:04:03 +08:00
---
-- Wait for tag (MFC)
2020-03-18 18:39:10 +08:00
local function wait ( )
read14a.waitFor14443a ( )
2020-03-17 18:37:38 +08:00
end
2020-03-21 17:04:03 +08:00
---
--
2020-03-18 18:39:10 +08:00
local function main ( args )
2020-03-21 17:04:03 +08:00
2020-03-19 17:29:39 +08:00
-- Arguments for the script
2020-03-21 19:37:40 +08:00
for o , a in getopt.getopt ( args , ' hd ' ) do
2020-03-19 17:29:39 +08:00
if o == ' h ' then return help ( ) end
2020-03-21 19:37:40 +08:00
if o == ' d ' then DEBUG = true end
2020-03-19 17:29:39 +08:00
end
2020-03-21 17:04:03 +08:00
local files = { } -- Array for eml files
local b_keys = { } -- Array for B keys
local eml = { } -- Array for data in block 32
local num_dumps = 0 -- num of found eml dump files
local tab = string.rep ( ' - ' , 64 )
--
2020-03-18 18:39:10 +08:00
wait ( )
print ( tab )
2020-03-21 17:04:03 +08:00
2020-03-21 19:34:58 +08:00
local length = 25
local e = 16
2020-03-21 17:04:03 +08:00
-- Detect 7 byte card
if string.len ( GetUID ( ) ) == 14 then
2020-03-21 19:34:58 +08:00
length = 31
e = 22
2020-03-18 18:39:10 +08:00
end
2020-03-21 19:34:58 +08:00
dropfield ( )
2020-03-21 17:04:03 +08:00
---List all EML files in /client
2020-03-21 19:34:58 +08:00
local dumpEML = " find '.' -iname '*dump.eml' -type f "
local p = assert ( io.popen ( dumpEML ) )
for _ in p : lines ( ) do
-- The length of eml file
if string.len ( _ ) == length then
num_dumps = num_dumps + 1
-- cut UID from eml file
files [ num_dumps ] = string.sub ( _ , 9 , e )
print ( ' ' .. num_dumps .. ' | ' .. files [ num_dumps ] )
2020-03-17 18:37:38 +08:00
end
2020-03-18 18:39:10 +08:00
end
2020-03-21 19:40:16 +08:00
p.close ( )
2020-03-17 18:37:38 +08:00
2020-03-21 19:34:58 +08:00
if num_dumps == 0 then return oops ( " Didn't find any dump files " ) end
2020-03-17 18:37:38 +08:00
print ( tab )
2020-03-21 17:04:03 +08:00
print ( ' Your card has UID ' .. GetUID ( ) )
print ( ' ' )
print ( ' Select which dump to write (1 until ' .. num_dumps .. ' ) ' )
2020-03-18 18:39:10 +08:00
print ( tab )
2020-03-21 17:04:03 +08:00
io.write ( ' --> ' )
2020-03-17 18:37:38 +08:00
2020-03-18 18:39:10 +08:00
local no = tonumber ( io.read ( ) )
print ( tab )
2020-03-21 19:34:58 +08:00
print ( ' You have been selected card dump ' .. no .. ' , with UID : ' .. files [ no ] )
2020-03-21 17:04:03 +08:00
--- Load eml file
2020-03-21 19:40:16 +08:00
local dumpfile = assert ( io.open ( ' ./hf-mf- ' .. files [ no ] .. ' -dump.eml ' , ' r ' ) )
for _ in dumpfile : lines ( ) do table.insert ( eml , _ ) ; end
dumpfile.close ( )
2020-03-21 17:04:03 +08:00
--- Extract B key from EML file
local b = 0
2020-03-18 18:39:10 +08:00
for i = 1 , # eml do
if ( i % 4 == 0 ) then
repeat
b = b + 1
2020-03-21 17:04:03 +08:00
-- Cut key from block
2020-03-21 19:34:58 +08:00
b_keys [ b ] = string.sub ( eml [ i ] , ( # eml [ i ] - 11 ) , # eml [ i ] )
2020-03-18 18:39:10 +08:00
until b % 4 == 0
end
end
2020-03-21 17:04:03 +08:00
print ( tab )
2020-03-21 19:34:58 +08:00
dbg ( b_keys )
dbg ( eml )
2020-03-17 18:37:38 +08:00
2020-03-21 17:04:03 +08:00
--- Change UID on certain version of magic Gen3 card.
if ( utils.confirm ( ' Change UID ? ' ) == true ) then
2020-03-18 18:39:10 +08:00
wait ( )
2020-03-21 19:34:58 +08:00
--core.console('hf 14a raw -s -c -t 2000 90f0cccc10'..tostring(eml[1]))
print ( ' hf 14a raw -s -c -t 2000 90f0cccc10 ' .. tostring ( eml [ 1 ] ) )
2020-03-18 18:39:10 +08:00
print ( tab )
2020-03-21 17:04:03 +08:00
print ( ' The new card UID : ' .. GetUID ( ) )
2020-03-18 18:39:10 +08:00
end
print ( tab )
2020-03-21 17:04:03 +08:00
--- Lock UID
if ( utils.confirm ( ' Permanent lock UID ? (card can never change uid again) ' ) == true ) then
2020-03-18 18:39:10 +08:00
wait ( )
core.console ( ' hf 14a raw -s -c -t 2000 90fd111100 ' )
end
2020-03-21 17:04:03 +08:00
print ( tab )
--- Writing blocks
local default_key = ' FFFFFFFFFFFF '
local default_key_blk = ' FFFFFFFFFFFF78778800FFFFFFFFFFFF '
local empty = string.rep ( ' 0 ' , 32 )
local cmd_wrbl = ' hf mf wrbl %d B %s %s '
2020-03-17 18:37:38 +08:00
2020-03-21 17:04:03 +08:00
if ( utils.confirm ( ' Are you using a empty card with default key? ' ) == true ) then
2020-03-17 18:37:38 +08:00
wait ( )
for i = 1 , # eml do
2020-03-21 19:37:40 +08:00
core.console ( string.format ( cmd_wrbl , ( i - 1 ) , default_key , eml [ i ] ) )
2020-03-17 18:37:38 +08:00
end
else
2020-03-18 18:39:10 +08:00
print ( tab )
2020-03-21 17:04:03 +08:00
if ( utils.confirm ( ' Delete ALL data and write all keys to 0x ' .. default_key .. ' ? ' ) == true ) then
2020-03-18 18:39:10 +08:00
wait ( )
for i = 1 , # eml do
if ( i % 4 == 0 ) then
2020-03-21 19:37:40 +08:00
core.console ( string.format ( cmd_wrbl , ( i - 1 ) , b_keys [ i ] , default_key_blk ) )
2020-03-18 18:39:10 +08:00
else
2020-03-21 19:37:40 +08:00
core.console ( string.format ( cmd_wrbl , ( i - 1 ) , b_keys [ i ] , empty ) )
2020-03-18 18:39:10 +08:00
end
end
else
2020-03-21 17:04:03 +08:00
print ( tab )
print ( ' Writing to card ' )
2020-03-18 18:39:10 +08:00
wait ( )
for i = 1 , # eml do
2020-03-21 19:37:40 +08:00
core.console ( string.format ( cmd_wrbl , ( i - 1 ) , b_keys [ i ] , eml [ i ] ) )
2020-03-18 18:39:10 +08:00
end
2020-03-17 18:37:38 +08:00
end
end
2020-03-21 17:04:03 +08:00
dropfield ( )
print ( tab )
print ( ' Done ' )
2020-03-17 18:37:38 +08:00
end
2020-03-18 18:39:10 +08:00
2020-03-21 17:04:03 +08:00
main ( args )