mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 13:00:42 -07:00
Merge branch 'master' into update_4x50
update 201130 2
This commit is contained in:
commit
9d52801259
9 changed files with 341 additions and 18 deletions
|
@ -95,7 +95,7 @@ void RunMod(void) {
|
||||||
|
|
||||||
WAIT_BUTTON_RELEASED();
|
WAIT_BUTTON_RELEASED();
|
||||||
|
|
||||||
CopyHIDtoT55x7(0, high[selected], low[selected], 0);
|
CopyHIDtoT55x7(0, high[selected], low[selected], 0, false, false);
|
||||||
Dbprintf("[=] cloned %x %x %08x", selected, high[selected], low[selected]);
|
Dbprintf("[=] cloned %x %x %08x", selected, high[selected], low[selected]);
|
||||||
|
|
||||||
LEDsoff();
|
LEDsoff();
|
||||||
|
|
|
@ -121,7 +121,7 @@ void RunMod(void) {
|
||||||
Dbprintf("[=] cloning %x | %x%08x", selected, high[selected], low[selected]);
|
Dbprintf("[=] cloning %x | %x%08x", selected, high[selected], low[selected]);
|
||||||
|
|
||||||
// high2, high, low, no longFMT
|
// high2, high, low, no longFMT
|
||||||
CopyHIDtoT55x7(0, high[selected], low[selected], 0);
|
CopyHIDtoT55x7(0, high[selected], low[selected], 0, false, false);
|
||||||
|
|
||||||
DbpString("[=] cloned done");
|
DbpString("[=] cloned done");
|
||||||
|
|
||||||
|
|
|
@ -874,7 +874,7 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
}
|
}
|
||||||
case CMD_LF_HID_CLONE: {
|
case CMD_LF_HID_CLONE: {
|
||||||
lf_hidsim_t *payload = (lf_hidsim_t *)packet->data.asBytes;
|
lf_hidsim_t *payload = (lf_hidsim_t *)packet->data.asBytes;
|
||||||
CopyHIDtoT55x7(payload->hi2, payload->hi, payload->lo, payload->longFMT);
|
CopyHIDtoT55x7(payload->hi2, payload->hi, payload->lo, payload->longFMT, payload->Q5, payload->EM);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_LF_IO_WATCH: {
|
case CMD_LF_IO_WATCH: {
|
||||||
|
|
|
@ -2190,10 +2190,8 @@ void T55xxWakeUp(uint32_t pwd, uint8_t flags) {
|
||||||
reply_ng(CMD_LF_T55XX_WAKEUP, PM3_SUCCESS, NULL, 0);
|
reply_ng(CMD_LF_T55XX_WAKEUP, PM3_SUCCESS, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*-------------- Cloning routines -----------*/
|
/*-------------- Cloning routines -----------*/
|
||||||
static void WriteT55xx(uint32_t *blockdata, uint8_t startblock, uint8_t numblocks) {
|
static void WriteT55xx(uint32_t *blockdata, uint8_t startblock, uint8_t numblocks) {
|
||||||
|
|
||||||
t55xx_write_block_t cmd;
|
t55xx_write_block_t cmd;
|
||||||
cmd.pwd = 0;
|
cmd.pwd = 0;
|
||||||
cmd.flags = 0;
|
cmd.flags = 0;
|
||||||
|
@ -2203,11 +2201,18 @@ static void WriteT55xx(uint32_t *blockdata, uint8_t startblock, uint8_t numblock
|
||||||
cmd.blockno = i - 1;
|
cmd.blockno = i - 1;
|
||||||
T55xxWriteBlock((uint8_t *)&cmd);
|
T55xxWriteBlock((uint8_t *)&cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
/* disabled until verified.
|
||||||
|
static void WriteEM4x05(uint32_t *blockdata, uint8_t startblock, uint8_t numblocks) {
|
||||||
|
for (uint8_t i = numblocks + startblock; i > startblock; i--) {
|
||||||
|
EM4xWriteWord(i - 1, blockdata[i - 1], 0, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
// Copy HID id to card and setup block 0 config
|
// Copy HID id to card and setup block 0 config
|
||||||
void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT) {
|
void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT, bool q5, bool em) {
|
||||||
uint32_t data[] = {0, 0, 0, 0, 0, 0, 0};
|
uint32_t data[] = {0, 0, 0, 0, 0, 0, 0};
|
||||||
uint8_t last_block = 0;
|
uint8_t last_block = 0;
|
||||||
|
|
||||||
|
@ -2244,11 +2249,21 @@ void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT) {
|
||||||
data[0] = T55x7_BITRATE_RF_50 | T55x7_MODULATION_FSK2a | last_block << T55x7_MAXBLOCK_SHIFT;
|
data[0] = T55x7_BITRATE_RF_50 | T55x7_MODULATION_FSK2a | last_block << T55x7_MAXBLOCK_SHIFT;
|
||||||
|
|
||||||
//TODO add selection of chip for Q5 or T55x7
|
//TODO add selection of chip for Q5 or T55x7
|
||||||
// data[0] = T5555_SET_BITRATE(50) | T5555_MODULATION_FSK2 | T5555_INVERT_OUTPUT | last_block << T5555_MAXBLOCK_SHIFT;
|
if (q5) {
|
||||||
|
data[0] = T5555_SET_BITRATE(50) | T5555_MODULATION_FSK2 | T5555_INVERT_OUTPUT | last_block << T5555_MAXBLOCK_SHIFT;
|
||||||
|
} else if (em) {
|
||||||
|
data[0] = (EM4x05_SET_BITRATE(50) | EM4x05_MODULATION_FSK2 | EM4x05_INVERT | EM4x05_SET_NUM_BLOCKS(last_block));
|
||||||
|
}
|
||||||
|
|
||||||
LED_D_ON();
|
LED_D_ON();
|
||||||
|
if (em) {
|
||||||
|
Dbprintf("Clone HID Prox to EM4x05 is untested and disabled until verified");
|
||||||
|
//WriteEM4x05(data, 0, last_block + 1);
|
||||||
|
} else {
|
||||||
WriteT55xx(data, 0, last_block + 1);
|
WriteT55xx(data, 0, last_block + 1);
|
||||||
|
}
|
||||||
LED_D_OFF();
|
LED_D_OFF();
|
||||||
|
reply_ng(CMD_LF_HID_CLONE, PM3_SUCCESS, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// clone viking tag to T55xx
|
// clone viking tag to T55xx
|
||||||
|
@ -2265,7 +2280,12 @@ void CopyVikingtoT55xx(uint8_t *blocks, bool q5, bool em) {
|
||||||
data[2] = bytes_to_num(blocks + 4, 4);
|
data[2] = bytes_to_num(blocks + 4, 4);
|
||||||
|
|
||||||
// Program the data blocks for supplied ID and the block 0 config
|
// Program the data blocks for supplied ID and the block 0 config
|
||||||
|
if (em) {
|
||||||
|
Dbprintf("Clone Viking to EM4x05 is untested and disabled until verified");
|
||||||
|
//WriteEM4x05(data, 0, 3);
|
||||||
|
} else {
|
||||||
WriteT55xx(data, 0, 3);
|
WriteT55xx(data, 0, 3);
|
||||||
|
}
|
||||||
LED_D_OFF();
|
LED_D_OFF();
|
||||||
reply_ng(CMD_LF_VIKING_CLONE, PM3_SUCCESS, NULL, 0);
|
reply_ng(CMD_LF_VIKING_CLONE, PM3_SUCCESS, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,8 +39,7 @@ int lf_awid_watch(int findone, uint32_t *high, uint32_t *low); // Realtime demod
|
||||||
int lf_em410x_watch(int findone, uint32_t *high, uint64_t *low);
|
int lf_em410x_watch(int findone, uint32_t *high, uint64_t *low);
|
||||||
int lf_io_watch(int findone, uint32_t *high, uint32_t *low);
|
int lf_io_watch(int findone, uint32_t *high, uint32_t *low);
|
||||||
|
|
||||||
void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT); // Clone an HID card to T5557/T5567
|
void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT, bool q5, bool em); // Clone an HID card to T5557/T5567
|
||||||
|
|
||||||
void CopyVikingtoT55xx(uint8_t *blocks, bool q5, bool em);
|
void CopyVikingtoT55xx(uint8_t *blocks, bool q5, bool em);
|
||||||
|
|
||||||
int copy_em410x_to_t55xx(uint8_t card, uint8_t clock, uint32_t id_hi, uint32_t id_lo);
|
int copy_em410x_to_t55xx(uint8_t card, uint8_t clock, uint32_t id_hi, uint32_t id_lo);
|
||||||
|
|
82
client/luascripts/mfc_hammerlite.lua
Normal file
82
client/luascripts/mfc_hammerlite.lua
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
local getopt = require('getopt')
|
||||||
|
local lib14a = require('read14a')
|
||||||
|
local cmds = require('commands')
|
||||||
|
local ansicolors = require('ansicolors')
|
||||||
|
|
||||||
|
copyright = 'Copyright 2020 A. Ozkal, released under GPLv2+.'
|
||||||
|
author = 'Ave'
|
||||||
|
version = 'v0.1.1'
|
||||||
|
desc = [[
|
||||||
|
This script writes a bunch of random blocks to a Mifare Classic card
|
||||||
|
]]
|
||||||
|
example = [[
|
||||||
|
script run mfc_hammerlite -w 1000 -k FFFFFFFFFFFF
|
||||||
|
]]
|
||||||
|
usage = [[
|
||||||
|
script run mfc_hammerlite [-h] [-w <writecount>] [-k <key>]
|
||||||
|
]]
|
||||||
|
arguments = [[
|
||||||
|
-h : This help
|
||||||
|
-w <writeroundcount> : Amount of write rounds to be done to each block (optional, default: 100)
|
||||||
|
-k <key> : A key for the sectors
|
||||||
|
]]
|
||||||
|
|
||||||
|
local function help()
|
||||||
|
print(author)
|
||||||
|
print(version)
|
||||||
|
print(desc)
|
||||||
|
print(ansicolors.cyan..'Usage'..ansicolors.reset)
|
||||||
|
print(usage)
|
||||||
|
print(ansicolors.cyan..'Arguments'..ansicolors.reset)
|
||||||
|
print(arguments)
|
||||||
|
print(ansicolors.cyan..'Example usage'..ansicolors.reset)
|
||||||
|
print(example)
|
||||||
|
end
|
||||||
|
|
||||||
|
function randhex(len)
|
||||||
|
result = ""
|
||||||
|
for i = 1,len,1
|
||||||
|
do
|
||||||
|
-- 48-57 numbers, 65-70 a-f
|
||||||
|
hex = math.random(0, 15)
|
||||||
|
if hex >= 10 then
|
||||||
|
hex = hex + 7
|
||||||
|
end
|
||||||
|
result = result..string.char(48 + hex)
|
||||||
|
end
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
---
|
||||||
|
-- The main entry point
|
||||||
|
function main(args)
|
||||||
|
-- param defaults
|
||||||
|
loopcount = 100
|
||||||
|
verifyevery = 10
|
||||||
|
key = "FFFFFFFFFFFF"
|
||||||
|
|
||||||
|
-- Read the parameters
|
||||||
|
for o, a in getopt.getopt(args, 'hw:k:') do
|
||||||
|
if o == 'h' then return help() end
|
||||||
|
if o == 'w' then loopcount = tonumber(a) end
|
||||||
|
if o == 'k' then key = a end
|
||||||
|
end
|
||||||
|
|
||||||
|
starttime = os.time()
|
||||||
|
|
||||||
|
for i = 1,loopcount,1
|
||||||
|
do
|
||||||
|
for a = 1,63,1
|
||||||
|
do
|
||||||
|
if ((a + 1) % 4 ~= 0) and a ~= 0 then -- :)
|
||||||
|
data = randhex(32)
|
||||||
|
-- core.console('hf mf rdbl '..a..' A FFFFFFFFFFFF')
|
||||||
|
core.console('hf mf wrbl '..a..' A '..key..' '..data)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
print("Hammering complete.")
|
||||||
|
end
|
||||||
|
|
||||||
|
main(args)
|
189
client/luascripts/ntag_hammertime.lua
Normal file
189
client/luascripts/ntag_hammertime.lua
Normal file
|
@ -0,0 +1,189 @@
|
||||||
|
local getopt = require('getopt')
|
||||||
|
local lib14a = require('read14a')
|
||||||
|
local cmds = require('commands')
|
||||||
|
local ansicolors = require('ansicolors')
|
||||||
|
|
||||||
|
copyright = 'Copyright 2020 A. Ozkal, released under GPLv2+.'
|
||||||
|
author = 'Ave'
|
||||||
|
version = 'v2.1.3'
|
||||||
|
desc = [[
|
||||||
|
This script writes a bunch of random blocks to a NTAG or MFUL card to test its actual write limits
|
||||||
|
]]
|
||||||
|
example = [[
|
||||||
|
script run ntag_hammertime -w 1000 -r 50 -z 50 -f 5 -s 4 -e 129
|
||||||
|
]]
|
||||||
|
usage = [[
|
||||||
|
script run ntag_hammertime [-h] [-w <writecount>] [-r <readevery>] [-z <reselectevery>] [-f <maximumfails>] [-s <writestartblock>] [-e <writeendblock>]
|
||||||
|
]]
|
||||||
|
arguments = [[
|
||||||
|
-h : This help
|
||||||
|
-w <writeroundcount> : Amount of write rounds to be done to each block (optional, default: 100)
|
||||||
|
-r <readevery> : Verify frequency (reads and checks written values every x rounds, optional, default: 10)
|
||||||
|
-z <reselectevery> : Reselect frequency (reselects card once every x rounds, optional, default: 10)
|
||||||
|
-f <maximumfails> : Maximum consequent fails (read/write) that will trigger a fail state (optional, default: 3)
|
||||||
|
-s <writestartblock> : Block number for writes to be started to (optional, inclusive, decimal, default: 4)
|
||||||
|
-e <writeendblock> : Block number for writes to be ended on (optional, inclusive, decimal, default: 129)
|
||||||
|
]]
|
||||||
|
|
||||||
|
local function help()
|
||||||
|
print(author)
|
||||||
|
print(version)
|
||||||
|
print(desc)
|
||||||
|
print(ansicolors.cyan..'Usage'..ansicolors.reset)
|
||||||
|
print(usage)
|
||||||
|
print(ansicolors.cyan..'Arguments'..ansicolors.reset)
|
||||||
|
print(arguments)
|
||||||
|
print(ansicolors.cyan..'Example usage'..ansicolors.reset)
|
||||||
|
print(example)
|
||||||
|
end
|
||||||
|
|
||||||
|
function randhex(len)
|
||||||
|
result = ""
|
||||||
|
for i = 1,len,1
|
||||||
|
do
|
||||||
|
-- 48-57 numbers, 65-70 a-f
|
||||||
|
hex = math.random(0, 15)
|
||||||
|
if hex >= 10 then
|
||||||
|
hex = hex + 7
|
||||||
|
end
|
||||||
|
result = result..string.char(48 + hex)
|
||||||
|
end
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Used to send raw data to the firmware to subsequently forward the data to the card.
|
||||||
|
-- from mifareplus.lua
|
||||||
|
local function sendRaw(rawdata, crc, power)
|
||||||
|
-- print(("<sent>: %s"):format(rawdata))
|
||||||
|
|
||||||
|
local flags = lib14a.ISO14A_COMMAND.ISO14A_RAW
|
||||||
|
if crc then
|
||||||
|
flags = flags + lib14a.ISO14A_COMMAND.ISO14A_APPEND_CRC
|
||||||
|
end
|
||||||
|
if power then
|
||||||
|
flags = flags + lib14a.ISO14A_COMMAND.ISO14A_NO_DISCONNECT
|
||||||
|
end
|
||||||
|
|
||||||
|
local command = Command:newMIX{cmd = cmds.CMD_HF_ISO14443A_READER,
|
||||||
|
arg1 = flags, -- Send raw
|
||||||
|
arg2 = string.len(rawdata) / 2, -- arg2 contains the length, which is half the length of the ASCII-string rawdata
|
||||||
|
data = rawdata
|
||||||
|
}
|
||||||
|
local ignore_response = false
|
||||||
|
local result, err = command:sendMIX(ignore_response)
|
||||||
|
if result then
|
||||||
|
--unpack the first 4 parts of the result as longs, and the last as an extremely long string to later be cut down based on arg1, the number of bytes returned
|
||||||
|
local count,cmd,arg1,arg2,arg3,data = bin.unpack('LLLLH512',result)
|
||||||
|
|
||||||
|
returned_bytes = string.sub(data, 1, arg1 * 2)
|
||||||
|
if #returned_bytes > 0 then
|
||||||
|
-- print(("<recvd>: %s"):format(returned_bytes)) -- need to multiply by 2 because the hex digits are actually two bytes when they are strings
|
||||||
|
return returned_bytes
|
||||||
|
else
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
else
|
||||||
|
print("Error sending the card raw data.")
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function selectCard(keepField, arg2, attemptCount)
|
||||||
|
for i = 1,attemptCount,1
|
||||||
|
do
|
||||||
|
if lib14a.read(keepField, arg2) then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
---
|
||||||
|
-- The main entry point
|
||||||
|
function main(args)
|
||||||
|
failcounter = 0
|
||||||
|
|
||||||
|
-- param defaults
|
||||||
|
loopcount = 100
|
||||||
|
verifyevery = 10
|
||||||
|
reselectevery = 10
|
||||||
|
failmax = 3
|
||||||
|
blockstart = 4
|
||||||
|
blockend = 129
|
||||||
|
|
||||||
|
-- Read the parameters
|
||||||
|
for o, a in getopt.getopt(args, 'hw:r:z:f:s:e:') do
|
||||||
|
if o == 'h' then return help() end
|
||||||
|
if o == 'w' then loopcount = tonumber(a) end
|
||||||
|
if o == 'r' then verifyevery = tonumber(a) end
|
||||||
|
if o == 'z' then reselectevery = tonumber(a) end
|
||||||
|
if o == 'f' then failmax = tonumber(a) end
|
||||||
|
if o == 's' then blockstart = tonumber(a) end
|
||||||
|
if o == 'e' then blockend = tonumber(a) end
|
||||||
|
end
|
||||||
|
|
||||||
|
starttime = os.time()
|
||||||
|
|
||||||
|
if selectCard(true, false, 3) ~= true then
|
||||||
|
return print("Select failed.")
|
||||||
|
end
|
||||||
|
for i = 1,loopcount,1
|
||||||
|
do
|
||||||
|
for block = blockstart,blockend,1
|
||||||
|
do
|
||||||
|
data = randhex(8)
|
||||||
|
print(i..": Writing "..data.." to block "..block..".")
|
||||||
|
blockhex = string.format("%02x", block)
|
||||||
|
result = sendRaw("A2"..blockhex..data, true, true)
|
||||||
|
if result then -- if false/nil, that's a fail right there
|
||||||
|
print(ansicolors.green.."Got "..result.."."..ansicolors.reset) -- We want this to be 0A
|
||||||
|
failcounter = 0
|
||||||
|
else
|
||||||
|
print(ansicolors.red.."Write FAILED."..ansicolors.reset)
|
||||||
|
failcounter = failcounter + 1
|
||||||
|
goto continue
|
||||||
|
end
|
||||||
|
|
||||||
|
if i % verifyevery == 0 then
|
||||||
|
result = sendRaw("30"..blockhex, true, true)
|
||||||
|
if result then -- if false, that's a fail right there
|
||||||
|
result = string.sub(result, 0, 8)
|
||||||
|
if result ~= data then
|
||||||
|
print(ansicolors.red.."Read IMPROPER, supposed to be "..data..", got "..result.."."..ansicolors.reset)
|
||||||
|
failcounter = failcounter + 1
|
||||||
|
goto continue
|
||||||
|
else
|
||||||
|
print(ansicolors.green.."Read matches the write."..ansicolors.reset)
|
||||||
|
failcounter = 0
|
||||||
|
end
|
||||||
|
else
|
||||||
|
print(ansicolors.red.."Read FAILED."..ansicolors.reset)
|
||||||
|
failcounter = failcounter + 1
|
||||||
|
goto continue
|
||||||
|
end
|
||||||
|
end
|
||||||
|
::continue::
|
||||||
|
|
||||||
|
if failcounter >= failmax then
|
||||||
|
-- close field
|
||||||
|
lib14a.read(false, false)
|
||||||
|
return print(ansicolors.red.."Test failed after "..(os.time() - starttime).." seconds, "..(i*(blockend-blockstart)).." writes and "..math.floor((i*(blockend-blockstart))/verifyevery).." reads."..ansicolors.reset)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if i % reselectevery == 0 then
|
||||||
|
-- reselect
|
||||||
|
sendRaw("", false, false)
|
||||||
|
if selectCard(true, false, 3) ~= true then
|
||||||
|
return print("Reselect failed.")
|
||||||
|
end
|
||||||
|
print("Reselected card, current rate: "..(i*(blockend-blockstart))/(os.time() - starttime).." writes/s.")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- close field
|
||||||
|
lib14a.read(false, false)
|
||||||
|
print("Successfully completed test in "..(os.time() - starttime).." seconds, did "..(loopcount*(blockend-blockstart)).." writes and "..math.floor((loopcount*(blockend-blockstart))/verifyevery).." reads.")
|
||||||
|
end
|
||||||
|
|
||||||
|
main(args)
|
|
@ -167,7 +167,7 @@ static int CmdHIDDemod(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// this read is the "normal" read, which download lf signal and tries to demod here.
|
// this read is the "normal" read, which download lf signal and tries to demod here.
|
||||||
static int CmdHIDRead(const char *Cmd) {
|
static int CmdHIDReader(const char *Cmd) {
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "lf hid reader",
|
CLIParserInit(&ctx, "lf hid reader",
|
||||||
"read a HID Prox tag",
|
"read a HID Prox tag",
|
||||||
|
@ -318,6 +318,8 @@ static int CmdHIDClone(const char *Cmd) {
|
||||||
"lf hid clone -r 01f0760643c3 -> HID P10001 40 bit\n"
|
"lf hid clone -r 01f0760643c3 -> HID P10001 40 bit\n"
|
||||||
"lf hid clone -r 01400076000c86 -> HID Corporate 48 bit\n"
|
"lf hid clone -r 01400076000c86 -> HID Corporate 48 bit\n"
|
||||||
"lf hid clone -w H10301 --fc 118 --cn 1603 -> HID 10301 26 bit\n"
|
"lf hid clone -w H10301 --fc 118 --cn 1603 -> HID 10301 26 bit\n"
|
||||||
|
"lf hid clone -w H10301 --fc 118 --cn 1603 --q5 -> HID 10301 26 bit, encode for Q5/T5555 tag\n"
|
||||||
|
"lf hid clone -w H10301 --fc 118 --cn 1603 --em -> HID 10301 26 bit, encode for EM4305/4469"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
@ -329,7 +331,8 @@ static int CmdHIDClone(const char *Cmd) {
|
||||||
arg_int0("i", NULL, "<dec>", "issue level"),
|
arg_int0("i", NULL, "<dec>", "issue level"),
|
||||||
arg_int0("o", "oem", "<dec>", "OEM code"),
|
arg_int0("o", "oem", "<dec>", "OEM code"),
|
||||||
arg_strx0("r", "raw", "<hex>", "raw bytes"),
|
arg_strx0("r", "raw", "<hex>", "raw bytes"),
|
||||||
// arg_lit0("q", "Q5", "optional - specify writing to Q5/T5555 tag"),
|
arg_lit0(NULL, "q5", "optional - specify writing to Q5/T5555 tag"),
|
||||||
|
arg_lit0(NULL, "em", "optional - specify writing to EM4305/4469 tag"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
|
@ -349,9 +352,15 @@ static int CmdHIDClone(const char *Cmd) {
|
||||||
char raw[40] = {0};
|
char raw[40] = {0};
|
||||||
CLIParamStrToBuf(arg_get_str(ctx, 6), (uint8_t *)raw, sizeof(raw), &raw_len);
|
CLIParamStrToBuf(arg_get_str(ctx, 6), (uint8_t *)raw, sizeof(raw), &raw_len);
|
||||||
|
|
||||||
//bool q5 = arg_get_lit(ctx, 7);
|
bool q5 = arg_get_lit(ctx, 7);
|
||||||
|
bool em = arg_get_lit(ctx, 8);
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
|
if (q5 && em) {
|
||||||
|
PrintAndLogEx(FAILED, "Can't specify both Q5 and EM4305 at the same time");
|
||||||
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
|
|
||||||
wiegand_message_t packed;
|
wiegand_message_t packed;
|
||||||
memset(&packed, 0, sizeof(wiegand_message_t));
|
memset(&packed, 0, sizeof(wiegand_message_t));
|
||||||
|
|
||||||
|
@ -375,6 +384,17 @@ static int CmdHIDClone(const char *Cmd) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char cardtype[16] = {"T55x7"};
|
||||||
|
// Q5
|
||||||
|
if (q5) {
|
||||||
|
snprintf(cardtype, sizeof(cardtype), "Q5/T5555");
|
||||||
|
}
|
||||||
|
|
||||||
|
// EM4305
|
||||||
|
if (em) {
|
||||||
|
snprintf(cardtype, sizeof(cardtype), "EM4305/4469");
|
||||||
|
}
|
||||||
|
|
||||||
if (raw_len == 0) {
|
if (raw_len == 0) {
|
||||||
PrintAndLogEx(INFO, "Preparing to clone HID tag");
|
PrintAndLogEx(INFO, "Preparing to clone HID tag");
|
||||||
HIDTryUnpack(&packed, false);
|
HIDTryUnpack(&packed, false);
|
||||||
|
@ -387,11 +407,22 @@ static int CmdHIDClone(const char *Cmd) {
|
||||||
payload.hi = packed.Mid;
|
payload.hi = packed.Mid;
|
||||||
payload.lo = packed.Bot;
|
payload.lo = packed.Bot;
|
||||||
payload.longFMT = (packed.Mid > 0xFFF);
|
payload.longFMT = (packed.Mid > 0xFFF);
|
||||||
|
payload.Q5 = q5;
|
||||||
|
payload.EM = em;
|
||||||
|
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandNG(CMD_LF_HID_CLONE, (uint8_t *)&payload, sizeof(payload));
|
SendCommandNG(CMD_LF_HID_CLONE, (uint8_t *)&payload, sizeof(payload));
|
||||||
PrintAndLogEx(SUCCESS, "Done");
|
|
||||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf hid read`") " to verify");
|
PacketResponseNG resp;
|
||||||
|
WaitForResponse(CMD_LF_HID_CLONE, &resp);
|
||||||
|
if (resp.status == PM3_SUCCESS) {
|
||||||
|
PrintAndLogEx(INFO, "Done");
|
||||||
|
} else {
|
||||||
|
PrintAndLogEx(FAILED, "Failed cloning");
|
||||||
|
return resp.status;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf hid reader`") " to verify");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -561,7 +592,7 @@ static int CmdHIDBrute(const char *Cmd) {
|
||||||
static command_t CommandTable[] = {
|
static command_t CommandTable[] = {
|
||||||
{"help", CmdHelp, AlwaysAvailable, "this help"},
|
{"help", CmdHelp, AlwaysAvailable, "this help"},
|
||||||
{"demod", CmdHIDDemod, AlwaysAvailable, "demodulate HID Prox tag from the GraphBuffer"},
|
{"demod", CmdHIDDemod, AlwaysAvailable, "demodulate HID Prox tag from the GraphBuffer"},
|
||||||
{"read", CmdHIDRead, IfPm3Lf, "attempt to read and extract tag data"},
|
{"reader", CmdHIDReader, IfPm3Lf, "attempt to read and extract tag data"},
|
||||||
{"clone", CmdHIDClone, IfPm3Lf, "clone HID tag to T55x7"},
|
{"clone", CmdHIDClone, IfPm3Lf, "clone HID tag to T55x7"},
|
||||||
{"sim", CmdHIDSim, IfPm3Lf, "simulate HID tag"},
|
{"sim", CmdHIDSim, IfPm3Lf, "simulate HID tag"},
|
||||||
{"brute", CmdHIDBrute, IfPm3Lf, "bruteforce card number against reader"},
|
{"brute", CmdHIDBrute, IfPm3Lf, "bruteforce card number against reader"},
|
||||||
|
|
|
@ -238,6 +238,8 @@ typedef struct {
|
||||||
uint32_t hi;
|
uint32_t hi;
|
||||||
uint32_t lo;
|
uint32_t lo;
|
||||||
uint8_t longFMT;
|
uint8_t longFMT;
|
||||||
|
bool Q5;
|
||||||
|
bool EM;
|
||||||
} PACKED lf_hidsim_t;
|
} PACKED lf_hidsim_t;
|
||||||
|
|
||||||
// For CMD_LF_FSK_SIMULATE (FSK)
|
// For CMD_LF_FSK_SIMULATE (FSK)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue