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