]> git.zerfleddert.de Git - proxmark3-svn/blame_incremental - client/scripts/brutesim.lua
Redesign of lf hid card format handler as discussed with @marshmellow42
[proxmark3-svn] / client / scripts / brutesim.lua
... / ...
CommitLineData
1desc = [[\r
2\r
3 .-----------------------------------------------------------------.\r
4 / .-. .-. \\r
5| / \ BruteSim / \ |\r
6| |\_. | (bruteforce simulation for multiple tags) | /| |\r
7|\| | /| by |\ | |/|\r
8| `---' | Kenzy Carey | `---' |\r
9| | | |\r
10| |-----------------------------------------------------| |\r
11\ | | /\r
12 \ / \ /\r
13 `---' `---'\r
14]]\r
15author = [[ Kenzy Carey ]]\r
16usage = [[\r
17\r
18USAGE:\r
19script run brutesim -r rfid_tag -f facility_code -b base_card_number -c count -t timeout -d direction\r
20option argument description\r
21------ -------- -----------\r
22-r *see below RFID Tag: the RFID tag to emulate\r
23-f 0-999 Facility Code: The facility code (dfx: country id, 14a: type)\r
24-b 0-65535 Base Card Number: base card number to start from\r
25-c 1-65536 Count: number of cards to try\r
26-t .0-99999, pause Timeout: timeout between cards (use the word 'pause' to wait for user input)\r
27-d up, down Direction: direction to move through card numbers\r
28-h Show this\r
29\r
30*SUPPORTED TAGS: pyramid, awid, fdx, jablotron, noralsy, presco, visa2000, 14a, hid\r
31\r
32EXAMPLE: \r
33script run brutesim -r pyramid -f 10 -b 1000 -c 10 -t 1 -d down\r
34(the above example would bruteforce pyramid tags, starting at 10:1000, ending at 10:991, and waiting 1 second between each card)\r
35]]\r
36\r
37-- I wrote this as i was doing a PACS audit. This is far from complete, but is easily expandable.\r
38-- The idea was based on proxbrute, but i needed more options, and support for different readers.\r
39-- I dont know LUA, so I used Brian Redbeards lf_bulk_program.lua script as a starting point, sorry if its kludgy.\r
40 \r
41getopt = require('getopt') -- Used to get get command line arguments\r
42bit32 = require('bit32') -- Used to convert FC/CN to hex\r
43\r
44local function isempty(s) -- Check if a string is empty\r
45 return s == nil or s == ''\r
46end\r
47\r
48local function main(args)\r
49\r
50 print("") -- Print a blank line to make things look cleaner\r
51\r
52 for o, a in getopt.getopt(args, 'r:f:b:c:t:d:h') do -- Populate command like arguments\r
53 if o == 'r' then rfidtag = a end\r
54 if o == 'f' then facility = a end\r
55 if o == 'b' then baseid = a end\r
56 if o == 'c' then count = a end\r
57 if o == 't' then timeout = a end\r
58 if o == 'd' then direction = a end\r
59 if o == 'h' then return print(usage) end\r
60 end\r
61\r
62 if isempty(rfidtag) then -- Check to see if -r argument was passed \r
63 print("You must supply the flag -r (rfid tag)")\r
64 print(usage)\r
65 return\r
66 end\r
67 -- Check what RFID Tag we are using\r
68 if rfidtag == 'pyramid' then -- For eaach RFID Tag:\r
69 consolecommand = 'lf pyramid sim' -- Set the console command\r
70 rfidtagname = 'Farpointe/Pyramid' -- Set the display name\r
71 facilityrequired = 1 -- Set if FC is required\r
72 elseif rfidtag == 'awid' then\r
73 consolecommand = 'lf awid sim'\r
74 rfidtagname = 'AWID'\r
75 facilityrequired = 1\r
76 elseif rfidtag == 'fdx' then -- I'm not sure why you would need to bruteforce this ¯\_(ツ)_/¯ \r
77 consolecommand = 'lf fdx sim'\r
78 rfidtagname = 'FDX-B'\r
79 facilityrequired = 1\r
80 elseif rfidtag == 'jablotron' then\r
81 consolecommand = 'lf jablotron sim'\r
82 rfidtagname = 'Jablotron'\r
83 facilityrequired = 0\r
84 elseif rfidtag == 'noralsy' then\r
85 consolecommand = 'lf noralsy sim'\r
86 rfidtagname = 'Noralsy'\r
87 facilityrequired = 0\r
88 elseif rfidtag == 'presco' then\r
89 consolecommand = 'lf presco sim d'\r
90 rfidtagname = 'Presco'\r
91 facilityrequired = 0\r
92 elseif rfidtag == 'visa2000' then\r
93 consolecommand = 'lf visa2000 sim'\r
94 rfidtagname = 'Visa2000'\r
95 facilityrequired = 0\r
96 elseif rfidtag == '14a' then\r
97 consolecommand = 'hf 14a sim'\r
98 if facility == "1" then rfidtagname = 'MIFARE Classic' -- Here we use the -f option to read the 14a type instead of the facility code\r
99 elseif facility == "2" then rfidtagname = 'MIFARE Ultralight'\r
100 elseif facility == "3" then rfidtagname = 'MIFARE Desfire'\r
101 elseif facility == "4" then rfidtagname = 'ISO/IEC 14443-4'\r
102 elseif facility == "5" then rfidtagname = 'MIFARE Tnp3xxx'\r
103 else \r
104 print("Invalid 14a type (-f) supplied. Must be 1-5")\r
105 print(usage)\r
106 return\r
107 end\r
108 facilityrequired = 0 -- Disable the FC required check, as we used it for type instead of FC\r
109 elseif rfidtag == 'hid' then\r
110 consolecommand = 'lf hid sim'\r
111 rfidtagname = 'HID'\r
112 facilityrequired = 1\r
113 else -- Display error and exit out if bad RFID tag was supplied\r
114 print("Invalid rfid tag (-r) supplied")\r
115 print(usage)\r
116 return\r
117 end\r
118 \r
119 if isempty(baseid) then -- Display error and exit out if no starting id is set\r
120 print("You must supply the flag -b (base id)")\r
121 print(usage)\r
122 return\r
123 end\r
124\r
125 if isempty(count) then -- Display error and exit out of no count is set\r
126 print("You must supply the flag -c (count)")\r
127 print(usage)\r
128 return\r
129 end\r
130 \r
131 if facilityrequired == 1 then -- If FC is required\r
132 facilitymessage = " - Facility Code: " -- Add FC to status message\r
133 if isempty(facility) then -- If FC was left blank, display warning and set FC to 0 \r
134 print("Using 0 for the facility code as -f was not supplied")\r
135 facility = 0 \r
136 end\r
137 else -- If FC is not required\r
138 facility = "" -- Clear FC\r
139 facilitymessage = "" -- Remove FC from status message\r
140 end\r
141 \r
142 if isempty(timeout) then -- If timeout was not supplied, show warning and set timeout to 0\r
143 print("Using 0 for the timeout as -t was not supplied")\r
144 timeout = 0 \r
145 end\r
146 \r
147 if isempty(direction) then -- If direction was not supplied, show warning and set direction to down\r
148 print("Using down for direction as -d was not supplied")\r
149 direction = 'down' \r
150 end\r
151 \r
152 if tonumber(count) < 1 then\r
153 print("Count -c must be set to 1 or higher")\r
154 return\r
155 else\r
156 count = count -1 -- Make our count accurate by removing 1, because math\r
157 end \r
158 \r
159 if direction == 'down' then -- If counting down, set up our for loop to count down\r
160 endid = baseid - count\r
161 fordirection = -1\r
162 elseif direction == 'up' then -- If counting up, set our for loop to count up\r
163 endid = baseid + count\r
164 fordirection = 1\r
165 else -- If invalid direction was set, show warning and set up our for loop to count down\r
166 print("Invalid direction (-d) supplied, using down")\r
167 endid = baseid - count\r
168 fordirection = -1\r
169 end\r
170 \r
171 -- The code below was blatantly stolen from Brian Redbeard's lf_bulk_program.lua script \r
172 function toBits(num,bits)\r
173 bits = bits or math.max(1, select(2, math.frexp(num)))\r
174 local t = {}\r
175 for b = bits, 1, -1 do\r
176 t[b] = math.fmod(num, 2)\r
177 num = math.floor((num - t[b]) / 2)\r
178 end\r
179 return table.concat(t)\r
180 end\r
181\r
182 local function evenparity(s)\r
183 local _, count = string.gsub(s, "1", "")\r
184 local p = count % 2\r
185 if (p == 0) then\r
186 return(false)\r
187 else\r
188 return(true)\r
189 end\r
190 end\r
191 \r
192 local function isempty(s)\r
193 return s == nil or s == ''\r
194 end\r
195\r
196 local function cardHex(i,f)\r
197 fac = bit32.lshift(f,16)\r
198 id = bit32.bor(i, fac)\r
199 stream=toBits(id,26)\r
200 high = evenparity(string.sub(stream,0,12)) and 1 or 0\r
201 low = not evenparity(string.sub(stream,13)) and 1 or 0\r
202 bits = bit32.bor(bit32.lshift(id,1), low)\r
203 bits = bit32.bor(bits, bit32.lshift(high,25))\r
204 preamble = bit32.bor(0, bit32.lshift(1,5))\r
205 bits = bit32.bor(bits, bit32.lshift(1,26))\r
206 return ("%04x%08x"):format(preamble,bits)\r
207 end\r
208 -- End stolen code \r
209 \r
210 \r
211 print("") -- Display status message\r
212 print("BruteForcing "..rfidtagname..""..facilitymessage..""..facility.." - CardNumber Start: "..baseid.." - CardNumber End: "..endid.." - TimeOut: "..timeout)\r
213 print("")\r
214 for cardnum = baseid,endid,fordirection do -- Loop through for each count (-c)\r
215 if rfidtag == 'hid' then cardnum = cardHex(cardnum, facility) end -- If rfid tag is set to HID, convert card to HEX using the stolen code above \r
216 core.console(consolecommand..' '..facility..' '..cardnum) -- Send command to proxmark\r
217 if timeout == 'pause' then -- If timeout is set to pause, wait for user input\r
218 print("Press enter to continue ...")\r
219 io.read()\r
220 else -- Otherwise sleep for timeout duration\r
221 os.execute("sleep "..timeout.."")\r
222 end\r
223 end\r
224 core.console('hw ping') -- Ping the proxmark to stop emulation and see if its still responding\r
225 \r
226end -- Go bye bye\r
227\r
228\r
229main(args) -- Do the thing\r
Impressum, Datenschutz