proxmark3/client/src/cmdlfhid.c

637 lines
22 KiB
C
Raw Normal View History

//-----------------------------------------------------------------------------
// Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
// 2016,2017, marshmellow, iceman
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
// at your option, any later version. See the LICENSE.txt file for the text of
// the license.
//-----------------------------------------------------------------------------
2019-09-19 01:43:55 +08:00
// Low frequency HID commands (known)
//
// Useful resources:
// RF interface, programming a T55x7 clone, 26-bit HID H10301 encoding:
// http://www.proxmark.org/files/Documents/125%20kHz%20-%20HID/HID_format_example.pdf
//
// "Understanding Card Data Formats"
// https://www.hidglobal.com/sites/default/files/hid-understanding_card_data_formats-wp-en.pdf
//
// "What Format Do You Need?"
// https://www.hidglobal.com/sites/default/files/resource_files/hid-prox-br-en.pdf
//-----------------------------------------------------------------------------
Client cleanup and restructuring. Stage 1... Next Step is refactoring some of the giant functions which are just copy/paste of some other ones with just a few line changes, removing unnecessary 'goto' etc. The MS Windows version is broken with this commit but will be fixed soon. Everything can't be done all at once :P The commands are now hierarchical, for example: "hf 14a read" vs. "hf 14b read". You can also request help: "hf help", "data help", "hf 15 help" etc. Indents are now space-based, not tab-based anymore. Hopefully no one will be trolling about it, considering the suicide-prone work being done here ;) client/cmdhw.c, client/proxusb.c, client/cmdhw.h, client/proxusb.h, client/cmdmain.c, client/cmdlfhid.c, client/cmdmain.h, client/cmdlfhid.h, client/data.c, client/data.h, client/cmdhf.c, client/cmdlf.c, client/cmdhf.h, client/cmdhf15.c, client/cmdhf14b.c, client/cmdlf.h, client/cmdhf15.h, client/cmdhf14b.h, client/cmddata.c, client/cmddata.h, client/ui.c, client/cmdparser.c, client/cmdlfti.c, client/ui.h, client/cmdlfem4x.c, client/cmdparser.h, client/cmdlfti.h, client/cmdlfem4x.h, client/graph.c, client/graph.h, client/cmdhf14a.c, client/cmdhf14a.h, client/cmdhflegic.c, client/cmdhflegic.c: New files. client/cli.c, client/flasher.c, client/snooper.c, client/proxmark3.c, client/proxmark3.h, client/Makefile: Update accordingly. client/flash.h, client/flash.c, client/proxgui.cpp: Cosmetic changes. client/translate.h, client/command.c, client/gui.c, client/usb.c, client/prox.h: Remove. include/usb_cmd.h (CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443_SIM): Remove dead cmd. common/crc16.h: New file. common/crc16.c: Modify accordingly. common/iso14443crc.h: New file. common/iso14443_crc.c: Rename to common/iso14443crc.c: and modify accordingly. armsrc/lfops.c, armsrc/iso14443.c, armsrc/iso14443a.c: include .h files from the common directory instead of including the c files. common/Makefile.common, armsrc/Makefile: Modify accordingly.
2010-02-04 09:27:07 +08:00
#include "cmdlfhid.h"
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <inttypes.h>
#include "cmdparser.h" // command_t
#include "comms.h"
#include "commonutil.h" // ARRAYLEN
#include "cliparser.h"
#include "ui.h"
#include "graph.h"
#include "cmddata.h" // g_debugMode, demodbuff cmds
#include "cmdlf.h" // lf_read, lfsim_wait_check
#include "util_posix.h"
#include "lfdemod.h"
2019-10-13 06:48:26 +08:00
#include "wiegand_formats.h"
#include "wiegand_formatutils.h"
#include "cmdlfem4x05.h" // EM defines
#ifndef BITS
# define BITS 96
#endif
Client cleanup and restructuring. Stage 1... Next Step is refactoring some of the giant functions which are just copy/paste of some other ones with just a few line changes, removing unnecessary 'goto' etc. The MS Windows version is broken with this commit but will be fixed soon. Everything can't be done all at once :P The commands are now hierarchical, for example: "hf 14a read" vs. "hf 14b read". You can also request help: "hf help", "data help", "hf 15 help" etc. Indents are now space-based, not tab-based anymore. Hopefully no one will be trolling about it, considering the suicide-prone work being done here ;) client/cmdhw.c, client/proxusb.c, client/cmdhw.h, client/proxusb.h, client/cmdmain.c, client/cmdlfhid.c, client/cmdmain.h, client/cmdlfhid.h, client/data.c, client/data.h, client/cmdhf.c, client/cmdlf.c, client/cmdhf.h, client/cmdhf15.c, client/cmdhf14b.c, client/cmdlf.h, client/cmdhf15.h, client/cmdhf14b.h, client/cmddata.c, client/cmddata.h, client/ui.c, client/cmdparser.c, client/cmdlfti.c, client/ui.h, client/cmdlfem4x.c, client/cmdparser.h, client/cmdlfti.h, client/cmdlfem4x.h, client/graph.c, client/graph.h, client/cmdhf14a.c, client/cmdhf14a.h, client/cmdhflegic.c, client/cmdhflegic.c: New files. client/cli.c, client/flasher.c, client/snooper.c, client/proxmark3.c, client/proxmark3.h, client/Makefile: Update accordingly. client/flash.h, client/flash.c, client/proxgui.cpp: Cosmetic changes. client/translate.h, client/command.c, client/gui.c, client/usb.c, client/prox.h: Remove. include/usb_cmd.h (CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443_SIM): Remove dead cmd. common/crc16.h: New file. common/crc16.c: Modify accordingly. common/iso14443crc.h: New file. common/iso14443_crc.c: Rename to common/iso14443crc.c: and modify accordingly. armsrc/lfops.c, armsrc/iso14443.c, armsrc/iso14443a.c: include .h files from the common directory instead of including the c files. common/Makefile.common, armsrc/Makefile: Modify accordingly.
2010-02-04 09:27:07 +08:00
static int CmdHelp(const char *Cmd);
// sending three times. Didn't seem to break the previous sim?
2019-05-22 22:10:48 +08:00
static int sendPing(void) {
2020-12-01 17:42:55 +08:00
SendCommandNG(CMD_BREAK_LOOP, NULL, 0);
2019-05-08 05:35:09 +08:00
SendCommandNG(CMD_PING, NULL, 0);
2019-03-10 06:35:06 +08:00
clearCommandBuffer();
2019-04-18 18:43:35 +08:00
PacketResponseNG resp;
2019-05-08 05:35:09 +08:00
if (!WaitForResponseTimeout(CMD_PING, &resp, 1000))
2019-05-22 22:10:48 +08:00
return PM3_ETIMEOUT;
return PM3_SUCCESS;
}
static int sendTry(uint8_t format_idx, wiegand_card_t *card, uint32_t delay, bool verbose) {
wiegand_message_t packed;
memset(&packed, 0, sizeof(wiegand_message_t));
if (HIDPack(format_idx, card, &packed, true) == false) {
PrintAndLogEx(WARNING, "The card data could not be encoded in the selected format.");
2020-12-12 21:46:40 +08:00
return PM3_ESOFT;
}
2020-12-05 05:59:57 +08:00
if (verbose) {
PrintAndLogEx(INFO, "Trying FC: " _YELLOW_("%u") " CN: " _YELLOW_("%"PRIu64) " Issue level: " _YELLOW_("%u") " OEM: " _YELLOW_("%u")
2020-12-12 21:46:40 +08:00
, card->FacilityCode
, card->CardNumber
, card->IssueLevel
, card->OEM
);
2020-12-05 05:59:57 +08:00
}
lf_hidsim_t payload;
payload.hi2 = packed.Top;
payload.hi = packed.Mid;
payload.lo = packed.Bot;
2020-12-05 06:16:15 +08:00
payload.longFMT = (packed.Mid > 0xFFF);
2019-03-10 06:35:06 +08:00
clearCommandBuffer();
SendCommandNG(CMD_LF_HID_SIMULATE, (uint8_t *)&payload, sizeof(payload));
2019-10-13 06:48:26 +08:00
/*
PacketResponseNG resp;
WaitForResponse(CMD_LF_HID_SIMULATE, &resp);
if (resp.status == PM3_EOPABORTED)
return resp.status;
*/
2019-03-10 06:35:06 +08:00
msleep(delay);
2019-05-22 22:10:48 +08:00
return sendPing();
}
//by marshmellow (based on existing demod + holiman's refactor)
//HID Prox demod - FSK RF/50 with preamble of 00011101 (then manchester encoded)
//print full HID Prox ID and some bit format details if found
2020-09-28 17:50:20 +08:00
int demodHID(bool verbose) {
(void) verbose; // unused so far
// HID simulation etc uses 0/1 as signal data. This must be converted in order to demod it back again
2019-06-08 03:40:33 +08:00
if (isGraphBitstream()) {
convertGraphFromBitstream();
}
2019-03-10 06:35:06 +08:00
//raw fsk demod no manchester decoding no start bit finding just get binary from wave
2019-03-10 07:00:59 +08:00
uint32_t hi2 = 0, hi = 0, lo = 0;
2019-03-10 06:35:06 +08:00
uint8_t bits[GraphTraceLen];
2019-03-10 06:35:06 +08:00
size_t size = getFromGraphBuf(bits);
if (size == 0) {
2020-03-13 22:09:25 +08:00
PrintAndLogEx(DEBUG, "DEBUG: Error - " _RED_("HID not enough samples"));
2019-05-22 22:10:48 +08:00
return PM3_ESOFT;
2019-03-10 06:35:06 +08:00
}
//get binary from fsk wave
int waveIdx = 0;
int idx = HIDdemodFSK(bits, &size, &hi2, &hi, &lo, &waveIdx);
if (idx < 0) {
if (idx == -1)
2020-03-13 22:09:25 +08:00
PrintAndLogEx(DEBUG, "DEBUG: Error - " _RED_("HID not enough samples"));
2019-03-10 06:35:06 +08:00
else if (idx == -2)
2020-03-13 22:09:25 +08:00
PrintAndLogEx(DEBUG, "DEBUG: Error - " _RED_("HID just noise detected"));
2019-03-10 06:35:06 +08:00
else if (idx == -3)
2020-03-13 22:09:25 +08:00
PrintAndLogEx(DEBUG, "DEBUG: Error - " _RED_("HID problem during FSK demod"));
2019-03-10 06:35:06 +08:00
else if (idx == -4)
2020-03-13 22:09:25 +08:00
PrintAndLogEx(DEBUG, "DEBUG: Error - " _RED_("HID preamble not found"));
2019-03-10 06:35:06 +08:00
else if (idx == -5)
2020-03-13 22:52:25 +08:00
PrintAndLogEx(DEBUG, "DEBUG: Error - " _RED_("HID error in Manchester data, size %zu"), size);
2019-03-10 06:35:06 +08:00
else
2020-03-13 22:52:25 +08:00
PrintAndLogEx(DEBUG, "DEBUG: Error - " _RED_("HID error demoding fsk %d"), idx);
2019-03-10 06:35:06 +08:00
2019-05-22 22:10:48 +08:00
return PM3_ESOFT;
2019-03-10 06:35:06 +08:00
}
2019-04-07 03:46:00 +08:00
setDemodBuff(bits, size, idx);
2019-03-10 07:00:59 +08:00
setClockGrid(50, waveIdx + (idx * 50));
2019-03-10 06:35:06 +08:00
2019-03-10 07:00:59 +08:00
if (hi2 == 0 && hi == 0 && lo == 0) {
2020-03-13 22:09:25 +08:00
PrintAndLogEx(DEBUG, "DEBUG: Error - " _RED_("HID no values found"));
2019-05-22 22:10:48 +08:00
return PM3_ESOFT;
2019-03-10 06:35:06 +08:00
}
wiegand_message_t packed = initialize_message_object(hi2, hi, lo);
2020-11-07 08:32:43 +08:00
if (HIDTryUnpack(&packed, false) == false) {
printDemodBuff(0, false, false, true);
}
2020-11-17 03:06:33 +08:00
PrintAndLogEx(INFO, "raw: " _GREEN_("%08x%08x%08x"), hi2, hi, lo);
2019-03-10 06:35:06 +08:00
2020-03-13 22:52:25 +08:00
PrintAndLogEx(DEBUG, "DEBUG: HID idx: %d, Len: %zu, Printing Demod Buffer: ", idx, size);
2020-11-05 02:19:38 +08:00
if (g_debugMode) {
2020-11-05 19:02:54 +08:00
PrintAndLogEx(DEBUG, "raw: " _GREEN_("%08x%08x%08x"), hi2, hi, lo);
2020-11-07 08:32:43 +08:00
2020-11-05 02:19:38 +08:00
printDemodBuff(0, false, false, false);
}
2019-03-10 06:35:06 +08:00
2019-05-22 22:10:48 +08:00
return PM3_SUCCESS;
}
2020-09-28 17:50:20 +08:00
static int CmdHIDDemod(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf hid demod",
"Try to find HID Prox preamble, if found decode / descramble data",
"lf hid demod"
);
void *argtable[] = {
arg_param_begin,
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIParserFree(ctx);
2020-09-28 17:50:20 +08:00
return demodHID(true);
}
// this read is the "normal" read, which download lf signal and tries to demod here.
static int CmdHIDReader(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf hid reader",
"read a HID Prox tag",
"lf hid reader -@ -> continuous reader mode"
);
void *argtable[] = {
arg_param_begin,
arg_lit0("@", NULL, "optional - continuous reader mode"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
bool cm = arg_get_lit(ctx, 1);
CLIParserFree(ctx);
2020-12-01 18:26:54 +08:00
if (cm) {
PrintAndLogEx(INFO, "Press " _GREEN_("<Enter>") " to exit");
}
do {
lf_read(false, 16000);
demodHID(!cm);
} while (cm && !kbd_enter_pressed());
return PM3_SUCCESS;
}
// this read loops on device side.
// uses the demod in lfops.c
static int CmdHIDWatch(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf hid watch",
"Enables HID compatible reader mode printing details.\n"
"By default, values are printed and logged until the button is pressed or another USB command is issued.\n",
"lf hid watch"
2020-10-06 23:50:20 +08:00
);
void *argtable[] = {
arg_param_begin,
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIParserFree(ctx);
PrintAndLogEx(SUCCESS, "Watching for HID Prox cards - place tag on antenna");
PrintAndLogEx(INFO, "Press pm3-button to stop reading cards");
2019-03-10 06:35:06 +08:00
clearCommandBuffer();
2020-08-13 18:25:04 +08:00
SendCommandNG(CMD_LF_HID_WATCH, NULL, 0);
return lfsim_wait_check(CMD_LF_HID_WATCH);
Client cleanup and restructuring. Stage 1... Next Step is refactoring some of the giant functions which are just copy/paste of some other ones with just a few line changes, removing unnecessary 'goto' etc. The MS Windows version is broken with this commit but will be fixed soon. Everything can't be done all at once :P The commands are now hierarchical, for example: "hf 14a read" vs. "hf 14b read". You can also request help: "hf help", "data help", "hf 15 help" etc. Indents are now space-based, not tab-based anymore. Hopefully no one will be trolling about it, considering the suicide-prone work being done here ;) client/cmdhw.c, client/proxusb.c, client/cmdhw.h, client/proxusb.h, client/cmdmain.c, client/cmdlfhid.c, client/cmdmain.h, client/cmdlfhid.h, client/data.c, client/data.h, client/cmdhf.c, client/cmdlf.c, client/cmdhf.h, client/cmdhf15.c, client/cmdhf14b.c, client/cmdlf.h, client/cmdhf15.h, client/cmdhf14b.h, client/cmddata.c, client/cmddata.h, client/ui.c, client/cmdparser.c, client/cmdlfti.c, client/ui.h, client/cmdlfem4x.c, client/cmdparser.h, client/cmdlfti.h, client/cmdlfem4x.h, client/graph.c, client/graph.h, client/cmdhf14a.c, client/cmdhf14a.h, client/cmdhflegic.c, client/cmdhflegic.c: New files. client/cli.c, client/flasher.c, client/snooper.c, client/proxmark3.c, client/proxmark3.h, client/Makefile: Update accordingly. client/flash.h, client/flash.c, client/proxgui.cpp: Cosmetic changes. client/translate.h, client/command.c, client/gui.c, client/usb.c, client/prox.h: Remove. include/usb_cmd.h (CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443_SIM): Remove dead cmd. common/crc16.h: New file. common/crc16.c: Modify accordingly. common/iso14443crc.h: New file. common/iso14443_crc.c: Rename to common/iso14443crc.c: and modify accordingly. armsrc/lfops.c, armsrc/iso14443.c, armsrc/iso14443a.c: include .h files from the common directory instead of including the c files. common/Makefile.common, armsrc/Makefile: Modify accordingly.
2010-02-04 09:27:07 +08:00
}
static int CmdHIDSim(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf hid sim",
2020-12-01 17:42:55 +08:00
"Enables simulation of HID card with card number.\n"
"Simulation runs until the button is pressed or another USB command is issued.",
"lf hid sim -r 2006ec0c86 -> HID 10301 26 bit\n"
"lf hid sim -r 2e0ec00c87 -> HID Corporate 35 bit\n"
"lf hid sim -r 01f0760643c3 -> HID P10001 40 bit\n"
"lf hid sim -r 01400076000c86 -> HID Corporate 48 bit\n"
"lf hid sim -w H10301 --fc 118 --cn 1603 -> HID 10301 26 bit\n"
2020-10-06 23:50:20 +08:00
);
void *argtable[] = {
arg_param_begin,
arg_str0("w", "wiegand", "<format>", "see " _YELLOW_("`wiegand list`") " for available formats"),
arg_u64_0(NULL, "fc", "<dec>", "facility code"),
2020-10-12 04:40:05 +08:00
arg_u64_0(NULL, "cn", "<dec>", "card number"),
2020-12-05 06:16:15 +08:00
arg_u64_0("i", NULL, "<dec>", "issue level"),
arg_u64_0("o", "oem", "<dec>", "OEM code"),
arg_strx0("r", "raw", "<hex>", "raw bytes"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
char format[16] = {0};
int format_len = 0;
CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)format, sizeof(format), &format_len);
2020-10-12 04:40:05 +08:00
wiegand_card_t card;
memset(&card, 0, sizeof(wiegand_card_t));
card.FacilityCode = arg_get_u32_def(ctx, 2, 0);
card.CardNumber = arg_get_u32_def(ctx, 3, 0);
card.IssueLevel = arg_get_u32_def(ctx, 4, 0);
card.OEM = arg_get_u32_def(ctx, 5, 0);
2020-10-12 04:40:05 +08:00
int raw_len = 0;
char raw[40] = {0};
CLIParamStrToBuf(arg_get_str(ctx, 6), (uint8_t *)raw, sizeof(raw), &raw_len);
2020-10-12 04:40:05 +08:00
CLIParserFree(ctx);
wiegand_message_t packed;
memset(&packed, 0, sizeof(wiegand_message_t));
2020-10-12 04:40:05 +08:00
// format validation
int format_idx = HIDFindCardFormat((char *)format);
if (format_idx == -1 && raw_len == 0) {
PrintAndLogEx(WARNING, "Unknown format: " _YELLOW_("%s"), format);
return PM3_EINVARG;
}
if (raw_len) {
uint32_t top = 0, mid = 0, bot = 0;
hexstring_to_u96(&top, &mid, &bot, raw);
packed.Top = top;
packed.Mid = mid;
packed.Bot = bot;
} else {
if (HIDPack(format_idx, &card, &packed, true) == false) {
PrintAndLogEx(WARNING, "The card data could not be encoded in the selected format.");
return PM3_ESOFT;
2019-09-15 07:17:47 +08:00
}
}
if (raw_len == 0) {
2020-10-12 04:40:05 +08:00
PrintAndLogEx(INFO, "Simulating HID tag");
HIDTryUnpack(&packed, false);
} else {
2020-10-12 04:40:05 +08:00
PrintAndLogEx(INFO, "Simulating HID tag using raw " _GREEN_("%s"), raw);
2019-03-10 06:35:06 +08:00
}
2013-03-13 15:13:19 +08:00
lf_hidsim_t payload;
payload.hi2 = packed.Top;
payload.hi = packed.Mid;
payload.lo = packed.Bot;
payload.longFMT = (packed.Mid > 0xFFF);
2019-09-15 07:17:47 +08:00
2019-03-10 06:35:06 +08:00
clearCommandBuffer();
2019-09-15 07:17:47 +08:00
SendCommandNG(CMD_LF_HID_SIMULATE, (uint8_t *)&payload, sizeof(payload));
return lfsim_wait_check(CMD_LF_HID_SIMULATE);
2013-03-13 15:13:19 +08:00
}
static int CmdHIDClone(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf hid clone",
"clone a HID Prox tag to a T55x7, Q5/T5555 or EM4305/4469 tag.\n"
"Tag must be on the antenna when issuing this command.",
2020-12-05 05:30:15 +08:00
"lf hid clone -r 2006ec0c86 -> write raw value (HID 10301 26 bit)\n"
"lf hid clone -r 2e0ec00c87 -> write raw value (HID Corporate 35 bit)\n"
"lf hid clone -r 01f0760643c3 -> write raw value (HID P10001 40 bit)\n"
"lf hid clone -r 01400076000c86 -> write raw value (HID Corporate 48 bit)\n"
"lf hid clone -w H10301 --fc 118 --cn 1603 -> write raw value (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"
2020-10-06 23:50:20 +08:00
);
void *argtable[] = {
arg_param_begin,
arg_str0("w", "wiegand", "<format>", "see " _YELLOW_("`wiegand list`") " for available formats"),
arg_u64_0(NULL, "fc", "<dec>", "facility code"),
2020-10-12 04:40:05 +08:00
arg_u64_0(NULL, "cn", "<dec>", "card number"),
arg_int0("i", NULL, "<dec>", "issue level"),
arg_int0("o", "oem", "<dec>", "OEM code"),
arg_strx0("r", "raw", "<hex>", "raw bytes"),
arg_lit0(NULL, "q5", "optional - specify writing to Q5/T5555 tag"),
arg_lit0(NULL, "em", "optional - specify writing to EM4305/4469 tag"),
arg_str0(NULL, "bin", "<bin>", "Binary string i.e 0001001001"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
2019-03-10 06:35:06 +08:00
char format[16] = {0};
int format_len = 0;
CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)format, sizeof(format), &format_len);
2020-10-12 04:40:05 +08:00
wiegand_card_t card;
memset(&card, 0, sizeof(wiegand_card_t));
card.FacilityCode = arg_get_u32_def(ctx, 2, 0);
card.CardNumber = arg_get_u32_def(ctx, 3, 0);
card.IssueLevel = arg_get_u32_def(ctx, 4, 0);
card.OEM = arg_get_u32_def(ctx, 5, 0);
2020-10-12 04:40:05 +08:00
int raw_len = 0;
char raw[40] = {0};
CLIParamStrToBuf(arg_get_str(ctx, 6), (uint8_t *)raw, sizeof(raw), &raw_len);
bool q5 = arg_get_lit(ctx, 7);
bool em = arg_get_lit(ctx, 8);
int bin_len = 63;
uint8_t bin[70] = {0};
CLIGetStrWithReturn(ctx, 9, bin, &bin_len);
2020-10-12 04:40:05 +08:00
CLIParserFree(ctx);
2019-03-10 06:35:06 +08:00
if (q5 && em) {
PrintAndLogEx(FAILED, "Can't specify both Q5 and EM4305 at the same time");
return PM3_EINVARG;
}
if (bin_len > 127) {
PrintAndLogEx(ERR, "Binary wiegand string must be less than 128 bits");
return PM3_EINVARG;
}
wiegand_message_t packed;
memset(&packed, 0, sizeof(wiegand_message_t));
2020-10-12 04:40:05 +08:00
// format validation
int format_idx = HIDFindCardFormat((char *)format);
if (format_idx == -1 && raw_len == 0) {
PrintAndLogEx(WARNING, "Unknown format: " _YELLOW_("%s"), format);
return PM3_EINVARG;
}
2019-03-10 06:35:06 +08:00
uint32_t top = 0, mid = 0, bot = 0;
if (raw_len) {
hexstring_to_u96(&top, &mid, &bot, raw);
packed.Top = top;
packed.Mid = mid;
packed.Bot = bot;
} else if (bin_len) {
2021-02-17 17:46:58 +08:00
int res = binstring_to_u96(&top, &mid, &bot, (const char*)bin);
if (res != bin_len) {
PrintAndLogEx(ERR, "Binary string contains none <0|1> chars");
return PM3_EINVARG;
}
packed.Top = top;
packed.Mid = mid;
packed.Bot = bot;
2019-03-10 06:35:06 +08:00
} else {
if (HIDPack(format_idx, &card, &packed, true) == false) {
PrintAndLogEx(WARNING, "The card data could not be encoded in the selected format.");
return PM3_ESOFT;
2019-03-10 06:35:06 +08:00
}
}
char cardtype[16] = {"T55x7"};
// Q5
if (q5) {
snprintf(cardtype, sizeof(cardtype), "Q5/T5555");
}
// EM4305
if (em) {
snprintf(cardtype, sizeof(cardtype), "EM4305/4469");
}
2020-10-09 02:32:45 +08:00
if (raw_len == 0) {
2020-10-12 04:40:05 +08:00
PrintAndLogEx(INFO, "Preparing to clone HID tag");
2020-10-09 02:32:45 +08:00
HIDTryUnpack(&packed, false);
} else {
2020-10-12 04:40:05 +08:00
PrintAndLogEx(INFO, "Preparing to clone HID tag using raw " _YELLOW_("%s"), raw);
2020-10-09 02:32:45 +08:00
}
lf_hidsim_t payload;
payload.hi2 = packed.Top;
payload.hi = packed.Mid;
payload.lo = packed.Bot;
payload.longFMT = (packed.Mid > 0xFFF);
payload.Q5 = q5;
payload.EM = em;
2019-03-10 06:35:06 +08:00
clearCommandBuffer();
SendCommandNG(CMD_LF_HID_CLONE, (uint8_t *)&payload, sizeof(payload));
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");
2019-05-22 22:10:48 +08:00
return PM3_SUCCESS;
2011-10-15 23:15:49 +08:00
}
2019-03-25 07:04:28 +08:00
/*
2019-03-10 06:35:06 +08:00
PrintAndLogEx(NORMAL, "HID | OEM | FC | CN | Wiegand | HID Formatted");
PrintAndLogEx(NORMAL, "----+-----+------+---------+-----------+--------------------");
PrintAndLogEx(NORMAL, " %u | %03u | %03u | %" PRIu64 " | %" PRIX64 " | %" PRIX64,
2019-03-10 07:00:59 +08:00
fmtlen[i],
oem,
fc,
cardnum,
wiegand,
blocks
);
2019-03-10 06:35:06 +08:00
}
PrintAndLogEx(NORMAL, "----+-----+-----+-------+-----------+--------------------");
*/
static int CmdHIDBrute(const char *Cmd) {
2020-03-02 00:15:48 +08:00
uint32_t delay = 1000;
int format_idx = -1;
int direction = 0;
uint8_t format[16] = {0};
int formatLen;
wiegand_card_t cn_hi, cn_low;
memset(&cn_hi, 0, sizeof(wiegand_card_t));
2020-03-02 00:15:48 +08:00
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf hid brute",
"Enables bruteforce of HID readers with specified facility code.\n"
"This is a attack against reader. if cardnumber is given, it starts with it and goes up / down one step\n"
"if cardnumber is not given, it starts with 1 and goes up to 65535",
"lf hid brute -w H10301 --fc 224\n"
"lf hid brute -w H10301 --fc 21 -d 2000\n"
"lf hid brute -v -w H10301 --fc 21 --cn 200 -d 2000\n"
2020-12-05 05:42:52 +08:00
"lf hid brute -v -w H10301 --fc 21 --cn 200 -d 2000 --up\n"
2020-10-06 23:50:20 +08:00
);
void *argtable[] = {
arg_param_begin,
arg_lit0("v", "verbose", "verbose logging, show all tries"),
arg_str1("w", "wiegand", "<format>", "see " _YELLOW_("`wiegand list`") " for available formats"),
2020-12-05 06:16:15 +08:00
arg_u64_0(NULL, "fc", "<dec>", "facility code"),
arg_u64_0(NULL, "cn", "<dec>", "card number to start with"),
arg_u64_0("i", "issue", "<dec>", "issue level"),
arg_u64_0("o", "oem", "<dec>", "OEM code"),
arg_u64_0("d", "delay", "<dec>", "delay betweens attempts in ms. Default 1000ms"),
arg_lit0(NULL, "up", "direction to increment card number. (default is both directions)"),
arg_lit0(NULL, "down", "direction to decrement card number. (default is both directions)"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
bool verbose = arg_get_lit(ctx, 1);
formatLen = sizeof(format);
CLIGetStrWithReturn(ctx, 2, format, &formatLen);
2020-10-06 23:50:20 +08:00
format_idx = HIDFindCardFormat((char *) format);
if (format_idx == -1) {
PrintAndLogEx(WARNING, "Unknown format: " _YELLOW_("%s"), format);
2020-10-05 19:38:04 +08:00
CLIParserFree(ctx);
return PM3_EINVARG;
}
2020-12-05 06:16:15 +08:00
cn_hi.FacilityCode = arg_get_u32_def(ctx, 3, 0);
cn_hi.CardNumber = arg_get_u32_def(ctx, 4, 0);
cn_hi.IssueLevel = arg_get_u32_def(ctx, 5, 0);
cn_hi.OEM = arg_get_u32_def(ctx, 6, 0);
delay = arg_get_u32_def(ctx, 7, 1000);
if (arg_get_lit(ctx, 8) && arg_get_lit(ctx, 9)) {
direction = 0;
} else if (arg_get_lit(ctx, 8)) {
direction = 1;
} else if (arg_get_lit(ctx, 9)) {
direction = 2;
}
2019-03-10 06:35:06 +08:00
CLIParserFree(ctx);
2020-11-02 08:46:47 +08:00
if (verbose) {
PrintAndLogEx(INFO, "Wiegand format#.. %i", format_idx);
PrintAndLogEx(INFO, "OEM#............. %u", cn_hi.OEM);
PrintAndLogEx(INFO, "ISSUE#........... %u", cn_hi.IssueLevel);
PrintAndLogEx(INFO, "Facility#........ %u", cn_hi.FacilityCode);
2020-03-02 00:15:48 +08:00
PrintAndLogEx(INFO, "Card#............ %" PRIu64, cn_hi.CardNumber);
2020-03-11 00:05:45 +08:00
switch (direction) {
case 0:
2020-12-05 05:59:57 +08:00
PrintAndLogEx(INFO, "Brute-forcing direction: " _YELLOW_("BOTH") " delay " _YELLOW_("%d"), delay);
break;
2020-03-02 00:15:48 +08:00
case 1:
2020-12-05 05:59:57 +08:00
PrintAndLogEx(INFO, "Brute-forcing direction: " _YELLOW_("UP") " delay " _YELLOW_("%d"), delay);
break;
case 2:
2020-12-05 05:59:57 +08:00
PrintAndLogEx(INFO, "Brute-forcing direction: " _YELLOW_("DOWN") " delay " _YELLOW_("%d"), delay);
break;
2020-03-11 00:05:45 +08:00
default:
break;
}
}
2020-12-05 05:59:57 +08:00
PrintAndLogEx(INFO, "Started brute-forcing HID Prox reader");
PrintAndLogEx(INFO, "Press pm3-button to abort simulation or press " _GREEN_("`<enter>`") " to exit");
// copy values to low.
cn_low = cn_hi;
2019-03-10 06:35:06 +08:00
// main loop
2020-10-23 07:24:54 +08:00
// iceman: could add options for bruteforcing OEM, ISSUE or FC as well..
bool exitloop = false;
bool fin_hi, fin_low;
fin_hi = fin_low = false;
do {
2019-03-10 06:35:06 +08:00
2019-05-01 05:52:40 +08:00
if (!session.pm3_present) {
2019-03-10 06:35:06 +08:00
PrintAndLogEx(WARNING, "Device offline\n");
2019-05-22 22:10:48 +08:00
return PM3_ENODATA;
2019-03-10 06:35:06 +08:00
}
if (kbd_enter_pressed()) {
2019-03-10 06:35:06 +08:00
PrintAndLogEx(INFO, "aborted via keyboard!");
return sendPing();
}
// do one up
if (direction != 2) {
if (cn_hi.CardNumber < 0xFFFF) {
cn_hi.CardNumber++;
2020-12-05 05:59:57 +08:00
if (sendTry(format_idx, &cn_hi, delay, verbose) != PM3_SUCCESS) {
return PM3_ESOFT;
}
} else {
fin_hi = true;
}
}
2020-03-11 00:05:45 +08:00
// do one down
if (direction != 1) {
if (cn_low.CardNumber > 0) {
cn_low.CardNumber--;
2020-12-05 05:59:57 +08:00
if (sendTry(format_idx, &cn_low, delay, verbose) != PM3_SUCCESS) {
return PM3_ESOFT;
}
} else {
fin_low = true;
}
2019-10-13 06:48:26 +08:00
}
switch (direction) {
2020-03-11 00:05:45 +08:00
case 0:
if (fin_hi && fin_low) {
exitloop = true;
}
break;
case 1:
exitloop = fin_hi;
break;
case 2:
exitloop = fin_low;
break;
2020-03-11 00:05:45 +08:00
default:
break;
}
} while (exitloop == false);
PrintAndLogEx(INFO, "Brute forcing finished");
2019-05-22 22:10:48 +08:00
return PM3_SUCCESS;
}
static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "this help"},
{"demod", CmdHIDDemod, AlwaysAvailable, "demodulate HID Prox tag from the GraphBuffer"},
{"reader", CmdHIDReader, IfPm3Lf, "attempt to read and extract tag data"},
2019-10-16 16:32:50 +08:00
{"clone", CmdHIDClone, IfPm3Lf, "clone HID tag to T55x7"},
{"sim", CmdHIDSim, IfPm3Lf, "simulate HID tag"},
{"brute", CmdHIDBrute, IfPm3Lf, "bruteforce card number against reader"},
{"watch", CmdHIDWatch, IfPm3Lf, "continuously watch for cards. Reader mode"},
{NULL, NULL, NULL, NULL}
Client cleanup and restructuring. Stage 1... Next Step is refactoring some of the giant functions which are just copy/paste of some other ones with just a few line changes, removing unnecessary 'goto' etc. The MS Windows version is broken with this commit but will be fixed soon. Everything can't be done all at once :P The commands are now hierarchical, for example: "hf 14a read" vs. "hf 14b read". You can also request help: "hf help", "data help", "hf 15 help" etc. Indents are now space-based, not tab-based anymore. Hopefully no one will be trolling about it, considering the suicide-prone work being done here ;) client/cmdhw.c, client/proxusb.c, client/cmdhw.h, client/proxusb.h, client/cmdmain.c, client/cmdlfhid.c, client/cmdmain.h, client/cmdlfhid.h, client/data.c, client/data.h, client/cmdhf.c, client/cmdlf.c, client/cmdhf.h, client/cmdhf15.c, client/cmdhf14b.c, client/cmdlf.h, client/cmdhf15.h, client/cmdhf14b.h, client/cmddata.c, client/cmddata.h, client/ui.c, client/cmdparser.c, client/cmdlfti.c, client/ui.h, client/cmdlfem4x.c, client/cmdparser.h, client/cmdlfti.h, client/cmdlfem4x.h, client/graph.c, client/graph.h, client/cmdhf14a.c, client/cmdhf14a.h, client/cmdhflegic.c, client/cmdhflegic.c: New files. client/cli.c, client/flasher.c, client/snooper.c, client/proxmark3.c, client/proxmark3.h, client/Makefile: Update accordingly. client/flash.h, client/flash.c, client/proxgui.cpp: Cosmetic changes. client/translate.h, client/command.c, client/gui.c, client/usb.c, client/prox.h: Remove. include/usb_cmd.h (CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443_SIM): Remove dead cmd. common/crc16.h: New file. common/crc16.c: Modify accordingly. common/iso14443crc.h: New file. common/iso14443_crc.c: Rename to common/iso14443crc.c: and modify accordingly. armsrc/lfops.c, armsrc/iso14443.c, armsrc/iso14443a.c: include .h files from the common directory instead of including the c files. common/Makefile.common, armsrc/Makefile: Modify accordingly.
2010-02-04 09:27:07 +08:00
};
static int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable);
2019-05-22 22:10:48 +08:00
return PM3_SUCCESS;
}
int CmdLFHID(const char *Cmd) {
2019-03-10 06:35:06 +08:00
clearCommandBuffer();
2019-04-19 06:47:51 +08:00
return CmdsParse(CommandTable, Cmd);
Client cleanup and restructuring. Stage 1... Next Step is refactoring some of the giant functions which are just copy/paste of some other ones with just a few line changes, removing unnecessary 'goto' etc. The MS Windows version is broken with this commit but will be fixed soon. Everything can't be done all at once :P The commands are now hierarchical, for example: "hf 14a read" vs. "hf 14b read". You can also request help: "hf help", "data help", "hf 15 help" etc. Indents are now space-based, not tab-based anymore. Hopefully no one will be trolling about it, considering the suicide-prone work being done here ;) client/cmdhw.c, client/proxusb.c, client/cmdhw.h, client/proxusb.h, client/cmdmain.c, client/cmdlfhid.c, client/cmdmain.h, client/cmdlfhid.h, client/data.c, client/data.h, client/cmdhf.c, client/cmdlf.c, client/cmdhf.h, client/cmdhf15.c, client/cmdhf14b.c, client/cmdlf.h, client/cmdhf15.h, client/cmdhf14b.h, client/cmddata.c, client/cmddata.h, client/ui.c, client/cmdparser.c, client/cmdlfti.c, client/ui.h, client/cmdlfem4x.c, client/cmdparser.h, client/cmdlfti.h, client/cmdlfem4x.h, client/graph.c, client/graph.h, client/cmdhf14a.c, client/cmdhf14a.h, client/cmdhflegic.c, client/cmdhflegic.c: New files. client/cli.c, client/flasher.c, client/snooper.c, client/proxmark3.c, client/proxmark3.h, client/Makefile: Update accordingly. client/flash.h, client/flash.c, client/proxgui.cpp: Cosmetic changes. client/translate.h, client/command.c, client/gui.c, client/usb.c, client/prox.h: Remove. include/usb_cmd.h (CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443_SIM): Remove dead cmd. common/crc16.h: New file. common/crc16.c: Modify accordingly. common/iso14443crc.h: New file. common/iso14443_crc.c: Rename to common/iso14443crc.c: and modify accordingly. armsrc/lfops.c, armsrc/iso14443.c, armsrc/iso14443a.c: include .h files from the common directory instead of including the c files. common/Makefile.common, armsrc/Makefile: Modify accordingly.
2010-02-04 09:27:07 +08:00
}