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