Merge branch 'master' of github.com:RfidResearchGroup/proxmark3

* 'master' of github.com:RfidResearchGroup/proxmark3:
  refactor NG
  refactor
  textual
  refactored NG
  textual
  refactoring NG
  refactoring
  15 - use NG and refactoring
  textual
  using MIX
  textual
  textual
  textual
  Update .gitignore
  chg: script run didump - helptexts
  fix:  rename to match the new file
  chg: script run didump - use MIX
  chg: hw ping - shouldnt be converted yet..
This commit is contained in:
Philippe Teuwen 2019-05-07 23:38:28 +02:00
commit c505a59e3d
19 changed files with 484 additions and 429 deletions

1
.gitignore vendored
View file

@ -61,5 +61,6 @@ ppls patches/*
client/lualibs/mf_default_keys.lua client/lualibs/mf_default_keys.lua
client/lualibs/usb_cmd.lua client/lualibs/usb_cmd.lua
client/lualibs/pm3_cmd.lua
# recompiled # recompiled
fpga_version_info.c fpga_version_info.c

View file

@ -1,8 +1,8 @@
--[[ --[[
Handle Proxmark USB Commands Handle Proxmark Communication Commands
--]] --]]
local _commands = require('usb_cmd') local _commands = require('pm3_cmd')
local util = require('utils') local util = require('utils')
local TIMEOUT = 2000 local TIMEOUT = 2000

View file

@ -96,7 +96,7 @@ local function read14443a(dont_disconnect, no_rats)
command.arg1 = command.arg1 + ISO14A_COMMAND.ISO14A_NO_RATS command.arg1 = command.arg1 + ISO14A_COMMAND.ISO14A_NO_RATS
end end
local result,err = command:sendMIX() local result, err = command:sendMIX()
if result then if result then
local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL',result) local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL',result)
if arg0 == 0 then if arg0 == 0 then
@ -120,13 +120,13 @@ end
-- @return if successfull: an table containing card info -- @return if successfull: an table containing card info
-- @return if unsuccessfull : nil, error -- @return if unsuccessfull : nil, error
local function waitFor14443a() local function waitFor14443a()
print("Waiting for card... press any key to quit") print('Waiting for card... press any key to quit')
while not core.ukbhit() do while not core.ukbhit() do
res, err = read14443a() res, err = read14443a()
if res then return res end if res then return res end
-- err means that there was no response from card -- err means that there was no response from card
end end
return nil, "Aborted by user" return nil, 'Aborted by user'
end end
-- Sends an instruction to do nothing, only disconnect -- Sends an instruction to do nothing, only disconnect

View file

@ -2,7 +2,7 @@
This is a library to read 14443b tags. It can be used something like this This is a library to read 14443b tags. It can be used something like this
local reader = require('read14b') local reader = require('read14b')
result, err = reader.select1443b() result, err = reader.read14443b()
if not result then if not result then
print(err) print(err)
return return
@ -13,7 +13,10 @@
-- Loads the commands-library -- Loads the commands-library
local cmds = require('commands') local cmds = require('commands')
local utils = require('utils') local utils = require('utils')
-- Shouldn't take longer than 2.5 seconds
local TIMEOUT = 2500 local TIMEOUT = 2500
local ISO14B_COMMAND = { local ISO14B_COMMAND = {
ISO14B_CONNECT = 1, ISO14B_CONNECT = 1,
ISO14B_DISCONNECT = 2, ISO14B_DISCONNECT = 2,
@ -41,45 +44,16 @@ local function parse1443b(data)
--]] --]]
local count, uid, uidlen, atqb, chipid, cid = bin.unpack('H10CH7CC',data) local count, uid, uidlen, atqb, chipid, cid = bin.unpack('H10CH7CC',data)
uid = uid:sub(1, 2*uidlen) uid = uid:sub(1, 2 * uidlen)
return { uid = uid, uidlen = uidlen, atqb = atqb, chipid = chipid, cid = cid } return {
uid = uid,
uidlen = uidlen,
atqb = atqb,
chipid = chipid,
cid = cid
}
end end
--- Sends a USBpacket to the device
-- @param command - the usb packet to send
-- @param ignoreresponse - if set to true, we don't read the device answer packet
-- which is usually recipe for fail. If not sent, the host will wait 2s for a
-- response of type CMD_ACK
-- @return packet,nil if successfull
-- nil, errormessage if unsuccessfull
local function sendToDevice(cmd, ignoreresponse)
--core.clearCommandBuffer()
local bytes = cmd:getBytes()
local count,c,arg0,arg1,arg2 = bin.unpack('LLLL',bytes)
local err = core.SendCommand(cmd:getBytes())
if err then
print('ERROR',err)
return nil, err
end
if ignoreresponse then return nil,nil end
local response = core.WaitForResponseTimeout(cmds.CMD_ACK, TIMEOUT)
return response,nil
end
--- Picks out and displays the data read from a tag
-- Specifically, takes a usb packet, converts to a Command
-- (as in commands.lua), takes the data-array and
-- reads the number of bytes specified in arg1 (arg0 in c-struct)
-- and displays the data
-- @param usbpacket the data received from the device
local function showData(usbpacket)
local response = Command.parse(usbpacket)
local len = response.arg2 * 2
local data = string.sub(response.data, 0, len);
print("<< ",data)
end
-- This function does a connect and retrieves some info -- This function does a connect and retrieves some info
-- @return if successfull: an table containing card info -- @return if successfull: an table containing card info
-- @return if unsuccessfull : nil, error -- @return if unsuccessfull : nil, error
@ -95,18 +69,22 @@ local function read14443b(disconnect)
flags = flags + ISO14B_COMMAND.ISO14B_DISCONNECT flags = flags + ISO14B_COMMAND.ISO14B_DISCONNECT
end end
command = Command:new{cmd = cmds.CMD_ISO_14443B_COMMAND, arg1 = flags} command = Command:newMIX{
local result, err = sendToDevice(command, false) cmd = cmds.CMD_ISO_14443B_COMMAND,
arg1 = flags
}
local result, err = command:sendMIX()
if result then if result then
local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL',result) local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL',result)
if arg0 == 0 then if arg0 == 0 then
data = string.sub(result, count) data = string.sub(result, count)
info, err = parse1443b(data) info, err = parse1443b(data)
else else
err = "iso14443b card select failed" err = 'iso14443b card select failed'
end end
else else
err = "No response from card" err = 'No response from card'
end end
if err then if err then
@ -115,43 +93,42 @@ local function read14443b(disconnect)
end end
return info return info
end end
--PING / PONG - Custom Anticollison for Navigo.
-- AA / BB ?!?
-- local ping = ('BA00')
-- result, err = sendRaw(ping, 1, 1)
-- if result then
-- resp = Command.parse( result )
-- if arg1 == 0 then
-- return nil, "iso14443b card - PING/PONG failed"
-- end
-- showData(result)
-- else
-- err = "No response from card"
-- print(err)
-- return nil, err
-- end
--- ---
-- Waits for a mifare card to be placed within the vicinity of the reader. -- Waits for a mifare card to be placed within the vicinity of the reader.
-- @return if successfull: an table containing card info -- @return if successfull: an table containing card info
-- @return if unsuccessfull : nil, error -- @return if unsuccessfull : nil, error
local function waitFor14443b() local function waitFor14443b()
print("Waiting for card... press any key to quit") print('Waiting for card... press any key to quit')
while not core.ukbhit() do while not core.ukbhit() do
res, err = read14443b(false) res, err = read14443b(false)
if res then return res end if res then return res end
-- err means that there was no response from card -- err means that there was no response from card
end end
return nil, "Aborted by user" return nil, 'Aborted by user'
end
---
-- turns on the HF field.
local function connect14443b()
local c = Command:newMIX{cmd = cmds.CMD_ISO_14443B_COMMAND, arg1 = ISO14B_COMMAND.ISO14B_CONNECT}
return c.sendMIX(true)
end
---
-- Sends an instruction to do nothing, only disconnect
local function disconnect14443b()
local c = Command:newMIX{cmd = cmds.CMD_ISO_14443B_COMMAND, arg1 = ISO14B_COMMAND.ISO14B_DISCONNECT}
-- We can ignore the response here, no ACK is returned for this command
-- Check /armsrc/iso14443b.c, ReaderIso14443b() for details
return c.sendMIX(true)
end end
local library = { local library = {
read = read14443b, read = read14443b,
waitFor14443b = waitFor14443b, waitFor14443b = waitFor14443b,
parse1443b = parse1443b, parse1443b = parse1443b,
sendToDevice = sendToDevice, connect = connect14443b,
showData = showData, disconnect = disconnect14443b,
ISO14B_COMMAND = ISO14B_COMMAND, ISO14B_COMMAND = ISO14B_COMMAND,
} }

View file

@ -13,27 +13,15 @@
-- Loads the commands-library -- Loads the commands-library
local cmds = require('commands') local cmds = require('commands')
local utils = require('utils') local utils = require('utils')
local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
-- Shouldn't take longer than 2 seconds
local TIMEOUT = 2000
--- Sends a USBpacket to the device local ISO15_COMMAND = {
-- @param command - the usb packet to send ISO15_REQ_SUBCARRIER_SINGLE = 0,
-- @param ignoreresponse - if set to true, we don't read the device answer packet ISO15_REQ_DATARATE_HIGH = 2,
-- which is usually recipe for fail. If not sent, the host will wait 2s for a ISO15_REQ_NONINVENTORY = 0,
-- response of type CMD_ACK }
-- @return packet,nil if successfull
-- nil, errormessage if unsuccessfull
local function sendToDevice(command, ignoreresponse)
local err = core.SendCommand(command:getBytes())
if err then
print(err)
return nil, err
end
if ignoreresponse then return nil, nil end
local response = core.WaitForResponseTimeout(cmds.CMD_ACK, TIMEOUT)
return response, nil
end
local function errorString15693(number) local function errorString15693(number)
local errors = {} local errors = {}
@ -50,7 +38,6 @@ local function errorString15693(number)
return errors[number] or "Reserved for Future Use or Custom command error." return errors[number] or "Reserved for Future Use or Custom command error."
end end
local function parse15693(data) local function parse15693(data)
local bytes = utils.ConvertAsciiToBytes(data) local bytes = utils.ConvertAsciiToBytes(data)
local tmp = utils.ConvertAsciiToHex(data) local tmp = utils.ConvertAsciiToHex(data)
@ -59,14 +46,14 @@ local function parse15693(data)
local crcStr = utils.Crc15(tmp, #tmp) local crcStr = utils.Crc15(tmp, #tmp)
if string.sub(crcStr, #crcStr - 3) ~= '470F' then if string.sub(crcStr, #crcStr - 3) ~= '470F' then
print("CRC", crc ) print('CRC', crc )
return nil, "CRC failed" return nil, 'CRC failed'
end end
if bytes[1] % 2 == 1 then if bytes[1] % 2 == 1 then
-- Above is a poor-mans bit check: -- Above is a poor-mans bit check:
-- recv[0] & ISO15_RES_ERROR //(0x01) -- recv[0] & ISO15_RES_ERROR //(0x01)
local err = "Tag returned error %i: %s" local err = 'Tag returned error %i: %s'
err = string.format(err, bytes[1], errorString15693(bytes[1])) err = string.format(err, bytes[1], errorString15693(bytes[1]))
return nil, err return nil, err
end end
@ -82,7 +69,6 @@ end
local function read15693(slow, dont_readresponse) local function read15693(slow, dont_readresponse)
--[[ --[[
We start by trying this command: We start by trying this command:
MANDATORY (present in ALL iso15693 tags) command (the example below is sent to a tag different from the above one): MANDATORY (present in ALL iso15693 tags) command (the example below is sent to a tag different from the above one):
@ -108,11 +94,13 @@ local function read15693(slow, dont_readresponse)
data = utils.Crc15("260100") data = utils.Crc15("260100")
command = Command:new{cmd = cmds.CMD_ISO_15693_COMMAND, command = Command:newMIX{
arg1 = #data / 2, cmd = cmds.CMD_ISO_15693_COMMAND,
arg2 = 1, arg1 = #data / 2,
arg3 = 1, arg2 = 1,
data = data} arg3 = 1,
data = data
}
if slow then if slow then
command.arg2 = 0 command.arg2 = 0
@ -121,24 +109,23 @@ local function read15693(slow, dont_readresponse)
command.arg3 = 0 command.arg3 = 0
end end
local result, err = sendToDevice(command, dont_readresponse) local result, err = command:sendMIX()
if not result then if result then
print(err) local count, cmd, len, arg2, arg3 = bin.unpack('LLLL', result)
return nil, "15693 identify: no answer" if len == 0 then
end return nil, 'iso15693 card select failed'
end
local count, cmd, len, arg2, arg3 = bin.unpack('LLLL', result)
if len > 0 then
data = string.sub(result, count, count+len-1) data = string.sub(result, count, count+len-1)
info, err = parse15693(data) info, err = parse15693(data)
if err then
print(err)
return nil, err
end
return info
else else
return nil, "Failed to get response" err = 'No response from card'
end end
if err then
print(err)
return nil, err
end
return info
end end
--- ---
@ -146,19 +133,28 @@ end
-- @return if successfull: an table containing card info -- @return if successfull: an table containing card info
-- @return if unsuccessfull : nil, error -- @return if unsuccessfull : nil, error
local function waitFor15693() local function waitFor15693()
print("Waiting for card... press any key to quit") print('Waiting for card... press any key to quit')
while not core.ukbhit() do while not core.ukbhit() do
res, err = read15693() res, err = read15693()
if res then return res end if res then return res end
-- err means that there was no response from card -- err means that there was no response from card
end end
return nil, "Aborted by user" return nil, 'Aborted by user'
end end
-- Sends an instruction to do nothing, only disconnect
local function disconnect15693()
local c = Command:newMIX{cmd = cmds.CMD_ISO_15693_COMMAND}
-- We can ignore the response here, no ACK is returned for this command
-- Check /armsrc/iso14443a.c, ReaderIso14443a() for details
return c.sendMIX(true)
end
local library = { local library = {
read = read15693, read = read15693,
waitFor15693 = waitFor15693, waitFor15693 = waitFor15693,
parse15693 = parse15693, parse15693 = parse15693,
sendToDevice = sendToDevice, disconnect = disconnect15693,
} }
return library return library

View file

@ -115,10 +115,10 @@ return {
lookupManufacturer = function (value) lookupManufacturer = function (value)
if type(value) == 'string' then if type(value) == 'string' then
local v = tonumber(value, 16) local v = tonumber(value, 16)
print(string.format("WARNING: lookupManufacturer expects numeric value, converted %s into %x", value,v)) print(string.format('WARNING: lookupManufacturer expects numeric value, converted %s into %x', value,v))
value = v value = v
end end
return m[value] or "no tag-info available" return m[value] or 'no tag-info available'
end, end,
} }

View file

@ -2,11 +2,27 @@ local cmds = require('commands')
local getopt = require('getopt') local getopt = require('getopt')
local lib14a = require('read14a') local lib14a = require('read14a')
example = "script run 14araw -x 6000F57b" copyright = ''
author = "Martin Holst Swende" author = "Martin Holst Swende"
desc = version = 'v1.0.1'
[[ desc = [[
This is a script to allow raw 1444a commands to be sent and received. This is a script to allow raw 1444a commands to be sent and received.
]]
example = [[
# 1. Connect and don't disconnect
script run 14araw -p
# 2. Send mf auth, read response (nonce)
script run 14araw -o -x 6000F57b -p
# 3. disconnect
script run 14araw -o
# All three steps in one go:
script run 14araw -x 6000F57b
]]
usage = [[
script run 14araw -x 6000F57b
Arguments: Arguments:
-o do not connect - use this only if you previously used -p to stay connected -o do not connect - use this only if you previously used -p to stay connected
@ -17,18 +33,6 @@ Arguments:
-d Debug flag -d Debug flag
-t Topaz mode -t Topaz mode
-3 ISO14443-4 (use RATS) -3 ISO14443-4 (use RATS)
Examples :
# 1. Connect and don't disconnect
script run 14araw -p
# 2. Send mf auth, read response (nonce)
script run 14araw -o -x 6000F57b -p
# 3. disconnect
script run 14araw -o
# All three steps in one go:
script run 14araw -x 6000F57b
]] ]]
--[[ --[[
@ -41,7 +45,6 @@ device-side.
]] ]]
-- Some globals -- Some globals
local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
local DEBUG = false -- the debug flag local DEBUG = false -- the debug flag
------------------------------- -------------------------------
@ -51,21 +54,34 @@ local DEBUG = false -- the debug flag
--- ---
-- A debug printout-function -- A debug printout-function
local function dbg(args) local function dbg(args)
if DEBUG then if not DEBUG then return end
print("###", args) if type(args) == 'table' then
local i = 1
while args[i] do
dbg(args[i])
i = i+1
end
else
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()
return nil, err
end end
--- ---
-- Usage help -- Usage help
local function help() local function help()
print(copyright)
print(author)
print(version)
print(desc) print(desc)
print("Example usage") print('Example usage')
print(example) print(example)
print(usage)
end end
--- ---
-- The main entry point -- The main entry point
@ -83,31 +99,35 @@ function main(args)
-- Read the parameters -- Read the parameters
for o, a in getopt.getopt(args, 'orcpx:dt3') do for o, a in getopt.getopt(args, 'orcpx:dt3') do
if o == "o" then doconnect = false end if o == 'o' then doconnect = false end
if o == "r" then ignore_response = true end if o == 'r' then ignore_response = true end
if o == "c" then append_crc = true end if o == 'c' then append_crc = true end
if o == "p" then stayconnected = true end if o == 'p' then stayconnected = true end
if o == "x" then payload = a end if o == 'x' then payload = a end
if o == "d" then DEBUG = true end if o == 'd' then DEBUG = true end
if o == "t" then topaz_mode = true end if o == 't' then topaz_mode = true end
if o == "3" then no_rats = true end if o == '3' then no_rats = true end
end end
-- First of all, connect -- First of all, connect
if doconnect then if doconnect then
dbg("doconnect") dbg("doconnect")
-- We reuse the connect functionality from a
-- common library
info, err = lib14a.read(true, no_rats)
if err then return oops(err) end info, err = lib14a.read(true, no_rats)
print(("Connected to card, uid = %s"):format(info.uid)) if err then
lib14a.disconnect()
return oops(err)
end
print(('Connected to card, uid = %s'):format(info.uid))
end end
-- The actual raw payload, if any -- The actual raw payload, if any
if payload then if payload then
res,err = sendRaw(payload,{ignore_response = ignore_response, topaz_mode = topaz_mode, append_crc = append_crc}) res, err = sendRaw(payload,{ignore_response = ignore_response, topaz_mode = topaz_mode, append_crc = append_crc})
if err then return oops(err) end if err then
lib14a.disconnect()
return oops(err)
end
if not ignoreresponse then if not ignoreresponse then
-- Display the returned data -- Display the returned data
@ -116,7 +136,7 @@ function main(args)
end end
-- And, perhaps disconnect? -- And, perhaps disconnect?
if not stayconnected then if not stayconnected then
disconnect() lib14a.disconnect()
end end
end end
@ -132,11 +152,10 @@ function showdata(usbpacket)
--print("data length:",len) --print("data length:",len)
local data = string.sub(tostring(cmd_response.data), 0, len); local data = string.sub(tostring(cmd_response.data), 0, len);
print("<< ",data) print("<< ",data)
--print("----------------")
end end
function sendRaw(rawdata, options) function sendRaw(rawdata, options)
print(">> ", rawdata) print('>> ', rawdata)
local flags = lib14a.ISO14A_COMMAND.ISO14A_NO_DISCONNECT + lib14a.ISO14A_COMMAND.ISO14A_RAW local flags = lib14a.ISO14A_COMMAND.ISO14A_NO_DISCONNECT + lib14a.ISO14A_COMMAND.ISO14A_RAW
@ -147,39 +166,32 @@ function sendRaw(rawdata, options)
flags = flags + lib14a.ISO14A_COMMAND.ISO14A_APPEND_CRC flags = flags + lib14a.ISO14A_COMMAND.ISO14A_APPEND_CRC
end end
local command = Command:new{cmd = cmds.CMD_READER_ISO_14443a, local command = Command:newMIX{cmd = cmds.CMD_READER_ISO_14443a,
arg1 = flags, -- Send raw arg1 = flags, -- Send raw
-- arg2 contains the length, which is half the length -- arg2 contains the length, which is half the length
-- of the ASCII-string rawdata -- of the ASCII-string rawdata
arg2 = string.len(rawdata)/2, arg2 = string.len(rawdata)/2,
data = rawdata} data = rawdata}
return lib14a.sendToDevice(command, options.ignore_response) return command:sendMIX(options.ignore_response)
end end
-- Sends an instruction to do nothing, only disconnect
function disconnect()
local command = Command:new{cmd = cmds.CMD_READER_ISO_14443a, arg1 = 0,}
-- We can ignore the response here, no ACK is returned for this command
-- Check /armsrc/iso14443a.c, ReaderIso14443a() for details
return lib14a.sendToDevice(command,true)
end
------------------------- -------------------------
-- Testing -- Testing
------------------------- -------------------------
function selftest() function selftest()
DEBUG = true DEBUG = true
dbg("Performing test") dbg('Performing test')
main() main()
main("-p") main('-p')
main(" -o -x 6000F57b -p") main(' -o -x 6000F57b -p')
main("-o") main('-o')
main("-x 6000F57b") main('-x 6000F57b')
dbg("Tests done") dbg('Tests done')
end end
-- Flip the switch here to perform a sanity check. -- Flip the switch here to perform a sanity check.
-- It read a nonce in two different ways, as specified in the usage-section -- It read a nonce in two different ways, as specified in the usage-section
if "--test"==args then if '--test'==args then
selftest() selftest()
else else
-- Call the main -- Call the main

View file

@ -15,9 +15,13 @@ local luamiibo = luamiibo_open()
local function nfc_read_amiibo () local function nfc_read_amiibo ()
local command = Command:new{cmd = cmds.CMD_MIFAREU_READCARD, arg1 = 0, arg2 = 135} local command = Command:newMIX{
cmd = cmds.CMD_MIFAREU_READCARD,
arg1 = 0,
arg2 = 135
}
local result, err = reader.sendToDevice(command) local result, err = command.sendMIX()
if result then if result then
-- Do Mifare Ultralight read -- Do Mifare Ultralight read
local count, cmd, arg0, data_len, offset = bin.unpack('LLLL', result) local count, cmd, arg0, data_len, offset = bin.unpack('LLLL', result)
@ -85,8 +89,13 @@ local function emulate_amiibo (amiibo_data)
print(string.format('Simulating with UID: 0x%04x 0x%04x', uid_first, uid_second)) print(string.format('Simulating with UID: 0x%04x 0x%04x', uid_first, uid_second))
-- Begin simulating NTAG215 -- Begin simulating NTAG215
local simCmd = Command:new{cmd = cmds.CMD_SIMULATE_TAG_ISO_14443a, arg1 = 7, arg2 = uid_first, arg3 = uid_second} local simCmd = Command:newMIX{
local _, err = reader.sendToDevice(simCmd) cmd = cmds.CMD_SIMULATE_TAG_ISO_14443a,
arg1 = 7,
arg2 = uid_first,
arg3 = uid_second
}
local _, err = simCmd.sendMIX()
if err then if err then
print('Failed to start simulator', err) print('Failed to start simulator', err)
return return

View file

@ -33,21 +33,22 @@ local bxor = bit32.bxor
-- 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
local i = 1 local i = 1
while args[i] do while args[i] do
dbg(args[i]) dbg(args[i])
i = i+1 i = i+1
end end
else else
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)
return nil,err core.clearCommandBuffer()
return nil, err
end end
--- ---
-- Usage help -- Usage help
@ -58,6 +59,7 @@ local function help()
print(desc) print(desc)
print('Example usage') print('Example usage')
print(example) print(example)
print(usage)
end end
--- ---
-- Exit message -- Exit message
@ -142,8 +144,8 @@ local function main(args)
-- Arguments for the script -- Arguments for the script
for o, a in getopt.getopt(args, 'hu:') do for o, a in getopt.getopt(args, 'hu:') do
if o == "h" then return help() end if o == 'h' then return help() end
if o == "u" then uid = a; useUID = true end if o == 'u' then uid = a; useUID = true end
end end
if useUID then if useUID then
@ -160,7 +162,7 @@ local function main(args)
-- simple tag check -- simple tag check
if 0x09 ~= tag.sak then if 0x09 ~= tag.sak then
if 0x4400 ~= tag.atqa then if 0x4400 ~= tag.atqa then
return oops(('[fail] found tag %s :: looking for Mifare Mini 0.3k'):format(tag.name)) return oops(('[!] found tag %s :: looking for Mifare Mini 0.3k'):format(tag.name))
end end
end end
uid = tag.uid uid = tag.uid

View file

@ -31,22 +31,22 @@ local bxor = bit32.bxor
-- 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
local i = 1 local i = 1
while args[i] do while args[i] do
dbg(args[i]) dbg(args[i])
i = i+1 i = i+1
end end
else else
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)
return nil,err core.clearCommandBuffer()
return nil, err
end end
--- ---
-- Usage help -- Usage help
@ -57,10 +57,11 @@ local function help()
print(desc) print(desc)
print("Example usage") print("Example usage")
print(example) print(example)
print(usage)
end end
-- --
-- Exit message -- Exit message
function exitMsg(msg) local function exitMsg(msg)
print( string.rep('--',20) ) print( string.rep('--',20) )
print( string.rep('--',20) ) print( string.rep('--',20) )
print(msg) print(msg)
@ -138,6 +139,7 @@ local function pwdgen(uid)
local pwd3 = bxor( entry[4], uidbytes[7]) local pwd3 = bxor( entry[4], uidbytes[7])
return string.format('%02X%02X%02X%02X', pwd0, pwd1, pwd2, pwd3) return string.format('%02X%02X%02X%02X', pwd0, pwd1, pwd2, pwd3)
end end
-- --
-- main -- main
local function main(args) local function main(args)
@ -151,8 +153,8 @@ local function main(args)
-- Arguments for the script -- Arguments for the script
for o, a in getopt.getopt(args, 'hu:') do for o, a in getopt.getopt(args, 'hu:') do
if o == "h" then return help() end if o == 'h' then return help() end
if o == "u" then uid = a; useUID = true end if o == 'u' then uid = a; useUID = true end
end end
if useUID then if useUID then

View file

@ -3,8 +3,9 @@ local getopt = require('getopt')
local lib14a = require('read14a') local lib14a = require('read14a')
local utils = require('utils') local utils = require('utils')
copyright = ''
author = 'Iceman' author = 'Iceman'
version = 'v1.0.0' version = 'v1.0.1'
desc = [[ desc = [[
This script calculates mifare keys based on uid diversification for mizip. This script calculates mifare keys based on uid diversification for mizip.
Algo not found by me. Algo not found by me.
@ -28,30 +29,31 @@ local bxor = bit32.bxor
local _xortable = { local _xortable = {
--[[ sector key A/B, 6byte xor --[[ sector key A/B, 6byte xor
--]] --]]
{1, "09125a2589e5", "F12C8453D821"}, {1, '09125a2589e5', 'F12C8453D821'},
{2, "AB75C937922F", "73E799FE3241"}, {2, 'AB75C937922F', '73E799FE3241'},
{3, "E27241AF2C09", "AA4D137656AE"}, {3, 'E27241AF2C09', 'AA4D137656AE'},
{4, "317AB72F4490", "B01327272DFD"}, {4, '317AB72F4490', 'B01327272DFD'},
} }
--- ---
-- 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
local i = 1 local i = 1
while args[i] do while args[i] do
dbg(args[i]) dbg(args[i])
i = i+1 i = i+1
end end
else else
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)
return nil,err core.clearCommandBuffer()
return nil, err
end end
--- ---
-- Usage help -- Usage help
@ -62,6 +64,7 @@ local function help()
print(desc) print(desc)
print("Example usage") print("Example usage")
print(example) print(example)
print(usage)
end end
-- --
-- Exit message -- Exit message
@ -163,8 +166,8 @@ local function main(args)
-- Arguments for the script -- Arguments for the script
for o, a in getopt.getopt(args, 'hu:') do for o, a in getopt.getopt(args, 'hu:') do
if o == "h" then return help() end if o == 'h' then return help() end
if o == "u" then uid = a ; useUID = true end if o == 'u' then uid = a ; useUID = true end
end end
if useUID then if useUID then
@ -181,7 +184,7 @@ local function main(args)
-- simple tag check -- simple tag check
if 0x09 ~= tag.sak then if 0x09 ~= tag.sak then
if 0x4400 ~= tag.atqa then if 0x4400 ~= tag.atqa then
return oops(('[fail] found tag %s :: looking for Mifare Mini 0.3k'):format(tag.name)) return oops(('[!] found tag %s :: looking for Mifare Mini 0.3k'):format(tag.name))
end end
end end
uid = tag.uid uid = tag.uid

View file

@ -4,27 +4,22 @@ local lib14b = require('read14b')
local utils = require('utils') local utils = require('utils')
local iso7816 = require('7816_error') local iso7816 = require('7816_error')
example = "script runs 14b raw commands to query a CAPLYPSO tag" copyright = ''
author = "Iceman, 2016" author = 'Iceman'
desc = version = 'v1.0.1'
[[ desc = [[
This is a script to communicate with a CALYSPO / 14443b tag using the '14b raw' commands This is a script to communicate with a CALYSPO / 14443b tag using the '14b raw' commands
]]
example = [[
script run calypso -b 11223344
]]
usage = [[
script run calypso -h -b
Arguments: Arguments:
-b 123 h this helptext
Examples : b raw bytes to send
script run f -b 11223344
script run f
Examples :
# 1. Connect and don't disconnect
script run f
# 2. Send mf auth, read response
script run f
# 3. disconnect
script run f
]] ]]
--[[ --[[
@ -33,21 +28,6 @@ Check there for details about data format and how commands are interpreted on th
device-side. device-side.
]] ]]
---
--
local function calypso_switch_on_field()
local flags = lib14b.ISO14B_COMMAND.ISO14B_CONNECT
local c = Command:new{cmd = cmds.CMD_ISO_14443B_COMMAND, arg1 = flags}
return lib14b.sendToDevice(c, true)
end
---
-- Disconnect (poweroff) the antenna forcing a disconnect of a 14b tag.
local function calypso_switch_off_field()
local flags = lib14b.ISO14B_COMMAND.ISO14B_DISCONNECT
local c = Command:new{cmd = cmds.CMD_ISO_14443B_COMMAND, arg1 = flags}
return lib14b.sendToDevice(c, true)
end
local function calypso_parse(result) local function calypso_parse(result)
local r = Command.parse(result) local r = Command.parse(result)
local len = r.arg2 * 2 local len = r.arg2 * 2
@ -61,23 +41,34 @@ end
--- ---
-- A debug printout-function -- A debug printout-function
local function dbg(args) local function dbg(args)
if DEBUG then if not DEBUG then return end
print("###", args) if type(args) == 'table' then
local i = 1
while args[i] do
dbg(args[i])
i = i+1
end
else
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)
calypso_switch_off_field() lib14b.disconnect()
return nil, err return nil, err
end end
--- ---
-- Usage help -- Usage help
local function help() local function help()
print(copyright)
print(author)
print(version)
print(desc) print(desc)
print("Example usage") print('Example usage')
print(example) print(example)
print(usage))
end end
-- --
-- helper function, give current count of items in lua-table. -- helper function, give current count of items in lua-table.
@ -122,15 +113,13 @@ local function calypso_send_cmd_raw(data, ignoreresponse )
data = data or "00" data = data or "00"
command = Command:new{cmd = cmds.CMD_ISO_14443B_COMMAND, command = Command:newMIX{
arg1 = flags, cmd = cmds.CMD_ISO_14443B_COMMAND,
arg2 = #data/2, -- LEN of data, half the length of the ASCII-string hex string arg1 = flags,
arg3 = 0, arg2 = #data/2, -- LEN of data, half the length of the ASCII-string hex string
data = data} -- data bytes (commands etc) data = data} -- data bytes (commands etc)
result, err = lib14b.sendToDevice(command, false)
result, err = command:sendMIX(ignoreresponse)
if ignoreresponse then return response, err end
if result then if result then
local r = calypso_parse(result) local r = calypso_parse(result)
return r, nil return r, nil
@ -185,26 +174,26 @@ local _calypso_cmds = {
-- Electronic Transaction log file -- Electronic Transaction log file
--["01.Select ICC file"] = '0294 a4 00 0002 3f00', --['01.Select ICC file'] = '0294 a4 00 0002 3f00',
["01.Select ICC file"] = '0294 a4 080004 3f00 0002', ['01.Select ICC file'] = '0294 a4 080004 3f00 0002',
["02.ICC"] = '0394 b2 01 041d', ['02.ICC'] = '0394 b2 01 041d',
["03.Select EnvHol file"] = '0294 a4 080004 2000 2001', ['03.Select EnvHol file'] = '0294 a4 080004 2000 2001',
["04.EnvHol1"] = '0394 b2 01 041d', ['04.EnvHol1'] = '0394 b2 01 041d',
["05.Select EvLog file"] = '0294 a4 080004 2000 2010', ['05.Select EvLog file'] = '0294 a4 080004 2000 2010',
["06.EvLog1"] = '0394 b2 01 041d', ['06.EvLog1'] = '0394 b2 01 041d',
["07.EvLog2"] = '0294 b2 02 041d', ['07.EvLog2'] = '0294 b2 02 041d',
["08.EvLog3"] = '0394 b2 03 041d', ['08.EvLog3'] = '0394 b2 03 041d',
["09.Select ConList file"]= '0294 a4 080004 2000 2050', ['09.Select ConList file']= '0294 a4 080004 2000 2050',
["10.ConList"] = '0394 b2 01 041d', ['10.ConList'] = '0394 b2 01 041d',
["11.Select Contra file"] = '0294 a4 080004 2000 2020', ['11.Select Contra file'] = '0294 a4 080004 2000 2020',
["12.Contra1"] = '0394 b2 01 041d', ['12.Contra1'] = '0394 b2 01 041d',
["13.Contra2"] = '0294 b2 02 041d', ['13.Contra2'] = '0294 b2 02 041d',
["14.Contra3"] = '0394 b2 03 041d', ['14.Contra3'] = '0394 b2 03 041d',
["15.Contra4"] = '0294 b2 04 041d', ['15.Contra4'] = '0294 b2 04 041d',
["16.Select Counter file"]= '0394 a4 080004 2000 2069', ['16.Select Counter file']= '0394 a4 080004 2000 2069',
["17.Counter"] = '0294 b2 01 041d', ['17.Counter'] = '0294 b2 01 041d',
["18.Select SpecEv file"] = '0394 a4 080004 2000 2040', ['18.Select SpecEv file'] = '0394 a4 080004 2000 2040',
["19.SpecEv1"] = '0294 b2 01 041d', ['19.SpecEv1'] = '0294 b2 01 041d',
} }
--- ---
@ -218,11 +207,12 @@ function main(args)
local data, apdu, flags, uid, cid, result, err, card local data, apdu, flags, uid, cid, result, err, card
-- Read the parameters -- Read the parameters
for o, a in getopt.getopt(args, 'h') do for o, a in getopt.getopt(args, 'h') do
if o == "h" then return help() end if o == 'h' then return help() end
if o == 'b' then bytes = a end
end end
calypso_switch_on_field() lib14b.connect()
-- Select 14b tag. -- Select 14b tag.
card, err = lib14b.waitFor14443b() card, err = lib14b.waitFor14443b()
if not card then return oops(err) end if not card then return oops(err) end
@ -248,7 +238,7 @@ function main(args)
--result, err = calypso_send_cmd_raw('0294a40800043f000002',false) --select ICC file --result, err = calypso_send_cmd_raw('0294a40800043f000002',false) --select ICC file
for i, apdu in spairs(_calypso_cmds) do for i, apdu in spairs(_calypso_cmds) do
print('>>', i ) print('>>', i )
apdu = apdu:gsub("%s+","") apdu = apdu:gsub('%s+', '')
result, err = calypso_send_cmd_raw(apdu , false) result, err = calypso_send_cmd_raw(apdu , false)
if result then if result then
calypso_apdu_status(result.data) calypso_apdu_status(result.data)
@ -257,18 +247,18 @@ function main(args)
print('<< no answer') print('<< no answer')
end end
end end
calypso_switch_off_field() lib14b.disconnect()
end end
--- ---
-- a simple selftest function, tries to convert -- a simple selftest function, tries to convert
function selftest() function selftest()
DEBUG = true DEBUG = true
dbg("Performing test") dbg('Performing test')
dbg("Tests done") dbg('Tests done')
end end
-- Flip the switch here to perform a sanity check. -- Flip the switch here to perform a sanity check.
-- It read a nonce in two different ways, as specified in the usage-section -- It read a nonce in two different ways, as specified in the usage-section
if "--test"==args then if '--test'==args then
selftest() selftest()
else else
-- Call the main -- Call the main

View file

@ -1,12 +1,16 @@
--[[
A sampe script file on how to implement at cmd line inteface.
--]]
print("This is how a cmd-line interface could be implemented\nPrint 'exit' to exit.\n") print("This is how a cmd-line interface could be implemented\nPrint 'exit' to exit.\n")
local answer local answer
repeat repeat
io.write("$>") io.write("$>")
io.flush() io.flush()
answer=io.read() answer = io.read()
if answer ~= 'exit' then if answer ~= 'exit' then
local func = assert(loadstring("return " .. answer)) local func = assert(loadstring("return " .. answer))
io.write("\n"..tostring(func() or "").."\n"); io.write("\n"..tostring(func() or "").."\n");
end--]] end--]]
until answer=="exit" until answer == "exit"
print("Bye\n"); print("Bye\n");

View file

@ -7,29 +7,48 @@ local lib14a = require('read14a')
local json = require('dkjson') local json = require('dkjson')
local toys = require('default_toys_di') local toys = require('default_toys_di')
example =[[ copyright = ''
script run didump author = 'Iceman'
script run didump -t version = 'v1.0.1'
script run didump -r
]]
author = "Iceman"
usage = "script run didump -h -t"
desc = [[ desc = [[
This is a script to dump and decrypt the data of a specific type of Mifare Mini token. This is a script to dump and decrypt the data of a specific type of Mifare Mini token.
The dump is decrypted. If a raw dump is wanted, use the -r parameter The dump is decrypted. If a raw dump is wanted, use the -r parameter
]]
example = [[
script run didump
-- selftest
script run didump -t
-- Generate raw dump, into json.
script run didump -r
-- load file
script run didump -i dumpdata.json
]]
usage = [[
script run didump -h -t -r -d -e -v -i dumpdata.json
Arguments: Arguments:
-h : this help h this helptext
-r : raw r raw
-t : selftest t selftest
d decrypt data
e encrypt data
v validate data
i dumpdata.json load json dump file
end
]] ]]
local band=bit32.band -- Some shortcuts
local bor=bit32.bor local band = bit32.band
local bnot=bit32.bnot local bor = bit32.bor
local bxor=bit32.bxor local bnot = bit32.bnot
local lsh=bit32.lshift local bxor = bit32.bxor
local rsh=bit32.rshift local lsh = bit32.lshift
local rsh = bit32.rshift
-- Some globals
local FOO = 'AF62D2EC0491968CC52A1A7165F865FE' local FOO = 'AF62D2EC0491968CC52A1A7165F865FE'
local BAR = '286329204469736E65792032303133' local BAR = '286329204469736E65792032303133'
local MIS = '0A14FD0507FF4BCD026BA83F0A3B89A9' local MIS = '0A14FD0507FF4BCD026BA83F0A3B89A9'
@ -44,29 +63,33 @@ local CHECKSUM_OFFSET = 12; -- +1???
-- 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
local i = 1 local i = 1
while args[i] do while args[i] do
print("###", args[i]) print('###', args[i])
i = i+1 i = i+1
end end
else else
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 false return nil, err
end end
--- ---
-- Usage help -- Usage help
local function help() local function help()
print(copyright)
print(author)
print(version)
print(desc) print(desc)
print("Example usage") print('Example usage')
print(example) print(example)
print(usage)
end end
--- ---
-- --
@ -370,21 +393,7 @@ local function updateChecksum(data)
return string.format("%s%X", part, chksum) return string.format("%s%X", part, chksum)
end end
--- ---
-- receives the answer from deviceside, used with a readblock command --
local function waitCmd()
local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT)
if response then
local count,cmd,arg0 = bin.unpack('LL',response)
if(arg0==1) then
local count,arg1,arg2,data = bin.unpack('LLH511',response,count)
return data:sub(1,32)
else
return nil, "Couldn't read block.."
end
end
return nil, "No response from device"
end
local function keygen(uid) local function keygen(uid)
local data = MIS..uid..BAR local data = MIS..uid..BAR
local hash = utils.ConvertAsciiToBytes(utils.Sha1Hex(data)) local hash = utils.ConvertAsciiToBytes(utils.Sha1Hex(data))
@ -397,7 +406,6 @@ local function keygen(uid)
hash[6+1] hash[6+1]
) )
end end
--- encode 'table' into a json formatted string --- encode 'table' into a json formatted string
-- --
local function convert_to_json( obj ) local function convert_to_json( obj )
@ -449,6 +457,29 @@ local function create_key(uid)
key = key..utils.SwapEndiannessStr( sha:sub(25,32), 32 ) key = key..utils.SwapEndiannessStr( sha:sub(25,32), 32 )
return key return key
end end
---
-- decode response and get the blockdata from a normal mifare read command
local function getblockdata(response)
if not response then
return nil, 'No response from device'
end
local count, cmd, arg0 = bin.unpack('LL', response)
if arg0 == 1 then
local count, arg1, arg2, data = bin.unpack('LLH511', response, count)
return data:sub(1, 32)
else
return nil, "Couldn't read block.. ["..arg0.."]"
end
end
local function readblock( blocknum, key )
-- Read block N
local c = Command:newMIX{cmd = cmds.CMD_MIFARE_READBL, arg1 = blocknum, data = key}
local b, err = getblockdata(c:sendMIX())
if not b then return oops(err) end
return b
end
--- reads all blocks from tag --- reads all blocks from tag
-- --
local function readtag(mfkey, aeskey ) local function readtag(mfkey, aeskey )
@ -463,11 +494,8 @@ local function readtag(mfkey, aeskey )
end end
-- read block from tag. -- read block from tag.
cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = blockNo ,arg2 = 0,arg3 = 0, data = mfkey} local blockdata = readblock(blockNo, mfkey)
local err = core.SendCommand(cmd:getBytes()) if not blockdata then return oops('[!] failed reading block') end
if err then return oops(err) end
local blockdata, err = waitCmd()
if err then return oops(err) end
-- rules: -- rules:
-- the following blocks is NOT encrypted -- the following blocks is NOT encrypted
@ -488,7 +516,6 @@ local function readtag(mfkey, aeskey )
else else
-- Sectorblocks, not encrypted, but we add our known key to it since it is normally zeros. -- Sectorblocks, not encrypted, but we add our known key to it since it is normally zeros.
blockdata = mfkey..blockdata:sub(13,20)..mfkey blockdata = mfkey..blockdata:sub(13,20)..mfkey
--dbg(blockdata:sub(13,20))
end end
table.insert(tagdata, blockdata) table.insert(tagdata, blockdata)
end end
@ -549,12 +576,12 @@ function main(args)
-- Read the parameters -- Read the parameters
for o, a in getopt.getopt(args, 'htdevi:') do for o, a in getopt.getopt(args, 'htdevi:') do
if o == "h" then help() return end if o == 'h' then help() return end
if o == "t" then return selftest() end if o == 't' then return selftest() end
if o == "d" then shall_dec = true end if o == 'd' then shall_dec = true end
if o == "e" then shall_enc = true end if o == 'e' then shall_enc = true end
if o == "v" then shall_validate = true end if o == 'v' then shall_validate = true end
if o == "i" then input = load_json(a) end if o == 'i' then input = load_json(a) end
end end
-- Turn off Debug -- Turn off Debug
@ -562,7 +589,10 @@ function main(args)
-- GET TAG UID -- GET TAG UID
tag, err = lib14a.read(false, true) tag, err = lib14a.read(false, true)
if not tag then return oops(err) end if err then
lib14a.disconnect()
return oops(err)
end
core.clearCommandBuffer() core.clearCommandBuffer()
-- simple tag check -- simple tag check

View file

@ -2,37 +2,54 @@ local getopt = require('getopt')
local bin = require('bin') local bin = require('bin')
local dumplib = require('html_dumplib') local dumplib = require('html_dumplib')
copyright = ''
author = 'Iceman'
version = 'v1.0.1'
desc =[[
This script takes an dumpfile on EML (ASCII) format and converts it to the PM3 dumpbin file to be used with `hf mf restore`
]]
example =[[ example =[[
1. script run emul2dump 1. script run emul2dump
2. script run emul2dump -i myfile.eml 2. script run emul2dump -i myfile.eml
3. script run emul2dump -i myfile.eml -o myfile.bin 3. script run emul2dump -i myfile.eml -o myfile.bin
]] ]]
author = "Iceman" usage = [[
usage = "script run emul2dump [-i <file>] [-o <file>]" script run emul2dump [-i <file>] [-o <file>]
desc =[[
This script takes an dumpfile on EML (ASCII) format and converts it to the PM3 dumpbin file to be used with "hf mf restore"
Arguments: Arguments:
-h This help -h This help
-i <filename> Specifies the dump-file (input). If omitted, 'dumpdata.eml' is used -i <filename> Specifies the dump-file (input). If omitted, 'dumpdata.eml' is used
-o <filename> Specifies the output file. If omitted, <currdate>.bin is used. -o <filename> Specifies the output file. If omitted, <currdate>.bin is used.
]]
]]
--- ---
-- This is only meant to be used when errors occur -- This is only meant to be used when errors occur
function oops(err) local function oops(err)
print("ERROR: ",err) 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 end
--- ---
-- Usage help -- Usage help
function help() local function help()
print(copyright)
print(author)
print(version)
print(desc) print(desc)
print("Example usage") print('Example usage')
print(example) print(example)
print(usage)
end end
-- --
-- Exit message -- Exit message
function ExitMsg(msg) local function ExitMsg(msg)
print( string.rep('--',20) ) print( string.rep('--',20) )
print( string.rep('--',20) ) print( string.rep('--',20) )
print(msg) print(msg)
@ -41,20 +58,20 @@ end
local function main(args) local function main(args)
local input = "dumpdata.eml" local input = 'dumpdata.eml'
local output = os.date("%Y-%m-%d_%H%M%S.bin"); local output = os.date('%Y-%m-%d_%H%M%S.bin');
-- Arguments for the script -- Arguments for the script
for o, a in getopt.getopt(args, 'hi:o:') do for o, a in getopt.getopt(args, 'hi:o:') do
if o == "h" then return help() end if o == 'h' then return help() end
if o == "i" then input = a end if o == 'i' then input = a end
if o == "o" then output = a end if o == 'o' then output = a end
end end
local filename, err = dumplib.convert_eml_to_bin(input,output) local filename, err = dumplib.convert_eml_to_bin(input,output)
if err then return oops(err) end if err then return oops(err) end
ExitMsg(("Wrote a BIN dump to the file %s"):format(filename)) ExitMsg(('Wrote a BIN dump to the file %s'):format(filename))
end end
main(args) main(args)

View file

@ -4,12 +4,18 @@ getopt = require('getopt')
bin = require('bin') bin = require('bin')
dumplib = require('html_dumplib') dumplib = require('html_dumplib')
example = "script run emul2html -o dumpdata.eml " copyright = ''
author = "Martin Holst Swende" author = 'Martin Holst Swende'
usage = "script run htmldump [-i <file>] [-o <file>]" version = 'v1.0.1'
desc =[[ desc = [[
This script takes a dumpfile on EML (ASCII) format and produces a html based dump, which is a This script takes a dumpfile on EML (ASCII) format and produces a html based dump, which is a
bit more easily analyzed. bit more easily analyzed.
]]
example = [[
script run emul2html -o dumpdata.eml
]]
usage = [[
script run htmldump [-i <file>] [-o <file>]
Arguments: Arguments:
-h This help -h This help
@ -18,45 +24,54 @@ Arguments:
]] ]]
------------------------------- -- Some globals
-- Some utilities local DEBUG = false -- the debug flag
-------------------------------
--- ---
-- A debug printout-function -- A debug printout-function
function dbg(args) local function dbg(args)
if DEBUG then if not DEBUG then return end
print("###", args) if type(args) == 'table' then
local i = 1
while args[i] do
dbg(args[i])
i = i+1
end
else
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
function oops(err) local function oops(err)
print("ERROR: ",err) print('ERROR:', err)
core.clearCommandBuffer()
return nil, err
end end
--- ---
-- Usage help -- Usage help
function help() local function help()
print(copyright)
print(author)
print(version)
print(desc) print(desc)
print("Example usage") print('Example usage')
print(example) print(example)
print(usage)
end end
local function main(args) local function main(args)
local input = "dumpdata.eml" local input = 'dumpdata.eml'
local output = os.date("%Y-%m-%d_%H%M%S.html"); local output = os.date('%Y-%m-%d_%H%M%S.html');
for o, a in getopt.getopt(args, 'i:o:h') do for o, a in getopt.getopt(args, 'i:o:h') do
if o == "h" then return help() end if o == 'h' then return help() end
if o == "i" then input = a end if o == 'i' then input = a end
if o == "o" then output = a end if o == 'o' then output = a end
end end
local filename, err = dumplib.convert_eml_to_html(input,output) local filename, err = dumplib.convert_eml_to_html(input,output)
if err then return oops(err) end if err then return oops(err) end
print(("Wrote a HTML dump to the file %s"):format(filename)) print(('Wrote a HTML dump to the file %s'):format(filename))
end end
--[[ --[[

View file

@ -4,6 +4,19 @@ local bin = require('bin')
local lib14a = require('read14a') local lib14a = require('read14a')
local utils = require('utils') local utils = require('utils')
copyright = ''
author = 'Iceman'
version = 'v1.0.1'
desc = [[
This script will generate 'hf mf wrbl' commands for each block to format a Mifare card.
Alla datablocks gets 0x00
As default the script sets the keys A/B to 0xFFFFFFFFFFFF
and the access bytes will become 0x78,0x77,0x88
The GDB will become 0x00
The script will skip the manufactoring block 0.
]]
example = [[ example = [[
-- generate commands -- generate commands
1. script run formatMifare 1. script run formatMifare
@ -14,22 +27,8 @@ example = [[
-- generate commands and execute them against card. -- generate commands and execute them against card.
3. script run formatMifare -x 3. script run formatMifare -x
]] ]]
copyright = ''
version = ''
author = 'Iceman'
usage = [[ usage = [[
script run formatMifare -k <key> -n <key> -a <access> -x script run formatMifare -k <key> -n <key> -a <access> -x
]]
desc = [[
This script will generate 'hf mf wrbl' commands for each block to format a Mifare card.
Alla datablocks gets 0x00
As default the script sets the keys A/B to 0xFFFFFFFFFFFF
and the access bytes will become 0x78,0x77,0x88
The GDB will become 0x00
The script will skip the manufactoring block 0.
Arguments: Arguments:
-h - this help -h - this help
@ -38,6 +37,7 @@ Arguments:
-a <access> - the new access bytes that will be written to the card -a <access> - the new access bytes that will be written to the card
-x - execute the commands aswell. -x - execute the commands aswell.
]] ]]
local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
local DEBUG = true -- the debug flag local DEBUG = true -- the debug flag
local CmdString = 'hf mf wrbl %d B %s %s' local CmdString = 'hf mf wrbl %d B %s %s'
@ -45,39 +45,39 @@ local numBlocks = 64
local numSectors = 16 local numSectors = 16
--- ---
-- A debug printout-function -- A debug printout-function
function dbg(args) local function dbg(args)
if not DEBUG then if not DEBUG then return end
return if type(args) == 'table' then
end
if type(args) == "table" then
local i = 1 local i = 1
while result[i] do while args[i] do
dbg(result[i]) dbg(args[i])
i = i+1 i = i+1
end end
else else
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
function oops(err) local function oops(err)
print("ERROR: ",err) print('ERROR:', err)
core.clearCommandBuffer()
return nil, err
end end
--- ---
-- Usage help -- Usage help
function help() local function help()
print(copyright) print(copyright)
print(author) print(author)
print(version) print(version)
print(desc) print(desc)
print("Example usage") print('Example usage')
print(example) print(example)
print(usage)
end end
-- --
-- Exit message -- Exit message
function ExitMsg(msg) local function ExitMsg(msg)
print( string.rep('--',20) ) print( string.rep('--',20) )
print( string.rep('--',20) ) print( string.rep('--',20) )
print(msg) print(msg)
@ -91,7 +91,7 @@ function GetCardInfo()
print(err) print(err)
return return
end end
print(("Found: %s"):format(result.name)) print(('Found: %s'):format(result.name))
core.clearCommandBuffer() core.clearCommandBuffer()
@ -138,11 +138,11 @@ local function main(args)
-- Arguments for the script -- Arguments for the script
for o, a in getopt.getopt(args, 'hk:n:a:x') do for o, a in getopt.getopt(args, 'hk:n:a:x') do
if o == "h" then return help() end if o == 'h' then return help() end
if o == "k" then OldKey = a end if o == 'k' then OldKey = a end
if o == "n" then NewKey = a end if o == 'n' then NewKey = a end
if o == "a" then Accessbytes = a end if o == 'a' then Accessbytes = a end
if o == "x" then x = true end if o == 'x' then x = true end
end end
-- validate input args. -- validate input args.
@ -169,29 +169,29 @@ local function main(args)
print( string.format('Old key: %s', OldKey)) print( string.format('Old key: %s', OldKey))
print( string.format('New key: %s', NewKey)) print( string.format('New key: %s', NewKey))
print( string.format('New Access: %s', Accessbytes)) print( string.format('New Access: %s', Accessbytes))
print( string.rep('--',20) ) print( string.rep('--', 20) )
-- Set new block data -- Set new block data
local EMPTY_BL = string.rep('00',16) local EMPTY_BL = string.rep('00', 16)
local EMPTY_SECTORTRAIL = string.format('%s%s%s%s',NewKey,Accessbytes,'00',NewKey) local EMPTY_SECTORTRAIL = string.format('%s%s%s%s', NewKey, Accessbytes, '00', NewKey)
dbg( string.format('New sector-trailer : %s',EMPTY_SECTORTRAIL)) dbg( string.format('New sector-trailer : %s', EMPTY_SECTORTRAIL))
dbg( string.format('New emptyblock: %s',EMPTY_BL)) dbg( string.format('New emptyblock: %s', EMPTY_BL))
dbg('') dbg('')
if x then if x then
print('[Warning] you have used the EXECUTE parameter, which means this will run these commands against card.') print('[Warning] you have used the EXECUTE parameter, which means this will run these commands against card.')
end end
-- Ask -- Ask
local dialogResult = utils.confirm("Do you want to erase this card") local dialogResult = utils.confirm('Do you want to erase this card')
if dialogResult == false then if dialogResult == false then
return ExitMsg('Quiting it is then. Your wish is my command...') return ExitMsg('Quiting it is then. Your wish is my command...')
end end
print( string.rep('--',20) ) print( string.rep('--', 20) )
-- main loop -- main loop
for block=0,numBlocks,1 do for block = 0, numBlocks, 1 do
local reminder = (block+1) % 4 local reminder = (block+1) % 4
local cmd local cmd
@ -207,7 +207,7 @@ local function main(args)
end end
if core.ukbhit() then if core.ukbhit() then
print("aborted by user") print('aborted by user')
break break
end end
end end

View file

@ -135,11 +135,11 @@ local function main(args)
--13-14 --13-14
-- find tag -- find tag
result, err = lib14a.read(false, true) local card, err = lib14a.read(false, true)
if not result then return oops(err) end if not card then return oops(err) end
-- load keys -- load keys
local akeys = pre.GetAll(result.uid) local akeys = pre.GetAll(card.uid)
local keyA = akeys:sub(1, 12 ) local keyA = akeys:sub(1, 12 )
local b0 = readblock(0, keyA) local b0 = readblock(0, keyA)
@ -154,7 +154,7 @@ local function main(args)
core.clearCommandBuffer() core.clearCommandBuffer()
-- wipe card. -- wipe card.
local cmd = (csetuid..'%s %s %s w'):format(result.uid, atqa, sak) local cmd = (csetuid..'%s %s %s w'):format(card.uid, atqa, sak)
core.console(cmd) core.console(cmd)
core.clearCommandBuffer() core.clearCommandBuffer()

View file

@ -6,8 +6,7 @@ local utils = require('utils')
copyright = '' copyright = ''
author = 'Iceman' author = 'Iceman'
version = 'v1.0.1' version = 'v1.0.1'
desc = desc = [[
[[
This is a script that reads AZTEK iso14443a tags. This is a script that reads AZTEK iso14443a tags.
It starts from block 0, and ends at default block 20. Use 'b' to say different endblock. It starts from block 0, and ends at default block 20. Use 'b' to say different endblock.
xor: the first three block (0,1,2) is not XORED. The rest seems to be xored. xor: the first three block (0,1,2) is not XORED. The rest seems to be xored.
@ -106,14 +105,6 @@ function sendRaw(rawdata, options)
return command:sendMIX(options.ignore_response) return command:sendMIX(options.ignore_response)
end end
--
-- Sends an instruction to do nothing, only disconnect
function disconnect()
local command = Command:newMIX{cmd = cmds.CMD_READER_ISO_14443a, arg1 = 0,}
-- We can ignore the response here, no ACK is returned for this command
-- Check /armsrc/iso14443a.c, ReaderIso14443a() for details
return command:sendMIX(true)
end
--- ---
-- The main entry point -- The main entry point
function main(args) function main(args)
@ -130,7 +121,10 @@ function main(args)
-- First of all, connect -- First of all, connect
info, err = lib14a.read(true, true) info, err = lib14a.read(true, true)
if err then disconnect() return oops(err) end if err then
lib14a.disconnect()
return oops(err)
end
core.clearCommandBuffer() core.clearCommandBuffer()
local blockData = {} local blockData = {}
@ -143,7 +137,10 @@ function main(args)
for block = 00, endblock do for block = 00, endblock do
local cmd = string.format('10%02x00', block) local cmd = string.format('10%02x00', block)
res, err = sendRaw(cmd , {ignore_response = ignore_response}) res, err = sendRaw(cmd , {ignore_response = ignore_response})
if err then disconnect() return oops(err) end if err then
lib14a.disconnect()
return oops(err)
end
local cmd_response = Command.parse(res) local cmd_response = Command.parse(res)
local len = tonumber(cmd_response.arg1) * 2 local len = tonumber(cmd_response.arg1) * 2
@ -153,7 +150,7 @@ function main(args)
table.insert(blockData, data) table.insert(blockData, data)
end end
print("----+------------------+-------------------") print("----+------------------+-------------------")
disconnect() lib14a.disconnect()
local filename, err = utils.WriteDumpFile(info.uid, blockData) local filename, err = utils.WriteDumpFile(info.uid, blockData)
if err then return oops(err) end if err then return oops(err) end