diff --git a/CHANGELOG.md b/CHANGELOG.md index c456ac64d..119971155 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,22 @@ 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 verbose flag to `hf iclass encode` (@natesales) + - Fixed `Makefile` regression that broke `make install` (@henrygab) + - Fixed `lf em 4x70 brute` - now works as expected (@adite) + - Fixed the lf sampling when bits_per_sample is less than 8 (@wh201906) + - Added `lf em 4x70 brute` command (@adite) + - Added documentation for usage of Proxmark3 under WSL2 (@henrygab) + - Fixed device permissions via updated `udev` rules (@henrygab) + - Added `--back` option to `clear` command to clear the scrollback buffer (@wh201906) + +## [Nitride.4.16191][2023-01-29] + - Changed `build_all_firmwares.sh` to fit GENERIC 256kb firmware images (@doegox) + - Fixed some coverity fixes (@iceman1001) + - Fixed `make accessrights` on Fedora (@mooey5775) + - Fixed `hf mfu info` - can now identify the 50 pF version of NTAG 210u(micro) (@mjacksn) + - Added `hf 15` sub-commands for controlling EAS, AFI, privacy mode, and the setting of passwords on SLIX tags (@mjacksn) + - Added new magic gen4 cards command in docs (@McEloff) - Added `hf tesla info` - intital information command to read TESLA cards (@iceman1001) - Changed `hf emrtd info` - looking for lower case .bin extensions (@iceman1001) - Changed `hf emrtd dump` - looking for lower case .bin extensions (@iceman1001) @@ -40,7 +56,6 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Fixed `pm3` shell script now automatically detects WSL2 with USBIPD serial ports (@iceman1001) - Fixed `trace list -c` - annotation of CRC bytes now is colored or squared if no ansi colors is supported (@iceman1001) - Fixed `trace list -t mf` - now also finds UID if anticollision is partial captured, to be used for mfkey (@iceman1001) - - Fixed `make accessrights` on Fedora (@mooey5775) ## [Radium.4.15864][2022-10-29] - Changed `lf indala sim` - now accepts fc / cn (@iceman1001) @@ -1363,9 +1378,10 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Mifare simulation, `hf mf sim` (was broken a long time) (@pwpiwi) - Major improvements in LF area and data operations. (@marshmellow42, @iceman1001) - Issues regarding LF simulation (@pwpiwi) + - Issue interpreting NXP "get sys info" command return value for icode tags. (@mjacksn) ### Added - iClass functionality: full simulation of iclass tags, so tags can be simulated with data (not only CSN). Not yet support for write/update, but readers do not seem to enforce update. (@holiman). - iClass decryption. Proxmark can now decrypt data on an iclass tag, but requires you to have the HID decryption key locally on your computer, as this is not bundled with the sourcecode. - `hf 15 info` can detect NTAG 5 tags - - `hf 15 info` include an EAS status check on more of the icode tags which support EAS (SLI, SLIX, SLIX-L, and SLIX-S) \ No newline at end of file + - `hf 15 info` include an EAS status check on more of the icode tags which support EAS (SLI, SLIX, SLIX-L, and SLIX-S) diff --git a/Makefile b/Makefile index 0cb778ec6..c482af694 100644 --- a/Makefile +++ b/Makefile @@ -65,7 +65,13 @@ ifneq (,$(INSTALLSIMFW)) endif ifeq ($(platform),Linux) $(Q)$(INSTALLSUDO) $(MKDIR) $(DESTDIR)$(UDEV_PREFIX) - $(Q)$(INSTALLSUDO) $(CP) driver/77-pm3-usb-device-blacklist.rules $(DESTDIR)$(UDEV_PREFIX)/77-pm3-usb-device-blacklist.rules +# If user is running ArchLinux, use group 'uucp' +# Else, use group 'dialout' + ifneq ($(wildcard /etc/arch-release),) + $(Q)$(INSTALLSUDO) $(CP) driver/77-pm3-usb-device-blacklist-uucp.rules $(DESTDIR)$(UDEV_PREFIX)/77-pm3-usb-device-blacklist.rules + else + $(Q)$(INSTALLSUDO) $(CP) driver/77-pm3-usb-device-blacklist-dialout.rules $(DESTDIR)$(UDEV_PREFIX)/77-pm3-usb-device-blacklist.rules + endif endif uninstall: common/uninstall @@ -256,8 +262,15 @@ endif # configure system to ignore PM3 device as a modem (ModemManager blacklist, effective *only* if ModemManager is not using _strict_ policy) # Read doc/md/ModemManager-Must-Be-Discarded.md for more info udev: - $(SUDO) cp -rf driver/77-pm3-usb-device-blacklist.rules $(DESTDIR)$(UDEV_PREFIX)/77-pm3-usb-device-blacklist.rules +ifneq ($(wildcard /etc/arch-release),) +# If user is running ArchLinux, use group 'uucp' + $(SUDO) cp -rf driver/77-pm3-usb-device-blacklist-uucp.rules $(DESTDIR)$(UDEV_PREFIX)/77-pm3-usb-device-blacklist.rules +else +# Else, use group 'dialout' + $(SUDO) cp -rf driver/77-pm3-usb-device-blacklist-dialout.rules $(DESTDIR)$(UDEV_PREFIX)/77-pm3-usb-device-blacklist.rules +endif $(SUDO) udevadm control --reload-rules + $(SUDO) udevadm trigger --action=change # configure system to add user to the dialout group and if bluetooth group exists, add user to it # you need to logout, relogin to get this access right correct. diff --git a/Makefile.platform.sample b/Makefile.platform.sample index 5dc19e8f0..21fb2137e 100644 --- a/Makefile.platform.sample +++ b/Makefile.platform.sample @@ -7,6 +7,19 @@ PLATFORM=PM3RDV4 #PLATFORM_EXTRAS=BTADDON #STANDALONE=LF_SAMYRUN +# Uncomment the lines below in order to make a 256KB image +# and comment out the lines above + +#PLATFORM=PM3GENERIC +#PLATFORM_SIZE=256 +#STANDALONE= +#SKIP_HITAG=1 +#SKIP_FELICA=1 +#SKIP_HFPLOT=1 +#SKIP_NFCBARCODE=1 +#SKIP_ZX8211=1 +#SKIP_LF=1 + # To accelerate repetitive compilations: # Install package "ccache" -> Debian/Ubuntu: /usr/lib/ccache, Fedora/CentOS/RHEL: /usr/lib64/ccache # And uncomment the following line diff --git a/armsrc/Standalone/lf_prox2brute.c b/armsrc/Standalone/lf_prox2brute.c index 4f092007f..ecfaac9e3 100644 --- a/armsrc/Standalone/lf_prox2brute.c +++ b/armsrc/Standalone/lf_prox2brute.c @@ -57,19 +57,19 @@ void RunMod(void) { WDT_HIT(); // exit from SamyRun, send a usbcommand. if (data_available()) { // early exit - DbpString("[=] You can take the shell back :) ..."); + DbpString("[=] You can take the shell back :) ..."); LEDsoff(); return; } } - + LED_C_ON(); WAIT_BUTTON_RELEASED(); // We are now ready to start brutforcing card numbers LEDsoff(); Dbprintf("[=] Starting HID ProxII Bruteforce from card %08x to %08x", CARDNUM_START, MIN(CARDNUM_END, 0xFFFF)); - + for (cardnum = CARDNUM_START ; cardnum <= MIN(CARDNUM_END, 0xFFFF) ; cardnum++) { WDT_HIT(); @@ -92,14 +92,14 @@ void RunMod(void) { // switch leds to be able to know (aproximatly) which card number worked (64 tries loop) LED_A_INV(); // switch led A every try - if ((cardnum-CARDNUM_START) % 8 == 7) // switch led B every 8 tries + if ((cardnum - CARDNUM_START) % 8 == 7) // switch led B every 8 tries LED_B_INV(); - if ((cardnum-CARDNUM_START) % 16 == 15) // switch led C every 16 tries + if ((cardnum - CARDNUM_START) % 16 == 15) // switch led C every 16 tries LED_C_INV(); - if ((cardnum-CARDNUM_START) % 32 == 31) // switch led D every 32 tries + if ((cardnum - CARDNUM_START) % 32 == 31) // switch led D every 32 tries LED_D_INV(); } - + SpinErr((LED_A | LED_B | LED_C | LED_D), 250, 5); // Xmax tree Dbprintf("[=] Ending HID ProxII Bruteforce from card %08x to %08x", CARDNUM_START, cardnum - 1); diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 76d9ac3c0..bc22f1834 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -453,6 +453,12 @@ static void SendCapabilities(void) { capabilities.baudrate = g_usart_baudrate; #endif +#ifdef RDV4 + capabilities.is_rdv4 = true; +#else + capabilities.is_rdv4 = false; +#endif + #ifdef WITH_FLASH capabilities.compiled_with_flash = true; capabilities.hw_available_flash = FlashInit(); @@ -1221,6 +1227,10 @@ static void PacketReceived(PacketCommandNG *packet) { em4x70_write_key((em4x70_data_t *)packet->data.asBytes, true); break; } + case CMD_LF_EM4X70_BRUTE: { + em4x70_brute((em4x70_data_t *)packet->data.asBytes, true); + break; + } #endif #ifdef WITH_ZX8211 @@ -1287,20 +1297,76 @@ static void PacketReceived(PacketCommandNG *packet) { SetTag15693Uid(payload->uid); break; } - case CMD_HF_ISO15693_SLIX_L_DISABLE_PRIVACY: { + case CMD_HF_ISO15693_SLIX_DISABLE_EAS: { struct p { uint8_t pwd[4]; + bool usepwd; } PACKED; struct p *payload = (struct p *) packet->data.asBytes; - DisablePrivacySlixLIso15693(payload->pwd); + DisableEAS_AFISlixIso15693(payload->pwd, payload->usepwd); break; } - case CMD_HF_ISO15693_SLIX_L_DISABLE_AESAFI: { + case CMD_HF_ISO15693_SLIX_ENABLE_EAS: { + struct p { + uint8_t pwd[4]; + bool usepwd; + } PACKED; + struct p *payload = (struct p *) packet->data.asBytes; + EnableEAS_AFISlixIso15693(payload->pwd, payload->usepwd); + break; + } + case CMD_HF_ISO15693_SLIX_WRITE_PWD: { + struct p { + uint8_t old_pwd[4]; + uint8_t new_pwd[4]; + uint8_t pwd_id; + } PACKED; + struct p *payload = (struct p *) packet->data.asBytes; + WritePasswordSlixIso15693(payload->old_pwd, payload->new_pwd, payload->pwd_id); + break; + } + case CMD_HF_ISO15693_SLIX_DISABLE_PRIVACY: { struct p { uint8_t pwd[4]; } PACKED; struct p *payload = (struct p *) packet->data.asBytes; - DisableEAS_AFISlixLIso15693(payload->pwd); + DisablePrivacySlixIso15693(payload->pwd); + break; + } + case CMD_HF_ISO15693_SLIX_ENABLE_PRIVACY: { + struct p { + uint8_t pwd[4]; + } PACKED; + struct p *payload = (struct p *)packet->data.asBytes; + EnablePrivacySlixIso15693(payload->pwd); + break; + } + case CMD_HF_ISO15693_SLIX_PASS_PROTECT_AFI: { + struct p { + uint8_t pwd[4]; + } PACKED; + struct p *payload = (struct p *)packet->data.asBytes; + PassProtectAFISlixIso15693(payload->pwd); + break; + } + case CMD_HF_ISO15693_WRITE_AFI: { + struct p { + uint8_t pwd[4]; + bool use_pwd; + uint8_t uid[8]; + bool use_uid; + uint8_t afi; + } PACKED; + struct p *payload = (struct p *)packet->data.asBytes; + WriteAFIIso15693(payload->pwd, payload->use_pwd, payload->uid, payload->use_uid, payload->afi); + break; + } + case CMD_HF_ISO15693_SLIX_PASS_PROTECT_EAS: { + struct p { + uint8_t pwd[4]; + } PACKED; + struct p *payload = (struct p *)packet->data.asBytes; + PassProtextEASSlixIso15693(payload->pwd); break; } diff --git a/armsrc/em4x70.c b/armsrc/em4x70.c index 4dad5f236..066aad58f 100644 --- a/armsrc/em4x70.c +++ b/armsrc/em4x70.c @@ -21,6 +21,7 @@ #include "dbprint.h" #include "lfadc.h" #include "commonutil.h" +#include "optimized_cipherutils.h" #include "em4x70.h" #include "appmain.h" // tear @@ -85,7 +86,7 @@ static int em4x70_receive(uint8_t *bits, size_t length); static bool find_listen_window(bool command); static void init_tag(void) { - memset(tag.data, 0x00, ARRAYLEN(tag.data)); + memset(tag.data, 0x00, sizeof(tag.data)); } static void em4x70_setup_read(void) { @@ -298,14 +299,14 @@ static bool check_ack(void) { // returns true if signal structue corresponds to ACK, anything else is // counted as NAK (-> false) // ACK 64 + 64 - // NACK 64 + 48 + // NAK 64 + 48 if (check_pulse_length(get_pulse_length(FALLING_EDGE), 2 * EM4X70_T_TAG_FULL_PERIOD) && check_pulse_length(get_pulse_length(FALLING_EDGE), 2 * EM4X70_T_TAG_FULL_PERIOD)) { // ACK return true; } - // Othewise it was a NACK or Listen Window + // Otherwise it was a NAK or Listen Window return false; } @@ -339,7 +340,7 @@ static int authenticate(const uint8_t *rnd, const uint8_t *frnd, uint8_t *respon uint8_t grnd[EM4X70_MAX_RECEIVE_LENGTH] = {0}; int num = em4x70_receive(grnd, 20); if (num < 20) { - Dbprintf("Auth failed"); + if (g_dbglevel >= DBG_EXTENDED) Dbprintf("Auth failed"); return PM3_ESOFT; } bits2bytes(grnd, 24, response); @@ -349,6 +350,80 @@ static int authenticate(const uint8_t *rnd, const uint8_t *frnd, uint8_t *respon return PM3_ESOFT; } +static int set_byte(uint8_t *target, int value) { + int c = value > 0xFF; + *target = reflect8(value); + return c; +} + +static int bruteforce(const uint8_t address, const uint8_t *rnd, const uint8_t *frnd, uint16_t start_key, uint8_t *response) { + + uint8_t auth_resp[3] = {0}; + uint8_t rev_rnd[7]; + uint8_t temp_rnd[7]; + + reverse_arraycopy((uint8_t *)rnd, rev_rnd, sizeof(rev_rnd)); + memcpy(temp_rnd, rnd, sizeof(temp_rnd)); + + for (int k = start_key; k <= 0xFFFF; ++k) { + int c = 0; + + WDT_HIT(); + + uint16_t rev_k = reflect16(k); + switch (address) { + case 9: + c = set_byte(&temp_rnd[0], rev_rnd[0] + (rev_k & 0xFF)); + c = set_byte(&temp_rnd[1], rev_rnd[1] + c + ((rev_k >> 8) & 0xFF)); + c = set_byte(&temp_rnd[2], rev_rnd[2] + c); + c = set_byte(&temp_rnd[3], rev_rnd[3] + c); + c = set_byte(&temp_rnd[4], rev_rnd[4] + c); + c = set_byte(&temp_rnd[5], rev_rnd[5] + c); + set_byte(&temp_rnd[6], rev_rnd[6] + c); + break; + + case 8: + c = set_byte(&temp_rnd[2], rev_rnd[2] + (rev_k & 0xFF)); + c = set_byte(&temp_rnd[3], rev_rnd[3] + c + ((rev_k >> 8) & 0xFF)); + c = set_byte(&temp_rnd[4], rev_rnd[4] + c); + c = set_byte(&temp_rnd[5], rev_rnd[5] + c); + set_byte(&temp_rnd[6], rev_rnd[6] + c); + break; + + case 7: + c = set_byte(&temp_rnd[4], rev_rnd[4] + (rev_k & 0xFF)); + c = set_byte(&temp_rnd[5], rev_rnd[5] + c + ((rev_k >> 8) & 0xFF)); + set_byte(&temp_rnd[6], rev_rnd[6] + c); + break; + + default: + Dbprintf("Bad block number given: %d", address); + return PM3_ESOFT; + } + + // Report progress every 256 attempts + if ((k % 0x100) == 0) { + Dbprintf("Trying: %04X", k); + } + + // Due to performance reason, we only try it once. Therefore you need a very stable RFID communcation. + if (authenticate(temp_rnd, frnd, auth_resp) == PM3_SUCCESS) { + if (g_dbglevel >= DBG_INFO) + Dbprintf("Authentication success with rnd: %02X%02X%02X%02X%02X%02X%02X", temp_rnd[0], temp_rnd[1], temp_rnd[2], temp_rnd[3], temp_rnd[4], temp_rnd[5], temp_rnd[6]); + response[0] = (k >> 8) & 0xFF; + response[1] = k & 0xFF; + return PM3_SUCCESS; + } + + if (BUTTON_PRESS() || data_available()) { + Dbprintf("EM4x70 Bruteforce Interrupted"); + return PM3_EOPABORTED; + } + } + + return PM3_ESOFT; +} + static int send_pin(const uint32_t pin) { // sends pin code for unlocking @@ -576,7 +651,7 @@ static int em4x70_receive(uint8_t *bits, size_t length) { } if (!foundheader) { - Dbprintf("Failed to find read header"); + if (g_dbglevel >= DBG_EXTENDED) Dbprintf("Failed to find read header"); return 0; } @@ -738,6 +813,27 @@ void em4x70_auth(em4x70_data_t *etd, bool ledcontrol) { reply_ng(CMD_LF_EM4X70_AUTH, status, response, sizeof(response)); } +void em4x70_brute(em4x70_data_t *etd, bool ledcontrol) { + uint8_t status = 0; + uint8_t response[2] = {0}; + + command_parity = etd->parity; + + init_tag(); + em4x70_setup_read(); + + // Find the Tag + if (get_signalproperties() && find_em4x70_tag()) { + + // Bruteforce partial key + status = bruteforce(etd->address, etd->rnd, etd->frnd, etd->start_key, response) == PM3_SUCCESS; + } + + StopTicks(); + lf_finalize(ledcontrol); + reply_ng(CMD_LF_EM4X70_BRUTE, status, response, sizeof(response)); +} + void em4x70_write_pin(em4x70_data_t *etd, bool ledcontrol) { uint8_t status = 0; diff --git a/armsrc/em4x70.h b/armsrc/em4x70.h index 363f119e3..0fd640f86 100644 --- a/armsrc/em4x70.h +++ b/armsrc/em4x70.h @@ -32,6 +32,7 @@ typedef enum { void em4x70_info(em4x70_data_t *etd, bool ledcontrol); void em4x70_write(em4x70_data_t *etd, bool ledcontrol); +void em4x70_brute(em4x70_data_t *etd, bool ledcontrol); void em4x70_unlock(em4x70_data_t *etd, bool ledcontrol); void em4x70_auth(em4x70_data_t *etd, bool ledcontrol); void em4x70_write_pin(em4x70_data_t *etd, bool ledcontrol); diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 23b46cf54..f5960626e 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -1229,6 +1229,17 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data, tag_r AddCrc14A(rPPS, sizeof(rPPS) - 2); + if (tagType == 7) { + uint8_t pwd[4]; + uint8_t gen_pwd[4]; + uint16_t start = (*pages - 1) * 4 + MFU_DUMP_PREFIX_LENGTH; + emlGetMemBt(pwd, start, sizeof(pwd)); + Uint4byteToMemBe(gen_pwd, ul_ev1_pwdgenB(data)); + if (memcmp(pwd, gen_pwd, sizeof(pwd)) == 0) { + rPACK[0] = 0x80; + rPACK[1] = 0x80; + } + } AddCrc14A(rPACK, sizeof(rPACK) - 2); static tag_response_info_t responses_init[] = { diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index ab650da8f..daa84f886 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -177,6 +177,36 @@ static void CodeIso15693AsReaderEOF(void) { } +static int get_uid_slix(uint32_t start_time, uint32_t *eof_time, uint8_t *uid) { + + uint8_t *answer = BigBuf_malloc(ISO15693_MAX_RESPONSE_LENGTH); + memset(answer, 0x00, ISO15693_MAX_RESPONSE_LENGTH); + + start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER; + + uint8_t cmd[5] = {0}; + BuildIdentifyRequest(cmd); + uint16_t recvlen = 0; + SendDataTag(cmd, sizeof(cmd), false, true, answer, ISO15693_MAX_RESPONSE_LENGTH, start_time, ISO15693_READER_TIMEOUT, eof_time, &recvlen); + + if (recvlen != 12) { + return PM3_ETIMEOUT; + } + + uid[0] = answer[2]; + uid[1] = answer[3]; + uid[2] = answer[4]; + uid[3] = answer[5]; + uid[4] = answer[6]; + uid[5] = answer[7]; + uid[6] = answer[8]; + uid[7] = answer[9]; + + BigBuf_free(); + return PM3_SUCCESS; +} + + // encode data using "1 out of 256" scheme // data rate is 1,66 kbit/s (fc/8192) // is designed for more robust communication over longer distances @@ -2431,6 +2461,8 @@ void DirectTag15693Command(uint32_t datalen, uint32_t speed, uint32_t recv, uint case ISO15693_WRITE_AFI: case ISO15693_LOCK_AFI: case ISO15693_WRITE_DSFID: + case ISO15693_WRITE_PASSWORD: + case ISO15693_PASSWORD_PROTECT_EAS: case ISO15693_LOCK_DSFID: timeout = ISO15693_READER_TIMEOUT_WRITE; request_answer = data[0] & ISO15_REQ_OPTION; @@ -2640,7 +2672,7 @@ void SetTag15693Uid(const uint8_t *uid) { switch_off(); } -static void init_password_15693_slixl(uint8_t *buffer, uint8_t *pwd, const uint8_t *rnd) { +static void init_password_15693_Slix(uint8_t *buffer, uint8_t *pwd, const uint8_t *rnd) { memcpy(buffer, pwd, 4); if (rnd) { buffer[0] ^= rnd[0]; @@ -2650,14 +2682,14 @@ static void init_password_15693_slixl(uint8_t *buffer, uint8_t *pwd, const uint8 } } -static bool get_rnd_15693_slixl(uint32_t start_time, uint32_t *eof_time, uint8_t *rnd) { +static bool get_rnd_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t *rnd) { // 0x04, == NXP from manufacture id list. uint8_t c[] = {ISO15_REQ_DATARATE_HIGH, ISO15693_GET_RANDOM_NUMBER, 0x04, 0x00, 0x00 }; AddCrc15(c, 3); uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH]; uint16_t recvlen = 0; - int res = SendDataTag(c, sizeof(c), false, true, recvbuf, sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT_WRITE, eof_time, &recvlen); + int res = SendDataTag(c, sizeof(c), true, true, recvbuf, sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT_WRITE, eof_time, &recvlen); if (res != PM3_SUCCESS && recvlen != 5) { return false; } @@ -2668,15 +2700,16 @@ static bool get_rnd_15693_slixl(uint32_t start_time, uint32_t *eof_time, uint8_t return true; } -static uint32_t set_pass_15693_slixl(uint32_t start_time, uint32_t *eof_time, uint8_t pass_id, uint8_t *password) { +static uint32_t disable_privacy_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t pass_id, uint8_t *password) { + uint8_t rnd[2]; - if (get_rnd_15693_slixl(start_time, eof_time, rnd) == false) { + if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) { return PM3_ETIMEOUT; } // 0x04, == NXP from manufacture id list. - uint8_t c[] = {ISO15_REQ_DATARATE_HIGH, ISO15693_SET_PASSWORD, 0x04, pass_id, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - init_password_15693_slixl(&c[4], password, rnd); + uint8_t c[] = { ISO15_REQ_DATARATE_HIGH, ISO15693_SET_PASSWORD, 0x04, pass_id, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + init_password_15693_Slix(&c[4], password, rnd); AddCrc15(c, 8); start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER; @@ -2689,16 +2722,226 @@ static uint32_t set_pass_15693_slixl(uint32_t start_time, uint32_t *eof_time, ui return PM3_SUCCESS; } -/* -static uint32_t enable_privacy_15693_slixl(uint32_t start_time, uint32_t *eof_time, uint8_t *uid, uint8_t pass_id, uint8_t *password) { +static uint32_t set_pass_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t pass_id, uint8_t *password, uint8_t *uid) { + + uint8_t rnd[2]; - if (get_rnd_15693_slixl(start_time, eof_time, rnd) == false) { + if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) { + return PM3_ETIMEOUT; + } + + // 0x04, == NXP from manufacture id list. + uint8_t c[] = { (ISO15_REQ_DATARATE_HIGH | ISO15_REQ_ADDRESS), ISO15693_SET_PASSWORD, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, pass_id, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + init_password_15693_Slix(&c[12], password, rnd); + + memcpy(&c[3], uid, 8); + AddCrc15(c, 16); + + start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER; + uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH]; + uint16_t recvlen = 0; + + int res = SendDataTag(c, sizeof(c), false, true, recvbuf, sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT_WRITE, eof_time, &recvlen); + if (res != PM3_SUCCESS && recvlen != 3) { + return PM3_EWRONGANSWER; + } + return PM3_SUCCESS; +} + +static uint32_t set_privacy_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t *password) { + uint8_t rnd[2]; + if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) { + return PM3_ETIMEOUT; + } + + // 0x04, == NXP from manufacture id list. + uint8_t c[] = { ISO15_REQ_DATARATE_HIGH, 0xBA, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + init_password_15693_Slix(&c[3], password, rnd); + AddCrc15(c, 7); + + start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER; + uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH]; + uint16_t recvlen = 0; + int res = SendDataTag(c, sizeof(c), false, true, recvbuf, sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT_WRITE, eof_time, &recvlen); + if (res != PM3_SUCCESS && recvlen != 3) { + return PM3_EWRONGANSWER; + } + return PM3_SUCCESS; +} + +static uint32_t disable_eas_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t *password, bool usepwd) { + + uint8_t uid[8]; + get_uid_slix(start_time, eof_time, uid); + + uint8_t rnd[2]; + if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) { + return PM3_ETIMEOUT; + } + + if (usepwd) { + + int res_setpass = set_pass_15693_Slix(start_time, eof_time, 0x10, password, uid); + + if (res_setpass != PM3_SUCCESS) { + return PM3_EWRONGANSWER; + } + } + + // 0x04, == NXP from manufacture id list. + uint8_t c[] = { ISO15_REQ_DATARATE_HIGH, 0xA3, 0x04, 0x00, 0x00}; + AddCrc15(c, 3); + + start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER; + uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH]; + uint16_t recvlen = 0; + int res = SendDataTag(c, sizeof(c), false, true, recvbuf, sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT_WRITE, eof_time, &recvlen); + if (res != PM3_SUCCESS && recvlen != 3) { + return PM3_EWRONGANSWER; + } + return PM3_SUCCESS; +} + + +static uint32_t enable_eas_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t *password, bool usepwd) { + + uint8_t uid[8]; + get_uid_slix(start_time, eof_time, uid); + + uint8_t rnd[2]; + if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) { + return PM3_ETIMEOUT; + } + + if (usepwd) { + int res_setpass = set_pass_15693_Slix(start_time, eof_time, 0x10, password, uid); + + if (res_setpass != PM3_SUCCESS) { + return PM3_EWRONGANSWER; + } + } + // 0x04, == NXP from manufacture id list. + uint8_t c[] = { ISO15_REQ_DATARATE_HIGH, 0xA2, 0x04, 0x00, 0x00}; + //init_password_15693_Slix(&c[3], password, rnd); + AddCrc15(c, 3); + + start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER; + uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH]; + uint16_t recvlen = 0; + int res = SendDataTag(c, sizeof(c), false, true, recvbuf, sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT_WRITE, eof_time, &recvlen); + if (res != PM3_SUCCESS && recvlen != 3) { + return PM3_EWRONGANSWER; + } + return PM3_SUCCESS; +} + +static uint32_t write_password_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t pwd_id, uint8_t *password, uint8_t *uid) { + + uint8_t new_pwd_cmd[] = { (ISO15_REQ_DATARATE_HIGH | ISO15_REQ_ADDRESS), ISO15693_WRITE_PASSWORD, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, pwd_id, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + memcpy(&new_pwd_cmd[3], uid, 8); + memcpy(&new_pwd_cmd[12], password, 4); + + AddCrc15(new_pwd_cmd, 16); + + start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER; + uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH]; + uint16_t recvlen = 0; + + int res_wrp = SendDataTag(new_pwd_cmd, sizeof(new_pwd_cmd), false, true, recvbuf, sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT_WRITE, eof_time, &recvlen); + if (res_wrp != PM3_SUCCESS && recvlen != 3) { + return PM3_EWRONGANSWER; + } + + return PM3_SUCCESS; +} + +static uint32_t pass_protect_EASAFI_15693_Slix(uint32_t start_time, uint32_t *eof_time, bool set_option_flag, uint8_t *password) { + + uint8_t flags; + + if (set_option_flag) + flags = ISO15_REQ_DATARATE_HIGH | ISO15_REQ_OPTION; + else + flags = ISO15_REQ_DATARATE_HIGH; + + + uint8_t uid[8]; + get_uid_slix(start_time, eof_time, uid); + + uint8_t rnd[2]; + if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) { + return PM3_ETIMEOUT; + } + + int res_setpass = set_pass_15693_Slix(start_time, eof_time, 0x10, password, uid); + + if (res_setpass != PM3_SUCCESS) { + return PM3_EWRONGANSWER; + } + + uint8_t new_pass_protect_cmd[] = { flags, ISO15693_PASSWORD_PROTECT_EAS, 0x04, 0x00, 0x00}; + AddCrc15(new_pass_protect_cmd, 3); + + start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER; + uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH]; + uint16_t recvlen = 0; + + int res = SendDataTag(new_pass_protect_cmd, sizeof(new_pass_protect_cmd), false, true, recvbuf, sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT_WRITE, eof_time, &recvlen); + if (res != PM3_SUCCESS && recvlen != 3) { + return PM3_EWRONGANSWER; + } + + return PM3_SUCCESS; +} + +static uint32_t write_afi_15693(uint32_t start_time, uint32_t *eof_time, uint8_t *password, bool usepwd, uint8_t *uid, bool use_uid, uint8_t afi) { + + if (!use_uid) { + int res_getuid = get_uid_slix(start_time, eof_time, uid); + + if (res_getuid != PM3_SUCCESS) { + return res_getuid; + } + } + + if (usepwd) { + int res_setpass = set_pass_15693_Slix(start_time, eof_time, 0x10, password, uid); + + if (res_setpass != PM3_SUCCESS) { + return PM3_EWRONGANSWER; + } + } + + uint8_t cmd[] = { ISO15_REQ_DATARATE_HIGH | ISO15_REQ_ADDRESS, ISO15693_WRITE_AFI, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + memcpy(&cmd[2], uid, 8); + cmd[10] = afi; + AddCrc15(cmd, 11); + + start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER; + uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH]; + uint16_t recvlen = 0; + + int res = SendDataTag(cmd, sizeof(cmd), false, true, recvbuf, sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT_WRITE, eof_time, &recvlen); + if (res != PM3_SUCCESS || recvlen != 3) { + return PM3_EWRONGANSWER; + } + + return PM3_SUCCESS; +} + +/* +static uint32_t enable_privacy_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t *uid, uint8_t pass_id, uint8_t *password) { + uint8_t rnd[2]; + if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) { return PM3_ETIMEOUT; } uint8_t c[] = {ISO15_REQ_DATARATE_HIGH | ISO15_REQ_ADDRESS, ISO15693_ENABLE_PRIVACY, pass_id, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; memcpy(&c[3], uid, 8); - init_password_15693_slixl(&c[11], password, rnd); + init_password_15693_Slix(&c[11], password, rnd); AddCrc15(c, 15); start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER; @@ -2711,16 +2954,16 @@ static uint32_t enable_privacy_15693_slixl(uint32_t start_time, uint32_t *eof_ti return PM3_SUCCESS; } -static uint32_t write_password_15693_slixl(uint32_t start_time, uint32_t *eof_time, uint8_t *uid, uint8_t pass_id, uint8_t *password) { +static uint32_t write_password_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t *uid, uint8_t pass_id, uint8_t *password) { uint8_t rnd[2]; - if (get_rnd_15693_slixl(start_time, eof_time, rnd) == false) { + if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) { return PM3_ETIMEOUT; } uint8_t c[] = {ISO15_REQ_DATARATE_HIGH | ISO15_REQ_ADDRESS, ISO15693_WRITE_PASSWORD, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; memcpy(&c[3], uid, 8); c[11] = pass_id; - init_password_15693_slixl(&c[12], password, NULL); + init_password_15693_Slix(&c[12], password, NULL); AddCrc15(c, 16); start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER; @@ -2734,16 +2977,16 @@ static uint32_t write_password_15693_slixl(uint32_t start_time, uint32_t *eof_ti return PM3_SUCCESS; } -static uint32_t destroy_15693_slixl(uint32_t start_time, uint32_t *eof_time, uint8_t *uid, uint8_t *password) { +static uint32_t destroy_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t *uid, uint8_t *password) { uint8_t rnd[2]; - if (get_rnd_15693_slixl(start_time, eof_time, rnd) == false) { + if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) { return PM3_ETIMEOUT; } uint8_t c[] = {ISO15_REQ_DATARATE_HIGH | ISO15_REQ_ADDRESS, ISO15693_DESTROY, ISO15693_ENABLE_PRIVACY, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; memcpy(&c[3], uid, 8); - init_password_15693_slixl(&c[11], password, rnd); + init_password_15693_Slix(&c[11], password, rnd); AddCrc15(c, 15); start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER; @@ -2758,8 +3001,32 @@ static uint32_t destroy_15693_slixl(uint32_t start_time, uint32_t *eof_time, uin */ -// Sets a PRIVACY password to all ZEROS -void DisablePrivacySlixLIso15693(uint8_t *password) { +void WritePasswordSlixIso15693(uint8_t *old_password, uint8_t *new_password, uint8_t pwd_id) { + LED_D_ON(); + Iso15693InitReader(); + StartCountSspClk(); + uint32_t start_time = 0, eof_time = 0; + int res = PM3_EFAILED; + + uint8_t uid[8]; + get_uid_slix(start_time, &eof_time, uid); + + res = set_pass_15693_Slix(start_time, &eof_time, pwd_id, old_password, uid); + if (res != PM3_SUCCESS) { + reply_ng(CMD_HF_ISO15693_SLIX_WRITE_PWD, res, NULL, 0); + switch_off(); + return; + } + + res = write_password_15693_Slix(start_time, &eof_time, pwd_id, new_password, uid); + + reply_ng(CMD_HF_ISO15693_SLIX_WRITE_PWD, res, NULL, 0); + + switch_off(); + +} + +void DisablePrivacySlixIso15693(uint8_t *password) { LED_D_ON(); Iso15693InitReader(); StartCountSspClk(); @@ -2769,13 +3036,12 @@ void DisablePrivacySlixLIso15693(uint8_t *password) { // 0x04 Privacy // 0x08 Destroy SLIX-L // 0x10 EAS/AFI - int res = set_pass_15693_slixl(start_time, &eof_time, 0x04, password); - reply_ng(CMD_HF_ISO15693_SLIX_L_DISABLE_PRIVACY, res, NULL, 0); + int res = disable_privacy_15693_Slix(start_time, &eof_time, 0x04, password); + reply_ng(CMD_HF_ISO15693_SLIX_DISABLE_PRIVACY, res, NULL, 0); switch_off(); } -// Sets a EAS/AFI password to all ZEROS -void DisableEAS_AFISlixLIso15693(uint8_t *password) { +void EnablePrivacySlixIso15693(uint8_t *password) { LED_D_ON(); Iso15693InitReader(); StartCountSspClk(); @@ -2785,8 +3051,71 @@ void DisableEAS_AFISlixLIso15693(uint8_t *password) { // 0x04 Privacy // 0x08 Destroy SLIX-L // 0x10 EAS/AFI - int res = set_pass_15693_slixl(start_time, &eof_time, 0x10, password); - reply_ng(CMD_HF_ISO15693_SLIX_L_DISABLE_AESAFI, res, NULL, 0); + int res = set_privacy_15693_Slix(start_time, &eof_time, password); + reply_ng(CMD_HF_ISO15693_SLIX_ENABLE_PRIVACY, res, NULL, 0); switch_off(); } + +void DisableEAS_AFISlixIso15693(uint8_t *password, bool usepwd) { + LED_D_ON(); + Iso15693InitReader(); + StartCountSspClk(); + uint32_t start_time = 0, eof_time = 0; + + // Password identifier Password byte + // 0x04 Privacy + // 0x08 Destroy SLIX-L + // 0x10 EAS/AFI + int res = disable_eas_15693_Slix(start_time, &eof_time, password, usepwd); + + + + reply_ng(CMD_HF_ISO15693_SLIX_DISABLE_EAS, res, NULL, 0); + switch_off(); +} + +void EnableEAS_AFISlixIso15693(uint8_t *password, bool usepwd) { + LED_D_ON(); + Iso15693InitReader(); + StartCountSspClk(); + uint32_t start_time = 0, eof_time = 0; + + // Password identifier Password byte + // 0x04 Privacy + // 0x08 Destroy SLIX-L + // 0x10 EAS/AFI + int res = enable_eas_15693_Slix(start_time, &eof_time, password, usepwd); + reply_ng(CMD_HF_ISO15693_SLIX_ENABLE_EAS, res, NULL, 0); + switch_off(); +} + +void PassProtextEASSlixIso15693(uint8_t *password) { + LED_D_ON(); + Iso15693InitReader(); + StartCountSspClk(); + uint32_t start_time = 0, eof_time = 0; + int res = pass_protect_EASAFI_15693_Slix(start_time, &eof_time, false, password); + reply_ng(CMD_HF_ISO15693_SLIX_PASS_PROTECT_EAS, res, NULL, 0); + switch_off(); +} +void PassProtectAFISlixIso15693(uint8_t *password) { + LED_D_ON(); + Iso15693InitReader(); + StartCountSspClk(); + uint32_t start_time = 0, eof_time = 0; + int res = pass_protect_EASAFI_15693_Slix(start_time, &eof_time, true, password); + reply_ng(CMD_HF_ISO15693_SLIX_PASS_PROTECT_AFI, res, NULL, 0); + switch_off(); +} + +void WriteAFIIso15693(uint8_t *password, bool use_pwd, uint8_t *uid, bool use_uid, uint8_t afi) { + LED_D_ON(); + Iso15693InitReader(); + StartCountSspClk(); + uint32_t start_time = 0, eof_time = 0; + int res = write_afi_15693(start_time, &eof_time, password, use_pwd, uid, use_uid, afi); + //int res = PM3_SUCCESS; + reply_ng(CMD_HF_ISO15693_WRITE_AFI, res, NULL, 0); + switch_off(); +} diff --git a/armsrc/iso15693.h b/armsrc/iso15693.h index 2097b3769..b087edd2e 100644 --- a/armsrc/iso15693.h +++ b/armsrc/iso15693.h @@ -62,6 +62,12 @@ int SendDataTagEOF(uint8_t *recv, uint16_t max_recv_len, uint32_t start_time, ui void SetTag15693Uid(const uint8_t *uid); -void DisablePrivacySlixLIso15693(uint8_t *password); -void DisableEAS_AFISlixLIso15693(uint8_t *password); +void WritePasswordSlixIso15693(uint8_t *old_password, uint8_t *new_password, uint8_t pwd_id); +void DisablePrivacySlixIso15693(uint8_t *password); +void EnablePrivacySlixIso15693(uint8_t *password); +void DisableEAS_AFISlixIso15693(uint8_t *password, bool usepwd); +void EnableEAS_AFISlixIso15693(uint8_t *password, bool usepwd); +void PassProtextEASSlixIso15693(uint8_t *password); +void PassProtectAFISlixIso15693(uint8_t *password); +void WriteAFIIso15693(uint8_t *password, bool usepwd, uint8_t *uid, bool use_uid, uint8_t afi); #endif diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index a1ff37356..e716fa248 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -296,7 +296,9 @@ void LFSetupFPGAForADC(int divisor, bool reader_field) { uint32_t DoAcquisition(uint8_t decimation, uint8_t bits_per_sample, bool avg, int16_t trigger_threshold, bool verbose, uint32_t sample_size, uint32_t cancel_after, int32_t samples_to_skip, bool ledcontrol) { - initSampleBuffer(&sample_size); + initSampleBuffer(&sample_size); // sample size in bytes + sample_size <<= 3; // sample size in bits + sample_size /= bits_per_sample; // sample count if (g_dbglevel >= DBG_DEBUG) { printSamples(); @@ -368,8 +370,12 @@ uint32_t DoAcquisition(uint8_t decimation, uint8_t bits_per_sample, bool avg, in } // Ensure that DC offset removal and noise check is performed for any device-side processing - removeSignalOffset(data.buffer, samples.total_saved); - computeSignalProperties(data.buffer, samples.total_saved); + if (bits_per_sample == 8) + { + // these functions only consider bps==8 + removeSignalOffset(data.buffer, samples.total_saved); + computeSignalProperties(data.buffer, samples.total_saved); + } return data.numbits; } /** diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 881c72df0..a522b001b 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -3,36 +3,46 @@ # -- iceman fork version -- # -- contribute to this list, sharing is caring -- # -# Defaultkey(firstkeyusedbyprogramifnouserdefinedkey) +# Default key FFFFFFFFFFFF -# Blankkey +# +# Blank key 000000000000 +# # NFC Forum MADkey A0A1A2A3A4A5 +# # MAD access key A (reversed) A5A4A3A2A1A0 +# # MAD access key B 89ECA97F8C2A # +# B0B1B2B3B4B5 C0C1C2C3C4C5 D0D1D2D3D4D5 AABBCCDDEEFF 4D3A99C351DD 1A982C7E459A +# # key A Wien D3F7D3F7D3F7 +# # key B Wien 5A1B85FCE20A # +# 714C5C886E97 587EE5F9350F A0478CC39091 533CB6C723F6 8FD0A4F256E9 +# # iCopy-X E00000000000 # +# E7D6064C5860 B27CCAB30DBD # @@ -40,6 +50,9 @@ B27CCAB30DBD D2ECE8B9395E # NSCP default key 1494E81663D7 +# +# NFC tools +7c9fb8474242 # # Kiev keys 569369C5A0E5 @@ -54,31 +67,41 @@ F14EE7CAE863 # RKF # Västtrafiken KeyA, RKF ÖstgötaTrafiken KeyA FC00018778F7 +# # Västtrafiken KeyA 0297927C0F77 54726176656C +# # Västtrafiken KeyB 00000FFE2488 776974687573 EE0042F88840 +# # RKF SLKeyA 26940B21FF5D A64598A77478 +# # RKF SLKeyB 5C598C9C58B5 E4D2770A89BE -# RKF RejskortDanmark KeyA +# +# RKF Rejskort Danmark KeyA 722BFCC5375F -# RKF RejskortDanmark KeyB +# +# RKF Rejskort Danmark KeyB F1D83F964314 -# RKF JOJOPRIVAKeyA +# +# RKF JOJOPRIVA KeyA 505249564141 -# RKF JOJOPRIVAKeyB +# +# RKF JOJOPRIVA KeyB 505249564142 -# RKF JOJOGROUPKeyA +# +# RKF JOJOGROUP KeyA 47524F555041 434F4D4D4F41 -# RKF JOJOGROUPKeyB +# +# RKF JOJOGROUP KeyB 47524F555042 434F4D4D4F42 # @@ -108,11 +131,14 @@ F1D83F964314 200000000000 222222222222 27DD91F1FCF1 -# DirectoryandeventlogKeyB +# +# Directory and eventlog KeyB 2BA9621E0A36 -# DirectoryandeventlogKeyA +# +# Directory and eventlog KeyA 4AF9D7ADEBE4 # +# 333333333333 33F974B42769 34D1DF9934C5 @@ -131,9 +157,11 @@ A00000000000 A053A292A4AF A94133013401 AAAAAAAAAAAA -# Keyfromladyada.net +# +# Key from ladyada.net ABCDEF123456 # +# B00000000000 B127C6F41436 BBBBBBBBBBBB @@ -147,7 +175,9 @@ EEEEEEEEEEEE # data from forum FFFFFF545846 # +# F1A97341A9FC +# # hotel system 44AB09010845 85FED980EA5A @@ -157,7 +187,9 @@ F1A97341A9FC # ARD (fr) key B 4A2B29111213 # +# 4143414F5250 +# # Tehran Railway A9B43414F585 1FB235AC1388 @@ -169,13 +201,17 @@ F4A9EF2AFC6D # # S0 B 89EAC97F8C2A +# # S4 A 43C7600DEE6B +# # S6 A 0120BF672A64 +# # S6 B FB0B20DF1F34 # +# A9F953DEF0A3 # # Data from forum @@ -233,14 +269,17 @@ AAFB06045877 # gym # Fysiken A 3E65E4FB65B3 +# # Fysiken B 25094DF6F148 +# # CleverFit A05DBD98E0FC # # Hotel KeyCard D3B595E9DD63 AFBECD121004 +# # SimonsVoss 6471A5EF2D1A # @@ -396,9 +435,11 @@ C52876869800 # Data from mall # playland balikesir ABBA1234FCB0 +# # A trio bowling bahcelievler 314F495254FF 4152414B4E41 +# # karinca park nigde 4E474434FFFF # @@ -477,18 +518,21 @@ D9A37831DCE5 C5CFE06D9EA3 C0DECE673829 # +# A56C2DF9A26D # # Data from https://pastebin.com/vbwast74 -# 68D3F7307C89 +# # Smart Rider. Western Australian Public Transport Cards 568C9083F71C # # Bangkok metro key 97F5DA640B18 +# # Metro Valencia key A8844B0BCA06 +# # HTC Eindhoven key 857464D3AAD1 # @@ -501,6 +545,7 @@ A8844B0BCA06 # French VIGIK # VIGIK1 A 314B49474956 +# # VIGIK1 B 564C505F4D41 BA5B895DA162 @@ -508,16 +553,20 @@ BA5B895DA162 # Vigik mystery Keys Mifare 1k EV1 (S50) # 16 A 5C8FF9990DA2 +# # 17 A 75CCB59C9BED +# # 16 B D01AFEEB890A +# # 17 B 4B791BEA7BCC # # BTCINO UNDETERMINED SPREAKD 0x01->0x13 key 021209197591 # +# 2EF720F2AF76 414C41524F4E 424C41524F4E @@ -676,6 +725,7 @@ F7A39753D018 410B9B40B872 2CB1A90071C8 # +# 8697389ACA26 1AB23CD45EF6 013889343891 @@ -691,6 +741,7 @@ EC0A9B1A9E06 0F230695923F 0000014B5C31 # +# BEDB604CC9D1 B8A1F613CF3D B578F38A5C61 @@ -699,12 +750,15 @@ B66AC040203A 2E641D99AD5B AD4FB33388BF 69FB7B7CD8EE +# # Hotel 2A6D9205E7CA 13B91C226E56 +# # KABA Hotel Locks 2A2C13CC242A # +# 27FBC86A00D0 01FA3FC68349 # @@ -761,8 +815,10 @@ D58023BA2BDC 2ED3B15E7C0F F66224EE1E89 # +# 60012E9BA3FA # +# DE1FCBEC764B 81BFBE8CACBA BFF123126C9B @@ -775,11 +831,13 @@ D80511FC2AB4 BB467463ACD6 E67C8010502D FF58BA1B4478 +# # Data from https://pastebin.com/Kz8xp4ev FBF225DC5D58 # # Data https://pastebin.com/BEm6bdAE # vingcard.txt +# Note: most likely diversified 4708111C8604 3D50D902EA48 96A301BCE267 @@ -801,10 +859,12 @@ D58660D1ACDE 50A11381502C C01FC822C6E5 0854BF31111E -# More keys: +# +# More keys 8A19D40CF2B5 AE8587108640 -# SafLock standalone door locks. +# +# SafLock standalone door locks 135B88A94B8B # # Russian Troika card @@ -863,7 +923,7 @@ F8493407799D 6B8BD9860763 D3A297DC2698 # -# Keys from MifareClassicTool project +# Keys from Mifare Classic Tool project 044CE1872BC3 045CECA15535 0BE5FAC8B06A @@ -918,7 +978,6 @@ FD8705E721B0 00ADA2CD516D # # -## 237A4D0D9119 0ED7846C2BC9 FFFFD06F83E3 @@ -965,12 +1024,13 @@ A2B2C9D187FB # Hotel Adina 9EBC3EB37130 # -# most likely diversed individual keys. +# most likely diversifed individual keys. # data from https://github.com/korsehindi/proxmark3/commit/24fdbfa9a1d5c996aaa5c192bc07e4ab28db4c5c 491CDC863104 A2F63A485632 98631ED2B229 19F1FFE02563 +# # Argentina 563A22C01FC8 43CA22C13091 @@ -983,7 +1043,6 @@ AFBECD120454 842146108088 # # TAPCARD PUBLIC TRANSPORT LA -# EA1B88DF0A76 D1991E71E2C5 05F89678CFCF @@ -1018,7 +1077,6 @@ E3AD9E9BA5D4 6C9EC046C1A4 # # ROC HIGHSCHOOL ACCESSCARD -# B021669B44BB B18CDCDE52B7 A22647F422AE @@ -1050,8 +1108,7 @@ BE7C4F6C7A9A 5EC7938F140A 82D58AA49CCB # -# MELONCARD -# +# MELON CARD 323334353637 # # @@ -1071,7 +1128,6 @@ A7FB4824ACBF 10F3BEBC01DF # # Transportes Insular La Palma -# 0172066B2F03 0000085F0000 1A80B93F7107 @@ -1106,7 +1162,6 @@ B1A862985913 F3F0172066B2 # # Tehran ezpay -# 38A88AEC1C43 CBD2568BC7C6 7BCB4774EC8F @@ -1124,7 +1179,6 @@ D3B1C7EA5C53 BB3D7B11D224 # # Chaco -# B210CFA436D2 B8B1CFA646A8 A9F95891F0A4 @@ -1147,11 +1201,11 @@ A0004A000036 4243414F5250 DFE73BE48AC6 # +# B069D0D03D17 000131B93F28 # # From the DFW Area, TX, USA -# A506370E7C0F 26396F2042E7 70758FDD31E0 @@ -1169,7 +1223,6 @@ B47058139187 67CC03B7D577 # # From the HTL Mödling, NÖ, AT -# A5524645CD91 D964406E67B4 99858A49C119 @@ -1179,7 +1232,6 @@ C27D999912EA 4C60F4B15BA8 # # CAFE + CO, AT -# 35D850D10A24 4B511F4D28DD E45230E7A9E8 @@ -1187,27 +1239,25 @@ E45230E7A9E8 FB6C88B7E279 # # Metro Card, AT -# 223C3427108A # # Unknown, AT -# 23D4CDFF8DA3 E6849FCC324B 12FD3A94DF0E # # Unknown, AT -# 0B83797A9C64 39AD2963D3D1 +# # Hotel Berlin Classic room A KEY 34B16CD59FF8 +# # Hotel Berlin Classic room B KEY BB2C0007D022 # # Coinmatic laundry Smart card # data from: https://pastebin.com/XZQiLtUf -# 0734BFB93DAB 85A438F72A8A # @@ -1215,6 +1265,7 @@ BB2C0007D022 58AC17BF3629 B62307B62307 # +# A2A3CCA2A3CC # # Granada, ES Transport Card @@ -1260,6 +1311,7 @@ B8937130B6BA D7744A1A0C44 82908B57EF4F FE04ECFE5577 +# # comfort inn hotel 4D57414C5648 4D48414C5648 @@ -1306,13 +1358,11 @@ A82045A10949 # # funnivarium # forum ankara -# 2602FFFFFFFF # # macera adasi # ankara kentpark # INACTIVE -# 0A4600FF00FF DFF293979FA7 4D6F62692E45 @@ -1321,21 +1371,17 @@ DFF293979FA7 # petrol ofisi # positive card # ode-gec -# 0406080A0C0E # # konya elkart -# 988ACDECDFB0 120D00FFFFFF # # bowlingo # serdivan avym -# 4AE23A562A80 # -# kart54 -# +# kart 54 2AFFD6F88B97 A9F3F289B70C DB6819558A25 @@ -1346,20 +1392,16 @@ B16B2E573235 # # crazy park # kizilay avm -# 00DD300F4F10 # # kartsistem B -# FEE2A3FBC5B6 # # toru ent # taurus avm -# 005078565703 # # Ving? -# 0602721E8F06 FC0B50AF8700 F7BA51A9434E @@ -1407,7 +1449,6 @@ D0DDDF2933EC # # bursakart # bursa transport card -# 755D49191A78 DAC7E0CBA8FD 68D3263A8CD6 @@ -1418,30 +1459,29 @@ B2FE3B2875A6 # # playland # maltepe park -# ABCC1276FCB0 AABAFFCC7612 # # lunasan # kocaeli fair -# 26107E7006A0 # # gamefactory # ozdilek -# 17D071403C20 # +# 534F4C415249 534F4C303232 # # Nespresso, smart card -# key-gen algo, these keys are for one card +# key-gen algo, these keys are for one card (keys diversified) FF9A84635BD2 6F30126EE7E4 6039ABB101BB F1A1239A4487 # +# B882FD4A9F78 CD7FFFF81C4A AA0857C641A3 @@ -1524,9 +1564,10 @@ ABFEDC124578 5E594208EF02 AF9E38D36582 # -#Norwegian building site identication card. (HMS KORT) +# Norwegian building site identication card. (HMS KORT) # Key a 10DF4D1859C8 +# # Key B B5244E79B0C8 # @@ -1594,7 +1635,6 @@ F53E9F4114A9 AD38C17DE7D2 # # SUBE cards keys (new) -# 2DEB57A3EA8F 32C1BB023F87 70E3AD3F2D29 @@ -1623,7 +1663,6 @@ F5C1B3F62FDA 7E6545076619 # # SUBE cards keys (old) -# 4C5A766DFE3A 32C6768847F5 F68930789631 @@ -1651,7 +1690,9 @@ BFE25035B0C8 D5C172325DD3 992B152E834A CE75D7EADEAF -# Russian Podorozhnik card (Saint-Petersburg transport, may be combined with Troika) +# +# Russian Podorozhnik card (Saint-Petersburg transport) +# may be combined with Troika 038B5F9B5A2A 04DC35277635 0C420A20E056 @@ -1681,11 +1722,12 @@ D27058C6E2C7 E19504C39461 FA1FBB3F0F1F FF16014FEFC7 -################################## -# Keys from Flipper Zero Community # +# Keys from Flipper Zero Community # Last update: Aug 13, 2022 # +# unknown if keys are diversified or static default +# # Strelka Extension 5C83859F2224 66B504430416 @@ -1771,7 +1813,7 @@ CB9D507CE56D # Armenian Underground Ticket A0A1A2A8A4A5 # -# BadgeMaker Leaked from https://github.com/UberGuidoZ +# Badge Maker Leaked from https://github.com/UberGuidoZ 1A1B1C1D1E1F 1665FE2AE945 158B51947A8E @@ -1813,7 +1855,7 @@ D10008074A6F 6F6674776172 6520446F7665 # -# Apartment keyfobs (USA) from Corvette830 +# Apartment keyfobs (USA) (Corvette830) E60F8387F0B9 FFD46FF6C5EE 4F9661ED2E70 @@ -1822,8 +1864,8 @@ FFD46FF6C5EE 16CA203B811B 11AC8C8F3AF2 # -# The Westin Jakarta Indonesia from D4DB0D -# Peppers Hotel Unknown location from D4DB0D +# The Westin Jakarta Indonesia (D4DB0D) +# Peppers Hotel Unknown location (D4D0D) 6E0DD4136B0A 141940E9B71B 3B1D3AAC866E @@ -1836,12 +1878,12 @@ F09BB8DD142D B4B3FFEDBE0A 540E0D2D1D08 # -# Schlage 9691T Keyfob from seasnaill +# Schlage 9691T Keyfob (seasnaill) 7579B671051A 4F4553746B41 # # Vigik ScanBadge App (fr.badgevigik.scanbadge) -# Website https://badge-vigik.fr/ - By Alex` +# Website https://badge-vigik.fr/ (Alex) 0000A2B3C86F 021200C20307 021209197507 @@ -1868,6 +1910,7 @@ B4B3FFEDBE0A 9EB7C8A6D4E3 A22AE12C9013 AFC984A3576E +# # Vigik verified by quantum-x # https://github.com/RfidResearchGroup/proxmark3/pull/1742#issuecomment-1206113976 A00027000099 @@ -1892,8 +1935,8 @@ A00003000057 # iGuard Simple (and reverse) keys AAAAAAFFFFFF FFFFFFAAAAAA -# Added by VideoMan. -# Random Hotel A Key Sec 0 Blk 3 - KABA Lock +# +# Random Hotel A Key Sec 0 Blk 3 - KABA Lock (VideoMan) 3111A3A303EB # Transport system Uruguay - STM # Shared key - sec 0 blk 3 @@ -1910,9 +1953,9 @@ D144BD193063 8627C10A7014 453857395635 # -########################################## -# added by colonelborkmundus -# "the more, the marriott" mifare project +# Data from "the more, the marriott" mifare project (colonel borkmundus) +# +# Isn't theirs Saflok ? # # 1k - graduate hotel C49DAE1C6049 @@ -1984,4 +2027,4 @@ F72CD208FDF9 2158E314C3DF # # 1k - waldorf astoria -011C6CF459E8 \ No newline at end of file +011C6CF459E8 diff --git a/client/luascripts/hf_mfu_amiibo_sim.lua b/client/luascripts/hf_mfu_amiibo_sim.lua index 289e0b465..e00248c90 100644 --- a/client/luascripts/hf_mfu_amiibo_sim.lua +++ b/client/luascripts/hf_mfu_amiibo_sim.lua @@ -139,14 +139,10 @@ local function main(args) -- force lock bytes, otherwise the Amiibo won't be recognized blocks[16] = blocks[16]:sub(1, 4)..'0FE0' - -- add PWD and PACK if necessary + -- add PWD and PACK local uid = blocks[14]:sub(1, 6)..blocks[15]:sub(1, 8) - if blocks[147] == nil or blocks[147] == '00000000' then - blocks[147] = ("%08x"):format(bxor(bxor(tonumber(sub(uid, 2, 10), 16), tonumber(sub(uid, 6, 14), 16)), 0xaa55aa55)) - end - if blocks[148] == nil or blocks[148] == '00000000' then - blocks[148] = "80800000" - end + blocks[147] = ("%08x"):format(bxor(bxor(tonumber(sub(uid, 2, 10), 16), tonumber(sub(uid, 6, 14), 16)), 0xaa55aa55)) + blocks[148] = "80800000" err = LoadEmulator(uid, blocks) if err then return oops(err) end diff --git a/client/src/cmddata.c b/client/src/cmddata.c index 647c062a4..b9ca854f1 100644 --- a/client/src/cmddata.c +++ b/client/src/cmddata.c @@ -1230,7 +1230,7 @@ int FSKrawDemod(uint8_t rfLen, uint8_t invert, uint8_t fchigh, uint8_t fclow, bo PrintAndLogEx(NORMAL, ""); PrintAndLogEx(SUCCESS, _YELLOW_("%s") " decoded bitstream", GetFSKType(fchigh, fclow, invert)); PrintAndLogEx(INFO, "-----------------------"); - printDemodBuff(0, false, invert, false); + printDemodBuff(0, false, false, false); } goto out; } else { @@ -1779,7 +1779,7 @@ int getSamplesEx(uint32_t start, uint32_t end, bool verbose, bool ignore_lf_conf BitstreamOut_t bout = { got, bits_per_sample * n, 0}; uint32_t j = 0; - for (j = 0; j * bits_per_sample < n * 8 && j < n; j++) { + for (j = 0; j * bits_per_sample < n * 8 && j * bits_per_sample < MAX_GRAPH_TRACE_LEN * 8; j++) { uint8_t sample = getByte(bits_per_sample, &bout); g_GraphBuffer[j] = ((int) sample) - 127; } diff --git a/client/src/cmdflashmem.c b/client/src/cmdflashmem.c index f01531d55..7bbdf74c9 100644 --- a/client/src/cmdflashmem.c +++ b/client/src/cmdflashmem.c @@ -641,6 +641,10 @@ static int CmdFlashMemInfo(const char *Cmd) { // Verify (public key) bool is_verified = (mbedtls_rsa_pkcs1_verify(rsa, NULL, NULL, MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA1, 20, sha_hash, from_device) == 0); + if (got_private == false) { + mbedtls_rsa_free(rsa); + } + mbedtls_pk_free(&pkctx); PrintAndLogEx(NORMAL, ""); diff --git a/client/src/cmdhf14a.c b/client/src/cmdhf14a.c index d0ba31cd0..e1453be3b 100644 --- a/client/src/cmdhf14a.c +++ b/client/src/cmdhf14a.c @@ -1460,8 +1460,9 @@ static int CmdHF14AChaining(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf 14a chaining", "Enable/Disable ISO14443a input chaining. Maximum input length goes from ATS.", + "hf 14a chaining -> show chaining enable/disable state\n" "hf 14a chaining --off -> disable chaining\n" - "hf 14a chaining -> show chaining enable/disable state\n"); + ); void *argtable[] = { arg_param_begin, @@ -1473,6 +1474,7 @@ static int CmdHF14AChaining(const char *Cmd) { bool on = arg_get_lit(ctx, 1); bool off = arg_get_lit(ctx, 2); + CLIParserFree(ctx); if ((on + off) > 1) { PrintAndLogEx(INFO, "Select only one option"); @@ -1485,8 +1487,6 @@ static int CmdHF14AChaining(const char *Cmd) { if (off) Set_apdu_in_framing(false); - CLIParserFree(ctx); - PrintAndLogEx(INFO, "\nISO 14443-4 input chaining %s.\n", g_apdu_in_framing_enable ? "enabled" : "disabled"); return PM3_SUCCESS; } diff --git a/client/src/cmdhf15.c b/client/src/cmdhf15.c index 76fc4869a..10d239b94 100644 --- a/client/src/cmdhf15.c +++ b/client/src/cmdhf15.c @@ -652,14 +652,13 @@ static int CmdHF15Samples(const char *Cmd) { return PM3_SUCCESS; } -static int NxpTestEAS(uint8_t *uid) -{ - uint8_t fast = 1; +static int NxpTestEAS(uint8_t *uid) { + uint8_t fast = 1; uint8_t reply = 1; PacketResponseNG resp; uint16_t reqlen = 0; uint8_t req[PM3_CMD_DATA_SIZE] = {0}; - + req[reqlen++] |= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_NONINVENTORY | ISO15_REQ_ADDRESS; req[reqlen++] = ISO15693_EAS_ALARM; req[reqlen++] = 0x04; // IC manufacturer code @@ -681,7 +680,7 @@ static int NxpTestEAS(uint8_t *uid) if (resp.length < 2) { PrintAndLogEx(INFO, " EAS (Electronic Article Surveillance) is not active"); } else { - uint8_t * recv = resp.data.asBytes; + uint8_t *recv = resp.data.asBytes; if (!(recv[0] & ISO15_RES_ERROR)) { PrintAndLogEx(INFO, " EAS (Electronic Article Surveillance) is active."); @@ -689,56 +688,56 @@ static int NxpTestEAS(uint8_t *uid) } } } - + return PM3_SUCCESS; -} +} static int NxpCheckSig(uint8_t *uid) { - uint8_t fast = 1; + uint8_t fast = 1; uint8_t reply = 1; PacketResponseNG resp; uint16_t reqlen = 0; uint8_t req[PM3_CMD_DATA_SIZE] = {0}; - - // Check if we can also read the signature - req[reqlen++] |= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_NONINVENTORY | ISO15_REQ_ADDRESS; - req[reqlen++] = ISO15693_READ_SIGNATURE; - req[reqlen++] = 0x04; // IC manufacturer code - memcpy(req + 3, uid, 8); // add UID - reqlen += 8; - AddCrc15(req, reqlen); - reqlen += 2; + // Check if we can also read the signature + req[reqlen++] |= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_NONINVENTORY | ISO15_REQ_ADDRESS; + req[reqlen++] = ISO15693_READ_SIGNATURE; + req[reqlen++] = 0x04; // IC manufacturer code + memcpy(req + 3, uid, 8); // add UID + reqlen += 8; - clearCommandBuffer(); - SendCommandMIX(CMD_HF_ISO15693_COMMAND, reqlen, fast, reply, req, reqlen); + AddCrc15(req, reqlen); + reqlen += 2; - if (WaitForResponseTimeout(CMD_HF_ISO15693_COMMAND, &resp, 2000) == false) { - PrintAndLogEx(WARNING, "iso15693 timeout"); - DropField(); - return PM3_ETIMEOUT; - } + clearCommandBuffer(); + SendCommandMIX(CMD_HF_ISO15693_COMMAND, reqlen, fast, reply, req, reqlen); - DropField(); + if (WaitForResponseTimeout(CMD_HF_ISO15693_COMMAND, &resp, 2000) == false) { + PrintAndLogEx(WARNING, "iso15693 timeout"); + DropField(); + return PM3_ETIMEOUT; + } - if (resp.length < 2) { - PrintAndLogEx(WARNING, "iso15693 card doesn't answer to READ SIGNATURE command"); - return PM3_EWRONGANSWER; - } + DropField(); - uint8_t *recv = resp.data.asBytes; + if (resp.length < 2) { + PrintAndLogEx(WARNING, "iso15693 card doesn't answer to READ SIGNATURE command"); + return PM3_EWRONGANSWER; + } - if ((recv[0] & ISO15_RES_ERROR) == ISO15_RES_ERROR) { - PrintAndLogEx(ERR, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0])); - return PM3_EWRONGANSWER; - } + uint8_t *recv = resp.data.asBytes; - uint8_t signature[32] = {0x00}; - memcpy(signature, recv + 1, 32); + if ((recv[0] & ISO15_RES_ERROR) == ISO15_RES_ERROR) { + PrintAndLogEx(ERR, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0])); + return PM3_EWRONGANSWER; + } - nxp_15693_print_signature(uid, signature); - - return PM3_SUCCESS; + uint8_t signature[32] = {0x00}; + memcpy(signature, recv + 1, 32); + + nxp_15693_print_signature(uid, signature); + + return PM3_SUCCESS; } // Get NXP system information from SLIX2 tag/VICC @@ -790,14 +789,14 @@ static int NxpSysInfo(uint8_t *uid) { } bool support_signature = (recv[5] & 0x01); - bool support_easmode = (recv[4] & 0x03); + bool support_easmode = (recv[4] & 0x04); PrintAndLogEx(INFO, "--------- " _CYAN_("NXP Sysinfo") " ---------"); PrintAndLogEx(INFO, " raw : %s", sprint_hex(recv, 8)); PrintAndLogEx(INFO, " Password protection configuration:"); PrintAndLogEx(INFO, " * Page L read%s password protected", ((recv[2] & 0x01) ? "" : " not")); PrintAndLogEx(INFO, " * Page L write%s password protected", ((recv[2] & 0x02) ? "" : " not")); - PrintAndLogEx(INFO, " * Page H read%s password protected", ((recv[2] & 0x08) ? "" : " not")); + PrintAndLogEx(INFO, " * Page H read%s password protected", ((recv[2] & 0x10) ? "" : " not")); PrintAndLogEx(INFO, " * Page H write%s password protected", ((recv[2] & 0x20) ? "" : " not")); PrintAndLogEx(INFO, " Lock bits:"); @@ -810,23 +809,23 @@ static int NxpSysInfo(uint8_t *uid) { PrintAndLogEx(INFO, " * User memory password protection%s supported", ((recv[4] & 0x01) ? "" : " not")); PrintAndLogEx(INFO, " * Counter feature%s supported", ((recv[4] & 0x02) ? "" : " not")); PrintAndLogEx(INFO, " * EAS ID%s supported by EAS ALARM command", support_easmode ? "" : " not"); - PrintAndLogEx(INFO, " * EAS password protection%s supported", ((recv[4] & 0x04) ? "" : " not")); + PrintAndLogEx(INFO, " * EAS password protection%s supported", ((recv[4] & 0x08) ? "" : " not")); PrintAndLogEx(INFO, " * AFI password protection%s supported", ((recv[4] & 0x10) ? "" : " not")); PrintAndLogEx(INFO, " * Extended mode%s supported by INVENTORY READ command", ((recv[4] & 0x20) ? "" : " not")); PrintAndLogEx(INFO, " * EAS selection%s supported by extended mode in INVENTORY READ command", ((recv[4] & 0x40) ? "" : " not")); PrintAndLogEx(INFO, " * READ SIGNATURE command%s supported", support_signature ? "" : " not"); PrintAndLogEx(INFO, " * Password protection for READ SIGNATURE command%s supported", ((recv[5] & 0x02) ? "" : " not")); - PrintAndLogEx(INFO, " * STAY QUIET PERSISTENT command%s supported", ((recv[5] & 0x03) ? "" : " not")); + PrintAndLogEx(INFO, " * STAY QUIET PERSISTENT command%s supported", ((recv[5] & 0x04) ? "" : " not")); PrintAndLogEx(INFO, " * ENABLE PRIVACY command%s supported", ((recv[5] & 0x10) ? "" : " not")); PrintAndLogEx(INFO, " * DESTROY command%s supported", ((recv[5] & 0x20) ? "" : " not")); - PrintAndLogEx(INFO, " * Additional 32 bits feature flags are%s transmitted", ((recv[5] & 0x80) ? "" : " not")); + PrintAndLogEx(INFO, " * Additional 32 bits feature flags are%s transmitted", ((recv[7] & 0x80) ? "" : " not")); if (support_easmode) { - NxpTestEAS(uid); + NxpTestEAS(uid); } if (support_signature) { - NxpCheckSig(uid); + NxpCheckSig(uid); } return PM3_SUCCESS; @@ -968,16 +967,12 @@ static int CmdHF15Info(const char *Cmd) { if (data[8] == 0x04 && data[7] == 0x01 && nxp_version == 0x08) { PrintAndLogEx(DEBUG, "SLIX2 Detected, getting NXP System Info"); return NxpSysInfo(uid); - } - else if(data[8] == 0x04 && data[7] == 0x01 && nxp_version == 0x18) //If it is an NTAG 5 - { - PrintAndLogEx(DEBUG, "NTAG 5 Detected, getting NXP System Info"); + } else if (data[8] == 0x04 && data[7] == 0x01 && nxp_version == 0x18) { //If it is an NTAG 5 + PrintAndLogEx(DEBUG, "NTAG 5 Detected, getting NXP System Info"); return NxpSysInfo(uid); - } - else if(data[8] == 0x04 && (data[7] == 0x01 || data[7] == 0x02 || data[7] == 0x03)) //If SLI, SLIX, SLIX-l, or SLIX-S check EAS status - { - PrintAndLogEx(DEBUG, "SLI, SLIX, SLIX-L, or SLIX-S Detected checking EAS status"); - return NxpTestEAS(uid); + } else if (data[8] == 0x04 && (data[7] == 0x01 || data[7] == 0x02 || data[7] == 0x03)) { //If SLI, SLIX, SLIX-l, or SLIX-S check EAS status + PrintAndLogEx(DEBUG, "SLI, SLIX, SLIX-L, or SLIX-S Detected checking EAS status"); + return NxpTestEAS(uid); } PrintAndLogEx(NORMAL, ""); @@ -1357,94 +1352,81 @@ static int CmdHF15WriteAfi(const char *Cmd) { CLIParserInit(&ctx, "hf 15 writeafi", "Write AFI on card", "hf 15 writeafi -* --afi 12\n" - "hf 15 writeafi -u E011223344556677 --afi 12" + "hf 15 writeafi -u E011223344556677 --afi 12 -p 0F0F0F0F" ); - void *argtable[6 + 2] = {}; - uint8_t arglen = arg_add_default(argtable); - argtable[arglen++] = arg_int1(NULL, "afi", "", "AFI number (0-255)"); - argtable[arglen++] = arg_param_end; + void *argtable[5] = {}; + argtable[0] = arg_param_begin; + argtable[1] = arg_str0("u", "uid", "", "full UID, 8 bytes"); + argtable[2] = arg_int1(NULL, "afi", "", "AFI number (0-255)"); + argtable[3] = arg_str0("p", "pwd", "", "optional AFI/EAS password"); + argtable[4] = arg_param_end; - CLIExecWithReturn(ctx, Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, true); + + struct { + uint8_t pwd[4]; + bool use_pwd; + uint8_t uid[8]; + bool use_uid; + uint8_t afi; + } PACKED payload; - uint8_t uid[8]; int uidlen = 0; - CLIGetHexWithReturn(ctx, 1, uid, &uidlen); - bool unaddressed = arg_get_lit(ctx, 2); - bool scan = arg_get_lit(ctx, 3); - int fast = (arg_get_lit(ctx, 4) == false); - bool add_option = arg_get_lit(ctx, 5); + CLIGetHexWithReturn(ctx, 1, payload.uid, &uidlen); + + payload.afi = arg_get_int_def(ctx, 2, 0); + + int pwdlen; + CLIGetHexWithReturn(ctx, 3, payload.pwd, &pwdlen); - int afi = arg_get_int_def(ctx, 6, 0); CLIParserFree(ctx); + payload.use_pwd = false; + if (pwdlen == 4) { + payload.use_pwd = true; + } + + payload.use_uid = false; + if (uidlen == 8) { + payload.use_uid = true; + } + // sanity checks - if ((scan + unaddressed + uidlen) > 1) { - PrintAndLogEx(WARNING, "Select only one option /scan/unaddress/uid"); + if (uidlen != 0 && uidlen != 8) { + PrintAndLogEx(WARNING, "uid must be 8 hex bytes if provided"); return PM3_EINVARG; } - // request to be sent to device/card - uint16_t flags = arg_get_raw_flag(uidlen, unaddressed, scan, add_option); - uint8_t req[16] = {flags, ISO15693_WRITE_AFI}; - uint16_t reqlen = 2; - - if (unaddressed == false) { - if (scan) { - if (getUID(false, uid) != PM3_SUCCESS) { - PrintAndLogEx(WARNING, "no tag found"); - return PM3_EINVARG; - } - uidlen = 8; - } - - if (uidlen == 8) { - // add UID (scan, uid) - memcpy(req + reqlen, uid, sizeof(uid)); - reqlen += sizeof(uid); - } - PrintAndLogEx(SUCCESS, "Using UID... " _GREEN_("%s"), iso15693_sprintUID(NULL, uid)); + if (pwdlen > 0 && pwdlen != 4) { + PrintAndLogEx(WARNING, "password must be 4 hex bytes if provided"); + return PM3_ESOFT; } - // enforce, since we are writing - req[0] |= ISO15_REQ_OPTION; - - req[reqlen++] = (uint8_t)afi; - - AddCrc15(req, reqlen); - reqlen += 2; - - // arg: len, speed, recv? - // arg0 (datalen, cmd len? .arg0 == crc?) - // arg1 (speed == 0 == 1 of 256, == 1 == 1 of 4 ) - // arg2 (recv == 1 == expect a response) - uint8_t read_response = 1; - PacketResponseNG resp; clearCommandBuffer(); - SendCommandMIX(CMD_HF_ISO15693_COMMAND, reqlen, fast, read_response, req, reqlen); - - if (WaitForResponseTimeout(CMD_HF_ISO15693_COMMAND, &resp, 2000) == false) { - PrintAndLogEx(ERR, "iso15693 timeout"); + SendCommandNG(CMD_HF_ISO15693_WRITE_AFI, (uint8_t *)&payload, sizeof(payload)); + if (WaitForResponseTimeout(CMD_HF_ISO15693_WRITE_AFI, &resp, 2000) == false) { + PrintAndLogEx(WARNING, "timeout while waiting for reply"); DropField(); - return PM3_ETIMEOUT; - } - DropField(); - - if (resp.status == PM3_ETEAROFF) { - return resp.status; + return PM3_ESOFT; } - uint8_t *data = resp.data.asBytes; - - if ((data[0] & ISO15_RES_ERROR) == ISO15_RES_ERROR) { - PrintAndLogEx(ERR, "iso15693 card returned error %i: %s", data[0], TagErrorStr(data[0])); - return PM3_EWRONGANSWER; + switch (resp.status) { + case PM3_ETIMEOUT: { + PrintAndLogEx(WARNING, "no tag found"); + break; + } + case PM3_EWRONGANSWER: { + PrintAndLogEx(WARNING, "error writing AFI"); + break; + } + case PM3_SUCCESS: { + PrintAndLogEx(SUCCESS, "Wrote AFI 0x%02X", payload.afi); + break; + } } - - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(SUCCESS, "Wrote AFI 0x%02X", afi); - return PM3_SUCCESS; + return resp.status; } // Writes the DSFID (Data Storage Format Identifier) of a card @@ -2383,10 +2365,148 @@ static int CmdHF15CSetUID(const char *Cmd) { } } +static int CmdHF15SlixEASEnable(const char *Cmd) { + + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf 15 slixeasenable", + "Enable EAS mode on SLIX ISO-15693 tag", + "hf 15 slixeasenable -p 0F0F0F0F"); + + void *argtable[] = { + arg_param_begin, + arg_str0("p", "pwd", "", "optional password, 8 hex bytes"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + struct { + uint8_t pwd[4]; + bool usepwd; + } PACKED payload; + int pwdlen = 0; + + int ret_pwdparse = CLIParamHexToBuf(arg_get_str(ctx, 1), payload.pwd, 4, &pwdlen); + if ((pwdlen > 0 && pwdlen != 4) || ret_pwdparse != 0) { + PrintAndLogEx(WARNING, "password must be 4 hex bytes if provided"); + CLIParserFree(ctx); + return PM3_ESOFT; + } + + CLIParserFree(ctx); + + if (pwdlen > 0) { + PrintAndLogEx(INFO, "Trying to enable EAS mode using password " _GREEN_("%s") + , sprint_hex_inrow(payload.pwd, sizeof(payload.pwd)) + ); + payload.usepwd = true; + } else { + PrintAndLogEx(INFO, "Trying to enable EAS mode without using a password"); + payload.usepwd = false; + } + + + PacketResponseNG resp; + clearCommandBuffer(); + SendCommandNG(CMD_HF_ISO15693_SLIX_ENABLE_EAS, (uint8_t *)&payload, sizeof(payload)); + if (WaitForResponseTimeout(CMD_HF_ISO15693_SLIX_ENABLE_EAS, &resp, 2000) == false) { + PrintAndLogEx(WARNING, "timeout while waiting for reply"); + DropField(); + return PM3_ESOFT; + } + + switch (resp.status) { + case PM3_ETIMEOUT: { + PrintAndLogEx(WARNING, "no tag found"); + break; + } + case PM3_EWRONGANSWER: { + if (pwdlen > 0) { + PrintAndLogEx(WARNING, "the password provided was not accepted"); + } else { + PrintAndLogEx(WARNING, "either a password is required or EAS mode is locked"); + } + break; + } + case PM3_SUCCESS: { + PrintAndLogEx(SUCCESS, "EAS mode is now enabled ( " _GREEN_("ok") " ) "); + break; + } + } + return resp.status; +} + +static int CmdHF15SlixEASDisable(const char *Cmd) { + + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf 15 slixeasdisable", + "Disable EAS mode on SLIX ISO-15693 tag", + "hf 15 slixeasdisable -p 0F0F0F0F"); + + void *argtable[] = { + arg_param_begin, + arg_str0("p", "pwd", "", "optional password, 8 hex bytes"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + + struct { + uint8_t pwd[4]; + bool usepwd; + + } PACKED payload; + int pwdlen = 0; + + int ret_pwdparse = CLIParamHexToBuf(arg_get_str(ctx, 1), payload.pwd, 4, &pwdlen); + CLIParserFree(ctx); + + if ((pwdlen > 0 && pwdlen != 4) || ret_pwdparse != 0) { + PrintAndLogEx(WARNING, "password must be 4 hex bytes if provided"); + return PM3_ESOFT; + } + + if (pwdlen > 0) { + PrintAndLogEx(INFO, "Trying to disable EAS mode using password " _GREEN_("%s") + , sprint_hex_inrow(payload.pwd, sizeof(payload.pwd)) + ); + payload.usepwd = true; + } else { + PrintAndLogEx(INFO, "Trying to enable EAS mode without using a password"); + payload.usepwd = false; + } + + PacketResponseNG resp; + clearCommandBuffer(); + SendCommandNG(CMD_HF_ISO15693_SLIX_DISABLE_EAS, (uint8_t *)&payload, sizeof(payload)); + if (WaitForResponseTimeout(CMD_HF_ISO15693_SLIX_DISABLE_EAS, &resp, 2000) == false) { + PrintAndLogEx(WARNING, "timeout while waiting for reply"); + DropField(); + return PM3_ESOFT; + } + + switch (resp.status) { + case PM3_ETIMEOUT: { + PrintAndLogEx(WARNING, "no tag found"); + break; + } + case PM3_EWRONGANSWER: { + if (pwdlen > 0) { + PrintAndLogEx(WARNING, "the password provided was not accepted"); + } else { + PrintAndLogEx(WARNING, "either a password is required or EAS mode is locked"); + } + break; + } + case PM3_SUCCESS: { + PrintAndLogEx(SUCCESS, "EAS mode is now disabled ( " _GREEN_("ok") " ) "); + break; + } + } + return resp.status; +} + static int CmdHF15SlixDisable(const char *Cmd) { CLIParserContext *ctx; - CLIParserInit(&ctx, "hf 15 slixdisable", + CLIParserInit(&ctx, "hf 15 slixprivacydisable", "Disable privacy mode on SLIX ISO-15693 tag", "hf 15 slixdisable -p 0F0F0F0F"); @@ -2409,8 +2529,8 @@ static int CmdHF15SlixDisable(const char *Cmd) { PacketResponseNG resp; clearCommandBuffer(); - SendCommandNG(CMD_HF_ISO15693_SLIX_L_DISABLE_PRIVACY, (uint8_t *)&payload, sizeof(payload)); - if (WaitForResponseTimeout(CMD_HF_ISO15693_SLIX_L_DISABLE_PRIVACY, &resp, 2000) == false) { + SendCommandNG(CMD_HF_ISO15693_SLIX_DISABLE_PRIVACY, (uint8_t *)&payload, sizeof(payload)); + if (WaitForResponseTimeout(CMD_HF_ISO15693_SLIX_DISABLE_PRIVACY, &resp, 2000) == false) { PrintAndLogEx(WARNING, "timeout while waiting for reply"); DropField(); return PM3_ESOFT; @@ -2433,32 +2553,315 @@ static int CmdHF15SlixDisable(const char *Cmd) { return resp.status; } +static int CmdHF15SlixEnable(const char *Cmd) { + + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf 15 slixprivacyenable", + "Enable privacy mode on SLIX ISO-15693 tag", + "hf 15 slixenable -p 0F0F0F0F"); + + void *argtable[] = { + arg_param_begin, + arg_str1("p", "pwd", "", "password, 8 hex bytes"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, false); + struct { + uint8_t pwd[4]; + } PACKED payload; + int pwdlen = 0; + CLIGetHexWithReturn(ctx, 1, payload.pwd, &pwdlen); + CLIParserFree(ctx); + + PrintAndLogEx(INFO, "Trying to enable privacy mode using password " _GREEN_("%s") + , sprint_hex_inrow(payload.pwd, sizeof(payload.pwd)) + ); + + PacketResponseNG resp; + clearCommandBuffer(); + SendCommandNG(CMD_HF_ISO15693_SLIX_ENABLE_PRIVACY, (uint8_t *)&payload, sizeof(payload)); + if (WaitForResponseTimeout(CMD_HF_ISO15693_SLIX_ENABLE_PRIVACY, &resp, 2000) == false) { + PrintAndLogEx(WARNING, "timeout while waiting for reply"); + DropField(); + return PM3_ESOFT; + } + + switch (resp.status) { + case PM3_ETIMEOUT: { + PrintAndLogEx(WARNING, "no tag found"); + break; + } + case PM3_EWRONGANSWER: { + PrintAndLogEx(WARNING, "password was not accepted"); + break; + } + case PM3_SUCCESS: { + PrintAndLogEx(SUCCESS, "privacy mode is now enabled ( " _GREEN_("ok") " ) "); + break; + } + } + return resp.status; +} + +static int CmdHF15SlixWritePassword(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf 15 slixwritepwd", + "Write a password on a SLIX family ISO-15693 tag.n" + "Some tags do not support all different password types.", + "hf 15 slixwritepwd -t READ -o 00000000 -n 12131415"); + + void *argtable[] = { + arg_param_begin, + arg_str1("t", "type", "", "which password field to write to"), + arg_str0("o", "old", "", "old password (if present), 8 hex bytes"), + arg_str1("n", "new", "", "new password, 8 hex bytes"), + arg_param_end + }; + + CLIExecWithReturn(ctx, Cmd, argtable, false); + + struct { + uint8_t old_pwd[4]; + uint8_t new_pwd[4]; + uint8_t pwd_id; + } PACKED payload; + int pwdlen = 0; + + CLIGetHexWithReturn(ctx, 2, payload.old_pwd, &pwdlen); + + if (pwdlen > 0 && pwdlen != 4) { + PrintAndLogEx(WARNING, "old password must be 4 hex bytes if provided"); + CLIParserFree(ctx); + return PM3_ESOFT; + } + + CLIGetHexWithReturn(ctx, 3, payload.new_pwd, &pwdlen); + + if (pwdlen != 4) { + PrintAndLogEx(WARNING, "new password must be 4 hex bytes"); + CLIParserFree(ctx); + return PM3_ESOFT; + } + + int vlen = 0; + char value[10]; + CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)value, sizeof(value), &vlen); + CLIParserFree(ctx); + + if (vlen > 0) { + if (strcmp(value, "read") == 0) { + PrintAndLogEx(SUCCESS, "Selected read pass"); + payload.pwd_id = 0x01; + } else if (strcmp(value, "write") == 0) { + PrintAndLogEx(SUCCESS, "Selected write pass"); + payload.pwd_id = 0x02; + } else if (strcmp(value, "privacy") == 0) { + PrintAndLogEx(SUCCESS, "Selected privacy pass"); + payload.pwd_id = 0x04; + } else if (strcmp(value, "destroy") == 0) { + PrintAndLogEx(SUCCESS, "Selected destroy pass"); + payload.pwd_id = 0x08; + } else if (strcmp(value, "easafi") == 0) { + PrintAndLogEx(SUCCESS, "Selected easafi pass"); + payload.pwd_id = 0x10; + } else { + PrintAndLogEx(ERR, "t argument must be 'read', 'write', 'privacy', 'destroy', or 'easafi'"); + return PM3_EINVARG; + } + } + + PrintAndLogEx(INFO, "Trying to write " _YELLOW_("%s") " as " _YELLOW_("%s") " password" + , sprint_hex_inrow(payload.new_pwd, sizeof(payload.new_pwd)), value); + + PacketResponseNG resp; + clearCommandBuffer(); + SendCommandNG(CMD_HF_ISO15693_SLIX_WRITE_PWD, (uint8_t *)&payload, sizeof(payload)); + if (WaitForResponseTimeout(CMD_HF_ISO15693_SLIX_WRITE_PWD, &resp, 2000) == false) { + PrintAndLogEx(WARNING, "timeout while waiting for reply"); + DropField(); + return PM3_ESOFT; + } + + switch (resp.status) { + case PM3_ETIMEOUT: { + PrintAndLogEx(WARNING, "no tag found"); + break; + } + case PM3_EWRONGANSWER: { + PrintAndLogEx(WARNING, "password was not accepted"); + break; + } + case PM3_SUCCESS: { + PrintAndLogEx(SUCCESS, "password written ( " _GREEN_("ok") " ) "); + break; + } + } + return resp.status; +} + +static int CmdHF15AFIPassProtect(const char *Cmd) { + + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf 15 passprotectafi", + "This command enables the password protect of AFI.\n" + "*** OBS! This action can not be undone! ***", + "hf 15 passprotectafi -p 00000000 --force"); + + void *argtable[] = { + arg_param_begin, + arg_str1("p", "pwd", "", "EAS/AFI password, 8 hex bytes"), + arg_lit0(NULL, "force", "Force execution of command (irreversible) "), + arg_param_end + }; + + CLIExecWithReturn(ctx, Cmd, argtable, true); + + struct { + uint8_t pwd[4]; + } PACKED payload; + int pwdlen = 0; + + CLIGetHexWithReturn(ctx, 1, payload.pwd, &pwdlen); + + bool force = arg_get_lit(ctx, 2); + CLIParserFree(ctx); + + if (pwdlen != 4) { + PrintAndLogEx(WARNING, "password must be 4 hex bytes"); + return PM3_ESOFT; + } + + if (force == false) { + PrintAndLogEx(WARNING, "Use `--force` flag to override. OBS! Irreversable command"); + return PM3_ESOFT; + } + + PrintAndLogEx(INFO, "Trying to enable AFI password protection..."); + + PacketResponseNG resp; + clearCommandBuffer(); + SendCommandNG(CMD_HF_ISO15693_SLIX_PASS_PROTECT_AFI, (uint8_t *)&payload, sizeof(payload)); + if (WaitForResponseTimeout(CMD_HF_ISO15693_SLIX_PASS_PROTECT_AFI, &resp, 2000) == false) { + PrintAndLogEx(WARNING, "timeout while waiting for reply"); + DropField(); + return PM3_ESOFT; + } + + switch (resp.status) { + case PM3_ETIMEOUT: { + PrintAndLogEx(WARNING, "no tag found"); + break; + } + case PM3_EWRONGANSWER: { + PrintAndLogEx(WARNING, "error enabling AFI password protection"); + break; + } + case PM3_SUCCESS: { + PrintAndLogEx(SUCCESS, "AFI password protected ( " _GREEN_("ok") " ) "); + break; + } + } + return resp.status; + +} + +static int CmdHF15EASPassProtect(const char *Cmd) { + + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf 15 passprotecteas", + "This command enables the password protect of EAS.\n" + "*** OBS! This action can not be undone! ***", + "hf 15 passprotecteas -p 00000000 --force"); + + void *argtable[] = { + arg_param_begin, + arg_str1("p", "pwd", "", "EAS/AFI password, 8 hex bytes"), + arg_lit0(NULL, "force", "Force execution of command (irreversible) "), + arg_param_end + }; + + CLIExecWithReturn(ctx, Cmd, argtable, true); + + struct { + uint8_t pwd[4]; + } PACKED payload; + int pwdlen = 0; + + CLIGetHexWithReturn(ctx, 1, payload.pwd, &pwdlen); + + bool force = arg_get_lit(ctx, 2); + CLIParserFree(ctx); + + if (pwdlen != 4) { + PrintAndLogEx(WARNING, "password must be 4 hex bytes"); + return PM3_ESOFT; + } + + if (force == false) { + PrintAndLogEx(WARNING, "Use `--force` flag to override. OBS! Irreversable command"); + return PM3_ESOFT; + } + + PrintAndLogEx(INFO, "Trying to enable EAS password protection..."); + + PacketResponseNG resp; + clearCommandBuffer(); + SendCommandNG(CMD_HF_ISO15693_SLIX_PASS_PROTECT_EAS, (uint8_t *)&payload, sizeof(payload)); + if (WaitForResponseTimeout(CMD_HF_ISO15693_SLIX_PASS_PROTECT_EAS, &resp, 2000) == false) { + PrintAndLogEx(WARNING, "timeout while waiting for reply"); + DropField(); + return PM3_ESOFT; + } + + switch (resp.status) { + case PM3_ETIMEOUT: { + PrintAndLogEx(WARNING, "no tag found"); + break; + } + case PM3_EWRONGANSWER: { + PrintAndLogEx(WARNING, "error enabling EAS password protection"); + break; + } + case PM3_SUCCESS: { + PrintAndLogEx(SUCCESS, "EAS password protected ( " _GREEN_("ok") " ) "); + break; + } + } + return resp.status; +} + static command_t CommandTable[] = { - {"-----------", CmdHF15Help, AlwaysAvailable, "--------------------- " _CYAN_("General") " ---------------------"}, - {"help", CmdHF15Help, AlwaysAvailable, "This help"}, - {"list", CmdHF15List, AlwaysAvailable, "List ISO-15693 history"}, - {"demod", CmdHF15Demod, AlwaysAvailable, "Demodulate ISO-15693 from tag"}, - {"dump", CmdHF15Dump, IfPm3Iso15693, "Read all memory pages of an ISO-15693 tag, save to file"}, - {"info", CmdHF15Info, IfPm3Iso15693, "Tag information"}, - {"sniff", CmdHF15Sniff, IfPm3Iso15693, "Sniff ISO-15693 traffic"}, - {"raw", CmdHF15Raw, IfPm3Iso15693, "Send raw hex data to tag"}, - {"rdbl", CmdHF15Readblock, IfPm3Iso15693, "Read a block"}, - {"rdmulti", CmdHF15Readmulti, IfPm3Iso15693, "Reads multiple blocks"}, - {"reader", CmdHF15Reader, IfPm3Iso15693, "Act like an ISO-15693 reader"}, - {"restore", CmdHF15Restore, IfPm3Iso15693, "Restore from file to all memory pages of an ISO-15693 tag"}, - {"samples", CmdHF15Samples, IfPm3Iso15693, "Acquire samples as reader (enables carrier, sends inquiry)"}, - {"eload", CmdHF15ELoad, IfPm3Iso15693, "Load image file into emulator to be used by 'sim' command"}, - {"esave", CmdHF15ESave, IfPm3Iso15693, "Save emulator memory into image file"}, - {"eview", CmdHF15EView, IfPm3Iso15693, "View emulator memory"}, - {"sim", CmdHF15Sim, IfPm3Iso15693, "Fake an ISO-15693 tag"}, - {"slixdisable", CmdHF15SlixDisable, IfPm3Iso15693, "Disable privacy mode on SLIX ISO-15693 tag"}, - {"wrbl", CmdHF15Write, IfPm3Iso15693, "Write a block"}, - {"-----------", CmdHF15Help, IfPm3Iso15693, "----------------------- " _CYAN_("afi") " -----------------------"}, - {"findafi", CmdHF15FindAfi, IfPm3Iso15693, "Brute force AFI of an ISO-15693 tag"}, - {"writeafi", CmdHF15WriteAfi, IfPm3Iso15693, "Writes the AFI on an ISO-15693 tag"}, - {"writedsfid", CmdHF15WriteDsfid, IfPm3Iso15693, "Writes the DSFID on an ISO-15693 tag"}, - {"-----------", CmdHF15Help, IfPm3Iso15693, "----------------------- " _CYAN_("magic") " -----------------------"}, - {"csetuid", CmdHF15CSetUID, IfPm3Iso15693, "Set UID for magic card"}, + {"-----------", CmdHF15Help, AlwaysAvailable, "--------------------- " _CYAN_("General") " ---------------------"}, + {"help", CmdHF15Help, AlwaysAvailable, "This help"}, + {"list", CmdHF15List, AlwaysAvailable, "List ISO-15693 history"}, + {"demod", CmdHF15Demod, AlwaysAvailable, "Demodulate ISO-15693 from tag"}, + {"dump", CmdHF15Dump, IfPm3Iso15693, "Read all memory pages of an ISO-15693 tag, save to file"}, + {"info", CmdHF15Info, IfPm3Iso15693, "Tag information"}, + {"sniff", CmdHF15Sniff, IfPm3Iso15693, "Sniff ISO-15693 traffic"}, + {"raw", CmdHF15Raw, IfPm3Iso15693, "Send raw hex data to tag"}, + {"rdbl", CmdHF15Readblock, IfPm3Iso15693, "Read a block"}, + {"rdmulti", CmdHF15Readmulti, IfPm3Iso15693, "Reads multiple blocks"}, + {"reader", CmdHF15Reader, IfPm3Iso15693, "Act like an ISO-15693 reader"}, + {"restore", CmdHF15Restore, IfPm3Iso15693, "Restore from file to all memory pages of an ISO-15693 tag"}, + {"samples", CmdHF15Samples, IfPm3Iso15693, "Acquire samples as reader (enables carrier, sends inquiry)"}, + {"eload", CmdHF15ELoad, IfPm3Iso15693, "Load image file into emulator to be used by 'sim' command"}, + {"esave", CmdHF15ESave, IfPm3Iso15693, "Save emulator memory into image file"}, + {"eview", CmdHF15EView, IfPm3Iso15693, "View emulator memory"}, + {"sim", CmdHF15Sim, IfPm3Iso15693, "Fake an ISO-15693 tag"}, + {"slixwritepwd", CmdHF15SlixWritePassword, IfPm3Iso15693, "Writes a password on a SLIX ISO-15693 tag"}, + {"slixeasdisable", CmdHF15SlixEASDisable, IfPm3Iso15693, "Disable EAS mode on SLIX ISO-15693 tag"}, + {"slixeasenable", CmdHF15SlixEASEnable, IfPm3Iso15693, "Enable EAS mode on SLIX ISO-15693 tag"}, + {"slixprivacydisable", CmdHF15SlixDisable, IfPm3Iso15693, "Disable privacy mode on SLIX ISO-15693 tag"}, + {"slixprivacyenable", CmdHF15SlixEnable, IfPm3Iso15693, "Enable privacy mode on SLIX ISO-15693 tag"}, + {"passprotectafi", CmdHF15AFIPassProtect, IfPm3Iso15693, "Password protect AFI - Cannot be undone"}, + {"passprotecteas", CmdHF15EASPassProtect, IfPm3Iso15693, "Password protect EAS - Cannot be undone"}, + {"wrbl", CmdHF15Write, IfPm3Iso15693, "Write a block"}, + {"-----------", CmdHF15Help, IfPm3Iso15693, "----------------------- " _CYAN_("afi") " -----------------------"}, + {"findafi", CmdHF15FindAfi, IfPm3Iso15693, "Brute force AFI of an ISO-15693 tag"}, + {"writeafi", CmdHF15WriteAfi, IfPm3Iso15693, "Writes the AFI on an ISO-15693 tag"}, + {"writedsfid", CmdHF15WriteDsfid, IfPm3Iso15693, "Writes the DSFID on an ISO-15693 tag"}, + {"-----------", CmdHF15Help, IfPm3Iso15693, "----------------------- " _CYAN_("magic") " -----------------------"}, + {"csetuid", CmdHF15CSetUID, IfPm3Iso15693, "Set UID for magic card"}, {NULL, NULL, NULL, NULL} }; diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index 94d710f98..36bd3b3d2 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -3832,6 +3832,7 @@ static int CmdHFiClassEncode(const char *Cmd) { arg_u64_0(NULL, "cn", "", "card number"), arg_str0("w", "wiegand", "", "see " _YELLOW_("`wiegand list`") " for available formats"), arg_lit0(NULL, "shallow", "use shallow (ASK) reader modulation instead of OOK"), + arg_lit0("v", NULL, "verbose (print encoded blocks)"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, false); @@ -3877,6 +3878,7 @@ static int CmdHFiClassEncode(const char *Cmd) { CLIParamStrToBuf(arg_get_str(ctx, 9), (uint8_t *)format, sizeof(format), &format_len); bool shallow_mod = arg_get_lit(ctx, 10); + bool verbose = arg_get_lit(ctx, 11); CLIParserFree(ctx); @@ -3996,6 +3998,17 @@ static int CmdHFiClassEncode(const char *Cmd) { iclass_encrypt_block_data(credential + 24, enc_key); } + if (verbose) { + for (uint8_t i = 0; i < 4; i++) { + PrintAndLogEx(INFO, "Block %d/0x0%x -> " _YELLOW_("%s"), 6 + i, 6 + i, sprint_hex_inrow(credential + (i * 8), 8)); + } + } + + if (!g_session.pm3_present) { + PrintAndLogEx(ERR, "Device offline\n"); + return PM3_EFAILED; + } + int isok = PM3_SUCCESS; // write for (uint8_t i = 0; i < 4; i++) { diff --git a/client/src/cmdhflist.c b/client/src/cmdhflist.c index a19ecdea9..232d4af19 100644 --- a/client/src/cmdhflist.c +++ b/client/src/cmdhflist.c @@ -318,7 +318,7 @@ int applyIso14443a(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, bool i snprintf(exp, size, "AUTH-B(%d)", cmd[1]); break; } - case MIFARE_MAGIC_GDM_AUTH_KEYA:{ + case MIFARE_MAGIC_GDM_AUTH_KEYA: { if (cmdsize > 3) { snprintf(exp, size, "MAGIC AUTH-A(%d)", cmd[1]); MifareAuthState = masNt; diff --git a/client/src/cmdhfmfu.c b/client/src/cmdhfmfu.c index bc8c10859..a59859394 100644 --- a/client/src/cmdhfmfu.c +++ b/client/src/cmdhfmfu.c @@ -1472,6 +1472,7 @@ uint32_t GetHF14AMfU_Type(void) { else if (memcmp(version, "\x00\x34\x21\x01\x01\x00\x0E", 7) == 0) { tagtype = UL_EV1_128; break; } // Mikron JSC Russia EV1 41 pages tag else if (memcmp(version, "\x00\x04\x04\x01\x01\x00\x0B", 7) == 0) { tagtype = NTAG_210; break; } else if (memcmp(version, "\x00\x04\x04\x01\x02\x00\x0B", 7) == 0) { tagtype = NTAG_210u; break; } + else if (memcmp(version, "\x00\x04\x04\x02\x02\x00\x0B", 7) == 0) { tagtype = NTAG_210u; break; } else if (memcmp(version, "\x00\x04\x04\x01\x01\x00\x0E", 7) == 0) { tagtype = NTAG_212; break; } else if (memcmp(version, "\x00\x04\x04\x02\x01\x00\x0F", 7) == 0) { tagtype = NTAG_213; break; } else if (memcmp(version, "\x00\x53\x04\x02\x01\x00\x0F", 7) == 0) { tagtype = NTAG_213; break; } //Shanghai Feiju Microelectronics Co. Ltd. China (Xiaomi Air Purifier filter) diff --git a/client/src/cmdhftesla.c b/client/src/cmdhftesla.c index 2680daa90..940687cb4 100644 --- a/client/src/cmdhftesla.c +++ b/client/src/cmdhftesla.c @@ -29,7 +29,7 @@ #include "commonutil.h" // get_sw #include "protocols.h" // ISO7816 APDU return co-des #include "ui.h" -#include "cmdhf14a.h" // apdu chaining +#include "cmdhf14a.h" // apdu chaining #define TIMEOUT 2000 @@ -147,7 +147,7 @@ static int info_hf_tesla(void) { // --------------- CERT reading ---------------- Set_apdu_in_framing(true); - for (uint8_t i = 0; i < 4; i++) { + for (uint8_t i = 0; i < 5; i++) { uint8_t aSELECT_CERT[PM3_CMD_DATA_SIZE] = {0x80, 0x06, i, 0x00, 0x00, 0x00, 0xFF}; int aSELECT_CERT_n = 7; @@ -160,10 +160,10 @@ static int info_hf_tesla(void) { sw = get_sw(response, resplen); if (sw == ISO7816_OK) { - // save CETT for later + // save CERT for later uint8_t cert[515] = {0}; memcpy(cert, response, resplen - 2); - + PrintAndLogEx(INFO, "CERT # %i", i); PrintAndLogEx(INFO, "%s", sprint_hex_inrow(cert, resplen - 2)); } @@ -198,13 +198,24 @@ static int info_hf_tesla(void) { PrintAndLogEx(INFO, "--- " _CYAN_("Tag Information") " ---------------------------"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "PUBLIC KEY"); - for (int i=0; i < 3; i++) { + for (int i = 0; i < 3; i++) { PrintAndLogEx(INFO, "%d - %s", i, sprint_hex_inrow(pk[i], 65)); } - if (form_factor[1] == 1) { - PrintAndLogEx(INFO, "Form factor... %s (card)", sprint_hex_inrow(form_factor, sizeof(form_factor))); - } else if (form_factor[1] == 2){ - PrintAndLogEx(INFO, "Form factor... %s (phone app)", sprint_hex_inrow(form_factor, sizeof(form_factor))); + PrintAndLogEx(INFO, "Form factor... %s " NOLF, sprint_hex_inrow(form_factor, sizeof(form_factor))); + uint16_t form_factor_value = form_factor[0] << 8 | form_factor[1]; + switch (form_factor_value) { + case 0x0001: + PrintAndLogEx(NORMAL, "(card)"); + break; + case 0x0022: + PrintAndLogEx(NORMAL, "(fob)"); + break; + case 0x0031: + PrintAndLogEx(NORMAL, "(phone app)"); + break; + default: + PrintAndLogEx(NORMAL, "(unknown)"); + break; } if (sizeof(version) > 0) { @@ -217,7 +228,7 @@ static int info_hf_tesla(void) { if ((memcmp(pk[0], pk[1], 65) == 0)) { PrintAndLogEx(INFO, " GaussKey detected"); } - // + // return PM3_SUCCESS; } diff --git a/client/src/cmdhfwaveshare.c b/client/src/cmdhfwaveshare.c index 78c6ef825..8df62bcc1 100644 --- a/client/src/cmdhfwaveshare.c +++ b/client/src/cmdhfwaveshare.c @@ -712,17 +712,17 @@ static int start_drawing(uint8_t model_nr, uint8_t *black, uint8_t *red) { return PM3_ESOFT; } - if ((card.uidlen != 7) || ((memcmp(card.uid, "FSTN10m", 7) != 0) && (memcmp(card.uid, "WSDZ10m", 7) != 0))) { + if ((card.uidlen != 7) || ((memcmp(card.uid, "FSTN10m", 7) != 0) && (memcmp(card.uid, "FSTN11m", 7) != 0) && (memcmp(card.uid, "WSDZ10m", 7) != 0))) { PrintAndLogEx(WARNING, "Card doesn't look like Waveshare tag"); DropField(); return PM3_ESOFT; } - if (((model_nr != M1in54B) && (memcmp(card.uid, "FSTN10m", 7) == 0))) { + if (((model_nr != M1in54B) && ((memcmp(card.uid, "FSTN10m", 7) == 0) || (memcmp(card.uid, "FSTN11m", 7) == 0)))) { PrintAndLogEx(WARNING, "Card is a Waveshare tag 1.54\", not %s", models[model_nr].desc); DropField(); return PM3_ESOFT; } - if (((model_nr == M1in54B) && (memcmp(card.uid, "FSTN10m", 7) != 0))) { + if (((model_nr == M1in54B) && (memcmp(card.uid, "FSTN10m", 7) != 0) && (memcmp(card.uid, "FSTN11m", 7) != 0))) { PrintAndLogEx(WARNING, "Card is not a Waveshare tag 1.54\", check your model number"); DropField(); return PM3_ESOFT; diff --git a/client/src/cmdhw.c b/client/src/cmdhw.c index 0efa5eafe..ed208b5f5 100644 --- a/client/src/cmdhw.c +++ b/client/src/cmdhw.c @@ -1298,6 +1298,10 @@ void pm3_version(bool verbose, bool oneliner) { PrintAndLogEx(NORMAL, " FPC USART for BT add-on... %s", IfPm3FpcUsartHost() ? _GREEN_("present") : _YELLOW_("absent")); } else { PrintAndLogEx(NORMAL, " firmware.................. %s", _YELLOW_("PM3 GENERIC")); + if (IfPm3Flash()) { + PrintAndLogEx(NORMAL, " external flash............ %s", _GREEN_("present")); + } + if (IfPm3FpcUsartHost()) { PrintAndLogEx(NORMAL, " FPC USART for BT add-on... %s", _GREEN_("present")); } diff --git a/client/src/cmdlfem4x70.c b/client/src/cmdlfem4x70.c index 7021b2b95..e90c688c1 100644 --- a/client/src/cmdlfem4x70.c +++ b/client/src/cmdlfem4x70.c @@ -200,7 +200,7 @@ int CmdEM4x70Write(const char *Cmd) { } etd.address = (uint8_t) addr; - etd.word = BYTES2UINT16(word);; + etd.word = BYTES2UINT16(word); clearCommandBuffer(); SendCommandNG(CMD_LF_EM4X70_WRITE, (uint8_t *)&etd, sizeof(etd)); @@ -220,6 +220,104 @@ int CmdEM4x70Write(const char *Cmd) { return PM3_ESOFT; } +int CmdEM4x70Brute(const char *Cmd) { + + // From paper "Dismantling Megamos Crypto", Roel Verdult, Flavio D. Garcia and Barıs¸ Ege. + // Partial Key-Update Attack (optimized version) + em4x70_data_t etd = {0}; + + CLIParserContext *ctx; + + CLIParserInit(&ctx, "lf em 4x70 brute", + "Optimized partial key-update attack of 16-bit key block 7, 8 or 9 of an EM4x70\n" + "This attack does NOT write anything to the tag.\n" + "Before starting this attack, 0000 must be written to the 16-bit key block: 'lf em 4x70 write -b 9 -d 0000'.\n" + "After success, the 16-bit key block have to be restored with the key found: 'lf em 4x70 write -b 9 -d c0de'\n", + "lf em 4x70 brute -b 9 --rnd 45F54ADA252AAC --frn 4866BB70 --> bruteforcing key bits k95...k80\n" + ); + + void *argtable[] = { + arg_param_begin, + arg_lit0(NULL, "par", "Add parity bit when sending commands"), + arg_int1("b", "block", "", "block/word address, dec"), + arg_str1(NULL, "rnd", "", "Random 56-bit"), + arg_str1(NULL, "frn", "", "F(RN) 28-bit as 4 hex bytes"), + arg_str0("s", "start", "", "Start bruteforce enumeration from this key value"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + + etd.parity = arg_get_lit(ctx, 1); + + int addr = arg_get_int_def(ctx, 2, 0); + if (addr < 7 || addr > 9) { + PrintAndLogEx(FAILED, "block has to be within range [7, 9] got: %d", addr); + return PM3_EINVARG; + } + etd.address = (uint8_t) addr; + + int rnd_len = 7; + CLIGetHexWithReturn(ctx, 3, etd.rnd, &rnd_len); + + int frnd_len = 4; + CLIGetHexWithReturn(ctx, 4, etd.frnd, &frnd_len); + + uint32_t start_key = 0; + int res = arg_get_u32_hexstr_def_nlen(ctx, 5, 0, &start_key, 2, true); + if (res == 2) { + CLIParserFree(ctx); + PrintAndLogEx(WARNING, "start key parameter must be in range [0, FFFF]"); + return PM3_EINVARG; + } + etd.start_key = start_key; + + CLIParserFree(ctx); + + if (rnd_len != 7) { + PrintAndLogEx(FAILED, "Random number length must be 7 bytes instead of %d", rnd_len); + return PM3_EINVARG; + } + + if (frnd_len != 4) { + PrintAndLogEx(FAILED, "F(RN) length must be 4 bytes instead of %d", frnd_len); + return PM3_EINVARG; + } + + PrintAndLogEx(INFO, "click " _GREEN_("pm3 button") " or press " _GREEN_("Enter") " to exit"); + clearCommandBuffer(); + PacketResponseNG resp; + SendCommandNG(CMD_LF_EM4X70_BRUTE, (uint8_t *)&etd, sizeof(etd)); + + uint32_t timeout = 0; + for (;;) { + + if (kbd_enter_pressed()) { + SendCommandNG(CMD_BREAK_LOOP, NULL, 0); + PrintAndLogEx(DEBUG, "User aborted"); + break; + } + + if (WaitForResponseTimeout(CMD_LF_EM4X70_BRUTE, &resp, TIMEOUT)) { + if (resp.status) { + // Response is 16-bit partial key + PrintAndLogEx(INFO, "Partial Key Response: %02X %02X", resp.data.asBytes[0], resp.data.asBytes[1]); + return PM3_SUCCESS; + } + break; + } + + // should be done in about 60 minutes. + if (timeout > ((60 * 60000) / TIMEOUT)) { + PrintAndLogEx(WARNING, "\nNo response from Proxmark3. Aborting..."); + break; + } + timeout++; + } + + PrintAndLogEx(FAILED, "Bruteforce of partial key " _RED_("failed")); + return PM3_ESOFT; +} + int CmdEM4x70Unlock(const char *Cmd) { // send pin code to device, unlocking it for writing @@ -452,6 +550,7 @@ int CmdEM4x70WriteKey(const char *Cmd) { static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, + {"brute", CmdEM4x70Brute, IfPm3EM4x70, "Bruteforce EM4X70 to find partial Crypt Key"}, {"info", CmdEM4x70Info, IfPm3EM4x70, "Tag information EM4x70"}, {"write", CmdEM4x70Write, IfPm3EM4x70, "Write EM4x70"}, {"unlock", CmdEM4x70Unlock, IfPm3EM4x70, "Unlock EM4x70 for writing"}, diff --git a/client/src/cmdlfem4x70.h b/client/src/cmdlfem4x70.h index 5d46af3ca..12599713b 100644 --- a/client/src/cmdlfem4x70.h +++ b/client/src/cmdlfem4x70.h @@ -26,6 +26,7 @@ int CmdLFEM4X70(const char *Cmd); int CmdEM4x70Info(const char *Cmd); int CmdEM4x70Write(const char *Cmd); +int CmdEM4x70Brute(const char *Cmd); int CmdEM4x70Unlock(const char *Cmd); int CmdEM4x70Auth(const char *Cmd); int CmdEM4x70WritePIN(const char *Cmd); diff --git a/client/src/cmdmain.c b/client/src/cmdmain.c index 14e198f5c..11f9bfd7b 100644 --- a/client/src/cmdmain.c +++ b/client/src/cmdmain.c @@ -300,15 +300,23 @@ static int CmdClear(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "clear", "Clear the Proxmark3 client terminal screen", - "clear" + "clear -> clear the terminal screen\n" + "clear -b -> clear the terminal screen and the scrollback buffer" ); void *argtable[] = { arg_param_begin, + arg_lit0("b", "back", "also clear the scrollback buffer"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); + bool scrollback = arg_get_lit(ctx, 1); CLIParserFree(ctx); - PrintAndLogEx(NORMAL, _CLEAR_ _TOP_ ""); + + if (!scrollback) + PrintAndLogEx(NORMAL, _CLEAR_ _TOP_ ""); + else + PrintAndLogEx(NORMAL, _CLEAR_ _TOP_ _CLEAR_SCROLLBACK_ ""); + return PM3_SUCCESS; } diff --git a/client/src/cmdparser.c b/client/src/cmdparser.c index 96c5f0fb3..1c360e832 100644 --- a/client/src/cmdparser.c +++ b/client/src/cmdparser.c @@ -38,7 +38,7 @@ bool IfPm3Present(void) { bool IfPm3Rdv4Fw(void) { if (!IfPm3Present()) return false; - return (g_pm3_capabilities.compiled_with_flash) || (g_pm3_capabilities.compiled_with_smartcard); + return (g_pm3_capabilities.is_rdv4); } bool IfPm3Flash(void) { diff --git a/client/src/cmdscript.c b/client/src/cmdscript.c index 57cf54084..114205708 100644 --- a/client/src/cmdscript.c +++ b/client/src/cmdscript.c @@ -433,7 +433,7 @@ static int CmdScriptRun(const char *Cmd) { #else // The following line will implicitly pre-initialize Python PyConfig_SetBytesArgv(&py_conf, argc + 1, argv); - + // We disallowed in py_conf environment variables interfering with python interpreter's behavior. // Let's manually enable the ones we truly need. // This is required by Proxspace to work with an isolated Python configuration diff --git a/client/src/pm3line_vocabulory.h b/client/src/pm3line_vocabulory.h index 5a517c645..bcf196fe9 100644 --- a/client/src/pm3line_vocabulory.h +++ b/client/src/pm3line_vocabulory.h @@ -177,7 +177,13 @@ const static vocabulory_t vocabulory[] = { { 0, "hf 15 esave" }, { 0, "hf 15 eview" }, { 0, "hf 15 sim" }, - { 0, "hf 15 slixdisable" }, + { 0, "hf 15 slixwritepwd" }, + { 0, "hf 15 slixeasdisable" }, + { 0, "hf 15 slixeasenable" }, + { 0, "hf 15 slixprivacydisable" }, + { 0, "hf 15 slixprivacyenable" }, + { 0, "hf 15 passprotectafi" }, + { 0, "hf 15 passprotecteas" }, { 0, "hf 15 wrbl" }, { 0, "hf 15 findafi" }, { 0, "hf 15 writeafi" }, @@ -438,6 +444,12 @@ const static vocabulory_t vocabulory[] = { { 0, "hf st25ta protect" }, { 0, "hf st25ta pwd" }, { 0, "hf st25ta sim" }, + { 1, "hf tesla help" }, + { 0, "hf tesla info" }, + { 1, "hf tesla list" }, + { 1, "hf texkom help" }, + { 0, "hf texkom reader" }, + { 0, "hf texkom sim" }, { 1, "hf thinfilm help" }, { 0, "hf thinfilm info" }, { 1, "hf thinfilm list" }, @@ -453,9 +465,6 @@ const static vocabulory_t vocabulory[] = { { 0, "hf topaz rdbl" }, { 1, "hf topaz view" }, { 0, "hf topaz wrbl" }, - { 1, "hf texkom help" }, - { 0, "hf texkom reader" }, - { 0, "hf texkom sim" }, { 1, "hf xerox help" }, { 0, "hf xerox info" }, { 0, "hf xerox reader" }, diff --git a/client/src/preferences.c b/client/src/preferences.c index 28ae4d44f..99fb20d30 100644 --- a/client/src/preferences.c +++ b/client/src/preferences.c @@ -152,7 +152,7 @@ int preferences_save(void) { } uint8_t dummyData = 0x00; - size_t dummyDL = 0x00; + size_t dummyDL = 0x01; if (saveFileJSON(fn, jsfCustom, &dummyData, dummyDL, &preferences_save_callback) != PM3_SUCCESS) PrintAndLogEx(ERR, "Error saving preferences to \"%s\"", fn); diff --git a/client/src/proxmark3.c b/client/src/proxmark3.c index 9ca38a2a1..378b9f0dc 100644 --- a/client/src/proxmark3.c +++ b/client/src/proxmark3.c @@ -41,7 +41,7 @@ static int mainret = PM3_ESOFT; #ifndef LIBPM3 #define BANNERMSG1 "" -#define BANNERMSG2 " [ :snowflake: ]" +#define BANNERMSG2 " [ :coffee: ]" #define BANNERMSG3 "" typedef enum LogoMode { UTF8, ANSI, ASCII } LogoMode; diff --git a/client/src/util.c b/client/src/util.c index 63141d01c..b13c5e3a9 100644 --- a/client/src/util.c +++ b/client/src/util.c @@ -266,7 +266,7 @@ void print_hex_break(const uint8_t *data, const size_t len, uint8_t breaks) { uint8_t mod = len % breaks; if (mod) { - char buf[UTIL_BUFFER_SIZE_SPRINT + 3]; + char buf[UTIL_BUFFER_SIZE_SPRINT + 3] = {0}; hex_to_buffer((uint8_t *)buf, data + i, mod, (sizeof(buf) - 1), 0, 1, true); // add the spaces... @@ -291,7 +291,7 @@ void print_hex_noascii_break(const uint8_t *data, const size_t len, uint8_t brea uint8_t mod = len % breaks; if (mod) { - char buf[UTIL_BUFFER_SIZE_SPRINT + 3]; + char buf[UTIL_BUFFER_SIZE_SPRINT + 3] = {0}; hex_to_buffer((uint8_t *)buf, data + i, mod, (sizeof(buf) - 1), 0, 0, true); // add the spaces... @@ -307,7 +307,7 @@ static void print_buffer_ex(const uint8_t *data, const size_t len, int level, ui if ((data == NULL) || (len < 1)) return; - char buf[UTIL_BUFFER_SIZE_SPRINT + 3]; + char buf[UTIL_BUFFER_SIZE_SPRINT + 3] = {0}; int i; for (i = 0; i < len; i += breaks) { @@ -614,7 +614,7 @@ void bytes_to_bytebits(const void *src, const size_t srclen, void *dest) { // hh,gg,ff,ee,dd,cc,bb,aa, pp,oo,nn,mm,ll,kk,jj,ii // up to 64 bytes or 512 bits uint8_t *SwapEndian64(const uint8_t *src, const size_t len, const uint8_t blockSize) { - static uint8_t buf[64]; + static uint8_t buf[64] = {0}; memset(buf, 0x00, 64); uint8_t *tmp = buf; for (uint8_t block = 0; block < (uint8_t)(len / blockSize); block++) { diff --git a/common_arm/Makefile.hal b/common_arm/Makefile.hal index 68417eb60..0e9dd455b 100644 --- a/common_arm/Makefile.hal +++ b/common_arm/Makefile.hal @@ -95,6 +95,7 @@ ifeq ($(PLATFORM),PM3RDV4) PLATFORM_DEFS = -DWITH_SMARTCARD -DWITH_FLASH -DRDV4 PLTNAME = Proxmark3 RDV4 PLATFORM_FPGA = xc2s30 + RDV4 = yes else ifeq ($(PLATFORM),PM3OTHER) $(warning PLATFORM=PM3OTHER is deprecated, please use PLATFORM=PM3GENERIC) PLTNAME = Proxmark3 generic target diff --git a/doc/T5577_Guide.md b/doc/T5577_Guide.md index deab49d53..6c4eceaf5 100644 --- a/doc/T5577_Guide.md +++ b/doc/T5577_Guide.md @@ -393,8 +393,8 @@ required, please do not proceed. | Hex Data | Binary Data | |:--------:|:---------------------------------------| - | 00088040 | 000000000000100010000000111***0***0000 | - | 00088050 | 000000000000100010000000111***1***0000 | + | 000880E0 | 000000000000100010000000111***0***0000 | + | 000880F0 | 000000000000100010000000111***1***0000 | See how in the above we changed the bit in location 28 from a 0 to 1 0 = No Password, 1 = Use Password @@ -533,7 +533,7 @@ required, please do not proceed. [=] Downlink mode..... default/fixed bit length [=] Password set...... No ``` - Yes we can! We can see Block 0 is the correct config 00088040 + Yes we can! We can see Block 0 is the correct config 000880E0 # Part 2 – Configuration Blocks ^[Top](#top) diff --git a/doc/commands.json b/doc/commands.json index 1c21f81ba..3545a9b78 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -1101,14 +1101,16 @@ "command": "hf 14a chaining", "description": "Enable/Disable ISO14443a input chaining. Maximum input length goes from ATS.", "notes": [ - "hf 14a chaining disable -> disable chaining", - "hf 14a chaining -> show chaining enable/disable state" + "hf 14a chaining -> show chaining enable/disable state", + "hf 14a chaining --off -> disable chaining" ], "offline": false, "options": [ - "-h, --help This help" + "-h, --help This help", + "-1, --on enabled chaining", + "-0, --off disable chaining" ], - "usage": "hf 14a chaining [-h] []" + "usage": "hf 14a chaining [-h10]" }, "hf 14a config": { "command": "hf 14a config", @@ -1654,6 +1656,34 @@ ], "usage": "hf 15 list [-h1crux] [--frame] [-f ]" }, + "hf 15 passprotectafi": { + "command": "hf 15 passprotectafi", + "description": "This command enables the password protect of AFI. *** OBS! This action can not be undone! ***", + "notes": [ + "hf 15 passprotectafi -p 00000000 --force" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-p, --pwd EAS/AFI password, 8 hex bytes", + "--force Force execution of command (irreversible)" + ], + "usage": "hf 15 passprotectafi [-h] -p [--force]" + }, + "hf 15 passprotecteas": { + "command": "hf 15 passprotecteas", + "description": "This command enables the password protect of EAS. *** OBS! This action can not be undone! ***", + "notes": [ + "hf 15 passprotecteas -p 00000000 --force" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-p, --pwd EAS/AFI password, 8 hex bytes", + "--force Force execution of command (irreversible)" + ], + "usage": "hf 15 passprotecteas [-h] -p [--force]" + }, "hf 15 raw": { "command": "hf 15 raw", "description": "Sends raw bytes over ISO-15693 to card", @@ -1774,8 +1804,34 @@ ], "usage": "hf 15 sim [-h] -u <8b hex> [-b ]" }, - "hf 15 slixdisable": { - "command": "hf 15 slixdisable", + "hf 15 slixeasdisable": { + "command": "hf 15 slixeasdisable", + "description": "Disable EAS mode on SLIX ISO-15693 tag", + "notes": [ + "hf 15 slixeasdisable -p 0F0F0F0F" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-p, --pwd optional password, 8 hex bytes" + ], + "usage": "hf 15 slixeasdisable [-h] [-p ]" + }, + "hf 15 slixeasenable": { + "command": "hf 15 slixeasenable", + "description": "Enable EAS mode on SLIX ISO-15693 tag", + "notes": [ + "hf 15 slixeasenable -p 0F0F0F0F" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-p, --pwd optional password, 8 hex bytes" + ], + "usage": "hf 15 slixeasenable [-h] [-p ]" + }, + "hf 15 slixprivacydisable": { + "command": "hf 15 slixprivacydisable", "description": "Disable privacy mode on SLIX ISO-15693 tag", "notes": [ "hf 15 slixdisable -p 0F0F0F0F" @@ -1785,7 +1841,35 @@ "-h, --help This help", "-p, --pwd password, 8 hex bytes" ], - "usage": "hf 15 slixdisable [-h] -p " + "usage": "hf 15 slixprivacydisable [-h] -p " + }, + "hf 15 slixprivacyenable": { + "command": "hf 15 slixprivacyenable", + "description": "Enable privacy mode on SLIX ISO-15693 tag", + "notes": [ + "hf 15 slixenable -p 0F0F0F0F" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-p, --pwd password, 8 hex bytes" + ], + "usage": "hf 15 slixprivacyenable [-h] -p " + }, + "hf 15 slixwritepwd": { + "command": "hf 15 slixwritepwd", + "description": "Write a password on a SLIX family ISO-15693 tag", + "notes": [ + "hf 15 slixwritepwd -t READ -o 00000000 -n 12131415" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-t, --type which password field to write to (some tags do not support all password types)", + "-o, --old old password (if present), 8 hex bytes", + "-n, --new new password, 8 hex bytes" + ], + "usage": "hf 15 slixwritepwd [-h] -t [-o ] -n " }, "hf 15 sniff": { "command": "hf 15 sniff", @@ -1825,19 +1909,16 @@ "description": "Write AFI on card", "notes": [ "hf 15 writeafi -* --afi 12", - "hf 15 writeafi -u E011223344556677 --afi 12" + "hf 15 writeafi -u E011223344556677 --afi 12 -p 0F0F0F0F" ], "offline": false, "options": [ "-h, --help This help", "-u, --uid full UID, 8 bytes", - "--ua unaddressed mode", - "-* scan for tag", - "-2 use slower '1 out of 256' mode", - "-o, --opt set OPTION Flag (needed for TI)", - "--afi AFI number (0-255)" + "--afi AFI number (0-255)", + "-p, --pwd optional AFI/EAS password" ], - "usage": "hf 15 writeafi [-h*2o] [-u ] [--ua] --afi " + "usage": "hf 15 writeafi [-h] [-u ] --afi [-p ]" }, "hf 15 writedsfid": { "command": "hf 15 writedsfid", @@ -2881,7 +2962,7 @@ }, "hf help": { "command": "hf help", - "description": "-------- ----------------------- High Frequency ----------------------- 14a { ISO14443A RFIDs... } 14b { ISO14443B RFIDs... } 15 { ISO15693 RFIDs... } cipurse { Cipurse transport Cards... } epa { German Identification Card... } emrtd { Machine Readable Travel Document... } felica { ISO18092 / FeliCa RFIDs... } fido { FIDO and FIDO2 authenticators... } fudan { Fudan RFIDs... } gallagher { Gallagher DESFire RFIDs... } ksx6924 { KS X 6924 (T-Money, Snapper+) RFIDs } jooki { Jooki RFIDs... } iclass { ICLASS RFIDs... } legic { LEGIC RFIDs... } lto { LTO Cartridge Memory RFIDs... } mf { MIFARE RFIDs... } mfp { MIFARE Plus RFIDs... } mfu { MIFARE Ultralight RFIDs... } mfdes { MIFARE Desfire RFIDs... } ntag424 { NXP NTAG 4242 DNA RFIDs... } seos { SEOS RFIDs... } st25ta { ST25TA RFIDs... } thinfilm { Thinfilm RFIDs... } topaz { TOPAZ (NFC Type 1) RFIDs... } texkom { Texkom RFIDs... } xerox { Fuji/Xerox cartridge RFIDs... } waveshare { Waveshare NFC ePaper... } ----------- --------------------- General --------------------- help This help list List protocol data in trace buffer search Search for known HF tags", + "description": "-------- ----------------------- High Frequency ----------------------- 14a { ISO14443A RFIDs... } 14b { ISO14443B RFIDs... } 15 { ISO15693 RFIDs... } cipurse { Cipurse transport Cards... } epa { German Identification Card... } emrtd { Machine Readable Travel Document... } felica { ISO18092 / FeliCa RFIDs... } fido { FIDO and FIDO2 authenticators... } fudan { Fudan RFIDs... } gallagher { Gallagher DESFire RFIDs... } ksx6924 { KS X 6924 (T-Money, Snapper+) RFIDs } jooki { Jooki RFIDs... } iclass { ICLASS RFIDs... } legic { LEGIC RFIDs... } lto { LTO Cartridge Memory RFIDs... } mf { MIFARE RFIDs... } mfp { MIFARE Plus RFIDs... } mfu { MIFARE Ultralight RFIDs... } mfdes { MIFARE Desfire RFIDs... } ntag424 { NXP NTAG 4242 DNA RFIDs... } seos { SEOS RFIDs... } st25ta { ST25TA RFIDs... } tesla { TESLA Cards... } texkom { Texkom RFIDs... } thinfilm { Thinfilm RFIDs... } topaz { TOPAZ (NFC Type 1) RFIDs... } xerox { Fuji/Xerox cartridge RFIDs... } waveshare { Waveshare NFC ePaper... } ----------- --------------------- General --------------------- help This help list List protocol data in trace buffer search Search for known HF tags", "notes": [], "offline": true, "options": [], @@ -6684,6 +6765,47 @@ ], "usage": "hf st25ta sim [-h] -u " }, + "hf tesla help": { + "command": "hf tesla help", + "description": "help This help list List ISO 14443A/7816 history", + "notes": [], + "offline": true, + "options": [], + "usage": "" + }, + "hf tesla info": { + "command": "hf tesla info", + "description": "Get info about TESLA Key tag", + "notes": [ + "hf tesla info" + ], + "offline": false, + "options": [ + "-h, --help This help" + ], + "usage": "hf telsa info [-h]" + }, + "hf tesla list": { + "command": "hf tesla list", + "description": "Alias of `trace list -t 7816` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", + "notes": [ + "hf tesla list --frame -> show frame delay times", + "hf tesla list -1 -> use trace buffer" + ], + "offline": true, + "options": [ + "-h, --help This help", + "-1, --buffer use data from trace buffer", + "--frame show frame delay times", + "-c mark CRC bytes", + "-r show relative times (gap and duration)", + "-u display times in microseconds instead of clock cycles", + "-x show hexdump to convert to pcap(ng)", + "or to import into Wireshark using encapsulation type \"ISO 14443\"", + "-f, --file filename of dictionary" + ], + "usage": "hf tesla list [-h1crux] [--frame] [-f ]" + }, "hf texkom help": { "command": "hf texkom help", "description": "help This help", @@ -11365,7 +11487,7 @@ }, "script help": { "command": "script help", - "description": "This is a feature to run Lua/Cmd/Python scripts. You can place scripts within the luascripts/cmdscripts/pyscripts folders. --------------------------------------------------------------------------------------- script list available offline: yes", + "description": "This is a feature to run Lua/Cmd scripts. You can place scripts within the luascripts/cmdscripts folders. --------------------------------------------------------------------------------------- script list available offline: yes", "notes": [], "offline": true, "options": [], @@ -11760,8 +11882,8 @@ } }, "metadata": { - "commands_extracted": 739, + "commands_extracted": 748, "extracted_by": "PM3Help2JSON v1.00", - "extracted_on": "2023-01-15T01:24:39" + "extracted_on": "2023-01-29T17:39:28" } } \ No newline at end of file diff --git a/doc/commands.md b/doc/commands.md index 1c6110cea..382c98b58 100644 --- a/doc/commands.md +++ b/doc/commands.md @@ -236,7 +236,13 @@ Check column "offline" for their availability. |`hf 15 esave `|N |`Save emulator memory into image file` |`hf 15 eview `|N |`View emulator memory` |`hf 15 sim `|N |`Fake an ISO-15693 tag` -|`hf 15 slixdisable `|N |`Disable privacy mode on SLIX ISO-15693 tag` +|`hf 15 slixwritepwd `|N |`Writes a password on a SLIX ISO-15693 tag` +|`hf 15 slixeasdisable `|N |`Disable EAS mode on SLIX ISO-15693 tag` +|`hf 15 slixeasenable `|N |`Enable EAS mode on SLIX ISO-15693 tag` +|`hf 15 slixprivacydisable`|N |`Disable privacy mode on SLIX ISO-15693 tag` +|`hf 15 slixprivacyenable`|N |`Enable privacy mode on SLIX ISO-15693 tag` +|`hf 15 passprotectafi `|N |`Password protect AFI - Cannot be undone` +|`hf 15 passprotecteas `|N |`Password protect EAS - Cannot be undone` |`hf 15 wrbl `|N |`Write a block` |`hf 15 findafi `|N |`Brute force AFI of an ISO-15693 tag` |`hf 15 writeafi `|N |`Writes the AFI on an ISO-15693 tag` @@ -651,6 +657,28 @@ Check column "offline" for their availability. |`hf st25ta sim `|N |`Fake ISO 14443A/ST tag` +### hf tesla + + { TESLA Cards... } + +|command |offline |description +|------- |------- |----------- +|`hf tesla help `|Y |`This help` +|`hf tesla info `|N |`Tag information` +|`hf tesla list `|Y |`List ISO 14443A/7816 history` + + +### hf texkom + + { Texkom RFIDs... } + +|command |offline |description +|------- |------- |----------- +|`hf texkom help `|Y |`This help` +|`hf texkom reader `|N |`Act like a Texkom reader` +|`hf texkom sim `|N |`Simulate a Texkom tag` + + ### hf thinfilm { Thinfilm RFIDs... } @@ -682,17 +710,6 @@ Check column "offline" for their availability. |`hf topaz wrbl `|N |`Write block` -### hf texkom - - { Texkom RFIDs... } - -|command |offline |description -|------- |------- |----------- -|`hf texkom help `|Y |`This help` -|`hf texkom reader `|N |`Act like a Texkom reader` -|`hf texkom sim `|N |`Simulate a Texkom tag` - - ### hf xerox { Fuji/Xerox cartridge RFIDs... } diff --git a/doc/magic_cards_notes.md b/doc/magic_cards_notes.md index c8decbfe2..db8057e5e 100644 --- a/doc/magic_cards_notes.md +++ b/doc/magic_cards_notes.md @@ -1086,10 +1086,12 @@ CF 35 <2b ATQA><1b SAK> // Configure ATQA/SAK (swap ATQ CF 68 <00-02> // Configure UID length CF 69 <00-01> // (De)Activate Ultralight mode CF 6A <00-03> // Select Ultralight mode +CF 6B <1b> // Set Ultralight and M1 maximum read/write sectors CF C6 // Dump configuration CF CC // Factory test, returns 6666 CF CD <1b block number><16b block data> // Backdoor write 16b block CF CE <1b block number> // Backdoor read 16b block +CF CF <1b param> // Unknown CF F0 <30b configuration data> // Configure all params in one cmd CF F1 <30b configuration data> // Configure all params in one cmd and fuse the configuration permanently CF FE <4b new_password> // change password @@ -1304,6 +1306,19 @@ script run hf_mf_ultimatecard -m 02 ``` Now the card supports the 3DES UL-C authentication. +### Set Ultralight and M1 maximum read/write sectors +^[Top](#top) ^^[Gen4](#g4top) + +``` +hf 14a raw -s -c -t 1000 CF6B<1b blocks> +``` +Hexadecimal, maximum sector data, default 0xFF, range 0x00-0xFF + +Example: set maximum 63 blocks read/write for Mifare Classic 1K + +``` +hf 14a raw -s -c -t 1000 CF000000006B3F +``` ### Set shadow mode (GTU) ^[Top](#top) ^^[Gen4](#g4top) @@ -1365,6 +1380,20 @@ Example: write block0 with factory data, default pwd hf 14a raw -s -c -t 1000 CF00000000CD00112233441C000011778185BA18000000 ``` +### Unknown command +^[Top](#top) ^^[Gen4](#g4top) + +This command modifies one byte in configuration dump, but purpose one is unknown. + +``` +hf 14a raw -s -c -t 1000 CFCF<1b param> +``` + * `` + * `??`: ??? + +Example: +hf 14a raw -s -c -t 1000 CF00000000CF02 + ### Change backdoor password ^[Top](#top) ^^[Gen4](#g4top) @@ -1391,8 +1420,10 @@ hf 14a raw -s -c -t 1000 CFC6 ``` Default configuration: ``` -00000000000002000978009102DABC191010111213141516040008004F6B - ^^^^ ?? +00000000000002000978009102DABC191010111213141516040008006B024F6B + ^^^^ ?? + ^^ cf cmd cf: ?? this byte set by cmd cfcf, factory value 0x02 + ^^ cf cmd 6b: maximum read/write sectors, factory value 0x6b ^^ cf cmd 6a: UL mode ^^^^^^ cf cmd 35: ATQA/SAK ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cf cmd 34: ATS length & content diff --git a/doc/md/Installation_Instructions/Windows-WSL2-Installation-Instructions.md b/doc/md/Installation_Instructions/Windows-WSL2-Installation-Instructions.md new file mode 100644 index 000000000..9519b4849 --- /dev/null +++ b/doc/md/Installation_Instructions/Windows-WSL2-Installation-Instructions.md @@ -0,0 +1,224 @@ + + +# WSL2 Installation instructions + +## Table of Contents +- [WSL2 Installation instructions](#wsl2-installation-instructions) + - [Table of Contents](#table-of-contents) + - [Requirements](#requirements) + - [Install Kali Linux distribution](#install-kali-linux-distribution) + - [Driver installation (Windows 11)](#driver-installation-windows-11) + - [USBIPD hints](#usbipd-hints) + - [WSL2 / Kali Linux Installation](#wsl2--kali-linux-installation) + - [X Server Installation](#x-server-installation) + - [Clone the Iceman repository](#clone-the-iceman-repository) + - [Compile the project](#compile-the-project) + - [Install the udev rules](#install-the-udev-rules) + - [Inform udev that it really, really should work](#inform-udev-that-it-really-really-should-work) + - [Verify Device Exists](#verify-device-exists) + - [Using the client...](#using-the-client) + - [Done!](#done) + +This provides instructions on how to install, build, and use Proxmark3 +on Windows 11, using WSL2 (and Kali Linux). + +## Requirements +^[Top](#top) + +This WSL 2 method requires Windows 11 (Build 22000 or later), +WSL installed and [set to WSL2](https://learn.microsoft.com/en-us/windows/wsl/basic-commands#set-wsl-version-to-1-or-2), + +While WSL 2 does not itself support passing through USB or +serial devices, it can work by using the USB/IP open-source +project, [`usbipd-win`](https://github.com/dorssel/usbipd-win). + + +## Install Kali Linux distribution +^[Top](#top) + +Open the Windows App Store, and install Kali Linux. + +For WSL configuration, see [Manage and configure Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/wsl-config). + +Start the Kali Linux distribution at least once, to ensure it's fully installed. + +## Driver installation (Windows 11) +^[Top](#top) + +On the Windows (host) machine, install the +[latest release](https://github.com/dorssel/usbipd-win/releases) +of `usbpid-win` (typically an `.MSI` file). + +## USBIPD hints +^[Top](#top) + +This is *NOT* intended to be a full description of how to use USBIPD. +Rather, this is intended only to give a starting point, as ***the values +shown here are extremely likely to differ per machine***. + +It's presumed that you've already installed USBIPD. Plug the Proxmark +device into a USB port. Then, from a `cmd.exe` or `wt.exe` ***launched +with administrative permissions***: + +Get a list of attached devices. Example (NOTE: VID/PID for non-proxmark devices redacted) + +```cmd +C:\qwert> usbipd list + +Connected: +BUSID VID:PID DEVICE STATE +1-2 xxxx:xxxx USB Input Device Not shared +2-3 xxxx:xxxx USB Mass Storage Device Not shared +5-3 9ac4:4b8f USB Serial Device (COM31) Not shared + +Persisted: +GUID DEVICE +``` + +Take note of the `BUSID` for the proxmark device, which should show as a USB Serial Device. + +Setup that bus ID to always be redirected to the WSL distribution named `kali-linux`: + +```cmd +C:\qwert> usbipd wsl attach --busid 5-3 --distribution kali-linux --auto-attach +usbipd: info: Starting endless attach loop; press Ctrl+C to quit. +Attached +``` + +NOTE: You must leave that running in the background, to allow the device to automatically +re-attach to the WSL2 instance. + + + +## WSL2 / Kali Linux Installation +^[Top](#top) + +Start the Kali Linux distribution you installed. First, make sure +the distribution is up-to-date: + +```sh +sudo apt-get update +sudo apt-get upgrade -y +sudo apt-get auto-remove -y +``` + +then, install proxmark dependencies: + +```sh +sudo apt-get install --no-install-recommends \ + git ca-certificates build-essential pkg-config \ + libreadline-dev gcc-arm-none-eabi libnewlib-dev \ + libbz2-dev libpython3-dev qtbase5-dev libssl-dev +``` + +_note_ +If you don't need the graphical components of the Proxmark3 client, you can skip the installation of `qtbase5-dev`. +If you don't need support for Python3 scripts in the Proxmark3 client, you can skip the installation of `libpython3-dev`. + +## X Server Installation +^[Top](#top) + +TBD -- Installing [`Win-KeX`](https://www.kali.org/docs/wsl/win-kex/) has worked +to provide a fully integrated experience, with three distinct modes..... +However, WSL2 may have some functionality already built-in? + +## Clone the Iceman repository +^[Top](#top) + +```sh +cd ~/ +git clone https://github.com/RfidResearchGroup/proxmark3.git +``` + +## Compile the project +^[Top](#top) + +```sh +cd ~/proxmark3 +make clean && make -j +``` + +## Install the udev rules + +```sh +sudo make accessrights +sudo make udev +``` + +On Kali, the above does two things: +1. Ensures the user is a member of the `dialout` group +2. Copies the `./driver/77-pm3-usb-device-blacklist.rules` file to the `/etc/udev/rules.d/` directory + +This presumes that the file includes `MODE="660" GROUP="dialout"` at the end of the three match lines. +The goal is that Kali Linux will automatically apply the proper permissions when the device is attached. + +However, it may be necessary to give the `udev` service a kind reminder: + +## Inform udev that it really, really should work + +The following workaround appears to work to get udev to apply the permissions +appropriately. Note that this may need to be run again, such as when the WSL2 +distributions have been restarted. I don't know why ... but it's a small hiccup. + +```sh +sudo udevadm trigger --action=change +``` + +General instructions suggested to use `sudo udevadm control --reload-rules`. However, +this may simply result in the following cryptic error message: + +```sh +$ sudo udevadm control --reload-rules +[sudo] password for root: +Failed to send reload request: No such file or directory +``` + +_Note that the following should **NOT** be required:_ + +```sh +sudo service udev restart +``` + +## Verify Device Exists + +Verify the device exists, and has a symbolic link created: + +```sh +ls -lFA /dev/ttyACM* +ls -lFA /dev/pm3* +``` + + +The first should show the `rw` permissions for both owner +and group, and show the group as `dialout`: + +```sh +┌──(qwert㉿host)-[~] +└─$ ls -lFA /dev/ttyACM* +crw-rw---- 1 root dialout 166, 0 Jan 22 11:28 /dev/ttyACM0 +``` + +The second command should show that a symbolic link exists +from the friendly name `/dev/pm3-0` to the TTY device: + +```sh +┌──(qwert㉿host)-[~] +└─$ ls -lFA /dev/pm3* +lrwxrwxrwx 1 root root 7 Jan 17 19:46 /dev/pm3-0 -> ttyACM0 +``` + +## Using the client... + +```sh +┌──(qwert㉿host)-[~] +└─$ pushd ~/proxmark3 + +┌──(qwert㉿host)-[~] +└─$ ./pm3 +``` + +## Done! +^[Top](#top) + +Full [compilation instructions](/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md) may be helpful. + diff --git a/doc/md/Use_of_Proxmark/1_Validation.md b/doc/md/Use_of_Proxmark/1_Validation.md index 51a701388..a283b0d47 100644 --- a/doc/md/Use_of_Proxmark/1_Validation.md +++ b/doc/md/Use_of_Proxmark/1_Validation.md @@ -15,7 +15,7 @@ If all went well you should get some information about the firmware and memory usage as well as the prompt, something like this. ``` -[=] Session log /home/iceman/.proxmark3/logs/log_20220213.txt +[=] Session log /home/iceman/.proxmark3/logs/log_20230208.txt [+] loaded from JSON file /home/iceman/.proxmark3/preferences.json [=] Using UART port /dev/ttyS3 [=] Communicating with PM3 over USB-CDC @@ -28,48 +28,19 @@ If all went well you should get some information about the firmware and memory u 8888888P" 888 Y888P 888 "Y8b. 888 888 Y8P 888 888 888 888 888 " 888 Y88b d88P - 888 888 888 "Y8888P" [ Iceman ❄️ ] - + 888 888 888 "Y8888P" [ ☕ ] [ Proxmark3 RFID instrument ] - [ CLIENT ] - RRG/Iceman/master/v4.14831-269 2022-02-13 05:03:08 - compiled with............. GCC 10.3.0 - platform.................. Linux / x86_64 - Readline support.......... present - QT GUI support............ present - native BT support......... absent - Python script support..... present - Lua SWIG support.......... present - Python SWIG support....... present - - [ PROXMARK3 ] - device.................... RDV4 - firmware.................. RDV4 - external flash............ present - smartcard reader.......... present - FPC USART for BT add-on... absent - - [ ARM ] - bootrom: RRG/Iceman/master/v4.14831-269 2022-02-13 05:03:55 - os: RRG/Iceman/master/v4.14831-269 2022-02-13 05:03:49 - compiled with GCC 9.2.1 20191025 (release) [ARM/arm-9-branch revision 277599] - - [ FPGA ] - LF image 2s30vq100 2022-03-20 09:28:32 - HF image 2s30vq100 2022-03-20 09:02:07 - HF FeliCa image 2s30vq100 2022-03-20 09:28:28 - HF 15 image 2s30vq100 2022-03-20 09:01:59 - - [ Hardware ] - --= uC: AT91SAM7S512 Rev A - --= Embedded Processor: ARM7TDMI - --= Internal SRAM size: 64K bytes - --= Architecture identifier: AT91SAM7Sxx Series - --= Embedded flash memory 512K bytes ( 59% used ) + MCU....... AT91SAM7S512 Rev A + Memory.... 512 Kb ( 66% used ) + Client.... Iceman/master/v4.16191 2023-02-08 22:54:30 + Bootrom... Iceman/master/v4.16191 2023-02-08 22:54:26 + OS........ Iceman/master/v4.16191 2023-02-08 22:54:27 + Target.... RDV4 + [usb] pm3 --> ``` diff --git a/driver/77-pm3-usb-device-blacklist-dialout.rules b/driver/77-pm3-usb-device-blacklist-dialout.rules new file mode 100644 index 000000000..8d699faca --- /dev/null +++ b/driver/77-pm3-usb-device-blacklist-dialout.rules @@ -0,0 +1,22 @@ +# Proxmark3 linux modem-manager de-confliction file +# +# copy this file to /etc/udev/rules.d (or add the entry to the end of an existing file) +# and restart udev hotplug: +# +# 'sudo udevadm control --reload-rules' +# + +# proxmark3 +ACTION!="add|change", GOTO="pm3_usb_device_blacklist_end" +SUBSYSTEM!="tty", GOTO="pm3_ignore" + +ATTRS{idVendor}=="2d2d" ATTRS{idProduct}=="504d", ENV{ID_MM_DEVICE_IGNORE}="1" SYMLINK+="pm3-%n" MODE="660" GROUP="dialout" +ATTRS{idVendor}=="9ac4" ATTRS{idProduct}=="4b8f", ENV{ID_MM_DEVICE_IGNORE}="1" SYMLINK+="pm3-%n" MODE="660" GROUP="dialout" +ATTRS{idVendor}=="502d" ATTRS{idProduct}=="502d", ENV{ID_MM_DEVICE_IGNORE}="1" SYMLINK+="pm3-%n" MODE="660" GROUP="dialout" + +LABEL="pm3_ignore" +ATTRS{idVendor}=="2d2d" ATTRS{idProduct}=="504d", ENV{ID_MM_DEVICE_IGNORE}="1" +ATTRS{idVendor}=="9ac4" ATTRS{idProduct}=="4b8f", ENV{ID_MM_DEVICE_IGNORE}="1" +ATTRS{idVendor}=="502d" ATTRS{idProduct}=="502d", ENV{ID_MM_DEVICE_IGNORE}="1" + +LABEL="pm3_usb_device_blacklist_end" diff --git a/driver/77-pm3-usb-device-blacklist.rules b/driver/77-pm3-usb-device-blacklist-uucp.rules similarity index 82% rename from driver/77-pm3-usb-device-blacklist.rules rename to driver/77-pm3-usb-device-blacklist-uucp.rules index d939468f2..101381d95 100644 --- a/driver/77-pm3-usb-device-blacklist.rules +++ b/driver/77-pm3-usb-device-blacklist-uucp.rules @@ -10,9 +10,9 @@ ACTION!="add|change", GOTO="pm3_usb_device_blacklist_end" SUBSYSTEM!="tty", GOTO="pm3_ignore" -ATTRS{idVendor}=="2d2d" ATTRS{idProduct}=="504d", ENV{ID_MM_DEVICE_IGNORE}="1" SYMLINK+="pm3-%n" -ATTRS{idVendor}=="9ac4" ATTRS{idProduct}=="4b8f", ENV{ID_MM_DEVICE_IGNORE}="1" SYMLINK+="pm3-%n" -ATTRS{idVendor}=="502d" ATTRS{idProduct}=="502d", ENV{ID_MM_DEVICE_IGNORE}="1" SYMLINK+="pm3-%n" +ATTRS{idVendor}=="2d2d" ATTRS{idProduct}=="504d", ENV{ID_MM_DEVICE_IGNORE}="1" SYMLINK+="pm3-%n" MODE="660" GROUP="uucp" +ATTRS{idVendor}=="9ac4" ATTRS{idProduct}=="4b8f", ENV{ID_MM_DEVICE_IGNORE}="1" SYMLINK+="pm3-%n" MODE="660" GROUP="uucp" +ATTRS{idVendor}=="502d" ATTRS{idProduct}=="502d", ENV{ID_MM_DEVICE_IGNORE}="1" SYMLINK+="pm3-%n" MODE="660" GROUP="uucp" LABEL="pm3_ignore" ATTRS{idVendor}=="2d2d" ATTRS{idProduct}=="504d", ENV{ID_MM_DEVICE_IGNORE}="1" diff --git a/include/ansi.h b/include/ansi.h index c06c06e6b..20815bc03 100644 --- a/include/ansi.h +++ b/include/ansi.h @@ -21,18 +21,46 @@ #define AEND "\x1b[0m" -#define _BLUE_(s) "\x1b[34m" s AEND -#define _RED_(s) "\x1b[31m" s AEND -#define _GREEN_(s) "\x1b[32m" s AEND -#define _YELLOW_(s) "\x1b[33m" s AEND -#define _MAGENTA_(s) "\x1b[35m" s AEND -#define _CYAN_(s) "\x1b[36m" s AEND -#define _WHITE_(s) "\x1b[37m" s AEND +#define _BLACK_(s) "\x1b[30m" s AEND +#define _RED_(s) "\x1b[31m" s AEND +#define _GREEN_(s) "\x1b[32m" s AEND +#define _YELLOW_(s) "\x1b[33m" s AEND +#define _BLUE_(s) "\x1b[34m" s AEND +#define _MAGENTA_(s) "\x1b[35m" s AEND +#define _CYAN_(s) "\x1b[36m" s AEND +#define _WHITE_(s) "\x1b[37m" s AEND + +#define _BRIGHT_BLACK_(s) "\x1b[30;1m" s AEND +#define _BRIGHT_RED_(s) "\x1b[31;1m" s AEND +#define _BRIGHT_GREEN_(s) "\x1b[32;1m" s AEND +#define _BRIGHT_YELLOW_(s) "\x1b[33;1m" s AEND +#define _BRIGHT_BLUE_(s) "\x1b[34;1m" s AEND +#define _BRIGHT_MAGENTA_(s) "\x1b[35;1m" s AEND +#define _BRIGHT_CYAN_(s) "\x1b[36;1m" s AEND +#define _BRIGHT_WHITE_(s) "\x1b[37;1m" s AEND + +#define _BACK_BLACK_(s) "\x1b[40m" s AEND +#define _BACK_RED_(s) "\x1b[41m" s AEND +#define _BACK_GREEN_(s) "\x1b[42m" s AEND +#define _BACK_YELLOW_(s) "\x1b[43m" s AEND +#define _BACK_BLUE_(s) "\x1b[44m" s AEND +#define _BACK_MAGENTA_(s) "\x1b[45m" s AEND +#define _BACK_CYAN_(s) "\x1b[46m" s AEND +#define _BACK_WHITE_(s) "\x1b[47m" s AEND + +#define _BACK_BRIGHT_BLACK_(s) "\x1b[40;1m" s AEND +#define _BACK_BRIGHT_RED_(s) "\x1b[41;1m" s AEND +#define _BACK_BRIGHT_GREEN_(s) "\x1b[42;1m" s AEND +#define _BACK_BRIGHT_YELLOW_(s) "\x1b[43;1m" s AEND +#define _BACK_BRIGHT_BLUE_(s) "\x1b[44;1m" s AEND +#define _BACK_BRIGHT_MAGENTA_(s) "\x1b[45;1m" s AEND +#define _BACK_BRIGHT_CYAN_(s) "\x1b[46;1m" s AEND +#define _BACK_BRIGHT_WHITE_(s) "\x1b[47;1m" s AEND #define _CLEAR_ "\x1b[2J" +#define _CLEAR_SCROLLBACK_ "\x1b[3J" #define _TOP_ "\x1b[1;1f" - #if defined(HAVE_READLINE) // https://wiki.hackzine.org/development/misc/readline-color-prompt.html // Applications may indicate that the prompt contains diff --git a/include/em4x70.h b/include/em4x70.h index bce860bb1..734e83f48 100644 --- a/include/em4x70.h +++ b/include/em4x70.h @@ -42,6 +42,9 @@ typedef struct { // Used to write new key uint8_t crypt_key[12]; + // used for bruteforce the partial key + uint16_t start_key; + } em4x70_data_t; #endif /* EM4X70_H__ */ diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 95750b9b7..40a263442 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -205,6 +205,7 @@ typedef struct { // rdv4 bool hw_available_flash : 1; bool hw_available_smartcard : 1; + bool is_rdv4 : 1; } PACKED capabilities_t; #define CAPABILITIES_VERSION 6 extern capabilities_t g_pm3_capabilities; @@ -484,6 +485,7 @@ typedef struct { #define CMD_LF_EM4X70_AUTH 0x0263 #define CMD_LF_EM4X70_WRITEPIN 0x0264 #define CMD_LF_EM4X70_WRITEKEY 0x0265 +#define CMD_LF_EM4X70_BRUTE 0x0266 // Sampling configuration for LF reader/sniffer #define CMD_LF_SAMPLING_SET_CONFIG 0x021D #define CMD_LF_FSK_SIMULATE 0x021E @@ -519,8 +521,14 @@ typedef struct { #define CMD_HF_ISO15693_COMMAND 0x0313 #define CMD_HF_ISO15693_FINDAFI 0x0315 #define CMD_HF_ISO15693_CSETUID 0x0316 -#define CMD_HF_ISO15693_SLIX_L_DISABLE_PRIVACY 0x0317 -#define CMD_HF_ISO15693_SLIX_L_DISABLE_AESAFI 0x0318 +#define CMD_HF_ISO15693_SLIX_ENABLE_PRIVACY 0x0867 +#define CMD_HF_ISO15693_SLIX_DISABLE_PRIVACY 0x0317 +#define CMD_HF_ISO15693_SLIX_DISABLE_EAS 0x0318 +#define CMD_HF_ISO15693_SLIX_ENABLE_EAS 0x0862 +#define CMD_HF_ISO15693_SLIX_PASS_PROTECT_AFI 0x0863 +#define CMD_HF_ISO15693_SLIX_PASS_PROTECT_EAS 0x0864 +#define CMD_HF_ISO15693_SLIX_WRITE_PWD 0x0865 +#define CMD_HF_ISO15693_WRITE_AFI 0x0866 #define CMD_HF_TEXKOM_SIMULATE 0x0320 #define CMD_HF_ISO15693_EML_CLEAR 0x0330 #define CMD_HF_ISO15693_EML_SETMEM 0x0331 diff --git a/pm3 b/pm3 index c0b0869b0..52a8ffcc1 100755 --- a/pm3 +++ b/pm3 @@ -441,6 +441,7 @@ done # if a port is already provided, let's just run the command as such for ARG; do + shift if [ "$ARG" == "-p" ]; then CMD "$@" exit $? diff --git a/tools/build_all_firmwares.sh b/tools/build_all_firmwares.sh index b76f7a45a..644438032 100755 --- a/tools/build_all_firmwares.sh +++ b/tools/build_all_firmwares.sh @@ -22,7 +22,8 @@ echo "Destination: ${DEST:=firmware}" echo "Produce stats?: ${STATS:=false}" # Which parts to skip for the 256kb version? -SKIPS256="SKIP_HITAG=1 SKIP_LEGICRF=1 SKIP_FELICA=1 SKIP_EM4x50=1 SKIP_ISO14443b=1" +SKIPS256="SKIP_HITAG=1 SKIP_LEGICRF=1 SKIP_FELICA=1 SKIP_EM4x50=1 SKIP_ISO14443b=1 SKIP_NFCBARCODE=1 SKIP_ZX8211=1" + make $MKFLAGS bootrom || exit 1 chmod 644 bootrom/obj/bootrom.elf