X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/c00f0dbfda703611c4373ce5cbbff772c8942de1..16b04cb291feefce8f76c6b05f93b62d304be1ed:/client/scripts/mfkeys.lua diff --git a/client/scripts/mfkeys.lua b/client/scripts/mfkeys.lua new file mode 100644 index 00000000..135108f3 --- /dev/null +++ b/client/scripts/mfkeys.lua @@ -0,0 +1,143 @@ +--[[ + This is an example of Lua-scripting within proxmark3. This is a lua-side + implementation of hf mf chk + + This code is licensed to you under the terms of the GNU GPL, version 2 or, + at your option, any later version. See the LICENSE.txt file for the text of + the license. + + Copyright (C) 2013 m h swende +]] +-- Loads the commands-library +local cmds = require('commands') +-- Load the default keys +local keys = require('mf_default_keys') +local desc = +("This script implements check keys. It utilises a large list of default keys (currently %d keys).\ +If you want to add more, just put them inside mf_default_keys.lua. "):format(#keys) + +local TIMEOUT = 10000 -- 10 seconds + +local function checkCommand(command) + + --print("Sending this command : " .. tostring(command)) + local usbcommand = command:getBytes() + core.SendCommand(usbcommand) + local result = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT) + 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) + key = data:sub(1,12) + return key + else + --print("Key not found...") + return nil + end + else + print("Timeout while waiting for response. Increase TIMEOUT in keycheck.lua to wait longer") + return nil, "Timeout while waiting for device to respond" + end +end + + +function checkBlock(blockNo, keys, keyType) + -- The command data is only 512 bytes, each key is 6 bytes, meaning that we can send max 85 keys in one go. + -- If there's more, we need to split it up + local start, remaining= 1, #keys + local packets = {} + while remaining > 0 do + local n,data = remaining, nil + if remaining > 85 then n = 85 end + local data = table.concat(keys,"",start,n) + --print("data",data) + --print("data len", #data) + print(("Testing block %d, keytype %d, with %d keys"):format(blockNo, keyType, n)) + local command = Command:new{cmd = cmds.CMD_MIFARE_CHKKEYS, + arg1 = blockNo, + arg2 = keyType, + arg3 = n, + data = data} + local status = checkCommand(command) + if status then return status, blockNo end + start = start+n+1 + remaining = remaining - n + end + return nil +end + +-- A function to display the results +local function displayresults(results) + local sector, blockNo, keyA, keyB,_ + + print("________________________________________") + print("|Sector|Block| A | B |") + print("|--------------------------------------|") + + for sector,_ in pairs(results) do + blockNo, keyA, keyB = unpack(_) + + print(("| %3d | %3d |%s|%s|"):format(sector, blockNo, keyA, keyB )) + end + print("|--------------------------------------|") + +end +-- A little helper to place an item first in the list +local function placeFirst(akey, list) + akey = akey:lower() + if list[1] == akey then + -- Already at pole position + return list + end + local result = {akey} + --print(("Putting '%s' first"):format(akey)) + for i,v in ipairs(list) do + if v ~= akey then + result[#result+1] = v + end + end + return result +end + +local function main() + + print(desc); + + core.clearCommandBuffer() + local blockNo + local keyType = 0 -- A=0, B=1 + local result = {} + for sector=1,40,1 do + + --[[ + The mifare Classic 1k card has 16 sectors of 4 data blocks each. The + first 32 sectors of a mifare Classic 4k card consists of 4 data blocks and the remaining + 8 sectors consist of 16 data blocks. + --]] + local blockNo = sector * 4 -1 + + if sector > 32 then + blockNo = 32*4+ (sector-32)*16 -1 + end + + local keyA = checkBlock(blockNo, keys, 0) + if keyA then keys = placeFirst(keyA, keys) end + keyA = keyA or "" + + local keyB = checkBlock(blockNo, keys, 1) + if keyB then keys = placeFirst(keyB, keys) end + keyB = keyB or "" + + result[sector] = {blockNo, keyA, keyB } + + -- Check if user aborted + if core.ukbhit() then + print("Aborted by user") + break + end + end + displayresults(result) +end + +main() +