From edcb029af3cdf486faac82653a0abde53dc25d4a Mon Sep 17 00:00:00 2001 From: mazodude Date: Fri, 14 Dec 2018 15:31:50 +1000 Subject: [PATCH] Add script to test for MADs --- client/scripts/mifare_ad.lua | 186 +++++++++++++++++++++++++++++++++++ 1 file changed, 186 insertions(+) create mode 100644 client/scripts/mifare_ad.lua diff --git a/client/scripts/mifare_ad.lua b/client/scripts/mifare_ad.lua new file mode 100644 index 000000000..0f9c8219d --- /dev/null +++ b/client/scripts/mifare_ad.lua @@ -0,0 +1,186 @@ + +-- 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) \ No newline at end of file