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 getopt = require('getopt')
local cmds = require('commands')
local read14a = require('read14a')
--
---
-------------------------------
-- Notes
-------------------------------
---
--
--[[
---Suggestions of improvement:
--- 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 take several versions of same dump ( -1, -2, -3 ) styles.
--]]
--
---
-------------------------------
-- Script hat
-------------------------------
---
--
copyright = ''
author = 'Winds'
version = 'v1.0.0'
@ -42,16 +55,33 @@ example = [[
usage = [[
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
-------------------------------
---
--
local function dbg(args)
if not DEBUG then return end
if type(args) == 'table' then
@ -64,15 +94,25 @@ local function dbg(args)
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
--
---
-------------------------------
-- Usage help
-------------------------------
---
--
local function help()
print(copyright)
print(author)
@ -82,85 +122,171 @@ local function help()
print(example)
print(usage)
end
--
---
-------------------------------
-- GetUID
-------------------------------
---
--
local function GetUID()
return read14a.read(true, true).uid
end
---
--
local function dropfield()
read14a.disconnect()
core.clearCommandBuffer()
end
--
---
-------------------------------
-- Wait for tag (MFC)
-------------------------------
---
--
local function wait()
read14a.waitFor14443a()
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)
-- Arguments for the script
--
---
-------------------------------
-- Arguments for script
-------------------------------
---
--
for o, a in getopt.getopt(args, 'hd') do
if o == 'h' then return help() end
if o == 'd' then DEBUG = true 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()
print(tab)
local length = 25
local e = 16
-- Detect 7 byte card
--
---
-------------------------------
-- Detect 7/4 byte card
-------------------------------
---
--
if string.len(GetUID()) == 14 then
length = 31
e = 22
eml_file_uid_start = 18 -- For windows with '---------- ' prefix
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
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))
for _ in p:lines() do
-- The length of eml file
if string.len(_) == length then
if string.len(_) == eml_file_lengt then
num_dumps = num_dumps + 1
-- cut UID from eml file
files[num_dumps] = string.sub(_, 9, e)
-- cut UID from eml file
files[num_dumps] = string.sub(_, eml_file_uid_start, eml_file_uid_end) -- cut numeretic UID
print(' '..num_dumps..' | '..files[num_dumps])
end
end
--
p.close()
--
if num_dumps == 0 then return oops("Didn't find any dump files") end
--
print(tab)
print(' Your card has UID '..GetUID())
print('')
print(' Select which dump to write (1 until '..num_dumps..')')
print(tab)
io.write(' --> ')
local no = tonumber(io.read())
--
local uid_no = tonumber(io.read())
print(tab)
print(' You have been selected card dump ' .. no .. ', with UID : '..files[no])
--- Load eml file
local dumpfile = assert(io.open('./hf-mf-' .. files[no] .. '-dump.eml', 'r'))
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[uid_no] .. '-dump.eml', 'r'))
for _ in dumpfile:lines() do table.insert(eml, _); end
dumpfile.close()
--- Extract B key from EML file
--
---
-------------------------------
-- Extract B key from EML file
-------------------------------
---
--
local b = 0
for i = 1, #eml do
if (i % 4 == 0) then
@ -174,38 +300,44 @@ local function main(args)
print(tab)
dbg(b_keys)
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
wait()
--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]))
core.console(piswords_uid_change .. tostring(eml[1]))
print(tab)
print(' The new card UID : ' .. GetUID())
end
print(tab)
--- Lock UID
--checkmagic()
--
---
-------------------------------
-- Lock UID
-------------------------------
---
--
if (utils.confirm(' Permanent lock UID ? (card can never change uid again) ') == true) then
wait()
core.console('hf 14a raw -s -c -t 2000 90fd111100')
core.console(piswords_uid_lock)
end
--
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'
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]))
--
if checkkey() == true then
if (utils.confirm(' Card is Empty. Write selected dump to card ?') == true) then
for i = 1, #eml do
core.console(string.format(cmd_wrbl, (i-1), default_key, eml[i]))
end
end
else
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()
for i = 1, #eml do
if (i % 4 == 0) then
@ -216,16 +348,24 @@ local function main(args)
end
else
print(tab)
print('Writing to card')
wait()
for i = 1, #eml do
core.console(string.format(cmd_wrbl, (i-1), b_keys[i], eml[i]))
if (utils.confirm(' Write selected dump to card ?') == true) then
print(tab)
wait()
for i = 1, #eml do
core.console(string.format(cmd_wrbl, (i-1), b_keys[i], eml[i]))
end
end
end
end
dropfield()
print(tab)
print('Done')
print('You are welcome')
end
--
---
-------------------------------
-- Start Main function
-------------------------------
---
--
main(args)