Merge branch 'master' of https://github.com/RfidResearchGroup/proxmark3 into function/desfire-standalone

This commit is contained in:
Anže Jenšterle
2021-03-13 02:16:26 +01:00
67 changed files with 2957 additions and 1897 deletions

View File

@@ -71,13 +71,13 @@
static void DownloadTraceInstructions(void) {
Dbprintf("");
Dbprintf("To get the trace from flash and display it:");
Dbprintf("1. mem spiffs dump o "HF_14ASNIFF_LOGFILE" f trace.trc");
Dbprintf("2. trace load trace.trc");
Dbprintf("3. trace list 14a 1");
Dbprintf("1. mem spiffs dump -s "HF_14ASNIFF_LOGFILE" -d trace.trc");
Dbprintf("2. trace load -f trace.trc");
Dbprintf("3. trace list -t 14a -1");
}
void ModInfo(void) {
DbpString("hf_14asniff: standalone 'hf 14a sniff', storing in flashmem");
DbpString(" ISO14443a sniff, storing in flashmem");
DownloadTraceInstructions();
}

View File

@@ -130,27 +130,27 @@ static void download_instructions(uint8_t t) {
switch (t) {
case ICE_STATE_FULLSIM: {
DbpString("The emulator memory was saved to SPIFFS");
DbpString("1. " _YELLOW_("mem spiffs dump o " HF_ICLASS_FULLSIM_MOD_BIN " f " HF_ICLASS_FULLSIM_MOD" e"));
DbpString("1. " _YELLOW_("mem spiffs dump -s " HF_ICLASS_FULLSIM_MOD_BIN " -d " HF_ICLASS_FULLSIM_MOD" -e"));
DbpString("2. " _YELLOW_("hf iclass view -f " HF_ICLASS_FULLSIM_MOD_BIN));
break;
}
case ICE_STATE_ATTACK: {
DbpString("The collected data was saved to SPIFFS. The file names below may differ");
DbpString("1. " _YELLOW_("mem spiffs tree"));
DbpString("2. " _YELLOW_("mem spiffs dump o " HF_ICLASS_ATTACK_BIN " f " HF_ICLASS_ATTACK_BIN));
DbpString("2. " _YELLOW_("mem spiffs dump -s " HF_ICLASS_ATTACK_BIN " -d " HF_ICLASS_ATTACK_BIN));
DbpString("3. " _YELLOW_("hf iclass loclass -f " HF_ICLASS_ATTACK_BIN));
break;
}
case ICE_STATE_READER: {
DbpString("The found tags was saved to SPIFFS");
DbpString("1. " _YELLOW_("mem spiffs tree"));
DbpString("2. " _YELLOW_("mem spiffs dump h"));
DbpString("2. " _YELLOW_("mem spiffs dump -h"));
break;
}
case ICE_STATE_DUMP_SIM: {
DbpString("The found tag will be dumped to " HF_ICALSSS_READSIM_TEMP_BIN);
DbpString("1. " _YELLOW_("mem spiffs tree"));
DbpString("2. " _YELLOW_("mem spiffs dump h"));
DbpString("2. " _YELLOW_("mem spiffs dump -h"));
break;
}
}

View File

@@ -39,7 +39,7 @@
*
* To delete a dump file from flash:
*
* 1. mem spiffs remove hf-legic-XXYYZZWW-dump.bin
* 1. mem spiffs remove -f hf-legic-XXYYZZWW-dump.bin
*
*/
@@ -50,7 +50,7 @@ static void DownloadLogInstructions(void) {
Dbprintf("[=] " _YELLOW_("-") " mem spiffs tree");
Dbprintf("");
Dbprintf("[=] To save a dump file from flash to client:");
Dbprintf("[=] " _YELLOW_("-") " mem spiffs dump o hf-legic-UID-dump.bin f hf-legic-UID-dump.bin");
Dbprintf("[=] " _YELLOW_("-") " mem spiffs dump -s hf-legic-UID-dump.bin -d hf-legic-UID-dump.bin");
}
#endif

View File

@@ -36,7 +36,7 @@
*
* To retrieve log file from flash:
*
* 1. mem spiffs dump o lf_hidcollect.log f lf_hidcollect.log
* 1. mem spiffs dump -s lf_hidcollect.log -d lf_hidcollect.log
* Copies log file from flash to your client.
*
* 2. exit the Proxmark3 client
@@ -48,7 +48,7 @@
*
* To delete the log file from flash:
*
* 1. mem spiffs remove lf_hidcollect.log
* 1. mem spiffs remove -f lf_hidcollect.log
*/
#define LF_HIDCOLLECT_LOGFILE "lf_hidcollect.log"
@@ -57,7 +57,7 @@
static void DownloadLogInstructions(void) {
Dbprintf("");
Dbprintf("[=] To get the logfile from flash and display it:");
Dbprintf("[=] " _YELLOW_("1.") " mem spiffs dump o "LF_HIDCOLLECT_LOGFILE" f "LF_HIDCOLLECT_LOGFILE);
Dbprintf("[=] " _YELLOW_("1.") " mem spiffs dump -s "LF_HIDCOLLECT_LOGFILE" -d "LF_HIDCOLLECT_LOGFILE);
Dbprintf("[=] " _YELLOW_("2.") " exit proxmark3 client");
Dbprintf("[=] " _YELLOW_("3.") " cat "LF_HIDCOLLECT_LOGFILE);
}

View File

@@ -42,25 +42,25 @@
* - LED D: unmounting/sync'ing flash (normally < 100ms)
*
* To upload input file (eml format) to flash:
* - mem spiffs load f <filename> o lf_em4x50_simulate.eml
* - mem spiffs upload -s <filename> -d lf_em4x50_simulate.eml
*
* To retrieve password file from flash:
* - mem spiffs dump o lf_em4x50_passwords.log f <filename>
* - mem spiffs dump -s lf_em4x50_passwords.log
*
* To retrieve log file from flash:
* - mem spiffs dump o lf_em4x50_collect.log f <filename>
* - mem spiffs dump -s lf_em4x50_collect.log
*
* This module emits debug strings during normal operation -- so try it out in
* the lab connected to PM3 client before taking it into the field.
*
* To delete the input file from flash:
* - mem spiffs remove lf_em4x50_simulate.eml
* - mem spiffs remove -f lf_em4x50_simulate.eml
*
* To delete the log file from flash:
* - mem spiffs remove lf_em4x50_passwords.log
* - mem spiffs remove -f lf_em4x50_passwords.log
*
* To delete the log file from flash:
* - mem spiffs remove lf_em4x50_collect.log
* - mem spiffs remove -f lf_em4x50_collect.log
*/
#define STATE_SIM 0
@@ -77,14 +77,14 @@ static void LoadDataInstructions(const char *inputfile) {
Dbprintf("To load datafile to flash and display it:");
Dbprintf("1. edit input file %s", inputfile);
Dbprintf("2. start proxmark3 client");
Dbprintf("3. mem spiffs load f <filename> o %s", inputfile);
Dbprintf("3. mem spiffs upload -s <filename> -d %s", inputfile);
Dbprintf("4. start standalone mode");
}
static void DownloadLogInstructions(const char *logfile) {
Dbprintf("");
Dbprintf("To get the logfile from flash and display it:");
Dbprintf("1. mem spiffs dump o %s f <filename>", logfile);
Dbprintf("1. mem spiffs dump -s %s", logfile);
Dbprintf("2. exit proxmark3 client");
Dbprintf("3. cat <filename>");
}

View File

@@ -77,6 +77,7 @@ If your mode is using one of the unique features of the RDV4, add it to the prop
```
STANDALONE_MODES_REQ_SMARTCARD :=
STANDALONE_MODES_REQ_FLASH :=
STANDALONE_MODES_REQ_BT :=
```
## Update MAKEFILE.INC

View File

@@ -73,8 +73,8 @@ extern uint32_t _stack_start, _stack_end;
struct common_area common_area __attribute__((section(".commonarea")));
static int button_status = BUTTON_NO_CLICK;
static bool allow_send_wtx = false;
static uint16_t tearoff_delay_us = 0;
static bool tearoff_enabled = false;
uint16_t tearoff_delay_us = 0;
bool tearoff_enabled = false;
int tearoff_hook(void) {
if (tearoff_enabled) {
@@ -2078,7 +2078,7 @@ static void PacketReceived(PacketCommandNG *packet) {
Dbprintf("transfer to client failed :: | bytes between %d - %d (%d) | result: %d", i, i + len, len, result);
}
// Trigger a finish downloading signal with an ACK frame
reply_mix(CMD_ACK, 1, 0, 0, 0, 0);
reply_ng(CMD_SPIFFS_DOWNLOAD, PM3_SUCCESS, NULL, 0);
LED_B_OFF();
break;
}
@@ -2087,78 +2087,94 @@ static void PacketReceived(PacketCommandNG *packet) {
uint8_t filename[32];
uint8_t *pfilename = packet->data.asBytes;
memcpy(filename, pfilename, SPIFFS_OBJ_NAME_LEN);
if (DBGLEVEL >= DBG_DEBUG) Dbprintf("Filename received for spiffs STAT : %s", filename);
if (DBGLEVEL >= DBG_DEBUG) {
Dbprintf("Filename received for spiffs STAT : %s", filename);
}
int changed = rdv40_spiffs_lazy_mount();
uint32_t size = size_in_spiffs((char *)filename);
if (changed) rdv40_spiffs_lazy_unmount();
reply_mix(CMD_ACK, size, 0, 0, 0, 0);
if (changed) {
rdv40_spiffs_lazy_unmount();
}
reply_ng(CMD_SPIFFS_STAT, PM3_SUCCESS, (uint8_t *)&size, sizeof(uint32_t));
LED_B_OFF();
break;
}
case CMD_SPIFFS_REMOVE: {
LED_B_ON();
uint8_t filename[32];
uint8_t *pfilename = packet->data.asBytes;
memcpy(filename, pfilename, SPIFFS_OBJ_NAME_LEN);
if (DBGLEVEL >= DBG_DEBUG) Dbprintf("Filename received for spiffs REMOVE : %s", filename);
rdv40_spiffs_remove((char *) filename, RDV40_SPIFFS_SAFETY_SAFE);
struct p {
uint8_t len;
uint8_t fn[32];
} PACKED;
struct p *payload = (struct p *) packet->data.asBytes;
if (DBGLEVEL >= DBG_DEBUG) {
Dbprintf("Filename received for spiffs REMOVE : %s", payload->fn);
}
rdv40_spiffs_remove((char *)payload->fn, RDV40_SPIFFS_SAFETY_SAFE);
reply_ng(CMD_SPIFFS_REMOVE, PM3_SUCCESS, NULL, 0);
LED_B_OFF();
break;
}
case CMD_SPIFFS_RENAME: {
LED_B_ON();
uint8_t src[32];
uint8_t dest[32];
uint8_t *pfilename = packet->data.asBytes;
char *token;
token = strtok((char *)pfilename, ",");
strncpy((char *)src, token, sizeof(src) - 1);
token = strtok(NULL, ",");
strncpy((char *)dest, token, sizeof(dest) - 1);
struct p {
uint8_t slen;
uint8_t src[32];
uint8_t dlen;
uint8_t dest[32];
} PACKED;
struct p *payload = (struct p *) packet->data.asBytes;
if (DBGLEVEL >= DBG_DEBUG) {
Dbprintf("Filename received as source for spiffs RENAME : %s", src);
Dbprintf("Filename received as destination for spiffs RENAME : %s", dest);
Dbprintf("SPIFFS RENAME");
Dbprintf("Source........ %s", payload->src);
Dbprintf("Destination... %s", payload->dest);
}
rdv40_spiffs_rename((char *) src, (char *)dest, RDV40_SPIFFS_SAFETY_SAFE);
rdv40_spiffs_rename((char *)payload->src, (char *)payload->dest, RDV40_SPIFFS_SAFETY_SAFE);
reply_ng(CMD_SPIFFS_RENAME, PM3_SUCCESS, NULL, 0);
LED_B_OFF();
break;
}
case CMD_SPIFFS_COPY: {
LED_B_ON();
uint8_t src[32];
uint8_t dest[32];
uint8_t *pfilename = packet->data.asBytes;
char *token;
token = strtok((char *)pfilename, ",");
strncpy((char *)src, token, sizeof(src) - 1);
token = strtok(NULL, ",");
strncpy((char *)dest, token, sizeof(dest) - 1);
struct p {
uint8_t slen;
uint8_t src[32];
uint8_t dlen;
uint8_t dest[32];
} PACKED;
struct p *payload = (struct p *) packet->data.asBytes;
if (DBGLEVEL >= DBG_DEBUG) {
Dbprintf("Filename received as source for spiffs COPY : %s", src);
Dbprintf("Filename received as destination for spiffs COPY : %s", dest);
Dbprintf("SPIFFS COPY");
Dbprintf("Source........ %s", payload->src);
Dbprintf("Destination... %s", payload->dest);
}
rdv40_spiffs_copy((char *) src, (char *)dest, RDV40_SPIFFS_SAFETY_SAFE);
rdv40_spiffs_copy((char *)payload->src, (char *)payload->dest, RDV40_SPIFFS_SAFETY_SAFE);
reply_ng(CMD_SPIFFS_COPY, PM3_SUCCESS, NULL, 0);
LED_B_OFF();
break;
}
case CMD_SPIFFS_WRITE: {
LED_B_ON();
uint8_t filename[32];
uint32_t append = packet->oldarg[0];
uint32_t size = packet->oldarg[1];
uint8_t *data = packet->data.asBytes;
uint8_t *pfilename = packet->data.asBytes;
memcpy(filename, pfilename, SPIFFS_OBJ_NAME_LEN);
data += SPIFFS_OBJ_NAME_LEN;
if (DBGLEVEL >= DBG_DEBUG) Dbprintf("> Filename received for spiffs WRITE : %s with APPEND SET TO : %d", filename, append);
flashmem_write_t *payload = (flashmem_write_t *)packet->data.asBytes;
if (!append) {
rdv40_spiffs_write((char *) filename, (uint8_t *)data, size, RDV40_SPIFFS_SAFETY_SAFE);
} else {
rdv40_spiffs_append((char *) filename, (uint8_t *)data, size, RDV40_SPIFFS_SAFETY_SAFE);
if (DBGLEVEL >= DBG_DEBUG) {
Dbprintf("SPIFFS WRITE, dest `%s` with APPEND set to: %c", payload->fn, payload->append ? 'Y' : 'N');
}
reply_mix(CMD_ACK, 1, 0, 0, 0, 0);
if (payload->append) {
rdv40_spiffs_append((char *) payload->fn, payload->data, payload->bytes_in_packet, RDV40_SPIFFS_SAFETY_SAFE);
} else {
rdv40_spiffs_write((char *) payload->fn, payload->data, payload->bytes_in_packet, RDV40_SPIFFS_SAFETY_SAFE);
}
reply_ng(CMD_SPIFFS_WRITE, PM3_SUCCESS, NULL, 0);
LED_B_OFF();
break;
}
@@ -2202,6 +2218,10 @@ static void PacketReceived(PacketCommandNG *packet) {
Flash_CheckBusy(BUSY_TIMEOUT);
Flash_WriteEnable();
Flash_Erase4k(3, 0xB);
} else if (startidx == FLASH_MEM_SIGNATURE_OFFSET) {
Flash_CheckBusy(BUSY_TIMEOUT);
Flash_WriteEnable();
Flash_Erase4k(3, 0xF);
}
res = Flash_Write(startidx, data, len);

View File

@@ -1881,7 +1881,7 @@ void iClass_WriteBlock(uint8_t *msg) {
iclass_send_as_reader(write, write_len, &start_time, &eof_time);
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occured
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occurred
res = false;
switch_off();
if (payload->req.send_reply)

View File

@@ -2972,7 +2972,7 @@ void ReaderIso14443a(PacketCommandNG *c) {
}
}
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occured
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occurred
FpgaDisableTracing();
reply_mix(CMD_ACK, 0, 0, 0, NULL, 0);
} else {

View File

@@ -2092,7 +2092,7 @@ void SendRawCommand14443B_Ex(PacketCommandNG *c) {
uint32_t eof_time = 0;
CodeAndTransmit14443bAsReader(cmd, len, &start_time, &eof_time);
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occured
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occurred
FpgaDisableTracing();
reply_mix(CMD_HF_ISO14443B_COMMAND, -2, 0, 0, NULL, 0);
} else {

View File

@@ -1477,7 +1477,7 @@ int SendDataTag(uint8_t *send, int sendlen, bool init, bool speed_fast, uint8_t
tosend_t *ts = get_tosend();
TransmitTo15693Tag(ts->buf, ts->max, &start_time);
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occured
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occurred
res = PM3_ETEAROFF;
@@ -1598,7 +1598,7 @@ void ReaderIso15693(uint32_t parameter) {
uint32_t eof_time;
int recvlen = SendDataTag(cmd, sizeof(cmd), true, true, answer, ISO15693_MAX_RESPONSE_LENGTH, start_time, ISO15693_READER_TIMEOUT, &eof_time);
if (recvlen == PM3_ETEAROFF) { // tearoff occured
if (recvlen == PM3_ETEAROFF) { // tearoff occurred
reply_mix(CMD_ACK, recvlen, 0, 0, NULL, 0);
} else {
@@ -1928,7 +1928,7 @@ void DirectTag15693Command(uint32_t datalen, uint32_t speed, uint32_t recv, uint
uint32_t start_time = 0;
int recvlen = SendDataTag(data, datalen, true, speed, (recv ? recvbuf : NULL), sizeof(recvbuf), start_time, timeout, &eof_time);
if (recvlen == PM3_ETEAROFF) { // tearoff occured
if (recvlen == PM3_ETEAROFF) { // tearoff occurred
reply_mix(CMD_ACK, recvlen, 0, 0, NULL, 0);
} else {

View File

@@ -2639,7 +2639,7 @@ void EM4xWriteWord(uint8_t addr, uint32_t data, uint32_t pwd, uint8_t usepwd) {
SendForward(len, false);
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occured
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occurred
StopTicks();
reply_ng(CMD_LF_EM4X_WRITEWORD, PM3_ETEAROFF, NULL, 0);
} else {
@@ -2681,7 +2681,7 @@ void EM4xProtectWord(uint32_t data, uint32_t pwd, uint8_t usepwd) {
SendForward(len, false);
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occured
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occurred
StopTicks();
reply_ng(CMD_LF_EM4X_PROTECTWORD, PM3_ETEAROFF, NULL, 0);
} else {

View File

@@ -2713,20 +2713,15 @@ void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain) {
//
// Tear-off attack against MFU.
// - Moebius et al
void MifareU_Otp_Tearoff(uint8_t blno, uint32_t tearoff_time, uint8_t *datain) {
void MifareU_Otp_Tearoff(uint8_t blno, uint32_t tearoff_time, uint8_t *data_testwrite) {
uint8_t blockNo = blno;
uint8_t data_fullwrite[4] = {0x00};
uint8_t data_testwrite[4] = {0x00};
memcpy(data_fullwrite, datain, 4);
memcpy(data_testwrite, datain + 4, 4);
if (DBGLEVEL >= DBG_DEBUG) DbpString("Preparing OTP tear-off");
if (tearoff_time > 43000)
tearoff_time = 43000;
MifareUWriteBlockEx(blockNo, 0, data_fullwrite, false);
tearoff_delay_us = tearoff_time;
tearoff_enabled = true;
LEDsoff();
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
@@ -2750,15 +2745,9 @@ void MifareU_Otp_Tearoff(uint8_t blno, uint32_t tearoff_time, uint8_t *datain) {
return;
};
// send
ReaderTransmit(cmd, sizeof(cmd), NULL);
// Wait before cutting power. aka tear-off
LED_D_ON();
SpinDelayUsPrecision(tearoff_time);
if (DBGLEVEL >= DBG_DEBUG) Dbprintf(_YELLOW_("OTP tear-off triggered!"));
switch_off();
ReaderTransmit(cmd, sizeof(cmd), NULL);
tearoff_hook();
reply_ng(CMD_HF_MFU_OTP_TEAROFF, PM3_SUCCESS, NULL, 0);
}

View File

@@ -208,15 +208,12 @@ static void remove_from_spiffs(const char *filename) {
Dbprintf("errno %i\n", SPIFFS_errno(&fs));
}
static spiffs_stat stat_in_spiffs(const char *filename) {
spiffs_stat s;
if (SPIFFS_stat(&fs, filename, &s) < 0)
Dbprintf("errno %i\n", SPIFFS_errno(&fs));
return s;
}
uint32_t size_in_spiffs(const char *filename) {
spiffs_stat s = stat_in_spiffs(filename);
spiffs_stat s;
if (SPIFFS_stat(&fs, filename, &s) < 0) {
Dbprintf("errno %i\n", SPIFFS_errno(&fs));
return 0;
}
return s.size;
}