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

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

1
.gitignore vendored
View file

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

View file

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

View file

@ -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

View file

@ -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,
}

View file

@ -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,
command = Command:newMIX{
cmd = cmds.CMD_ISO_15693_COMMAND,
arg1 = #data / 2,
arg2 = 1,
arg3 = 1,
data = data}
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 result, err = command:sendMIX()
if result then
local count, cmd, len, arg2, arg3 = bin.unpack('LLLL', result)
if len > 0 then
if len == 0 then
return nil, 'iso15693 card select failed'
end
data = string.sub(result, count, count+len-1)
info, err = parse15693(data)
else
err = 'No response from card'
end
if err then
print(err)
return nil, err
end
return info
else
return nil, "Failed to get response"
end
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

View file

@ -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,
}

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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,
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
arg3 = 0,
data = data} -- data bytes (commands etc)
result, err = lib14b.sendToDevice(command, false)
if ignoreresponse then return response, err end
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

View file

@ -1,12 +1,16 @@
--[[
A sampe script file on how to implement at cmd line inteface.
--]]
print("This is how a cmd-line interface could be implemented\nPrint 'exit' to exit.\n")
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");

View file

@ -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

View file

@ -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)

View file

@ -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
--[[

View file

@ -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)
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

View file

@ -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()

View file

@ -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