Merge pull request #707 from Windslab/master

A lot of improvements
This commit is contained in:
Philippe Teuwen 2020-04-21 21:22:07 +02:00 committed by GitHub
commit 73c4a37684
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1,7 +1,14 @@
local utils = require('utils') local utils = require('utils')
local getopt = require('getopt') local getopt = require('getopt')
local cmds = require('commands')
local read14a = require('read14a') local read14a = require('read14a')
--
---
-------------------------------
-- Notes
-------------------------------
---
--
--[[ --[[
---Suggestions of improvement: ---Suggestions of improvement:
--- Add support another types of dumps: BIN, JSON --- Add support another types of dumps: BIN, JSON
@ -16,7 +23,13 @@ local read14a = require('read14a')
-- doesn't verify that card is magic gen3. -- doesn't verify that card is magic gen3.
-- doesn't take several versions of same dump ( -1, -2, -3 ) styles. -- doesn't take several versions of same dump ( -1, -2, -3 ) styles.
--]] --]]
--
---
-------------------------------
-- Script hat
-------------------------------
---
--
copyright = '' copyright = ''
author = 'Winds' author = 'Winds'
version = 'v1.0.0' version = 'v1.0.0'
@ -25,7 +38,7 @@ desc = [[
Works with both 4 and 7 bytes NXP MIFARE Classic 1K cards. Works with both 4 and 7 bytes NXP MIFARE Classic 1K cards.
The script also has the possibility to change UID and permanent lock uid on magic Gen3 cards. The script also has the possibility to change UID and permanent lock uid on magic Gen3 cards.
It supports the following functionality. It supports the following functionality.
1. Write it to the same of current card UID. 1. Write it to the same of current card UID.
@ -33,7 +46,7 @@ desc = [[
3. Change uid to match dump on magic Gen3 card. 3. Change uid to match dump on magic Gen3 card.
4. Permanent lock UID 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. 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. Script works in a wizard styled way.
]] ]]
example = [[ example = [[
@ -42,16 +55,33 @@ example = [[
usage = [[ usage = [[
Select your *.eml dump from list to write to the card. Select your *.eml dump from list to write to the card.
]] ]]
--
-- Some globals
local DEBUG = false -- the debug flag
-------------------------------
-- Some utilities
-------------------------------
--- ---
-------------------------------
-- Global variables
-------------------------------
---
--
local DEBUG = false -- the debug flag
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)
local empty = string.rep('0', 32) -- Writing blocks
local default_key = 'FFFFFFFFFFFF' -- Writing blocks
local default_key_type = '01' --KeyA: 00, KeyB: 01
local default_key_blk = 'FFFFFFFFFFFF78778800FFFFFFFFFFFF' -- Writing blocks
local piswords_uid_lock = 'hf 14a raw -s -c -t 2000 90fd111100'
local piswords_uid_change = 'hf 14a raw -s -c -t 2000 90f0cccc10'
local cmd_wrbl = 'hf mf wrbl %d B %s %s' -- Writing blocks
--
---
-------------------------------
-- A debug printout-function -- A debug printout-function
-------------------------------
---
--
local function dbg(args) local function dbg(args)
if not DEBUG then return end if not DEBUG then return end
if type(args) == 'table' then if type(args) == 'table' then
@ -64,15 +94,25 @@ local function dbg(args)
print('###', args) print('###', args)
end end
end end
--
--- ---
-------------------------------
-- This is only meant to be used when errors occur -- This is only meant to be used when errors occur
-------------------------------
---
--
local function oops(err) local function oops(err)
print('ERROR:', err) print('ERROR:', err)
core.clearCommandBuffer() core.clearCommandBuffer()
return nil, err return nil, err
end end
--
--- ---
-------------------------------
-- Usage help -- Usage help
-------------------------------
---
--
local function help() local function help()
print(copyright) print(copyright)
print(author) print(author)
@ -82,85 +122,171 @@ local function help()
print(example) print(example)
print(usage) print(usage)
end end
--
--- ---
-------------------------------
-- GetUID -- GetUID
-------------------------------
---
--
local function GetUID() local function GetUID()
return read14a.read(true, true).uid return read14a.read(true, true).uid
end end
---
-- --
local function dropfield() local function dropfield()
read14a.disconnect() read14a.disconnect()
core.clearCommandBuffer() core.clearCommandBuffer()
end end
--
--- ---
-------------------------------
-- Wait for tag (MFC) -- Wait for tag (MFC)
-------------------------------
---
--
local function wait() local function wait()
read14a.waitFor14443a() read14a.waitFor14443a()
end end
--
---
-------------------------------
-- Check 0xFFFFFFFFFFFF key for tag (MFC)
-------------------------------
---
--
local function getblockdata(response)
if response.Status == 0 then
return true
else
return false
end
end
--
local function checkkey()
local status = 0
for i = 1, #eml do
cmd = Command:newNG{cmd = cmds.CMD_HF_MIFARE_READBL, data = ('%02s%02s%s'):format((i-1), default_key_type, default_key)}
if (getblockdata(cmd:sendNG(false)) == true) then
status = status + 1
if default_key_type == '00' then
print(('%s %02s %s %s %s'):format('Block:', (i-1), 'KeyA', default_key, 'OK'))
else
print(('%s %02s %s %s %s'):format('Block:', (i-1), 'KeyB', default_key, 'OK'))
end
else
break
end
end
if status == #eml then
return true
end
end
--
---
-------------------------------
-- Check Pissword backdor
-------------------------------
---
--
local function checkmagic()
--Have no RAW ISO14443A command in appmain.c
cmd = Command:newNG{cmd = cmds.CMD_HF_ISO14443A_READER, data = piswords_uid_change .. GetUID()} -- sample check to pull the same UID to card and check response
if (getblockdata(cmd:sendNG(false)) == true) then
print('Magic')
else
print('Not magic')
end
end
--
---
-------------------------------
-- Main function
-------------------------------
--- ---
-- --
local function main(args) local function main(args)
--
-- Arguments for the script ---
-------------------------------
-- Arguments for script
-------------------------------
---
--
for o, a in getopt.getopt(args, 'hd') do for o, a in getopt.getopt(args, 'hd') do
if o == 'h' then return help() end if o == 'h' then return help() end
if o == 'd' then DEBUG = true end if o == 'd' then DEBUG = true end
end end
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)
-- --
wait() wait()
print(tab) print(tab)
--
local length = 25 ---
local e = 16 -------------------------------
-- Detect 7 byte card -- Detect 7/4 byte card
-------------------------------
---
--
if string.len(GetUID()) == 14 then if string.len(GetUID()) == 14 then
length = 31 eml_file_uid_start = 18 -- For windows with '---------- ' prefix
e = 22 eml_file_uid_end = 31
eml_file_lengt = 40
else
eml_file_uid_start = 18 -- For windows with '---------- ' prefix
eml_file_uid_end = 25
eml_file_lengt = 34
end end
dropfield() dropfield()
--
---List all EML files in /client ---
local dumpEML = "find '.' -iname '*dump.eml' -type f" -------------------------------
-- List all EML files in /client
-------------------------------
---
--
local dumpEML = 'find "." "*dump.eml"' -- Fixed for windows
local p = assert(io.popen(dumpEML)) local p = assert(io.popen(dumpEML))
for _ in p:lines() do for _ in p:lines() do
-- The length of eml file -- The length of eml file
if string.len(_) == length then if string.len(_) == eml_file_lengt then
num_dumps = num_dumps + 1 num_dumps = num_dumps + 1
-- cut UID from eml file -- cut UID from eml file
files[num_dumps] = string.sub(_, 9, e) files[num_dumps] = string.sub(_, eml_file_uid_start, eml_file_uid_end) -- cut numeretic UID
print(' '..num_dumps..' | '..files[num_dumps]) print(' '..num_dumps..' | '..files[num_dumps])
end end
end end
--
p.close() p.close()
--
if num_dumps == 0 then return oops("Didn't find any dump files") end if num_dumps == 0 then return oops("Didn't find any dump files") end
--
print(tab) print(tab)
print(' Your card has UID '..GetUID()) print(' Your card has UID '..GetUID())
print('') print('')
print(' Select which dump to write (1 until '..num_dumps..')') print(' Select which dump to write (1 until '..num_dumps..')')
print(tab) print(tab)
io.write(' --> ') io.write(' --> ')
--
local no = tonumber(io.read()) local uid_no = tonumber(io.read())
print(tab) print(tab)
print(' You have been selected card dump ' .. no .. ', with UID : '..files[no]) print(' You have been selected card dump No ' .. uid_no .. ', with UID: ' .. files[uid_no] .. '. Your card UID: ' .. GetUID())
--
--- Load eml file --
local dumpfile = assert(io.open('./hf-mf-' .. files[no] .. '-dump.eml', 'r')) ---
-------------------------------
-- Load eml file
-------------------------------
---
--
local dumpfile = assert(io.open('./hf-mf-' .. files[uid_no] .. '-dump.eml', 'r'))
for _ in dumpfile:lines() do table.insert(eml, _); end for _ in dumpfile:lines() do table.insert(eml, _); end
dumpfile.close() dumpfile.close()
--
--- Extract B key from EML file ---
-------------------------------
-- Extract B key from EML file
-------------------------------
---
--
local b = 0 local b = 0
for i = 1, #eml do for i = 1, #eml do
if (i % 4 == 0) then if (i % 4 == 0) then
@ -174,38 +300,44 @@ local function main(args)
print(tab) print(tab)
dbg(b_keys) dbg(b_keys)
dbg(eml) dbg(eml)
--
--- Change UID on certain version of magic Gen3 card. ---
-------------------------------
-- Change UID on certain version of magic Gen3 card.
-------------------------------
---
--
if (utils.confirm(' Change UID ?') == true) then if (utils.confirm(' Change UID ?') == true) then
wait() wait()
--core.console('hf 14a raw -s -c -t 2000 90f0cccc10'..tostring(eml[1])) core.console(piswords_uid_change .. tostring(eml[1]))
print('hf 14a raw -s -c -t 2000 90f0cccc10'..tostring(eml[1]))
print(tab) print(tab)
print(' The new card UID : ' .. GetUID()) print(' The new card UID : ' .. GetUID())
end end
print(tab) print(tab)
--checkmagic()
--- Lock UID --
---
-------------------------------
-- Lock UID
-------------------------------
---
--
if (utils.confirm(' Permanent lock UID ? (card can never change uid again) ') == true) then if (utils.confirm(' Permanent lock UID ? (card can never change uid again) ') == true) then
wait() wait()
core.console('hf 14a raw -s -c -t 2000 90fd111100') core.console(piswords_uid_lock)
end end
--
print(tab) print(tab)
--
--- Writing blocks if checkkey() == true then
local default_key = 'FFFFFFFFFFFF' if (utils.confirm(' Card is Empty. Write selected dump to card ?') == true) then
local default_key_blk = 'FFFFFFFFFFFF78778800FFFFFFFFFFFF' for i = 1, #eml do
local empty = string.rep('0', 32) core.console(string.format(cmd_wrbl, (i-1), default_key, eml[i]))
local cmd_wrbl = 'hf mf wrbl %d B %s %s' end
if (utils.confirm(' Are you using a empty card with default key?') == true) then
wait()
for i = 1, #eml do
core.console(string.format(cmd_wrbl, (i-1), default_key, eml[i]))
end end
else else
print(tab) print(tab)
if (utils.confirm(' Delete ALL data and write all keys to 0x'..default_key..' ?') == true) then if (utils.confirm(' Delete ALL data and write all keys to 0x' .. default_key .. ' ?') == true) then
wait() wait()
for i = 1, #eml do for i = 1, #eml do
if (i % 4 == 0) then if (i % 4 == 0) then
@ -216,16 +348,24 @@ local function main(args)
end end
else else
print(tab) print(tab)
print('Writing to card') if (utils.confirm(' Write selected dump to card ?') == true) then
wait() print(tab)
for i = 1, #eml do wait()
core.console(string.format(cmd_wrbl, (i-1), b_keys[i], eml[i])) for i = 1, #eml do
core.console(string.format(cmd_wrbl, (i-1), b_keys[i], eml[i]))
end
end end
end end
end end
dropfield() dropfield()
print(tab) print(tab)
print('Done') print('You are welcome')
end end
--
---
-------------------------------
-- Start Main function
-------------------------------
---
--
main(args) main(args)