3 .-----------------------------------------------------------------.
6 | |\_. | (bruteforce simulation for multiple tags) | /| |
8 | `---' | Kenzy Carey | `---' |
10 | |-----------------------------------------------------| |
15 author
= [[ Kenzy Carey ]]
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
30 *SUPPORTED TAGS: pyramid, awid, fdx, jablotron, noralsy, presco, visa2000, 14a, hid
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)
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.
41 getopt
= require('getopt') -- Used to get get command line arguments
42 bit32
= require('bit32') -- Used to convert FC/CN to hex
44 local function isempty(s
) -- Check if a string is empty
45 return s
== nil or s
== ''
48 local function main(args
)
50 print("") -- Print a blank line to make things look cleaner
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
62 if isempty(rfidtag
) then -- Check to see if -r argument was passed
63 print("You must supply the flag -r (rfid tag)")
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'
76 elseif rfidtag
== 'fdx' then -- I'm not sure why you would need to bruteforce this ¯\_(ツ)_/¯
77 consolecommand
= 'lf fdx sim'
80 elseif rfidtag
== 'jablotron' then
81 consolecommand
= 'lf jablotron sim'
82 rfidtagname
= 'Jablotron'
84 elseif rfidtag
== 'noralsy' then
85 consolecommand
= 'lf noralsy sim'
86 rfidtagname
= 'Noralsy'
88 elseif rfidtag
== 'presco' then
89 consolecommand
= 'lf presco sim d'
90 rfidtagname
= 'Presco'
92 elseif rfidtag
== 'visa2000' then
93 consolecommand
= 'lf visa2000 sim'
94 rfidtagname
= 'Visa2000'
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'
104 print("Invalid 14a type (-f) supplied. Must be 1-5")
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'
113 else -- Display error and exit out if bad RFID tag was supplied
114 print("Invalid rfid tag (-r) supplied")
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)")
125 if isempty(count
) then -- Display error and exit out of no count is set
126 print("You must supply the flag -c (count)")
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")
137 else -- If FC is not required
138 facility
= "" -- Clear FC
139 facilitymessage
= "" -- Remove FC from status message
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")
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")
152 if tonumber(count
) < 1 then
153 print("Count -c must be set to 1 or higher")
156 count
= count
-1 -- Make our count accurate by removing 1, because math
159 if direction
== 'down' then -- If counting down, set up our for loop to count down
160 endid
= baseid
- count
162 elseif direction
== 'up' then -- If counting up, set our for loop to count up
163 endid
= baseid
+ count
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
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
)))
175 for b
= bits
, 1, -1 do
176 t
[b
] = math
.fmod(num
, 2)
177 num
= math
.floor((num
- t
[b
]) / 2)
179 return table.concat(t
)
182 local function evenparity(s
)
183 local _
, count
= string.gsub(s
, "1", "")
192 local function isempty(s
)
193 return s
== nil or s
== ''
196 local function cardHex(i
,f
)
197 fac
= bit32
.lshift(f
,16)
198 id
= bit32
.bor(i
, fac
)
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
)
211 print("") -- Display status message
212 print("BruteForcing "..rfidtagname
..""..facilitymessage
..""..facility
.." - CardNumber Start: "..baseid
.." - CardNumber End: "..endid
.." - TimeOut: "..timeout
)
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 ...")
220 else -- Otherwise sleep for timeout duration
221 os
.execute("sleep "..timeout
.."")
224 core
.console('hw ping') -- Ping the proxmark to stop emulation and see if its still responding
229 main(args
) -- Do the thing