X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/0dae56d81ed737be4f2fa010326cbf41ea0af228..e88c04f924abb31589f9f58691fcf94238fead63:/client/scripts/mifare_autopwn.lua diff --git a/client/scripts/mifare_autopwn.lua b/client/scripts/mifare_autopwn.lua index ccb46c53..ce6db3c0 100644 --- a/client/scripts/mifare_autopwn.lua +++ b/client/scripts/mifare_autopwn.lua @@ -88,10 +88,35 @@ function mfcrack_inner() while not core.ukbhit() do local result = core.WaitForResponseTimeout(cmds.CMD_ACK,1000) if result then - -- Unpacking the three arg-parameters - local count,cmd,isOK = bin.unpack('LL',result) - if isOK ~= 1 then return nil, "Error occurred" end + --[[ + I don't understand, they cmd and args are defined as uint32_t, however, + looking at the returned data, they all look like 64-bit things: + + print("result", bin.unpack("HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH", result)) + + FF 00 00 00 00 00 00 00 <-- 64 bits of data + FE FF FF FF 00 00 00 00 <-- 64 bits of data + 00 00 00 00 00 00 00 00 <-- 64 bits of data + 00 00 00 00 00 00 00 00 <-- 64 bits of data + 04 7F 12 E2 00 <-- this is where 'data' starts + + So below I use LI to pick out the "FEFF FFFF", don't know why it works.. + --]] + -- Unpacking the arg-parameters + local count,cmd,isOK = bin.unpack('LI',result) + --print("response", isOK)--FF FF FF FF + if isOK == 0xFFFFFFFF then + return nil, "Button pressed. Aborted." + elseif isOK == 0xFFFFFFFE then + 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 -- The data-part is left @@ -123,8 +148,22 @@ function mfcrack_inner() return nil, "Aborted by user" end -function nested(key) - local cmd = string.format("hf mf nested 1 0 A %s d",key) +function nested(key,sak) + local typ = 1 + if 0x18 == sak then --NXP MIFARE Classic 4k | Plus 4k + typ = 4 + elseif 0x08 == sak then -- NXP MIFARE CLASSIC 1k | Plus 2k + typ= 1 + elseif 0x09 == sak then -- NXP MIFARE Mini 0.3k + typ = 0 + elseif 0x10 == sak then-- "NXP MIFARE Plus 2k" + typ = 2 + elseif 0x01 == sak then-- "NXP MIFARE TNP3xxx 1K" + typ = 1 + else + print("I don't know how many sectors there are on this type of card, defaulting to 16") + end + local cmd = string.format("hf mf nested %d 0 A %s d",typ,key) core.console(cmd) end @@ -149,7 +188,7 @@ end function main(args) - local verbose, exit,res,uid,err,_ + local verbose, exit,res,uid,err,_,sak local seen_uids = {} -- Read the parameters @@ -163,6 +202,7 @@ function main(args) if err then return oops(err) end -- Seen already? uid = res.uid + sak = res.sak if not seen_uids[uid] then -- Store it seen_uids[uid] = uid @@ -171,11 +211,16 @@ function main(args) local key, cnt res,err = mfcrack() if not res then return oops(err) end - _,key = bin.unpack("H6",res) + -- The key is actually 8 bytes, so a + -- 6-byte key is sent as 00XXXXXX + -- This means we unpack it as first + -- two bytes, then six bytes actual key data + -- We can discard first and second return values + _,_,key = bin.unpack("H2H6",res) print("Key ", key) -- Use nested attack - nested(key) + nested(key,sak) -- Dump info dump(uid) end