From 81ccfa734ed89abf04e107537ef0b6b1d9cd8365 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 25 Nov 2017 07:58:56 +0100 Subject: [PATCH] add: 'script run brutesim' - new script to show simple bruteforce by incrementing cardnumber against different readers. Both LF & HF. @kenzycarey (adjusted to fit into same script structure like the rest in iceman fork) --- client/scripts/brutesim.lua | 297 ++++++++++++++++++++++++++++++++++++ 1 file changed, 297 insertions(+) create mode 100644 client/scripts/brutesim.lua diff --git a/client/scripts/brutesim.lua b/client/scripts/brutesim.lua new file mode 100644 index 000000000..c438333ef --- /dev/null +++ b/client/scripts/brutesim.lua @@ -0,0 +1,297 @@ +local getopt = require('getopt') + +copyright = '' +author = 'Kenzy Carey' +version = '' +desc = [[ + + .-----------------------------------------------------------------. + / .-. .-. \ +| / \ BruteSim / \ | +| |\_. | (bruteforce simulation for multiple tags) | /| | +|\| | /| by |\ | |/| +| `---' | Kenzy Carey | `---' | +| | | | +| |-----------------------------------------------------| | +\ | | / + \ / \ / + `---' `---' + +*SUPPORTED TAGS: pyramid, awid, fdx, jablotron, noralsy, presco, visa2000, 14a, hid + +This script uses the proxmark3 implementations of simulation to bruteforce given ranges of id. +It uses both LF and HF simulations. + + -- Author note + -- I wrote this as i was doing a PACS audit. This is far from complete, but is easily expandable. + -- The idea was based on proxbrute, but i needed more options, and support for different readers. + -- I dont know LUA, so I used Brian Redbeards lf_bulk_program.lua script as a starting point, sorry if its kludgy. + +]] +example = [[ + -- (the above example would bruteforce pyramid tags, starting at 10:1000, ending at 10:991, and waiting 1 second between each card) + + script run brutesim -r pyramid -f 10 -b 1000 -c 10 -t 1 -d down +]] +usage = [[ + +script run brutesim -r rfid_tag -f facility_code -b base_card_number -c count -t timeout -d direction + +Arguments: + -h this help + -r *see below RFID Tag: the RFID tag to emulate + pyramid + awid + fdx + jablotron + noralsy + presco + visa2000 + 14a + hid + + -f 0-999 facility code (dfx: country id, 14a: type) + -b 0-65535 base card number to start from + -c 1-65536 number of cards to try + -t .0-99999, pause timeout between cards (use the word 'pause' to wait for user input) + -d up, down direction to move through card numbers +]] + +local DEBUG = true +local bor = bit32.bor +local bxor = bit32.bxor +local lshift = bit32.lshift +--- +-- A debug printout-function +local function dbg(args) + if type(args) == "table" then + local i = 1 + while args[i] do + dbg(args[i]) + i = i+1 + end + else + print("###", args) + end +end +--- +-- This is only meant to be used when errors occur +local function oops(err) + print("ERROR: ",err) + return nil,err +end +--- +-- Usage help +local function help() + print(copyright) + print(version) + print(desc) + print("Example usage") + print(example) +end +-- +-- Exit message +function exitMsg(msg) + print( string.rep('--',20) ) + print( string.rep('--',20) ) + print(msg) + print() +end +-- +-- Check if a string is empty +local function isempty(s) + return s == nil or s == '' +end + +-- The code below was blatantly stolen from Brian Redbeard's lf_bulk_program.lua script +local function toBits(num, bits) + bits = bits or math.max(1, select(2, math.frexp(num))) + local t = {} + for b = bits, 1, -1 do + t[b] = math.fmod(num, 2) + num = math.floor((num - t[b]) / 2) + end + return table.concat(t) +end +-- +-- check for parity in bit-string. +local function evenparity(s) + local _, count = string.gsub(s, "1", "") + local p = count % 2 + if (p == 0) then + return false + end + return true +end +-- +-- calcs hex for HID +local function cardHex(i, f) + fac = lshift(f, 16) + id = bor(i, fac) + stream = toBits(id, 26) + high = evenparity(string.sub(stream, 0, 12)) and 1 or 0 + low = not evenparity(string.sub(stream, 13)) and 1 or 0 + bits = bor(lshift(id, 1), low) + bits = bor(bits, lshift(high, 25)) + preamble = bor(0, lshift(1, 5)) + bits = bor(bits, lshift(1, 26)) + return ("%04x%08x"):format(preamble, bits) +end +-- +-- +local function main(args) + + print( string.rep('--',20) ) + print( string.rep('--',20) ) + print() + + for o, a in getopt.getopt(args, 'r:f:b:c:t:d:h') do -- Populate command like arguments + if o == 'r' then rfidtag = a end + if o == 'f' then facility = a end + if o == 'b' then baseid = a end + if o == 'c' then count = a end + if o == 't' then timeout = a end + if o == 'd' then direction = a end + if o == 'h' then return print(usage) end + end + + -- Check to see if -r argument was passed + if isempty(rfidtag) then + print("You must supply the flag -r (rfid tag)") + print(usage) + return + end + + -- Check what RFID Tag we are using + if rfidtag == 'pyramid' then + consolecommand = 'lf pyramid sim' -- set the console command + rfidtagname = 'Farpointe/Pyramid' -- set the display name + facilityrequired = 1 -- set if FC is required + elseif rfidtag == 'awid' then + consolecommand = 'lf awid sim' + rfidtagname = 'AWID' + facilityrequired = 1 + elseif rfidtag == 'fdx' then -- I'm not sure why you would need to bruteforce this ¯\_(ツ)_/¯ + consolecommand = 'lf fdx sim' + rfidtagname = 'FDX-B' + facilityrequired = 1 + elseif rfidtag == 'jablotron' then + consolecommand = 'lf jablotron sim' + rfidtagname = 'Jablotron' + facilityrequired = 0 + elseif rfidtag == 'noralsy' then + consolecommand = 'lf noralsy sim' + rfidtagname = 'Noralsy' + facilityrequired = 0 + elseif rfidtag == 'presco' then + consolecommand = 'lf presco sim d' + rfidtagname = 'Presco' + facilityrequired = 0 + elseif rfidtag == 'visa2000' then + consolecommand = 'lf visa2000 sim' + rfidtagname = 'Visa2000' + facilityrequired = 0 + elseif rfidtag == '14a' then + consolecommand = 'hf 14a sim' + if facility == "1" then rfidtagname = 'MIFARE Classic' -- Here we use the -f option to read the 14a type instead of the facility code + elseif facility == "2" then rfidtagname = 'MIFARE Ultralight' + elseif facility == "3" then rfidtagname = 'MIFARE Desfire' + elseif facility == "4" then rfidtagname = 'ISO/IEC 14443-4' + elseif facility == "5" then rfidtagname = 'MIFARE Tnp3xxx' + else + print("Invalid 14a type (-f) supplied. Must be 1-5") + print(usage) + return + end + facilityrequired = 0 -- Disable the FC required check, as we used it for type instead of FC + elseif rfidtag == 'hid' then + consolecommand = 'lf hid sim' + rfidtagname = 'HID' + facilityrequired = 1 + else -- Display error and exit out if bad RFID tag was supplied + print("Invalid rfid tag (-r) supplied") + print(usage) + return + end + + if isempty(baseid) then -- Display error and exit out if no starting id is set + print("You must supply the flag -b (base id)") + print(usage) + return + end + + if isempty(count) then -- Display error and exit out of no count is set + print("You must supply the flag -c (count)") + print(usage) + return + end + + if facilityrequired == 1 then -- If FC is required + facilitymessage = " - Facility Code: " -- Add FC to status message + if isempty(facility) then -- If FC was left blank, display warning and set FC to 0 + print("Using 0 for the facility code as -f was not supplied") + facility = 0 + end + else -- If FC is not required + facility = "" -- Clear FC + facilitymessage = "" -- Remove FC from status message + end + + if isempty(timeout) then -- If timeout was not supplied, show warning and set timeout to 0 + print("Using 0 for the timeout as -t was not supplied") + timeout = 0 + end + + if isempty(direction) then -- If direction was not supplied, show warning and set direction to down + print("Using down for direction as -d was not supplied") + direction = 'down' + end + + if tonumber(count) < 1 then + print("Count -c must be set to 1 or higher") + return + else + count = count -1 -- Make our count accurate by removing 1, because math + end + + if direction == 'down' then -- If counting down, set up our for loop to count down + endid = baseid - count + fordirection = -1 + elseif direction == 'up' then -- If counting up, set our for loop to count up + endid = baseid + count + fordirection = 1 + else -- If invalid direction was set, show warning and set up our for loop to count down + print("Invalid direction (-d) supplied, using down") + endid = baseid - count + fordirection = -1 + end + + + + -- display status message + print("") + print("BruteForcing "..rfidtagname..""..facilitymessage..""..facility.." - CardNumber Start: "..baseid.." - CardNumber End: "..endid.." - TimeOut: "..timeout) + print("") + + -- loop through for each count (-c) + for cardnum = baseid, endid, fordirection do + + -- If rfid tag is set to HID, convert card to HEX using the stolen code above + if rfidtag == 'hid' then cardnum = cardHex(cardnum, facility) end + + -- send command to proxmark + core.console(consolecommand..' '..facility..' '..cardnum) + + if timeout == 'pause' then + print("Press enter to continue ...") + io.read() + else + os.execute("sleep "..timeout.."") + end + end + + -- ping the proxmark to stop emulation and see if its still responding + core.console('hw ping') +end + +main(args) \ No newline at end of file