]> git.zerfleddert.de Git - proxmark3-svn/blame - client/scripts/mfkeys.lua
mf check keys in lua-space
[proxmark3-svn] / client / scripts / mfkeys.lua
CommitLineData
16b04cb2 1--[[
2 This is an example of Lua-scripting within proxmark3. This is a lua-side
3 implementation of hf mf chk
4
5 This code is licensed to you under the terms of the GNU GPL, version 2 or,
6 at your option, any later version. See the LICENSE.txt file for the text of
7 the license.
8
9 Copyright (C) 2013 m h swende <martin at swende.se>
10]]
11-- Loads the commands-library
12local cmds = require('commands')
13-- Load the default keys
14local keys = require('mf_default_keys')
15local desc =
16("This script implements check keys. It utilises a large list of default keys (currently %d keys).\
17If you want to add more, just put them inside mf_default_keys.lua. "):format(#keys)
18
19local TIMEOUT = 10000 -- 10 seconds
20
21local function checkCommand(command)
22
23 --print("Sending this command : " .. tostring(command))
24 local usbcommand = command:getBytes()
25 core.SendCommand(usbcommand)
26 local result = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT)
27 if result then
28 local count,cmd,arg0 = bin.unpack('LL',result)
29 if(arg0==1) then
30 local count,arg1,arg2,data = bin.unpack('LLH511',result,count)
31 key = data:sub(1,12)
32 return key
33 else
34 --print("Key not found...")
35 return nil
36 end
37 else
38 print("Timeout while waiting for response. Increase TIMEOUT in keycheck.lua to wait longer")
39 return nil, "Timeout while waiting for device to respond"
40 end
41end
42
43
44function checkBlock(blockNo, keys, keyType)
45 -- The command data is only 512 bytes, each key is 6 bytes, meaning that we can send max 85 keys in one go.
46 -- If there's more, we need to split it up
47 local start, remaining= 1, #keys
48 local packets = {}
49 while remaining > 0 do
50 local n,data = remaining, nil
51 if remaining > 85 then n = 85 end
52 local data = table.concat(keys,"",start,n)
53 --print("data",data)
54 --print("data len", #data)
55 print(("Testing block %d, keytype %d, with %d keys"):format(blockNo, keyType, n))
56 local command = Command:new{cmd = cmds.CMD_MIFARE_CHKKEYS,
57 arg1 = blockNo,
58 arg2 = keyType,
59 arg3 = n,
60 data = data}
61 local status = checkCommand(command)
62 if status then return status, blockNo end
63 start = start+n+1
64 remaining = remaining - n
65 end
66 return nil
67end
68
69-- A function to display the results
70local function displayresults(results)
71 local sector, blockNo, keyA, keyB,_
72
73 print("________________________________________")
74 print("|Sector|Block| A | B |")
75 print("|--------------------------------------|")
76
77 for sector,_ in pairs(results) do
78 blockNo, keyA, keyB = unpack(_)
79
80 print(("| %3d | %3d |%s|%s|"):format(sector, blockNo, keyA, keyB ))
81 end
82 print("|--------------------------------------|")
83
84end
85-- A little helper to place an item first in the list
86local function placeFirst(akey, list)
87 akey = akey:lower()
88 if list[1] == akey then
89 -- Already at pole position
90 return list
91 end
92 local result = {akey}
93 --print(("Putting '%s' first"):format(akey))
94 for i,v in ipairs(list) do
95 if v ~= akey then
96 result[#result+1] = v
97 end
98 end
99 return result
100end
101
102local function main()
103
104 print(desc);
105
106 core.clearCommandBuffer()
107 local blockNo
108 local keyType = 0 -- A=0, B=1
109 local result = {}
110 for sector=1,40,1 do
111
112 --[[
113 The mifare Classic 1k card has 16 sectors of 4 data blocks each. The
114 first 32 sectors of a mifare Classic 4k card consists of 4 data blocks and the remaining
115 8 sectors consist of 16 data blocks.
116 --]]
117 local blockNo = sector * 4 -1
118
119 if sector > 32 then
120 blockNo = 32*4+ (sector-32)*16 -1
121 end
122
123 local keyA = checkBlock(blockNo, keys, 0)
124 if keyA then keys = placeFirst(keyA, keys) end
125 keyA = keyA or ""
126
127 local keyB = checkBlock(blockNo, keys, 1)
128 if keyB then keys = placeFirst(keyB, keys) end
129 keyB = keyB or ""
130
131 result[sector] = {blockNo, keyA, keyB }
132
133 -- Check if user aborted
134 if core.ukbhit() then
135 print("Aborted by user")
136 break
137 end
138 end
139 displayresults(result)
140end
141
142main()
143
Impressum, Datenschutz