mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-03-31 09:23:54 +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/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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
--[[
|
--[[
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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()
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Reference in a new issue