-- Some utilities
-------------------------------
local DEBUG = false
+local MIFARE_AUTH_KEYA = 0x60
+local MIFARE_AUTH_KEYB = 0x61
---
-- A debug printout-function
function dbg(args)
function mfcrack()
core.clearCommandBuffer()
-- Build the mifare-command
- local cmd = Command:new{cmd = cmds.CMD_READER_MIFARE, arg1 = 1}
+ local cmd = Command:new{cmd = cmds.CMD_READER_MIFARE, arg1 = 1, arg2 = 0, arg3 = MIFARE_AUTH_KEYA}
local retry = true
while retry do
if errormessage then return nil, errormessage end
-- Try again..set arg1 to 0 this time.
- cmd = Command:new{cmd = cmds.CMD_READER_MIFARE, arg1 = 0}
+ cmd = Command:new{cmd = cmds.CMD_READER_MIFARE, arg1 = 0, arg2 = 0, arg3 = MIFARE_AUTH_KEYA}
end
return nil, "Aborted by user"
end
-
function mfcrack_inner()
while not core.ukbhit() do
local result = core.WaitForResponseTimeout(cmds.CMD_ACK,1000)
return nil, "Card is not vulnerable to Darkside attack (doesn't send NACK on authentication requests). You can try 'script run mfkeys' or 'hf mf chk' to test various known keys."
elseif isOK == 0xFFFFFFFD then
return nil, "Card is not vulnerable to Darkside attack (its random number generator is not predictable). You can try 'script run mfkeys' or 'hf mf chk' to test various known keys."
+ elseif isOK == 0xFFFFFFFC then
+ return nil, "The card's random number generator behaves somewhat weird (Mifare clone?). You can try 'script run mfkeys' or 'hf mf chk' to test various known keys."
elseif isOK ~= 1 then
return nil, "Error occurred"
end
local uid,nt,pl = get(4),get(4),get(8)
local ks,nr = get(8),get(4)
- local status, key = core.nonce2key(uid,nt, nr, pl,ks)
+ local status, key = core.nonce2key(uid, nt, nr, pl, ks)
if not status then return status,key end
if status > 0 then
-- The main entry point
function main(args)
-
local verbose, exit,res,uid,err,_,sak
local seen_uids = {}
-
+ local print_message = true
-- Read the parameters
for o, a in getopt.getopt(args, 'hd') do
if o == "h" then help() return end
end
while not exit do
+ if print_message then
+ print("Waiting for card or press any key to stop")
+ print_message = false
+ end
res, err = wait_for_mifare()
if err then return oops(err) end
-- Seen already?
if not seen_uids[uid] then
-- Store it
seen_uids[uid] = uid
- print("Card found, commencing crack", uid)
+ print("Card found, commencing crack on UID", uid)
-- Crack it
local key, cnt
res,err = mfcrack()
-- two bytes, then six bytes actual key data
-- We can discard first and second return values
_,_,key = bin.unpack("H2H6",res)
- print("Key ", key)
+ print("Found valid key: "..key);
-- Use nested attack
nested(key,sak)
-- Dump info
dump(uid)
+ print_message = true
end
end
end