From 34c1da7ad424d7156df02fcec950fcfe59657967 Mon Sep 17 00:00:00 2001 From: bogiton <34060135+bogiton@users.noreply.github.com> Date: Tue, 16 Oct 2018 19:39:29 +0000 Subject: [PATCH 1/9] Include the HF_BOG standalone mode --- armsrc/Makefile | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/armsrc/Makefile b/armsrc/Makefile index 8f0cd025e..8a576f001 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -24,7 +24,7 @@ APP_CFLAGS = -DWITH_CRC \ -DWITH_FLASH \ -DWITH_SMARTCARD \ -DWITH_HFSNOOP \ - -DWITH_LF_SAMYRUN \ + -DWITH_HF_BOG \ -DWITH_FPC \ -fno-strict-aliasing -ffunction-sections -fdata-sections @@ -42,6 +42,7 @@ APP_CFLAGS = -DWITH_CRC \ # -DWITH_HF_YOUNG # -DWITH_HF_MATTYRUN # -DWITH_HF_COLIN +# -DWITH_HF_BOG SRC_LCD = fonts.c LCD.c @@ -106,6 +107,10 @@ endif ifneq (,$(findstring WITH_HF_COLIN,$(APP_CFLAGS))) SRC_STANDALONE = vtsend.c hf_colin.c endif +# WITH_HF_BOG +ifneq (,$(findstring WITH_HF_BOG,$(APP_CFLAGS))) + SRC_STANDALONE = hf_bog.c +endif #the FPGA bitstream files. Note: order matters! FPGA_BITSTREAMS = fpga_lf.bit fpga_hf.bit From 8079613b37640b8f940bf412143b4ec6d9d7cbb6 Mon Sep 17 00:00:00 2001 From: bogiton <34060135+bogiton@users.noreply.github.com> Date: Tue, 16 Oct 2018 19:41:05 +0000 Subject: [PATCH 2/9] Add check for the HF_BOG directive for RunMod --- armsrc/appmain.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index a84a33d48..79eba9cf8 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1530,7 +1530,7 @@ void __attribute__((noreturn)) AppMain(void) { RunMod(); #endif -#if defined (WITH_ISO14443a) && ( defined (WITH_HF_YOUNG) || defined(WITH_HF_COLIN) || defined(WITH_HF_MATTYRUN) ) +#if defined (WITH_ISO14443a) && ( defined (WITH_HF_YOUNG) || defined(WITH_HF_COLIN) || defined(WITH_HF_MATTYRUN) || defined(WITH_HF_BOG) ) RunMod(); #endif From 1c2af2a5ed9bb376898178f6de1f2ff7a1f17f97 Mon Sep 17 00:00:00 2001 From: bogiton <34060135+bogiton@users.noreply.github.com> Date: Tue, 16 Oct 2018 19:50:18 +0000 Subject: [PATCH 3/9] Added hf_bog standalone --- armsrc/Standalone/hf_bog.c | 366 +++++++++++++++++++++++++++++++++++++ armsrc/Standalone/hf_bog.h | 31 ++++ 2 files changed, 397 insertions(+) create mode 100644 armsrc/Standalone/hf_bog.c create mode 100644 armsrc/Standalone/hf_bog.h diff --git a/armsrc/Standalone/hf_bog.c b/armsrc/Standalone/hf_bog.c new file mode 100644 index 000000000..5a279ebd9 --- /dev/null +++ b/armsrc/Standalone/hf_bog.c @@ -0,0 +1,366 @@ +//----------------------------------------------------------------------------- +// 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. +//----------------------------------------------------------------------------- +// main code for standalone HF Sniff (and ULC/NTAG/ULEV1 pwd storing) +//----------------------------------------------------------------------------- +#include "hf_bog.h" + +#define DELAY_READER_AIR2ARM_AS_SNIFFER (2 + 3 + 8) +#define DELAY_TAG_AIR2ARM_AS_SNIFFER (3 + 14 + 8) +#define MAX_PWDS_PER_SESSION 15 + +uint8_t ReadCounterFromFlash() { + uint8_t mem = 0; + + uint8_t isok = Flash_ReadData(0, &mem, 1); + if (isok == 1) + { + return mem; + } + + Dbprintf("Reading of counter from flashmem failed"); + return -1; +} + +uint8_t* ReadDataFromFlash(uint8_t datacnt) { + + uint16_t isok = 0; + + if (!datacnt) + { + uint8_t *tmp = BigBuf_malloc(4); + for (int i=0;i<4;i++) + tmp[i] = 0x00; + return tmp; + } + + size_t size = (datacnt + 1) * 4; + uint8_t *mem = BigBuf_malloc(size); + + isok = Flash_ReadData(0, mem, (datacnt + 1) * 4); + if (isok == ((datacnt + 1) * 4)) + { + Dbprintf("[OK] Data recovered from flashmem"); + return mem; + } + + Dbprintf("FlashMem reading failed | isok = %d", isok); + SpinDelay(100); + return 0; +} + +/* +void WriteDataToFlash(uint8_t *data, size_t size) +{ + uint8_t isok = 0; + + isok = Flash_WriteData(0, data, size); + + if (!isok) + { + Dbprintf("FlashMem write failed"); + SpinDelay(100); + + return; + } + + Dbprintf("[OK] Data written to flash!"); +} +*/ + +void EraseMemory() +{ + if (!FlashInit()){ + return; + } + + Flash_CheckBusy(BUSY_TIMEOUT); + Flash_WriteEnable(); + Flash_Erase4k(0,0); + + Dbprintf("[OK] Erased flash!"); + FlashStop(); + SpinDelay(100); +} + + +void WriteDataToFlash(uint8_t* data, size_t size) +{ + uint8_t isok = 0; + uint16_t res = 0; + uint32_t len = size; + uint32_t bytes_sent = 0; + uint32_t bytes_remaining = len; + + uint8_t buff[PAGESIZE]; + + if (!FlashInit()){ + return; + } + + Flash_CheckBusy(BUSY_TIMEOUT); + Flash_WriteEnable(); + Flash_Erase4k(0,0); + + while (bytes_remaining > 0) + { + Flash_CheckBusy(BUSY_TIMEOUT); + Flash_WriteEnable(); + + uint32_t bytes_in_packet = MIN(FLASH_MEM_BLOCK_SIZE, bytes_remaining); + + memcpy(buff, data + bytes_sent, bytes_in_packet); + + bytes_remaining -= bytes_in_packet; + res = Flash_WriteDataCont(bytes_sent, buff, bytes_in_packet); + bytes_sent += bytes_in_packet; + + isok = (res == bytes_in_packet) ? 1 : 0; + + if (!isok) + { + Dbprintf("FlashMem write failed [offset %u]", bytes_sent); + SpinDelay(100); + + return; + } + } + + Dbprintf("[OK] Data written to flash! [0-to offset %u]", bytes_sent); + FlashStop(); + + return; +} + +void RAMFUNC SniffAndStore(uint8_t param) { + + // Array to store the authpwds + uint8_t *capturedPwds = BigBuf_malloc(4 * MAX_PWDS_PER_SESSION); + + SpinDelay(500); + + /* This is actually copied from SniffIso14443a */ + + iso14443a_setup(FPGA_HF_ISO14443A_SNIFFER); + + // Allocate memory from BigBuf for some buffers + // free all previous allocations first + BigBuf_free(); BigBuf_Clear_ext(false); + clear_trace(); + set_tracing(true); + + // The command (reader -> tag) that we're receiving. + uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE); + uint8_t *receivedCmdPar = BigBuf_malloc(MAX_PARITY_SIZE); + + // The response (tag -> reader) that we're receiving. + uint8_t *receivedResp = BigBuf_malloc(MAX_FRAME_SIZE); + uint8_t *receivedRespPar = BigBuf_malloc(MAX_PARITY_SIZE); + + // The DMA buffer, used to stream samples from the FPGA + uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE); + uint8_t *data = dmaBuf; + + uint8_t previous_data = 0; + int dataLen = 0; + bool TagIsActive = false; + bool ReaderIsActive = false; + + // Set up the demodulator for tag -> reader responses. + DemodInit(receivedResp, receivedRespPar); + + // Set up the demodulator for the reader -> tag commands + UartInit(receivedCmd, receivedCmdPar); + + // Setup and start DMA. + if ( !FpgaSetupSscDma((uint8_t*) dmaBuf, DMA_BUFFER_SIZE) ){ + if (MF_DBGLEVEL > 1) Dbprintf("FpgaSetupSscDma failed. Exiting"); + return; + } + + tUart* uart = GetUart(); + tDemod* demod = GetDemod(); + + // We won't start recording the frames that we acquire until we trigger; + // a good trigger condition to get started is probably when we see a + // response from the tag. + // triggered == false -- to wait first for card + bool triggered = !(param & 0x03); + + uint32_t rsamples = 0; + + // Current captured passwords counter + uint8_t auth_attempts = 0; + + SpinDelay(50); + + // loop and listen + while (!BUTTON_PRESS()) { + WDT_HIT(); + LED_A_ON(); + + int register readBufDataP = data - dmaBuf; + int register dmaBufDataP = DMA_BUFFER_SIZE - AT91C_BASE_PDC_SSC->PDC_RCR; + if (readBufDataP <= dmaBufDataP) + dataLen = dmaBufDataP - readBufDataP; + else + dataLen = DMA_BUFFER_SIZE - readBufDataP + dmaBufDataP; + + // test for length of buffer + if (dataLen > DMA_BUFFER_SIZE) { // TODO: Check if this works properly + Dbprintf("[!] blew circular buffer! | datalen %u", dataLen); + break; + } + if (dataLen < 1) continue; + + // primary buffer was stopped( <-- we lost data! + if (!AT91C_BASE_PDC_SSC->PDC_RCR) { + AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) dmaBuf; + AT91C_BASE_PDC_SSC->PDC_RCR = DMA_BUFFER_SIZE; + //Dbprintf("[-] RxEmpty ERROR | data length %d", dataLen); // temporary + } + // secondary buffer sets as primary, secondary buffer was stopped + if (!AT91C_BASE_PDC_SSC->PDC_RNCR) { + AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dmaBuf; + AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE; + } + + LED_A_OFF(); + + // Need two samples to feed Miller and Manchester-Decoder + if (rsamples & 0x01) { + + if (!TagIsActive) { // no need to try decoding reader data if the tag is sending + uint8_t readerdata = (previous_data & 0xF0) | (*data >> 4); + if (MillerDecoding(readerdata, (rsamples-1)*4)) { + LED_C_ON(); + + // check - if there is a short 7bit request from reader + if ((!triggered) && (param & 0x02) && (uart->len == 1) && (uart->bitCount == 7)) triggered = true; + + if (triggered) { + if ((receivedCmd) && ((receivedCmd[0] == MIFARE_ULEV1_AUTH) || (receivedCmd[0] == MIFARE_ULC_AUTH_1))) { + Dbprintf("PWD-AUTH KEY: 0x%02x%02x%02x%02x", receivedCmd[1], receivedCmd[2], receivedCmd[3], receivedCmd[4]); + + // temporarily save the captured pwd in our array + memcpy(&capturedPwds[4 * auth_attempts], receivedCmd+1, 4); + auth_attempts++; + } + + if (!LogTrace(receivedCmd, + uart->len, + uart->startTime*16 - DELAY_READER_AIR2ARM_AS_SNIFFER, + uart->endTime*16 - DELAY_READER_AIR2ARM_AS_SNIFFER, + uart->parity, + true)) break; + } + /* ready to receive another command. */ + UartReset(); + /* reset the demod code, which might have been */ + /* false-triggered by the commands from the reader. */ + DemodReset(); + LED_B_OFF(); + } + ReaderIsActive = (uart->state != STATE_UNSYNCD); + } + + // no need to try decoding tag data if the reader is sending - and we cannot afford the time + if (!ReaderIsActive) { + uint8_t tagdata = (previous_data << 4) | (*data & 0x0F); + if (ManchesterDecoding(tagdata, 0, (rsamples-1)*4)) { + LED_B_ON(); + + if (!LogTrace(receivedResp, + demod->len, + demod->startTime*16 - DELAY_TAG_AIR2ARM_AS_SNIFFER, + demod->endTime*16 - DELAY_TAG_AIR2ARM_AS_SNIFFER, + demod->parity, + false)) break; + + if ((!triggered) && (param & 0x01)) triggered = true; + + // ready to receive another response. + DemodReset(); + // reset the Miller decoder including its (now outdated) input buffer + UartReset(); + //UartInit(receivedCmd, receivedCmdPar); + LED_C_OFF(); + } + TagIsActive = (demod->state != DEMOD_UNSYNCD); + } + } + + previous_data = *data; + rsamples++; + data++; + if (data == dmaBuf + DMA_BUFFER_SIZE) { + data = dmaBuf; + } + } // end main loop + + FpgaDisableSscDma(); + set_tracing(false); + + Dbprintf("Stopped sniffing"); + + SpinDelay(200); + + // Write stuff to flash + if (auth_attempts > 0) { + Dbprintf("[!] auth_attempts = %u", auth_attempts); + + // Read from flash the counter of pwds (to be used as flash mem offset) + uint8_t pwdcnt = 0; + pwdcnt = ReadCounterFromFlash(); + if (pwdcnt == 255) { + // Same as zero + pwdcnt = 0; + } + Dbprintf("[!] PWDs Offset = %u", pwdcnt); + + uint8_t *previousdata = ReadDataFromFlash(pwdcnt); + + // total size = (pwdcnt+1)*4 + 4 * auth_attempts + size_t total_size = (pwdcnt+1)*4 + 4 * auth_attempts; + // create new bigbuf to hold all data + uint8_t *total_data = BigBuf_malloc(total_size); + + // Add the previousdata array into total_data array + memcpy(total_data, previousdata, sizeof(*previousdata) * ((pwdcnt+1)*4)); + + // Copy bytes of capturedPwds immediately following bytes of previousdata + memcpy(total_data + ((pwdcnt+1)*4), capturedPwds, sizeof(*capturedPwds) * (4 * auth_attempts)); + + // change the counter byte + //memset (total_data,pwdcnt + auth_attempts,1); + total_data[0] = (uint8_t)(pwdcnt + auth_attempts); + + //EraseMemory(); + + //for (int i=0;i<(pwdcnt+1)*4 + 4 * auth_attempts;i++) + // Dbprintf("[!] total_data[%d] = 0x%02x", i, total_data[i]); + + //Flash_WriteData(0, total_data, (pwdcnt+1)*4 + 4 * auth_attempts); + WriteDataToFlash(total_data, (pwdcnt+1)*4 + 4 * auth_attempts); + + SpinDelay(200); + } +} + +void RunMod() +{ + Dbprintf("Sniffing started"); + SpinDelay(500); + + // param: + // bit 0 - trigger from first card answer + // bit 1 - trigger from first reader 7-bit request + SniffAndStore(0); + + LEDsoff(); + + SpinDelay(300); +} + diff --git a/armsrc/Standalone/hf_bog.h b/armsrc/Standalone/hf_bog.h new file mode 100644 index 000000000..8b7d4c695 --- /dev/null +++ b/armsrc/Standalone/hf_bog.h @@ -0,0 +1,31 @@ +//----------------------------------------------------------------------------- +// 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. +//----------------------------------------------------------------------------- +// StandAlone Mod +//----------------------------------------------------------------------------- + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef __HF_BOG_H +#define __HF_BOG_H + +#include "proxmark3.h" +#include "mifareutil.h" +#include "iso14443a.h" +#include "protocols.h" +#include "util.h" +#include "standalone.h" // standalone definitions +#include // for bool +#include +#include +#include "apps.h" +#include "printf.h" + +#include "parity.h" +#include "random.h" + +#endif /* __HF_BOG_H */ From 34775c81f57c58837fe86a2ae7d4733150d73331 Mon Sep 17 00:00:00 2001 From: bogiton <34060135+bogiton@users.noreply.github.com> Date: Sun, 21 Oct 2018 18:29:49 +0000 Subject: [PATCH 4/9] Added BogitoRun identification --- armsrc/appmain.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 79eba9cf8..2a3ae823a 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -453,7 +453,10 @@ void printStandAloneModes(void) { #if defined(WITH_HF_COLIN) DbpString(" HF Mifare ultra fast sniff/sim/clone - aka VIGIKPWN (Colin Brigato)"); #endif - +#if defined(WITH_HF_BOG) + DbpString(" HF 14a sniff standalone with ULC/ULEV1/NTAG auth storing in flashmem - aka BogitoRun (Bogito)"); +#endif + //DbpString("Running "); //Dbprintf(" Is Device attached to USB| %s", USB_ATTACHED() ? "Yes" : "No"); //Dbprintf(" Is Device attached to FPC| %s", 0 ? "Yes" : "No"); From 785ab8f73ea7374cd93e7afbbe8b4c74e4646a0a Mon Sep 17 00:00:00 2001 From: bogiton <34060135+bogiton@users.noreply.github.com> Date: Sun, 28 Oct 2018 12:01:36 +0000 Subject: [PATCH 5/9] Baudrate and optimization (removed counter) --- armsrc/Standalone/hf_bog.c | 174 +++++++++---------------------------- 1 file changed, 43 insertions(+), 131 deletions(-) diff --git a/armsrc/Standalone/hf_bog.c b/armsrc/Standalone/hf_bog.c index 5a279ebd9..38d08c320 100644 --- a/armsrc/Standalone/hf_bog.c +++ b/armsrc/Standalone/hf_bog.c @@ -8,68 +8,29 @@ #include "hf_bog.h" #define DELAY_READER_AIR2ARM_AS_SNIFFER (2 + 3 + 8) -#define DELAY_TAG_AIR2ARM_AS_SNIFFER (3 + 14 + 8) -#define MAX_PWDS_PER_SESSION 15 +#define DELAY_TAG_AIR2ARM_AS_SNIFFER (3 + 14 + 8) -uint8_t ReadCounterFromFlash() { - uint8_t mem = 0; +// Maximum number of auth attempts per standalone session +#define MAX_PWDS_PER_SESSION 20 - uint8_t isok = Flash_ReadData(0, &mem, 1); - if (isok == 1) + +uint8_t FindOffsetInFlash() { + uint8_t mem[4] = { 0x00, 0x00, 0x00, 0x00 }; + uint8_t eom[4] = { 0xFF, 0xFF, 0xFF, 0xFF }; + uint8_t memcnt = 0; + + while (1) { - return mem; + Flash_ReadData(memcnt, mem, 4); + if (memcmp(mem, eom, 4) == 0) { + break; + } + memcnt += 4; } - Dbprintf("Reading of counter from flashmem failed"); - return -1; + return memcnt; } -uint8_t* ReadDataFromFlash(uint8_t datacnt) { - - uint16_t isok = 0; - - if (!datacnt) - { - uint8_t *tmp = BigBuf_malloc(4); - for (int i=0;i<4;i++) - tmp[i] = 0x00; - return tmp; - } - - size_t size = (datacnt + 1) * 4; - uint8_t *mem = BigBuf_malloc(size); - - isok = Flash_ReadData(0, mem, (datacnt + 1) * 4); - if (isok == ((datacnt + 1) * 4)) - { - Dbprintf("[OK] Data recovered from flashmem"); - return mem; - } - - Dbprintf("FlashMem reading failed | isok = %d", isok); - SpinDelay(100); - return 0; -} - -/* -void WriteDataToFlash(uint8_t *data, size_t size) -{ - uint8_t isok = 0; - - isok = Flash_WriteData(0, data, size); - - if (!isok) - { - Dbprintf("FlashMem write failed"); - SpinDelay(100); - - return; - } - - Dbprintf("[OK] Data written to flash!"); -} -*/ - void EraseMemory() { if (!FlashInit()){ @@ -80,60 +41,11 @@ void EraseMemory() Flash_WriteEnable(); Flash_Erase4k(0,0); - Dbprintf("[OK] Erased flash!"); + if (MF_DBGLEVEL > 1) Dbprintf("[!] Erased flash!"); FlashStop(); SpinDelay(100); } - -void WriteDataToFlash(uint8_t* data, size_t size) -{ - uint8_t isok = 0; - uint16_t res = 0; - uint32_t len = size; - uint32_t bytes_sent = 0; - uint32_t bytes_remaining = len; - - uint8_t buff[PAGESIZE]; - - if (!FlashInit()){ - return; - } - - Flash_CheckBusy(BUSY_TIMEOUT); - Flash_WriteEnable(); - Flash_Erase4k(0,0); - - while (bytes_remaining > 0) - { - Flash_CheckBusy(BUSY_TIMEOUT); - Flash_WriteEnable(); - - uint32_t bytes_in_packet = MIN(FLASH_MEM_BLOCK_SIZE, bytes_remaining); - - memcpy(buff, data + bytes_sent, bytes_in_packet); - - bytes_remaining -= bytes_in_packet; - res = Flash_WriteDataCont(bytes_sent, buff, bytes_in_packet); - bytes_sent += bytes_in_packet; - - isok = (res == bytes_in_packet) ? 1 : 0; - - if (!isok) - { - Dbprintf("FlashMem write failed [offset %u]", bytes_sent); - SpinDelay(100); - - return; - } - } - - Dbprintf("[OK] Data written to flash! [0-to offset %u]", bytes_sent); - FlashStop(); - - return; -} - void RAMFUNC SniffAndStore(uint8_t param) { // Array to store the authpwds @@ -242,7 +154,7 @@ void RAMFUNC SniffAndStore(uint8_t param) { if (triggered) { if ((receivedCmd) && ((receivedCmd[0] == MIFARE_ULEV1_AUTH) || (receivedCmd[0] == MIFARE_ULC_AUTH_1))) { - Dbprintf("PWD-AUTH KEY: 0x%02x%02x%02x%02x", receivedCmd[1], receivedCmd[2], receivedCmd[3], receivedCmd[4]); + if (MF_DBGLEVEL > 1) Dbprintf("PWD-AUTH KEY: 0x%02x%02x%02x%02x", receivedCmd[1], receivedCmd[2], receivedCmd[3], receivedCmd[4]); // temporarily save the captured pwd in our array memcpy(&capturedPwds[4 * auth_attempts], receivedCmd+1, 4); @@ -309,50 +221,51 @@ void RAMFUNC SniffAndStore(uint8_t param) { // Write stuff to flash if (auth_attempts > 0) { - Dbprintf("[!] auth_attempts = %u", auth_attempts); + if (MF_DBGLEVEL > 1) Dbprintf("[!] Authentication attempts = %u", auth_attempts); - // Read from flash the counter of pwds (to be used as flash mem offset) - uint8_t pwdcnt = 0; - pwdcnt = ReadCounterFromFlash(); - if (pwdcnt == 255) { - // Same as zero - pwdcnt = 0; - } - Dbprintf("[!] PWDs Offset = %u", pwdcnt); + // Setting the SPI Baudrate to 48MHz to avoid the bit-flip issue (https://github.com/RfidResearchGroup/proxmark3/issues/34) + FlashmemSetSpiBaudrate(48000000); - uint8_t *previousdata = ReadDataFromFlash(pwdcnt); + // Find the offset in flash mem to continue writing the auth attempts + uint8_t memoffset = FindOffsetInFlash(); + if (MF_DBGLEVEL > 1) Dbprintf("[!] Memory offset = %u", memoffset); - // total size = (pwdcnt+1)*4 + 4 * auth_attempts - size_t total_size = (pwdcnt+1)*4 + 4 * auth_attempts; + // Get previous data from flash mem + uint8_t *previousdata = BigBuf_malloc(memoffset); + uint16_t readlen = Flash_ReadData(0, previousdata, memoffset); + if (MF_DBGLEVEL > 1) Dbprintf("[!] Read %u bytes from flash mem", readlen); + // create new bigbuf to hold all data + size_t total_size = memoffset + 4 * auth_attempts; uint8_t *total_data = BigBuf_malloc(total_size); // Add the previousdata array into total_data array - memcpy(total_data, previousdata, sizeof(*previousdata) * ((pwdcnt+1)*4)); + memcpy(total_data, previousdata, memoffset); // Copy bytes of capturedPwds immediately following bytes of previousdata - memcpy(total_data + ((pwdcnt+1)*4), capturedPwds, sizeof(*capturedPwds) * (4 * auth_attempts)); + memcpy(total_data + memoffset, capturedPwds, 4 * auth_attempts); - // change the counter byte - //memset (total_data,pwdcnt + auth_attempts,1); - total_data[0] = (uint8_t)(pwdcnt + auth_attempts); + // Erase first page of flash mem + EraseMemory(); - //EraseMemory(); + //for (int i=0; i 1) Dbprintf("[-] total_data[%d] = 0x%02x", i, total_data[i]); - //for (int i=0;i<(pwdcnt+1)*4 + 4 * auth_attempts;i++) - // Dbprintf("[!] total_data[%d] = 0x%02x", i, total_data[i]); + // Write total data to flash mem + uint16_t writelen = Flash_WriteData(0, total_data, memoffset + 4 * auth_attempts); + if (MF_DBGLEVEL > 1) Dbprintf("[!] Wrote %u bytes into flash mem", writelen); - //Flash_WriteData(0, total_data, (pwdcnt+1)*4 + 4 * auth_attempts); - WriteDataToFlash(total_data, (pwdcnt+1)*4 + 4 * auth_attempts); + SpinDelay(100); - SpinDelay(200); + // Reset the SPI Baudrate to the default value (24MHz) + FlashmemSetSpiBaudrate(24000000); } } void RunMod() { Dbprintf("Sniffing started"); - SpinDelay(500); + SpinDelay(200); // param: // bit 0 - trigger from first card answer @@ -363,4 +276,3 @@ void RunMod() SpinDelay(300); } - From 9bd7770dfe9ee4c540f58c2af901741bd3335e58 Mon Sep 17 00:00:00 2001 From: bogiton <34060135+bogiton@users.noreply.github.com> Date: Sun, 28 Oct 2018 12:04:44 +0000 Subject: [PATCH 6/9] Revert to default standalone mode --- armsrc/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/Makefile b/armsrc/Makefile index 8a576f001..d1895e7fa 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -24,7 +24,7 @@ APP_CFLAGS = -DWITH_CRC \ -DWITH_FLASH \ -DWITH_SMARTCARD \ -DWITH_HFSNOOP \ - -DWITH_HF_BOG \ + -DWITH_LF_SAMYRUN \ -DWITH_FPC \ -fno-strict-aliasing -ffunction-sections -fdata-sections From 43f90181b3e1ded43b4a012925edac8e7a9bf17c Mon Sep 17 00:00:00 2001 From: bogiton <34060135+bogiton@users.noreply.github.com> Date: Sun, 28 Oct 2018 13:34:42 +0000 Subject: [PATCH 7/9] Update hf_bog.c --- armsrc/Standalone/hf_bog.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/armsrc/Standalone/hf_bog.c b/armsrc/Standalone/hf_bog.c index 38d08c320..108c7ad59 100644 --- a/armsrc/Standalone/hf_bog.c +++ b/armsrc/Standalone/hf_bog.c @@ -11,7 +11,7 @@ #define DELAY_TAG_AIR2ARM_AS_SNIFFER (3 + 14 + 8) // Maximum number of auth attempts per standalone session -#define MAX_PWDS_PER_SESSION 20 +#define MAX_PWDS_PER_SESSION 64 uint8_t FindOffsetInFlash() { @@ -19,16 +19,16 @@ uint8_t FindOffsetInFlash() { uint8_t eom[4] = { 0xFF, 0xFF, 0xFF, 0xFF }; uint8_t memcnt = 0; - while (1) + while (memcnt < 4096) { Flash_ReadData(memcnt, mem, 4); if (memcmp(mem, eom, 4) == 0) { - break; + return memcnt; } memcnt += 4; } - return memcnt; + return 0; // wrap-around } void EraseMemory() @@ -48,11 +48,6 @@ void EraseMemory() void RAMFUNC SniffAndStore(uint8_t param) { - // Array to store the authpwds - uint8_t *capturedPwds = BigBuf_malloc(4 * MAX_PWDS_PER_SESSION); - - SpinDelay(500); - /* This is actually copied from SniffIso14443a */ iso14443a_setup(FPGA_HF_ISO14443A_SNIFFER); @@ -63,6 +58,9 @@ void RAMFUNC SniffAndStore(uint8_t param) { clear_trace(); set_tracing(true); + // Array to store the authpwds + uint8_t *capturedPwds = BigBuf_malloc(4 * MAX_PWDS_PER_SESSION); + // The command (reader -> tag) that we're receiving. uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE); uint8_t *receivedCmdPar = BigBuf_malloc(MAX_PARITY_SIZE); @@ -265,7 +263,8 @@ void RAMFUNC SniffAndStore(uint8_t param) { void RunMod() { Dbprintf("Sniffing started"); - SpinDelay(200); + + SpinDelay(200); // param: // bit 0 - trigger from first card answer From e14e47735512da332599afbf8fb67fb64fb45348 Mon Sep 17 00:00:00 2001 From: bogiton <34060135+bogiton@users.noreply.github.com> Date: Sun, 28 Oct 2018 13:48:27 +0000 Subject: [PATCH 8/9] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 20f1c1f8f..329eda594 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Added HF sniff standalone mode with optional storing of ULC/NTAG/ULEV1 authentication attempts (@bogiton) - Fix 'Lining up plot and control window' (@anticat) - Fix 'annoying focus behaviour' on OSX (@Anticat) - Implemented AppNap API, fixing #283 and #627 OSX USB comm issues (@AntiCat) From 2718e783dc219dec632e996094172a2aaaff1aa9 Mon Sep 17 00:00:00 2001 From: bogiton <34060135+bogiton@users.noreply.github.com> Date: Sun, 28 Oct 2018 13:54:38 +0000 Subject: [PATCH 9/9] Added small description --- armsrc/Standalone/hf_bog.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/armsrc/Standalone/hf_bog.c b/armsrc/Standalone/hf_bog.c index 108c7ad59..761e67b1a 100644 --- a/armsrc/Standalone/hf_bog.c +++ b/armsrc/Standalone/hf_bog.c @@ -5,6 +5,19 @@ //----------------------------------------------------------------------------- // main code for standalone HF Sniff (and ULC/NTAG/ULEV1 pwd storing) //----------------------------------------------------------------------------- + +/* +This can actually be used in two separate ways. +It can either be used to just HF 14a sniff on the go and/or grab the +authentication attempts for ULC/NTAG/ULEV1 into the flash mem (RDV4). + +The retrieved sniffing session can be acquired by connecting the device +to a client that supports the reconnect capability and issue 'hf 14a list'. + +In order to view the grabbed authentication attempts in the flash mem, +you can simply 'mem read l 256' from the client to view the stored quadlets. +*/ + #include "hf_bog.h" #define DELAY_READER_AIR2ARM_AS_SNIFFER (2 + 3 + 8) @@ -13,7 +26,6 @@ // Maximum number of auth attempts per standalone session #define MAX_PWDS_PER_SESSION 64 - uint8_t FindOffsetInFlash() { uint8_t mem[4] = { 0x00, 0x00, 0x00, 0x00 }; uint8_t eom[4] = { 0xFF, 0xFF, 0xFF, 0xFF };