fixes: 'script run mifareplus' behaves better now.

This commit is contained in:
iceman1001 2018-04-25 09:22:41 +02:00
commit f5257f5380

View file

@ -18,13 +18,13 @@ READPLAINNOMACUNMACED = "0336"
--- ---
-- 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)
end end
--- ---
-- Used to send raw data to the firmware to subsequently forward the data to the card. -- Used to send raw data to the firmware to subsequently forward the data to the card.
function sendRaw(rawdata, crc, power) local function sendRaw(rawdata, crc, power)
print(("<sent>: %s"):format(rawdata)) print(("<sent>: %s"):format(rawdata))
local flags = lib14a.ISO14A_COMMAND.ISO14A_RAW local flags = lib14a.ISO14A_COMMAND.ISO14A_RAW
@ -44,16 +44,30 @@ function sendRaw(rawdata, crc, power)
if result then if result then
--unpack the first 4 parts of the result as longs, and the last as an extremely long string to later be cut down based on arg1, the number of bytes returned --unpack the first 4 parts of the result as longs, and the last as an extremely long string to later be cut down based on arg1, the number of bytes returned
local count,cmd,arg1,arg2,arg3,data = bin.unpack('LLLLH512',result) local count,cmd,arg1,arg2,arg3,data = bin.unpack('LLLLH512',result)
returned_bytes = string.sub(data, 1, arg1 * 2) returned_bytes = string.sub(data, 1, arg1 * 2)
print(("<recvd>: %s"):format(returned_bytes)) -- need to multiply by 2 because the hex digits are actually two bytes when they are strings if #returned_bytes > 0 then
return returned_bytes print(("<recvd>: %s"):format(returned_bytes)) -- need to multiply by 2 because the hex digits are actually two bytes when they are strings
return returned_bytes
else
return nil
end
else else
err = "Error sending the card raw data." oops("Error sending the card raw data.")
oops(err) return nil
end end
end end
function writePerso() -- Sends an instruction to do nothing, only disconnect
local 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
local function writePerso()
-- Used to write any data, including the keys (Key A and Key B), for all the sectors. -- Used to write any data, including the keys (Key A and Key B), for all the sectors.
-- writePerso() command parameters: -- writePerso() command parameters:
-- 1 byte - 0xA8 - Command Code -- 1 byte - 0xA8 - Command Code
@ -130,7 +144,7 @@ function writePerso()
print("WritePerso finished! Card is ready to move into new security level.") print("WritePerso finished! Card is ready to move into new security level.")
end end
function writeBlock(blocknum, data) local function writeBlock(blocknum, data)
-- Method writes 16 bytes of the string sent (data) to the specified block number -- Method writes 16 bytes of the string sent (data) to the specified block number
-- The block numbers sent to the card need to be in little endian format (i.e. block 0x0001 is sent as 0x1000) -- The block numbers sent to the card need to be in little endian format (i.e. block 0x0001 is sent as 0x1000)
blocknum_little_endian = string.sub(blocknum, 3, 4) .. string.sub(blocknum, 1, 2) blocknum_little_endian = string.sub(blocknum, 3, 4) .. string.sub(blocknum, 1, 2)
@ -141,19 +155,19 @@ function writeBlock(blocknum, data)
end end
end end
function authenticateAES() local function authenticateAES()
-- Used to try to authenticate with the AES keys we programmed into the card, to ensure the authentication works correctly. -- Used to try to authenticate with the AES keys we programmed into the card, to ensure the authentication works correctly.
commandString = AUTH_FIRST commandString = AUTH_FIRST
commandString = commandString .. "" commandString = commandString .. ""
end end
function getVersion() local function getVersion()
sendRaw(GETVERS_INIT, true, true) sendRaw(GETVERS_INIT, true, true)
sendRaw(GETVERS_CONT, true, true) sendRaw(GETVERS_CONT, true, true)
sendRaw(GETVERS_CONT, true, true) sendRaw(GETVERS_CONT, true, true)
end end
function commitPerso(SL) local function commitPerso(SL)
--pass SL as "01" to move to SL1 or "03" to move to SL3. --pass SL as "01" to move to SL1 or "03" to move to SL3.
commandString = COMMITPERSO .. SL commandString = COMMITPERSO .. SL
response = sendRaw(commandString, true, true) --0x90 is returned upon success response = sendRaw(commandString, true, true) --0x90 is returned upon success
@ -162,7 +176,7 @@ function commitPerso(SL)
end end
end end
function calculateMAC(MAC_input) local function calculateMAC(MAC_input)
-- Pad the input if it is not a multiple of 16 bytes (32 nibbles). -- Pad the input if it is not a multiple of 16 bytes (32 nibbles).
if(string.len(MAC_input) % 32 ~= 0) then if(string.len(MAC_input) % 32 ~= 0) then
MAC_input = MAC_input .. "80" MAC_input = MAC_input .. "80"
@ -185,12 +199,14 @@ function calculateMAC(MAC_input)
return final_output return final_output
end end
function proximityCheck() local function proximityCheck()
--PreparePC-- --PreparePC--
commandString = PREPAREPC commandString = PREPAREPC
response = sendRaw(commandString, true, true) response = sendRaw(commandString, true, true)
if not response then return oops("not a Mifare plus card") end
OPT = string.sub(response, 5, 6) OPT = string.sub(response, 5, 6)
if(tonumber(OPT) == 1) then if tonumber(OPT) == 1 then
pps_present = true pps_present = true
else else
pps_present = false pps_present = false
@ -199,7 +215,7 @@ function proximityCheck()
if(pps_present == true) then if(pps_present == true) then
pps = string.sub(response, 11, 12) pps = string.sub(response, 11, 12)
else else
pps = nil pps = ''
end end
print("OPT = " .. OPT .. " pubRespTime = " .. pubRespTime .. " pps = " .. pps) print("OPT = " .. OPT .. " pubRespTime = " .. pubRespTime .. " pps = " .. pps)
@ -223,7 +239,7 @@ function proximityCheck()
--VerifyPC-- --VerifyPC--
MAC_input = "FD" .. OPT .. pubRespTime MAC_input = "FD" .. OPT .. pubRespTime
if(pps_present == true) then if pps_present then
MAC_input = MAC_input .. pps MAC_input = MAC_input .. pps
end end
rnum_concat = "" rnum_concat = ""
@ -240,7 +256,9 @@ function proximityCheck()
print("8-byte PCD MAC_tag (placeholder - currently incorrect) = " .. MAC_tag) print("8-byte PCD MAC_tag (placeholder - currently incorrect) = " .. MAC_tag)
commandString = VERIFYPC .. MAC_tag commandString = VERIFYPC .. MAC_tag
response = sendRaw(commandString, true, true) response = sendRaw(commandString, true, true)
print(response) print(#response, response)
if #response < 20 then return oops("Wrong response length (expected 20, got "..#response..") exiting") end
PICC_MAC = string.sub(response, 5, 20) PICC_MAC = string.sub(response, 5, 20)
print("8-byte MAC returned by PICC = " .. PICC_MAC) print("8-byte MAC returned by PICC = " .. PICC_MAC)
MAC_input = "90" .. string.sub(MAC_input, 3) MAC_input = "90" .. string.sub(MAC_input, 3)
@ -253,24 +271,20 @@ end
--- ---
-- The main entry point -- The main entry point
function main(args) function main(args)
-- Initialize the card using the already-present read14a library -- Initialize the card using the already-present read14a library
info,err = lib14a.read14443a(true, false) -- Perform PPS (Protocol and Parameter Selection) check to finish the ISO 14443-4 protocol.
--Perform PPS (Protocol and Parameter Selection) check to finish the ISO 14443-4 protocol. info,err = lib14a.read(true, false)
response = sendRaw("e050", true, true) if not info then oops(err); disconnect(); return; end
if(response == nil) then
err = "No response from RATS" --
end response = sendRaw("D01100", true, true)
response = sendRaw("D01100", true, true) if not response then oops("No response from PPS check"); disconnect(); return; end
if(response == nil) then
err = "No response from PPS check"
end
if err then
oops(err)
else
print(("Connected to card with a UID of %s."):format(info.uid))
end
print("Connected to")
print(" Type : "..info.name)
print(" UID : "..info.uid)
-- Now, the card is initialized and we can do more interesting things. -- Now, the card is initialized and we can do more interesting things.
--writePerso() --writePerso()
@ -292,7 +306,8 @@ function main(args)
-- Power off the Proxmark -- Power off the Proxmark
sendRaw(POWEROFF, false, false) sendRaw(POWEROFF, false, false)
disconnect()
end end
main(args) -- Call the main function main(args) -- Call the main function