proxmark3/client/scripts/mifare_ad.lua

186 lines
4.4 KiB
Lua
Raw Normal View History

2018-12-14 13:31:50 +08:00
-- Ability to read what card is there
local getopt = require('getopt')
local cmds = require('commands')
local taglib = require('taglib')
local desc =
[[This script will automatically check Mifare cards for MADs
(Mifare Application Directory)
Arguments:
-d debug logging on
-h this help
]]
local example = "script run xxx"
local author = "Mazodude"
---
-- PrintAndLog
function prlog(...)
print(...)
end
---
-- This is only meant to be used when errors occur
function oops(err)
prlog("ERROR: ",err)
return nil,err
end
---
-- Usage help
function help()
prlog(desc)
prlog("Example usage")
prlog(example)
end
function debug(...)
if DEBUG then
prlog("debug:", ...)
end
end
local function show(data)
if DEBUG then
local formatString = ("H%d"):format(string.len(data))
local _,hexdata = bin.unpack(formatString, data)
debug("Hexdata" , hexdata)
end
end
--- Fire up a connection with a tag, return uid
-- @return UID if successfull
-- @return nil, errormessage if unsuccessfull
local function open()
debug("Opening connection")
core.clearCommandBuffer()
local x = string.format("hf 14a raw -r -p -s")
debug(x)
core.console(x)
debug("done")
data, err = waitCmd(true)
if err then return oops(err) end
show(data)
local formatString = ("H%d"):format(string.len(data))
local _,uid = bin.unpack(formatString, data)
return uid
end
--- Shut down tag communication
-- return no return values
local function close()
debug("Closing connection")
core.clearCommandBuffer()
local x = string.format("hf 14a raw -r")
debug(x)
core.console(x)
debug("done")
--data, err = waitCmd(true)
--data, err = waitCmd(false)
end
-- waits for answer from pm3 device
local function checkCommand(command)
core.clearCommandBuffer()
local usb = command:getBytes()
core.SendCommand(usb)
local result = core.WaitForResponseTimeout(cmds.CMD_ACK, 1500)
if result then
local count, cmd, arg0 = bin.unpack('LL',result)
if(arg0==1) then
local count, arg1, arg2, data = bin.unpack('LLH511',result,count)
block = data:sub(33,64)
return block
else
return nil
end
else
print("Timeout while waiting for response. Increase TIMEOUT in mifare_ad.lua to wait longer")
return nil, "Timeout while waiting for device to respond"
end
end
---_ Gets data from a block
-- @return block if successfull
-- @return nil, errormessage if unsuccessfull
local function getBlock(block)
local data, err
core.clearCommandBuffer()
-- // params
-- uint8_t sectorNo = arg0;
-- uint8_t keyType = arg1;
-- uint64_t ui64Key = 0;
-- ui64Key = bytes_to_num(datain, 6);
local sectorNo = 0
local keyType = 0
local key = "A0A1A2A3A4A5";
debug(("Testing to auth with key %s"):format(key))
-- prlog(key);
local command = Command:new{cmd = cmds.CMD_MIFARE_READSC,
arg1 = sectorNo,
arg2 = keyType,
arg3 = 0,
data = key}
local data = checkCommand(command)
-- debug(command)
-- prlog(data)
if (data == nil) then return err, ("Could not auth with card - this tag does not have MADs") end
if string.len(data) < 32 then
return nil, ("Expected at least 32 bytes, got %d - this tag does not have MADs"):format(string.len(data))
end
-- -- Now, parse out the block data
b0 = string.sub(data,3,4)
return b0
end
--- This function is a lua-implementation of
-- cmdhf14a.c:waitCmd(uint8_t iSelect)
function waitCmd(iSelect)
local response = core.WaitForResponseTimeout(cmds.CMD_ACK,1000)
if response then
local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL',response)
local iLen = arg0
if iSelect then iLen = arg1 end
debug(("Received %i octets (arg0:%d, arg1:%d)"):format(iLen, arg0, arg1))
if iLen == 0 then return nil, "No response from tag" end
local recv = string.sub(response,count, iLen+count-1)
return recv
end
return nil, "No response from device"
end
local function main( args)
debug("script started")
local err, data, data2,k,v,i
-- Read the parameters
for o, a in getopt.getopt(args, 'hd') do
if o == "h" then help() return end
if o == "d" then DEBUG = true end
end
local uid = open()
if (uid==nil) then oops("No card present") return end
print(("UID: %s"):format(uid))
-- First, get block 1 byte 1
local block, err = getBlock(0)
if err then return oops(err) end
debug(("Checking block 0 sector 1 byte 1"))
debug(("Got byte: %s"):format(block))
-- prlog(block)
if block == "0F" then
print('Card has MADs v1')
end
-- Deactivate field
close()
end
main(args)