mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-03-19 19:38:52 +08:00
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:
commit
c505a59e3d
19 changed files with 484 additions and 429 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -61,5 +61,6 @@ ppls patches/*
|
|||
|
||||
client/lualibs/mf_default_keys.lua
|
||||
client/lualibs/usb_cmd.lua
|
||||
client/lualibs/pm3_cmd.lua
|
||||
# recompiled
|
||||
fpga_version_info.c
|
||||
|
|
|
@ -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 TIMEOUT = 2000
|
||||
|
||||
|
|
|
@ -96,7 +96,7 @@ local function read14443a(dont_disconnect, no_rats)
|
|||
command.arg1 = command.arg1 + ISO14A_COMMAND.ISO14A_NO_RATS
|
||||
end
|
||||
|
||||
local result,err = command:sendMIX()
|
||||
local result, err = command:sendMIX()
|
||||
if result then
|
||||
local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL',result)
|
||||
if arg0 == 0 then
|
||||
|
@ -120,13 +120,13 @@ end
|
|||
-- @return if successfull: an table containing card info
|
||||
-- @return if unsuccessfull : nil, error
|
||||
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
|
||||
res, err = read14443a()
|
||||
if res then return res end
|
||||
-- err means that there was no response from card
|
||||
end
|
||||
return nil, "Aborted by user"
|
||||
return nil, 'Aborted by user'
|
||||
end
|
||||
|
||||
-- Sends an instruction to do nothing, only disconnect
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
This is a library to read 14443b tags. It can be used something like this
|
||||
|
||||
local reader = require('read14b')
|
||||
result, err = reader.select1443b()
|
||||
result, err = reader.read14443b()
|
||||
if not result then
|
||||
print(err)
|
||||
return
|
||||
|
@ -13,7 +13,10 @@
|
|||
-- Loads the commands-library
|
||||
local cmds = require('commands')
|
||||
local utils = require('utils')
|
||||
|
||||
-- Shouldn't take longer than 2.5 seconds
|
||||
local TIMEOUT = 2500
|
||||
|
||||
local ISO14B_COMMAND = {
|
||||
ISO14B_CONNECT = 1,
|
||||
ISO14B_DISCONNECT = 2,
|
||||
|
@ -41,45 +44,16 @@ local function parse1443b(data)
|
|||
--]]
|
||||
|
||||
local count, uid, uidlen, atqb, chipid, cid = bin.unpack('H10CH7CC',data)
|
||||
uid = uid:sub(1, 2*uidlen)
|
||||
return { uid = uid, uidlen = uidlen, atqb = atqb, chipid = chipid, cid = cid }
|
||||
uid = uid:sub(1, 2 * uidlen)
|
||||
return {
|
||||
uid = uid,
|
||||
uidlen = uidlen,
|
||||
atqb = atqb,
|
||||
chipid = chipid,
|
||||
cid = cid
|
||||
}
|
||||
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
|
||||
-- @return if successfull: an table containing card info
|
||||
-- @return if unsuccessfull : nil, error
|
||||
|
@ -95,18 +69,22 @@ local function read14443b(disconnect)
|
|||
flags = flags + ISO14B_COMMAND.ISO14B_DISCONNECT
|
||||
end
|
||||
|
||||
command = Command:new{cmd = cmds.CMD_ISO_14443B_COMMAND, arg1 = flags}
|
||||
local result, err = sendToDevice(command, false)
|
||||
command = Command:newMIX{
|
||||
cmd = cmds.CMD_ISO_14443B_COMMAND,
|
||||
arg1 = flags
|
||||
}
|
||||
|
||||
local result, err = command:sendMIX()
|
||||
if result then
|
||||
local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL',result)
|
||||
if arg0 == 0 then
|
||||
data = string.sub(result, count)
|
||||
info, err = parse1443b(data)
|
||||
else
|
||||
err = "iso14443b card select failed"
|
||||
err = 'iso14443b card select failed'
|
||||
end
|
||||
else
|
||||
err = "No response from card"
|
||||
err = 'No response from card'
|
||||
end
|
||||
|
||||
if err then
|
||||
|
@ -115,43 +93,42 @@ local function read14443b(disconnect)
|
|||
end
|
||||
return info
|
||||
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.
|
||||
-- @return if successfull: an table containing card info
|
||||
-- @return if unsuccessfull : nil, error
|
||||
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
|
||||
res, err = read14443b(false)
|
||||
if res then return res end
|
||||
-- err means that there was no response from card
|
||||
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
|
||||
|
||||
local library = {
|
||||
read = read14443b,
|
||||
waitFor14443b = waitFor14443b,
|
||||
parse1443b = parse1443b,
|
||||
sendToDevice = sendToDevice,
|
||||
showData = showData,
|
||||
connect = connect14443b,
|
||||
disconnect = disconnect14443b,
|
||||
ISO14B_COMMAND = ISO14B_COMMAND,
|
||||
}
|
||||
|
||||
|
|
|
@ -13,27 +13,15 @@
|
|||
-- Loads the commands-library
|
||||
local cmds = require('commands')
|
||||
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
|
||||
-- @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(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 ISO15_COMMAND = {
|
||||
ISO15_REQ_SUBCARRIER_SINGLE = 0,
|
||||
ISO15_REQ_DATARATE_HIGH = 2,
|
||||
ISO15_REQ_NONINVENTORY = 0,
|
||||
}
|
||||
|
||||
local function errorString15693(number)
|
||||
local errors = {}
|
||||
|
@ -50,7 +38,6 @@ local function errorString15693(number)
|
|||
return errors[number] or "Reserved for Future Use or Custom command error."
|
||||
end
|
||||
|
||||
|
||||
local function parse15693(data)
|
||||
local bytes = utils.ConvertAsciiToBytes(data)
|
||||
local tmp = utils.ConvertAsciiToHex(data)
|
||||
|
@ -59,14 +46,14 @@ local function parse15693(data)
|
|||
local crcStr = utils.Crc15(tmp, #tmp)
|
||||
|
||||
if string.sub(crcStr, #crcStr - 3) ~= '470F' then
|
||||
print("CRC", crc )
|
||||
return nil, "CRC failed"
|
||||
print('CRC', crc )
|
||||
return nil, 'CRC failed'
|
||||
end
|
||||
|
||||
if bytes[1] % 2 == 1 then
|
||||
-- Above is a poor-mans bit check:
|
||||
-- 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]))
|
||||
return nil, err
|
||||
end
|
||||
|
@ -82,7 +69,6 @@ end
|
|||
local function read15693(slow, dont_readresponse)
|
||||
|
||||
--[[
|
||||
|
||||
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):
|
||||
|
||||
|
@ -108,11 +94,13 @@ local function read15693(slow, dont_readresponse)
|
|||
|
||||
data = utils.Crc15("260100")
|
||||
|
||||
command = Command:new{cmd = cmds.CMD_ISO_15693_COMMAND,
|
||||
arg1 = #data / 2,
|
||||
arg2 = 1,
|
||||
arg3 = 1,
|
||||
data = data}
|
||||
command = Command:newMIX{
|
||||
cmd = cmds.CMD_ISO_15693_COMMAND,
|
||||
arg1 = #data / 2,
|
||||
arg2 = 1,
|
||||
arg3 = 1,
|
||||
data = data
|
||||
}
|
||||
|
||||
if slow then
|
||||
command.arg2 = 0
|
||||
|
@ -121,24 +109,23 @@ local function read15693(slow, dont_readresponse)
|
|||
command.arg3 = 0
|
||||
end
|
||||
|
||||
local result, err = sendToDevice(command, dont_readresponse)
|
||||
if not result then
|
||||
print(err)
|
||||
return nil, "15693 identify: no answer"
|
||||
end
|
||||
|
||||
local count, cmd, len, arg2, arg3 = bin.unpack('LLLL', result)
|
||||
if len > 0 then
|
||||
local result, err = command:sendMIX()
|
||||
if result then
|
||||
local count, cmd, len, arg2, arg3 = bin.unpack('LLLL', result)
|
||||
if len == 0 then
|
||||
return nil, 'iso15693 card select failed'
|
||||
end
|
||||
data = string.sub(result, count, count+len-1)
|
||||
info, err = parse15693(data)
|
||||
if err then
|
||||
print(err)
|
||||
return nil, err
|
||||
end
|
||||
return info
|
||||
else
|
||||
return nil, "Failed to get response"
|
||||
err = 'No response from card'
|
||||
end
|
||||
|
||||
if err then
|
||||
print(err)
|
||||
return nil, err
|
||||
end
|
||||
return info
|
||||
end
|
||||
|
||||
---
|
||||
|
@ -146,19 +133,28 @@ end
|
|||
-- @return if successfull: an table containing card info
|
||||
-- @return if unsuccessfull : nil, error
|
||||
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
|
||||
res, err = read15693()
|
||||
if res then return res end
|
||||
-- err means that there was no response from card
|
||||
end
|
||||
return nil, "Aborted by user"
|
||||
return nil, 'Aborted by user'
|
||||
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 = {
|
||||
read = read15693,
|
||||
waitFor15693 = waitFor15693,
|
||||
parse15693 = parse15693,
|
||||
sendToDevice = sendToDevice,
|
||||
disconnect = disconnect15693,
|
||||
}
|
||||
|
||||
return library
|
||||
|
|
|
@ -115,10 +115,10 @@ return {
|
|||
lookupManufacturer = function (value)
|
||||
if type(value) == 'string' then
|
||||
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
|
||||
end
|
||||
|
||||
return m[value] or "no tag-info available"
|
||||
return m[value] or 'no tag-info available'
|
||||
end,
|
||||
}
|
||||
|
|
|
@ -2,11 +2,27 @@ local cmds = require('commands')
|
|||
local getopt = require('getopt')
|
||||
local lib14a = require('read14a')
|
||||
|
||||
example = "script run 14araw -x 6000F57b"
|
||||
copyright = ''
|
||||
author = "Martin Holst Swende"
|
||||
desc =
|
||||
[[
|
||||
version = 'v1.0.1'
|
||||
desc = [[
|
||||
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:
|
||||
-o do not connect - use this only if you previously used -p to stay connected
|
||||
|
@ -17,18 +33,6 @@ Arguments:
|
|||
-d Debug flag
|
||||
-t Topaz mode
|
||||
-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
|
||||
local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
|
||||
local DEBUG = false -- the debug flag
|
||||
|
||||
-------------------------------
|
||||
|
@ -51,21 +54,34 @@ local DEBUG = false -- the debug flag
|
|||
---
|
||||
-- A debug printout-function
|
||||
local function dbg(args)
|
||||
if DEBUG then
|
||||
print("###", 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)
|
||||
print('ERROR:', err)
|
||||
core.clearCommandBuffer()
|
||||
return nil, err
|
||||
end
|
||||
---
|
||||
-- Usage help
|
||||
local function help()
|
||||
print(copyright)
|
||||
print(author)
|
||||
print(version)
|
||||
print(desc)
|
||||
print("Example usage")
|
||||
print('Example usage')
|
||||
print(example)
|
||||
print(usage)
|
||||
end
|
||||
---
|
||||
-- The main entry point
|
||||
|
@ -83,31 +99,35 @@ function main(args)
|
|||
|
||||
-- Read the parameters
|
||||
for o, a in getopt.getopt(args, 'orcpx:dt3') do
|
||||
if o == "o" then doconnect = false end
|
||||
if o == "r" then ignore_response = true end
|
||||
if o == "c" then append_crc = true end
|
||||
if o == "p" then stayconnected = true end
|
||||
if o == "x" then payload = a end
|
||||
if o == "d" then DEBUG = true end
|
||||
if o == "t" then topaz_mode = true end
|
||||
if o == "3" then no_rats = true end
|
||||
if o == 'o' then doconnect = false end
|
||||
if o == 'r' then ignore_response = true end
|
||||
if o == 'c' then append_crc = true end
|
||||
if o == 'p' then stayconnected = true end
|
||||
if o == 'x' then payload = a end
|
||||
if o == 'd' then DEBUG = true end
|
||||
if o == 't' then topaz_mode = true end
|
||||
if o == '3' then no_rats = true end
|
||||
end
|
||||
|
||||
-- First of all, connect
|
||||
if doconnect then
|
||||
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
|
||||
print(("Connected to card, uid = %s"):format(info.uid))
|
||||
info, err = lib14a.read(true, no_rats)
|
||||
if err then
|
||||
lib14a.disconnect()
|
||||
return oops(err)
|
||||
end
|
||||
print(('Connected to card, uid = %s'):format(info.uid))
|
||||
end
|
||||
|
||||
-- The actual raw payload, if any
|
||||
if payload then
|
||||
res,err = sendRaw(payload,{ignore_response = ignore_response, topaz_mode = topaz_mode, append_crc = append_crc})
|
||||
if err then return oops(err) end
|
||||
res, err = sendRaw(payload,{ignore_response = ignore_response, topaz_mode = topaz_mode, append_crc = append_crc})
|
||||
if err then
|
||||
lib14a.disconnect()
|
||||
return oops(err)
|
||||
end
|
||||
|
||||
if not ignoreresponse then
|
||||
-- Display the returned data
|
||||
|
@ -116,7 +136,7 @@ function main(args)
|
|||
end
|
||||
-- And, perhaps disconnect?
|
||||
if not stayconnected then
|
||||
disconnect()
|
||||
lib14a.disconnect()
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -132,11 +152,10 @@ function showdata(usbpacket)
|
|||
--print("data length:",len)
|
||||
local data = string.sub(tostring(cmd_response.data), 0, len);
|
||||
print("<< ",data)
|
||||
--print("----------------")
|
||||
end
|
||||
|
||||
function sendRaw(rawdata, options)
|
||||
print(">> ", rawdata)
|
||||
print('>> ', rawdata)
|
||||
|
||||
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
|
||||
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
|
||||
-- arg2 contains the length, which is half the length
|
||||
-- of the ASCII-string rawdata
|
||||
arg2 = string.len(rawdata)/2,
|
||||
data = rawdata}
|
||||
return lib14a.sendToDevice(command, options.ignore_response)
|
||||
return command:sendMIX(options.ignore_response)
|
||||
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
|
||||
-------------------------
|
||||
function selftest()
|
||||
DEBUG = true
|
||||
dbg("Performing test")
|
||||
dbg('Performing test')
|
||||
main()
|
||||
main("-p")
|
||||
main(" -o -x 6000F57b -p")
|
||||
main("-o")
|
||||
main("-x 6000F57b")
|
||||
dbg("Tests done")
|
||||
main('-p')
|
||||
main(' -o -x 6000F57b -p')
|
||||
main('-o')
|
||||
main('-x 6000F57b')
|
||||
dbg('Tests done')
|
||||
end
|
||||
-- Flip the switch here to perform a sanity check.
|
||||
-- It read a nonce in two different ways, as specified in the usage-section
|
||||
if "--test"==args then
|
||||
if '--test'==args then
|
||||
selftest()
|
||||
else
|
||||
-- Call the main
|
||||
|
|
|
@ -15,9 +15,13 @@ local luamiibo = luamiibo_open()
|
|||
|
||||
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
|
||||
-- Do Mifare Ultralight read
|
||||
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))
|
||||
|
||||
-- Begin simulating NTAG215
|
||||
local simCmd = Command:new{cmd = cmds.CMD_SIMULATE_TAG_ISO_14443a, arg1 = 7, arg2 = uid_first, arg3 = uid_second}
|
||||
local _, err = reader.sendToDevice(simCmd)
|
||||
local simCmd = Command:newMIX{
|
||||
cmd = cmds.CMD_SIMULATE_TAG_ISO_14443a,
|
||||
arg1 = 7,
|
||||
arg2 = uid_first,
|
||||
arg3 = uid_second
|
||||
}
|
||||
local _, err = simCmd.sendMIX()
|
||||
if err then
|
||||
print('Failed to start simulator', err)
|
||||
return
|
||||
|
|
|
@ -33,21 +33,22 @@ local bxor = bit32.bxor
|
|||
-- A debug printout-function
|
||||
local function dbg(args)
|
||||
if not DEBUG then return end
|
||||
if type(args) == "table" then
|
||||
if type(args) == 'table' then
|
||||
local i = 1
|
||||
while args[i] do
|
||||
dbg(args[i])
|
||||
i = i+1
|
||||
end
|
||||
else
|
||||
print("###", args)
|
||||
print('###', args)
|
||||
end
|
||||
end
|
||||
---
|
||||
-- This is only meant to be used when errors occur
|
||||
local function oops(err)
|
||||
print("ERROR: ",err)
|
||||
return nil,err
|
||||
print('ERROR: ', err)
|
||||
core.clearCommandBuffer()
|
||||
return nil, err
|
||||
end
|
||||
---
|
||||
-- Usage help
|
||||
|
@ -58,6 +59,7 @@ local function help()
|
|||
print(desc)
|
||||
print('Example usage')
|
||||
print(example)
|
||||
print(usage)
|
||||
end
|
||||
---
|
||||
-- Exit message
|
||||
|
@ -142,8 +144,8 @@ local function main(args)
|
|||
|
||||
-- Arguments for the script
|
||||
for o, a in getopt.getopt(args, 'hu:') do
|
||||
if o == "h" then return help() end
|
||||
if o == "u" then uid = a; useUID = true end
|
||||
if o == 'h' then return help() end
|
||||
if o == 'u' then uid = a; useUID = true end
|
||||
end
|
||||
|
||||
if useUID then
|
||||
|
@ -160,7 +162,7 @@ local function main(args)
|
|||
-- simple tag check
|
||||
if 0x09 ~= tag.sak 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
|
||||
uid = tag.uid
|
||||
|
|
|
@ -31,22 +31,22 @@ local bxor = bit32.bxor
|
|||
-- A debug printout-function
|
||||
local function dbg(args)
|
||||
if not DEBUG then return end
|
||||
|
||||
if type(args) == "table" then
|
||||
if type(args) == 'table' then
|
||||
local i = 1
|
||||
while args[i] do
|
||||
dbg(args[i])
|
||||
i = i+1
|
||||
end
|
||||
else
|
||||
print("###", args)
|
||||
print('###', args)
|
||||
end
|
||||
end
|
||||
---
|
||||
-- This is only meant to be used when errors occur
|
||||
local function oops(err)
|
||||
print("ERROR: ",err)
|
||||
return nil,err
|
||||
print('ERROR: ', err)
|
||||
core.clearCommandBuffer()
|
||||
return nil, err
|
||||
end
|
||||
---
|
||||
-- Usage help
|
||||
|
@ -57,10 +57,11 @@ local function help()
|
|||
print(desc)
|
||||
print("Example usage")
|
||||
print(example)
|
||||
print(usage)
|
||||
end
|
||||
--
|
||||
-- Exit message
|
||||
function exitMsg(msg)
|
||||
local function exitMsg(msg)
|
||||
print( string.rep('--',20) )
|
||||
print( string.rep('--',20) )
|
||||
print(msg)
|
||||
|
@ -138,6 +139,7 @@ local function pwdgen(uid)
|
|||
local pwd3 = bxor( entry[4], uidbytes[7])
|
||||
return string.format('%02X%02X%02X%02X', pwd0, pwd1, pwd2, pwd3)
|
||||
end
|
||||
|
||||
--
|
||||
-- main
|
||||
local function main(args)
|
||||
|
@ -151,8 +153,8 @@ local function main(args)
|
|||
|
||||
-- Arguments for the script
|
||||
for o, a in getopt.getopt(args, 'hu:') do
|
||||
if o == "h" then return help() end
|
||||
if o == "u" then uid = a; useUID = true end
|
||||
if o == 'h' then return help() end
|
||||
if o == 'u' then uid = a; useUID = true end
|
||||
end
|
||||
|
||||
if useUID then
|
||||
|
|
|
@ -3,8 +3,9 @@ local getopt = require('getopt')
|
|||
local lib14a = require('read14a')
|
||||
local utils = require('utils')
|
||||
|
||||
copyright = ''
|
||||
author = 'Iceman'
|
||||
version = 'v1.0.0'
|
||||
version = 'v1.0.1'
|
||||
desc = [[
|
||||
This script calculates mifare keys based on uid diversification for mizip.
|
||||
Algo not found by me.
|
||||
|
@ -28,30 +29,31 @@ local bxor = bit32.bxor
|
|||
local _xortable = {
|
||||
--[[ sector key A/B, 6byte xor
|
||||
--]]
|
||||
{1, "09125a2589e5", "F12C8453D821"},
|
||||
{2, "AB75C937922F", "73E799FE3241"},
|
||||
{3, "E27241AF2C09", "AA4D137656AE"},
|
||||
{4, "317AB72F4490", "B01327272DFD"},
|
||||
{1, '09125a2589e5', 'F12C8453D821'},
|
||||
{2, 'AB75C937922F', '73E799FE3241'},
|
||||
{3, 'E27241AF2C09', 'AA4D137656AE'},
|
||||
{4, '317AB72F4490', 'B01327272DFD'},
|
||||
}
|
||||
---
|
||||
-- A debug printout-function
|
||||
local function dbg(args)
|
||||
if not DEBUG then return end
|
||||
if type(args) == "table" then
|
||||
if type(args) == 'table' then
|
||||
local i = 1
|
||||
while args[i] do
|
||||
dbg(args[i])
|
||||
i = i+1
|
||||
end
|
||||
else
|
||||
print("###", args)
|
||||
print('###', args)
|
||||
end
|
||||
end
|
||||
---
|
||||
-- This is only meant to be used when errors occur
|
||||
local function oops(err)
|
||||
print("ERROR: ",err)
|
||||
return nil,err
|
||||
print('ERROR: ', err)
|
||||
core.clearCommandBuffer()
|
||||
return nil, err
|
||||
end
|
||||
---
|
||||
-- Usage help
|
||||
|
@ -62,6 +64,7 @@ local function help()
|
|||
print(desc)
|
||||
print("Example usage")
|
||||
print(example)
|
||||
print(usage)
|
||||
end
|
||||
--
|
||||
-- Exit message
|
||||
|
@ -163,8 +166,8 @@ local function main(args)
|
|||
|
||||
-- Arguments for the script
|
||||
for o, a in getopt.getopt(args, 'hu:') do
|
||||
if o == "h" then return help() end
|
||||
if o == "u" then uid = a ; useUID = true end
|
||||
if o == 'h' then return help() end
|
||||
if o == 'u' then uid = a ; useUID = true end
|
||||
end
|
||||
|
||||
if useUID then
|
||||
|
@ -181,7 +184,7 @@ local function main(args)
|
|||
-- simple tag check
|
||||
if 0x09 ~= tag.sak 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
|
||||
uid = tag.uid
|
||||
|
|
|
@ -4,27 +4,22 @@ local lib14b = require('read14b')
|
|||
local utils = require('utils')
|
||||
local iso7816 = require('7816_error')
|
||||
|
||||
example = "script runs 14b raw commands to query a CAPLYPSO tag"
|
||||
author = "Iceman, 2016"
|
||||
desc =
|
||||
[[
|
||||
copyright = ''
|
||||
author = 'Iceman'
|
||||
version = 'v1.0.1'
|
||||
desc = [[
|
||||
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:
|
||||
-b 123
|
||||
Examples :
|
||||
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
|
||||
|
||||
h this helptext
|
||||
b raw bytes to send
|
||||
]]
|
||||
|
||||
--[[
|
||||
|
@ -33,21 +28,6 @@ Check there for details about data format and how commands are interpreted on th
|
|||
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 r = Command.parse(result)
|
||||
local len = r.arg2 * 2
|
||||
|
@ -61,23 +41,34 @@ end
|
|||
---
|
||||
-- A debug printout-function
|
||||
local function dbg(args)
|
||||
if DEBUG then
|
||||
print("###", 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)
|
||||
calypso_switch_off_field()
|
||||
print('ERROR: ', err)
|
||||
lib14b.disconnect()
|
||||
return nil, err
|
||||
end
|
||||
---
|
||||
-- Usage help
|
||||
local function help()
|
||||
print(copyright)
|
||||
print(author)
|
||||
print(version)
|
||||
print(desc)
|
||||
print("Example usage")
|
||||
print('Example usage')
|
||||
print(example)
|
||||
print(usage))
|
||||
end
|
||||
--
|
||||
-- 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"
|
||||
|
||||
command = Command:new{cmd = cmds.CMD_ISO_14443B_COMMAND,
|
||||
arg1 = flags,
|
||||
arg2 = #data/2, -- LEN of data, half the length of the ASCII-string hex string
|
||||
arg3 = 0,
|
||||
data = data} -- data bytes (commands etc)
|
||||
result, err = lib14b.sendToDevice(command, false)
|
||||
|
||||
if ignoreresponse then return response, err end
|
||||
command = Command:newMIX{
|
||||
cmd = cmds.CMD_ISO_14443B_COMMAND,
|
||||
arg1 = flags,
|
||||
arg2 = #data/2, -- LEN of data, half the length of the ASCII-string hex string
|
||||
data = data} -- data bytes (commands etc)
|
||||
|
||||
result, err = command:sendMIX(ignoreresponse)
|
||||
if result then
|
||||
local r = calypso_parse(result)
|
||||
return r, nil
|
||||
|
@ -185,26 +174,26 @@ local _calypso_cmds = {
|
|||
-- Electronic Transaction log file
|
||||
|
||||
|
||||
--["01.Select ICC file"] = '0294 a4 00 0002 3f00',
|
||||
["01.Select ICC file"] = '0294 a4 080004 3f00 0002',
|
||||
["02.ICC"] = '0394 b2 01 041d',
|
||||
["03.Select EnvHol file"] = '0294 a4 080004 2000 2001',
|
||||
["04.EnvHol1"] = '0394 b2 01 041d',
|
||||
["05.Select EvLog file"] = '0294 a4 080004 2000 2010',
|
||||
["06.EvLog1"] = '0394 b2 01 041d',
|
||||
["07.EvLog2"] = '0294 b2 02 041d',
|
||||
["08.EvLog3"] = '0394 b2 03 041d',
|
||||
["09.Select ConList file"]= '0294 a4 080004 2000 2050',
|
||||
["10.ConList"] = '0394 b2 01 041d',
|
||||
["11.Select Contra file"] = '0294 a4 080004 2000 2020',
|
||||
["12.Contra1"] = '0394 b2 01 041d',
|
||||
["13.Contra2"] = '0294 b2 02 041d',
|
||||
["14.Contra3"] = '0394 b2 03 041d',
|
||||
["15.Contra4"] = '0294 b2 04 041d',
|
||||
["16.Select Counter file"]= '0394 a4 080004 2000 2069',
|
||||
["17.Counter"] = '0294 b2 01 041d',
|
||||
["18.Select SpecEv file"] = '0394 a4 080004 2000 2040',
|
||||
["19.SpecEv1"] = '0294 b2 01 041d',
|
||||
--['01.Select ICC file'] = '0294 a4 00 0002 3f00',
|
||||
['01.Select ICC file'] = '0294 a4 080004 3f00 0002',
|
||||
['02.ICC'] = '0394 b2 01 041d',
|
||||
['03.Select EnvHol file'] = '0294 a4 080004 2000 2001',
|
||||
['04.EnvHol1'] = '0394 b2 01 041d',
|
||||
['05.Select EvLog file'] = '0294 a4 080004 2000 2010',
|
||||
['06.EvLog1'] = '0394 b2 01 041d',
|
||||
['07.EvLog2'] = '0294 b2 02 041d',
|
||||
['08.EvLog3'] = '0394 b2 03 041d',
|
||||
['09.Select ConList file']= '0294 a4 080004 2000 2050',
|
||||
['10.ConList'] = '0394 b2 01 041d',
|
||||
['11.Select Contra file'] = '0294 a4 080004 2000 2020',
|
||||
['12.Contra1'] = '0394 b2 01 041d',
|
||||
['13.Contra2'] = '0294 b2 02 041d',
|
||||
['14.Contra3'] = '0394 b2 03 041d',
|
||||
['15.Contra4'] = '0294 b2 04 041d',
|
||||
['16.Select Counter file']= '0394 a4 080004 2000 2069',
|
||||
['17.Counter'] = '0294 b2 01 041d',
|
||||
['18.Select SpecEv file'] = '0394 a4 080004 2000 2040',
|
||||
['19.SpecEv1'] = '0294 b2 01 041d',
|
||||
}
|
||||
|
||||
---
|
||||
|
@ -218,10 +207,11 @@ function main(args)
|
|||
local data, apdu, flags, uid, cid, result, err, card
|
||||
-- Read the parameters
|
||||
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
|
||||
|
||||
calypso_switch_on_field()
|
||||
lib14b.connect()
|
||||
|
||||
-- Select 14b tag.
|
||||
card, err = lib14b.waitFor14443b()
|
||||
|
@ -248,7 +238,7 @@ function main(args)
|
|||
--result, err = calypso_send_cmd_raw('0294a40800043f000002',false) --select ICC file
|
||||
for i, apdu in spairs(_calypso_cmds) do
|
||||
print('>>', i )
|
||||
apdu = apdu:gsub("%s+","")
|
||||
apdu = apdu:gsub('%s+', '')
|
||||
result, err = calypso_send_cmd_raw(apdu , false)
|
||||
if result then
|
||||
calypso_apdu_status(result.data)
|
||||
|
@ -257,18 +247,18 @@ function main(args)
|
|||
print('<< no answer')
|
||||
end
|
||||
end
|
||||
calypso_switch_off_field()
|
||||
lib14b.disconnect()
|
||||
end
|
||||
---
|
||||
-- a simple selftest function, tries to convert
|
||||
function selftest()
|
||||
DEBUG = true
|
||||
dbg("Performing test")
|
||||
dbg("Tests done")
|
||||
dbg('Performing test')
|
||||
dbg('Tests done')
|
||||
end
|
||||
-- Flip the switch here to perform a sanity check.
|
||||
-- It read a nonce in two different ways, as specified in the usage-section
|
||||
if "--test"==args then
|
||||
if '--test'==args then
|
||||
selftest()
|
||||
else
|
||||
-- Call the main
|
||||
|
|
|
@ -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")
|
||||
local answer
|
||||
repeat
|
||||
io.write("$>")
|
||||
io.flush()
|
||||
answer=io.read()
|
||||
answer = io.read()
|
||||
if answer ~= 'exit' then
|
||||
local func = assert(loadstring("return " .. answer))
|
||||
io.write("\n"..tostring(func() or "").."\n");
|
||||
end--]]
|
||||
until answer=="exit"
|
||||
until answer == "exit"
|
||||
print("Bye\n");
|
||||
|
|
|
@ -7,29 +7,48 @@ local lib14a = require('read14a')
|
|||
local json = require('dkjson')
|
||||
local toys = require('default_toys_di')
|
||||
|
||||
example =[[
|
||||
script run didump
|
||||
script run didump -t
|
||||
script run didump -r
|
||||
]]
|
||||
author = "Iceman"
|
||||
usage = "script run didump -h -t"
|
||||
copyright = ''
|
||||
author = 'Iceman'
|
||||
version = 'v1.0.1'
|
||||
desc = [[
|
||||
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
|
||||
]]
|
||||
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:
|
||||
-h : this help
|
||||
-r : raw
|
||||
-t : selftest
|
||||
h this helptext
|
||||
r raw
|
||||
t selftest
|
||||
d decrypt data
|
||||
e encrypt data
|
||||
v validate data
|
||||
i dumpdata.json load json dump file
|
||||
end
|
||||
]]
|
||||
|
||||
local band=bit32.band
|
||||
local bor=bit32.bor
|
||||
local bnot=bit32.bnot
|
||||
local bxor=bit32.bxor
|
||||
local lsh=bit32.lshift
|
||||
local rsh=bit32.rshift
|
||||
-- Some shortcuts
|
||||
local band = bit32.band
|
||||
local bor = bit32.bor
|
||||
local bnot = bit32.bnot
|
||||
local bxor = bit32.bxor
|
||||
local lsh = bit32.lshift
|
||||
local rsh = bit32.rshift
|
||||
|
||||
-- Some globals
|
||||
local FOO = 'AF62D2EC0491968CC52A1A7165F865FE'
|
||||
local BAR = '286329204469736E65792032303133'
|
||||
local MIS = '0A14FD0507FF4BCD026BA83F0A3B89A9'
|
||||
|
@ -44,29 +63,33 @@ local CHECKSUM_OFFSET = 12; -- +1???
|
|||
-- A debug printout-function
|
||||
local function dbg(args)
|
||||
if not DEBUG then return end
|
||||
if type(args) == "table" then
|
||||
if type(args) == 'table' then
|
||||
local i = 1
|
||||
while args[i] do
|
||||
print("###", args[i])
|
||||
print('###', args[i])
|
||||
i = i+1
|
||||
end
|
||||
else
|
||||
print("###", args)
|
||||
print('###', args)
|
||||
end
|
||||
end
|
||||
---
|
||||
-- This is only meant to be used when errors occur
|
||||
local function oops(err)
|
||||
print("ERROR: ",err)
|
||||
print('ERROR: ', err)
|
||||
core.clearCommandBuffer()
|
||||
return false
|
||||
return nil, err
|
||||
end
|
||||
---
|
||||
-- Usage help
|
||||
local function help()
|
||||
print(copyright)
|
||||
print(author)
|
||||
print(version)
|
||||
print(desc)
|
||||
print("Example usage")
|
||||
print('Example usage')
|
||||
print(example)
|
||||
print(usage)
|
||||
end
|
||||
---
|
||||
--
|
||||
|
@ -370,21 +393,7 @@ local function updateChecksum(data)
|
|||
return string.format("%s%X", part, chksum)
|
||||
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 data = MIS..uid..BAR
|
||||
local hash = utils.ConvertAsciiToBytes(utils.Sha1Hex(data))
|
||||
|
@ -397,7 +406,6 @@ local function keygen(uid)
|
|||
hash[6+1]
|
||||
)
|
||||
end
|
||||
|
||||
--- encode 'table' into a json formatted string
|
||||
--
|
||||
local function convert_to_json( obj )
|
||||
|
@ -449,6 +457,29 @@ local function create_key(uid)
|
|||
key = key..utils.SwapEndiannessStr( sha:sub(25,32), 32 )
|
||||
return key
|
||||
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
|
||||
--
|
||||
local function readtag(mfkey, aeskey )
|
||||
|
@ -463,11 +494,8 @@ local function readtag(mfkey, aeskey )
|
|||
end
|
||||
|
||||
-- read block from tag.
|
||||
cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = blockNo ,arg2 = 0,arg3 = 0, data = mfkey}
|
||||
local err = core.SendCommand(cmd:getBytes())
|
||||
if err then return oops(err) end
|
||||
local blockdata, err = waitCmd()
|
||||
if err then return oops(err) end
|
||||
local blockdata = readblock(blockNo, mfkey)
|
||||
if not blockdata then return oops('[!] failed reading block') end
|
||||
|
||||
-- rules:
|
||||
-- the following blocks is NOT encrypted
|
||||
|
@ -488,7 +516,6 @@ local function readtag(mfkey, aeskey )
|
|||
else
|
||||
-- Sectorblocks, not encrypted, but we add our known key to it since it is normally zeros.
|
||||
blockdata = mfkey..blockdata:sub(13,20)..mfkey
|
||||
--dbg(blockdata:sub(13,20))
|
||||
end
|
||||
table.insert(tagdata, blockdata)
|
||||
end
|
||||
|
@ -549,12 +576,12 @@ function main(args)
|
|||
|
||||
-- Read the parameters
|
||||
for o, a in getopt.getopt(args, 'htdevi:') do
|
||||
if o == "h" then help() return end
|
||||
if o == "t" then return selftest() end
|
||||
if o == "d" then shall_dec = true end
|
||||
if o == "e" then shall_enc = true end
|
||||
if o == "v" then shall_validate = true end
|
||||
if o == "i" then input = load_json(a) end
|
||||
if o == 'h' then help() return end
|
||||
if o == 't' then return selftest() end
|
||||
if o == 'd' then shall_dec = true end
|
||||
if o == 'e' then shall_enc = true end
|
||||
if o == 'v' then shall_validate = true end
|
||||
if o == 'i' then input = load_json(a) end
|
||||
end
|
||||
|
||||
-- Turn off Debug
|
||||
|
@ -562,7 +589,10 @@ function main(args)
|
|||
|
||||
-- GET TAG UID
|
||||
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()
|
||||
|
||||
-- simple tag check
|
||||
|
|
|
@ -2,37 +2,54 @@ local getopt = require('getopt')
|
|||
local bin = require('bin')
|
||||
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 =[[
|
||||
1. script run emul2dump
|
||||
2. script run emul2dump -i myfile.eml
|
||||
3. script run emul2dump -i myfile.eml -o myfile.bin
|
||||
]]
|
||||
author = "Iceman"
|
||||
usage = "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"
|
||||
usage = [[
|
||||
script run emul2dump [-i <file>] [-o <file>]
|
||||
|
||||
Arguments:
|
||||
-h This help
|
||||
-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.
|
||||
]]
|
||||
|
||||
]]
|
||||
---
|
||||
-- This is only meant to be used when errors occur
|
||||
function oops(err)
|
||||
print("ERROR: ",err)
|
||||
local function oops(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
|
||||
---
|
||||
-- Usage help
|
||||
function help()
|
||||
local function help()
|
||||
print(copyright)
|
||||
print(author)
|
||||
print(version)
|
||||
print(desc)
|
||||
print("Example usage")
|
||||
print('Example usage')
|
||||
print(example)
|
||||
print(usage)
|
||||
end
|
||||
--
|
||||
-- Exit message
|
||||
function ExitMsg(msg)
|
||||
local function ExitMsg(msg)
|
||||
print( string.rep('--',20) )
|
||||
print( string.rep('--',20) )
|
||||
print(msg)
|
||||
|
@ -41,20 +58,20 @@ end
|
|||
|
||||
local function main(args)
|
||||
|
||||
local input = "dumpdata.eml"
|
||||
local output = os.date("%Y-%m-%d_%H%M%S.bin");
|
||||
local input = 'dumpdata.eml'
|
||||
local output = os.date('%Y-%m-%d_%H%M%S.bin');
|
||||
|
||||
-- Arguments for the script
|
||||
for o, a in getopt.getopt(args, 'hi:o:') do
|
||||
if o == "h" then return help() end
|
||||
if o == "i" then input = a end
|
||||
if o == "o" then output = a end
|
||||
if o == 'h' then return help() end
|
||||
if o == 'i' then input = a end
|
||||
if o == 'o' then output = a end
|
||||
end
|
||||
|
||||
local filename, err = dumplib.convert_eml_to_bin(input,output)
|
||||
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
|
||||
|
||||
main(args)
|
||||
|
|
|
@ -4,12 +4,18 @@ getopt = require('getopt')
|
|||
bin = require('bin')
|
||||
dumplib = require('html_dumplib')
|
||||
|
||||
example = "script run emul2html -o dumpdata.eml "
|
||||
author = "Martin Holst Swende"
|
||||
usage = "script run htmldump [-i <file>] [-o <file>]"
|
||||
desc =[[
|
||||
copyright = ''
|
||||
author = 'Martin Holst Swende'
|
||||
version = 'v1.0.1'
|
||||
desc = [[
|
||||
This script takes a dumpfile on EML (ASCII) format and produces a html based dump, which is a
|
||||
bit more easily analyzed.
|
||||
]]
|
||||
example = [[
|
||||
script run emul2html -o dumpdata.eml
|
||||
]]
|
||||
usage = [[
|
||||
script run htmldump [-i <file>] [-o <file>]
|
||||
|
||||
Arguments:
|
||||
-h This help
|
||||
|
@ -18,45 +24,54 @@ Arguments:
|
|||
|
||||
]]
|
||||
|
||||
-------------------------------
|
||||
-- Some utilities
|
||||
-------------------------------
|
||||
|
||||
-- Some globals
|
||||
local DEBUG = false -- the debug flag
|
||||
---
|
||||
-- A debug printout-function
|
||||
function dbg(args)
|
||||
if DEBUG then
|
||||
print("###", args)
|
||||
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
|
||||
function oops(err)
|
||||
print("ERROR: ",err)
|
||||
local function oops(err)
|
||||
print('ERROR:', err)
|
||||
core.clearCommandBuffer()
|
||||
return nil, err
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Usage help
|
||||
function help()
|
||||
local function help()
|
||||
print(copyright)
|
||||
print(author)
|
||||
print(version)
|
||||
print(desc)
|
||||
print("Example usage")
|
||||
print('Example usage')
|
||||
print(example)
|
||||
print(usage)
|
||||
end
|
||||
|
||||
local function main(args)
|
||||
|
||||
local input = "dumpdata.eml"
|
||||
local output = os.date("%Y-%m-%d_%H%M%S.html");
|
||||
local input = 'dumpdata.eml'
|
||||
local output = os.date('%Y-%m-%d_%H%M%S.html');
|
||||
for o, a in getopt.getopt(args, 'i:o:h') do
|
||||
if o == "h" then return help() end
|
||||
if o == "i" then input = a end
|
||||
if o == "o" then output = a end
|
||||
if o == 'h' then return help() end
|
||||
if o == 'i' then input = a end
|
||||
if o == 'o' then output = a end
|
||||
end
|
||||
local filename, err = dumplib.convert_eml_to_html(input,output)
|
||||
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
|
||||
|
||||
--[[
|
||||
|
|
|
@ -4,6 +4,19 @@ local bin = require('bin')
|
|||
local lib14a = require('read14a')
|
||||
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 = [[
|
||||
-- generate commands
|
||||
1. script run formatMifare
|
||||
|
@ -14,22 +27,8 @@ example = [[
|
|||
-- generate commands and execute them against card.
|
||||
3. script run formatMifare -x
|
||||
]]
|
||||
copyright = ''
|
||||
version = ''
|
||||
author = 'Iceman'
|
||||
usage = [[
|
||||
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.
|
||||
|
||||
script run formatMifare -k <key> -n <key> -a <access> -x
|
||||
|
||||
Arguments:
|
||||
-h - this help
|
||||
|
@ -38,6 +37,7 @@ Arguments:
|
|||
-a <access> - the new access bytes that will be written to the card
|
||||
-x - execute the commands aswell.
|
||||
]]
|
||||
|
||||
local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
|
||||
local DEBUG = true -- the debug flag
|
||||
local CmdString = 'hf mf wrbl %d B %s %s'
|
||||
|
@ -45,39 +45,39 @@ local numBlocks = 64
|
|||
local numSectors = 16
|
||||
---
|
||||
-- A debug printout-function
|
||||
function dbg(args)
|
||||
if not DEBUG then
|
||||
return
|
||||
end
|
||||
|
||||
if type(args) == "table" then
|
||||
local function dbg(args)
|
||||
if not DEBUG then return end
|
||||
if type(args) == 'table' then
|
||||
local i = 1
|
||||
while result[i] do
|
||||
dbg(result[i])
|
||||
while args[i] do
|
||||
dbg(args[i])
|
||||
i = i+1
|
||||
end
|
||||
else
|
||||
print("###", args)
|
||||
print('###', args)
|
||||
end
|
||||
end
|
||||
---
|
||||
-- This is only meant to be used when errors occur
|
||||
function oops(err)
|
||||
print("ERROR: ",err)
|
||||
local function oops(err)
|
||||
print('ERROR:', err)
|
||||
core.clearCommandBuffer()
|
||||
return nil, err
|
||||
end
|
||||
---
|
||||
-- Usage help
|
||||
function help()
|
||||
local function help()
|
||||
print(copyright)
|
||||
print(author)
|
||||
print(version)
|
||||
print(desc)
|
||||
print("Example usage")
|
||||
print('Example usage')
|
||||
print(example)
|
||||
print(usage)
|
||||
end
|
||||
--
|
||||
-- Exit message
|
||||
function ExitMsg(msg)
|
||||
local function ExitMsg(msg)
|
||||
print( string.rep('--',20) )
|
||||
print( string.rep('--',20) )
|
||||
print(msg)
|
||||
|
@ -91,7 +91,7 @@ function GetCardInfo()
|
|||
print(err)
|
||||
return
|
||||
end
|
||||
print(("Found: %s"):format(result.name))
|
||||
print(('Found: %s'):format(result.name))
|
||||
|
||||
core.clearCommandBuffer()
|
||||
|
||||
|
@ -138,11 +138,11 @@ local function main(args)
|
|||
|
||||
-- Arguments for the script
|
||||
for o, a in getopt.getopt(args, 'hk:n:a:x') do
|
||||
if o == "h" then return help() end
|
||||
if o == "k" then OldKey = a end
|
||||
if o == "n" then NewKey = a end
|
||||
if o == "a" then Accessbytes = a end
|
||||
if o == "x" then x = true end
|
||||
if o == 'h' then return help() end
|
||||
if o == 'k' then OldKey = a end
|
||||
if o == 'n' then NewKey = a end
|
||||
if o == 'a' then Accessbytes = a end
|
||||
if o == 'x' then x = true end
|
||||
end
|
||||
|
||||
-- validate input args.
|
||||
|
@ -169,29 +169,29 @@ local function main(args)
|
|||
print( string.format('Old key: %s', OldKey))
|
||||
print( string.format('New key: %s', NewKey))
|
||||
print( string.format('New Access: %s', Accessbytes))
|
||||
print( string.rep('--',20) )
|
||||
print( string.rep('--', 20) )
|
||||
|
||||
-- Set new block data
|
||||
local EMPTY_BL = string.rep('00',16)
|
||||
local EMPTY_SECTORTRAIL = string.format('%s%s%s%s',NewKey,Accessbytes,'00',NewKey)
|
||||
-- Set new block data
|
||||
local EMPTY_BL = string.rep('00', 16)
|
||||
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 emptyblock: %s',EMPTY_BL))
|
||||
dbg( string.format('New sector-trailer : %s', EMPTY_SECTORTRAIL))
|
||||
dbg( string.format('New emptyblock: %s', EMPTY_BL))
|
||||
dbg('')
|
||||
|
||||
if x then
|
||||
print('[Warning] you have used the EXECUTE parameter, which means this will run these commands against card.')
|
||||
end
|
||||
-- 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
|
||||
return ExitMsg('Quiting it is then. Your wish is my command...')
|
||||
end
|
||||
|
||||
print( string.rep('--',20) )
|
||||
print( string.rep('--', 20) )
|
||||
|
||||
-- main loop
|
||||
for block=0,numBlocks,1 do
|
||||
for block = 0, numBlocks, 1 do
|
||||
|
||||
local reminder = (block+1) % 4
|
||||
local cmd
|
||||
|
@ -207,7 +207,7 @@ local function main(args)
|
|||
end
|
||||
|
||||
if core.ukbhit() then
|
||||
print("aborted by user")
|
||||
print('aborted by user')
|
||||
break
|
||||
end
|
||||
end
|
||||
|
|
|
@ -135,11 +135,11 @@ local function main(args)
|
|||
--13-14
|
||||
|
||||
-- find tag
|
||||
result, err = lib14a.read(false, true)
|
||||
if not result then return oops(err) end
|
||||
local card, err = lib14a.read(false, true)
|
||||
if not card then return oops(err) end
|
||||
|
||||
-- load keys
|
||||
local akeys = pre.GetAll(result.uid)
|
||||
local akeys = pre.GetAll(card.uid)
|
||||
local keyA = akeys:sub(1, 12 )
|
||||
|
||||
local b0 = readblock(0, keyA)
|
||||
|
@ -154,7 +154,7 @@ local function main(args)
|
|||
core.clearCommandBuffer()
|
||||
|
||||
-- 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.clearCommandBuffer()
|
||||
|
||||
|
|
|
@ -6,8 +6,7 @@ local utils = require('utils')
|
|||
copyright = ''
|
||||
author = 'Iceman'
|
||||
version = 'v1.0.1'
|
||||
desc =
|
||||
[[
|
||||
desc = [[
|
||||
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.
|
||||
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)
|
||||
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
|
||||
function main(args)
|
||||
|
@ -130,7 +121,10 @@ function main(args)
|
|||
|
||||
-- First of all, connect
|
||||
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()
|
||||
|
||||
local blockData = {}
|
||||
|
@ -143,7 +137,10 @@ function main(args)
|
|||
for block = 00, endblock do
|
||||
local cmd = string.format('10%02x00', block)
|
||||
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 len = tonumber(cmd_response.arg1) * 2
|
||||
|
@ -153,7 +150,7 @@ function main(args)
|
|||
table.insert(blockData, data)
|
||||
end
|
||||
print("----+------------------+-------------------")
|
||||
disconnect()
|
||||
lib14a.disconnect()
|
||||
|
||||
local filename, err = utils.WriteDumpFile(info.uid, blockData)
|
||||
if err then return oops(err) end
|
||||
|
|
Loading…
Add table
Reference in a new issue