X-Git-Url: http://cvs.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/51defdd4a2bb20022acaf7b94d67c3ab0d86fb96..d8b7a5f29453ba32c9486b97e5afc8fb5e3cba34:/client/scripts/mifare_autopwn.lua?ds=sidebyside

diff --git a/client/scripts/mifare_autopwn.lua b/client/scripts/mifare_autopwn.lua
index 8d0d358f..f7edfd08 100644
--- a/client/scripts/mifare_autopwn.lua
+++ b/client/scripts/mifare_autopwn.lua
@@ -66,7 +66,7 @@ end
 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}
 	
 	local retry = true
 	while retry do
@@ -78,20 +78,44 @@ function mfcrack()
 		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}
 	end	
 	return nil, "Aborted by user"
 end
 
-
 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
@@ -108,7 +132,7 @@ function mfcrack_inner()
 			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 
@@ -133,6 +157,8 @@ function nested(key,sak)
 		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
@@ -160,10 +186,9 @@ end
 -- 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
@@ -171,6 +196,10 @@ function main(args)
 	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?
@@ -179,7 +208,7 @@ function main(args)
 		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()
@@ -190,12 +219,13 @@ function main(args)
 			-- 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