Merge branch 'master' into smartcard-relay

This commit is contained in:
Grayson Martin
2023-09-12 22:30:59 -05:00
1001 changed files with 51581 additions and 4531 deletions
+1 -1
View File
@@ -41,7 +41,7 @@ jobs:
run: sudo apt-get update
- name: Install dependencies
run: sudo apt-get install -yqq make autoconf build-essential ca-certificates pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev libbz2-dev libbluetooth-dev libpython3-dev python3 python3-dev libpython3-all-dev liblua5.2-dev liblua5.2-0 lua5.2 sed libssl-dev
run: sudo apt-get install -yqq make autoconf build-essential ca-certificates pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev libbz2-dev liblz4-dev libbluetooth-dev libpython3-dev python3 python3-dev libpython3-all-dev liblua5.2-dev liblua5.2-0 lua5.2 sed libssl-dev
- name: Install Python dependencies
run: |
+3 -3
View File
@@ -26,7 +26,7 @@ jobs:
run: sudo apt-get update
- name: Install dependencies
run: sudo apt-get install -yqq make autoconf build-essential ca-certificates pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev libbz2-dev libbluetooth-dev libpython3-dev python3 python3-dev libpython3-all-dev liblua5.2-dev liblua5.2-0 lua5.2 sed libssl-dev
run: sudo apt-get install -yqq make autoconf build-essential ca-certificates pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev libbz2-dev liblz4-dev libbluetooth-dev libpython3-dev python3 python3-dev libpython3-all-dev liblua5.2-dev liblua5.2-0 lua5.2 sed libssl-dev
- name: Install Python dependencies
run: |
@@ -58,7 +58,7 @@ jobs:
run: sudo apt-get update
- name: Install dependencies
run: sudo apt-get install -yqq make autoconf build-essential ca-certificates pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev libbz2-dev libbluetooth-dev libpython3-dev python3 python3-dev libpython3-all-dev liblua5.2-dev liblua5.2-0 lua5.2 sed libssl-dev
run: sudo apt-get install -yqq make autoconf build-essential ca-certificates pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev libbz2-dev liblz4-dev libbluetooth-dev libpython3-dev python3 python3-dev libpython3-all-dev liblua5.2-dev liblua5.2-0 lua5.2 sed libssl-dev
- name: Install Python dependencies
run: |
@@ -91,7 +91,7 @@ jobs:
run: sudo apt-get update
- name: Install dependencies
run: sudo apt-get install -yqq make autoconf build-essential ca-certificates pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev libbz2-dev libbluetooth-dev libpython3-dev python3 python3-dev libpython3-all-dev liblua5.2-dev liblua5.2-0 lua5.2 sed libssl-dev
run: sudo apt-get install -yqq make autoconf build-essential ca-certificates pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev libbz2-dev liblz4-dev libbluetooth-dev libpython3-dev python3 python3-dev libpython3-all-dev liblua5.2-dev liblua5.2-0 lua5.2 sed libssl-dev
- name: Install Python dependencies
run: |
+2 -3
View File
@@ -18,6 +18,5 @@ jobs:
- name: check unique keys in dic files
shell: bash
run: |
find . -type f -name "*.dic" | xargs -I {} sh -c "echo {} && cat {} | grep -v '#' | sort | uniq -i -d -c | sort -n -r "
if [[ $(find . -type f -name "*.dic" | xargs -I {} sh -c "echo {} && cat {} | grep -v '#' | sort | uniq -i -d -c | sort -n -r " | grep -v "./" | wc -l) -gt 0 ]]; then exit 1; fi
find . -type f -name "*.dic" | xargs -I {} sh -c "echo {} && cat {} | sed 's/ *#.*//;/^$/d' | sort | uniq -i -d -c | sort -n -r "
if [[ $(find . -type f -name "*.dic" | xargs -I {} sh -c "echo {} && cat {} | sed 's/ *#.*//;/^$/d' | sort | uniq -i -d -c | sort -n -r " | grep -v '^\./' | wc -l) -gt 0 ]]; then exit 1; fi
+1
View File
@@ -110,6 +110,7 @@ jobs:
gcc-arm-none-eabi
libnewlib-dev
libbz2-dev
liblz4-dev
qtbase5-dev
cmake
libpython3-dev
+6 -6
View File
@@ -39,7 +39,7 @@ function print_config {
function setup_serial_port {
if [ -z "$SerialPort" ]; then
pm3list=$($VSCODEPATH/../pm3 --list 2>/dev/null)
#Use first port listed
#Use first port listed
export SerialPort=$(echo $pm3list | head -n 1 | cut -c 4-)
if [ -z "$SerialPort" ]; then
echo >&2 "[!!] No serial port found, please set SerialPort manually"
@@ -129,17 +129,17 @@ fi
HOSTOS=$(uname | awk '{print toupper($0)}')
if [ "$HOSTOS" = "LINUX" ]; then
if uname -a|grep -q Microsoft; then
if uname -a|grep -q Microsoft; then
setup_wsl
else
else
setup_linux
fi
fi
elif [ "$HOSTOS" = "DARWIN" ]; then
echo >&2 "[!!] MacOS not supported, sorry!"
exit 1
elif [[ "$HOSTOS" =~ MINGW(32|64)_NT* ]]; then
setup_ps
else
echo >&2 "[!!] Host OS not recognized, abort: $HOSTOS"
exit 1
echo >&2 "[!!] Host OS not recognized, abort: $HOSTOS"
exit 1
fi
+57 -8
View File
@@ -4,13 +4,62 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
## [unreleased][unreleased]
- Use proxmark3 as a generic smartcard reader with other software with `smart relay` (@gm3197)
- Fixed `utils.lua` library function "convertdectohex" wasn't working (@iceman1001)
- Added `hf iclass creditepurse` command to allow crediting the epurse debit value (@nvx)
## [Raccoon.4.17140][2023-09-09]
- Changed text and adjust pm3_test case for mf_aes_brute (@doegox)
- Fix CPPChecker warnings (@doegox)
- Fix TubmleWeed docker setup (@doegox)
- Added default keys (@ernestask) (@craftbyte)
- Fixed MFU authentication to send PACK correctly (@shallax)
- Fixed list output when line has 16 bytes (@piru)
- Changed AIDlist w new entries (@kormax)
- Swapped to OE1 for Shallow modulation on RDV4. Thanks to @gentilkiwi for testing (@d18c7db)
- Changed iClass SIO and Legacy credential detection to be more reliable (@nvx)
- Add hf_cardhopper standalone mode for long-distance relay attacks (@startrekdude)
- Added `hf iclass esetblk` - set iClass emulator memory block data (@nvx)
- Added cryptorf regressiontests (@iceman1001)
- Fixed `cryptorf/sma_multi` - local state used in multithread (@iceman1001)
- Changed `fpga_compress` - better deallocation of memory and closing of file handles (@iceman1001)
- Changed `hf search` - less swaps of fpga images on device side (@iceman1001)
- Changed `mkversion.sh` - now regenerates version_pm3.c (and consequently the binaries) only when needed (@doegox)
- Added `data atr` - a command to lookup ATR (@iceman1001)
- Fixed bug in ATR lookup fct, thanks @DidierA (@iceman1001)
- Updated ATR list (@iceman1001)
- Changed `mem load -m` - now correctly erase all allocated flash memory (@iceman1001)
- Fixed emulator quick dump to handle MFC Ev1 extra sectors (@iceman100)
- Removed some empty dump files (@iceman1001)
- Added a fct to choose fpga mode (@iceman1001)
- Changed `hf mf eload/gsave` - fast uploading to emulator memory (@iceman1001)
- Added empty dump files with keys for easy simulation (@iceman1001)
- Added `hf 15 view` - view ISO15693 dump files (@iceman1001)
- Fixed `hf iclass config` - now loops correct in keyroll generation (@iceman1001)
- Added `hf iclass sam` - skeleton command (@iceman1001)
- Changed `lf cotag demo` - a new decoder (@iceman1001)
- Changed `hf legic view/eview/info` - now in verbose mode will print raw hex dump (@iceman1001)
- Added new test for cotag demod using data commands in pm3_test.sh (@iceman1001)
- Added new sample trace file for cotag w fc/272. Thanks s1acky! (@iceman1001)
- Fixed `hf legic eload` - now it doesn't crash client (@doegox)
- Changed `lf hitag *` - rework client side (@doegox)
- Changed data commands to handle ask/nrz clocks above 256 (@iceman1001)
- Added `data envelope` - almost acts like data askedgedetect (@iceman1001)
- Added `data cthreshold` - acts like an inverted dirtythreshold command. Remove center values (@iceman1001)
- Added `hf mfp list` - interprets MIFARE Plus commands in traces (@DidierA)
- Changed `hf legic sim` - loop and return codes on deviceside updated to DEFINES (@iceman1001)
- Changed `hf legic einfo` - now accepts the three different cardsizes as params (@iceman1001)
- Fixed `lf cotag reader -1` - now doesn't fail (@iceman1001)
- Added support for LZ4 compressed hardnested tables (@doegox)
- Changed `emv reader -v` - now tries to print found transactions logs (@iceman1001)
- Added ISO4217 currency lookup (@iceman1001)
- Fixed bad free in loadfilebinarykey fct. Thanks to @gentilkiwi
- Changed `emv reader -v` - now can decode track1/2 data if found (@iceman1001)
- Added `emv reader` - act as a EMV reader (@iceman1001)
- Added support for Apple Wallet NFC Passes with the Value Added Services protocol implementation (@gm3197)
- Fix compiling liblua on iOS (@The-SamminAter)
- Fixed compiling liblua on iOS (@The-SamminAter)
- Changed `hf_mf_luxeo_dump.lua` - now have list of keys to iterate (@iceman1001)
- Fixed the timeout of TCP connections (@wh201906)
- Made the connection timeout configurable (@wh201906)
- Changed the connection timeout configurable (@wh201906)
## [Seven.4.16717][2023-06-25]
- Change `hf 14a info` - now identifes QL88 tags (@iceman1001)
@@ -27,7 +76,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
- Added more default keys (@iceman1001) Thanks anon!
- Fixed `pm3-flash-all` shell script now correctly identify the if running on outdated bootloader (@iceman1001)
- Fixed `hf 15693/iclass sniff` trace timings (@nvx)
- Fix LegicCash segment handling in `hf_legic.lua` script (@jmichelp)
- Fixed LegicCash segment handling in `hf_legic.lua` script (@jmichelp)
- Fixed `trace list` - now handles marking of crc bytes w color a bit better (@iceman1001)
- Changed `hf mfu pwdgen -r` - now generates pwd/pack for Philips Sonicare, thanks @ckuenzi, @atc1441 (@iceman1001)
- Changed `hf mfu info` - now detects Philips Sonicare devices (@iceman1001)
@@ -117,11 +166,11 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
- Changed `hf mfu info` - now also does a simple OTP fingerprinting (@iceman1001)
- Changed `hf mf wrbl` - now checks for strict readonly ACL's in the data to write (@iceman1001)
- Changed `hf mf view` - verbose printing if strict readonly ACL's exists in dump file (@iceman1001)
- Add command `piv authsign` to get a buffer signed by the selected key (@jmichelp)
- Add command `piv scan` which tries to read all known containers on PIV (@jmichelp)
- Add support for PIV commands, over wired and contactless interfaces (@jmichelp)
- Add `--shallow` option to `hf iclass` reader commands to do shallow (ASK) reader modulation instead of OOK (@nvx)
- Improved NXP SLI/SLIX series tag identification (@nvx)
- Added command `piv authsign` to get a buffer signed by the selected key (@jmichelp)
- Added command `piv scan` which tries to read all known containers on PIV (@jmichelp)
- Added support for PIV commands, over wired and contactless interfaces (@jmichelp)
- Added `--shallow` option to `hf iclass` reader commands to do shallow (ASK) reader modulation instead of OOK (@nvx)
- Change and improved NXP SLI/SLIX series tag identification (@nvx)
- Fixed buffer overflow in "lf em 4x05 sniff" (@HeinrichsH)
- Fixed potential NULL array printing (@jmichelp)
- Added PIV aid to resource file (@jmichelp)
+16 -7
View File
@@ -29,7 +29,7 @@ ifneq (,$(DESTDIR))
endif
endif
all clean install uninstall check: %: client/% bootrom/% armsrc/% recovery/% mfkey/% nonce2key/% mf_nonce_brute/% mfd_aes_brute/% fpga_compress/%
all clean install uninstall check: %: client/% bootrom/% armsrc/% recovery/% mfkey/% nonce2key/% mf_nonce_brute/% mfd_aes_brute/% fpga_compress/% cryptorf/%
# hitag2crack toolsuite is not yet integrated in "all", it must be called explicitly: "make hitag2crack"
#all clean install uninstall check: %: hitag2crack/%
@@ -39,7 +39,7 @@ INSTALLSCRIPTS=pm3 pm3-flash pm3-flash-all pm3-flash-bootrom pm3-flash-fullimage
INSTALLSHARES=tools/jtag_openocd traces
INSTALLDOCS=doc/*.md doc/md
install: all common/install
install: common/install
common/install:
$(info [@] Installing common resources to $(MYDESTDIR)$(PREFIX)...)
@@ -109,6 +109,9 @@ endif
$(Q)-$(INSTALLSUDO) $(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH)
# tests
cryptorf/check: FORCE
$(info [*] CHECK $(patsubst %/check,%,$@))
$(Q)$(BASH) tools/pm3_tests.sh $(CHECKARGS) $(patsubst %/check,%,$@)
mfkey/check: FORCE
$(info [*] CHECK $(patsubst %/check,%,$@))
$(Q)$(BASH) tools/pm3_tests.sh $(CHECKARGS) $(patsubst %/check,%,$@)
@@ -145,6 +148,9 @@ common/check: FORCE
check: common/check
$(info [*] ALL CHECKS DONE)
cryptorf/%: FORCE
$(info [*] MAKE $@)
$(Q)$(MAKE) --no-print-directory -C tools/cryptorf $(patsubst cryptorf/%,%,$@) DESTDIR=$(MYDESTDIR)
mfkey/%: FORCE
$(info [*] MAKE $@)
$(Q)$(MAKE) --no-print-directory -C tools/mfkey $(patsubst mfkey/%,%,$@) DESTDIR=$(MYDESTDIR)
@@ -170,7 +176,7 @@ client/%: FORCE cleanifplatformchanged
$(info [*] MAKE $@)
$(Q)$(MAKE) --no-print-directory -C client $(patsubst client/%,%,$@) DESTDIR=$(MYDESTDIR)
recovery/all: bootrom/all armsrc/all
recovery/install: bootrom/all armsrc/all
recovery/install: bootrom/install armsrc/install
recovery/%: FORCE cleanifplatformchanged
$(info [*] MAKE $@)
$(Q)$(MAKE) --no-print-directory -C recovery $(patsubst recovery/%,%,$@) DESTDIR=$(MYDESTDIR)
@@ -196,6 +202,7 @@ help:
@echo "+ recovery - Make bootrom and fullimage files for JTAG flashing"
@echo
@echo "+ client - Make only the OS-specific host client"
@echo "+ cryptorf - Make tools/cryptorf"
@echo "+ mfkey - Make tools/mfkey"
@echo "+ nonce2key - Make tools/nonce2key"
@echo "+ mf_nonce_brute - Make tools/mf_nonce_brute"
@@ -232,6 +239,8 @@ fullimage/uninstall: armsrc/uninstall
recovery: recovery/all
cryptorf: cryptorf/all
mfkey: mfkey/all
nonce2key: nonce2key/all
@@ -318,10 +327,10 @@ style:
# Make sure python3 is installed
@command -v python3 >/dev/null || ( echo "Please install 'python3' package first" ; exit 1 )
# Update commands.json, patch port in case it was run under Windows
[ -x client/proxmark3 ] && client/proxmark3 --fulltext | sed 's#com[0-9]#/dev/ttyacm0#'|python3 client/pyscripts/pm3_help2json.py - doc/commands.json
[ -x client/proxmark3 ] && client/proxmark3 --fulltext | sed 's#com[0-9]#/dev/ttyACM0#'|python3 client/pyscripts/pm3_help2json.py - doc/commands.json
# Update the readline autocomplete autogenerated code
[ -x client/proxmark3 ] && client/proxmark3 --fulltext | python3 client/pyscripts/pm3_help2list.py - client/src/pm3line_vocabulory.h
[ -x client/proxmark3 ] && client/proxmark3 --fulltext | python3 client/pyscripts/pm3_help2list.py - client/src/pm3line_vocabulary.h
# Detecting weird codepages and tabs.
@@ -370,10 +379,10 @@ release:
# - Tagging temporarily...
@git tag -a -m "Release $(VERSION) - $(RELEASE_NAME)" $(VERSION)
# - Changing default version information based on new tag
@$(SH) tools/mkversion.sh > common/default_version_pm3.c.tmp && $(MV) common/default_version_pm3.c.tmp common/default_version_pm3.c
@$(SH) tools/mkversion.sh --force common/default_version_pm3.c
# - Removing mkversion calls
@sed -i 's#^.*\.\./tools/mkversion.sh.*|| #\t$$(Q)#' client/Makefile bootrom/Makefile armsrc/Makefile
@sed -i '/COMMAND/s/sh .*|| //' client/CMakeLists.txt
@sed -i '/COMMAND/s/sh .*|| //' client/CMakeLists.txt client/experimental_lib/CMakeLists.txt
# - Deleting tag...
@git tag -d $(VERSION)
# - Amending commit...
+4 -4
View File
@@ -35,9 +35,9 @@ The Proxmark3 is the swiss-army tool of RFID, allowing for interactions with the
| :------------------: | :------------------: |
| [Linux - Setup and Build](/doc/md/Installation_Instructions/Linux-Installation-Instructions.md) | [Compilation Instructions](/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md)|
| [Linux - Important notes on ModemManager](/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md) | [Validating Proxmark3 Client Functionality](/doc/md/Use_of_Proxmark/1_Validation.md)|
| [Mac OS X - Homebrew & Upgrading HomeBrew Tap Formula](/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md) | [First Use and Verification](/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md)|
| [Mac OS X - MacPorts](/doc/md/Installation_Instructions/Mac-OS-X-MacPorts-Installation-Instructions.md) | [Commands & Features](/doc/md/Use_of_Proxmark/3_Commands-and-Features.md)|
| [Mac OS X - Setup and Build](/doc/md/Installation_Instructions/Mac-OS-X-Compile-From-Source-Instructions.md) ||
| [macOS - Homebrew & Upgrading HomeBrew Tap Formula](/doc/md/Installation_Instructions/macOS-Homebrew-Installation-Instructions.md) | [First Use and Verification](/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md)|
| [macOS - MacPorts](/doc/md/Installation_Instructions/macOS-MacPorts-Installation-Instructions.md) | [Commands & Features](/doc/md/Use_of_Proxmark/3_Commands-and-Features.md)|
| [macOS - Setup and Build](/doc/md/Installation_Instructions/macOS-Compile-From-Source-Instructions.md) ||
| [Windows - Setup and Build](/doc/md/Installation_Instructions/Windows-Installation-Instructions.md) ||
| [Termux / Android - Setup and Build](/doc/termux_notes.md) ||
| [Blue Shark Manual](/doc/bt_manual_v10.md) | [Command Cheat Sheet](/doc/cheatsheet.md)|
@@ -184,7 +184,7 @@ This repo compiles nicely on
- Windows/MinGW environment
- Ubuntu, ParrotOS, Gentoo, Pentoo, Kali, NetHunter, Arch Linux, Fedora, Debian, Raspbian
- Android / Termux
- Mac OS X / Homebrew (or MacPorts, experimental) / Apple Silicon M1
- macOS / Homebrew (or MacPorts, experimental) / Apple Silicon M1
- Docker container
- [ Iceman repo based ubuntu 18.04 container ](https://hub.docker.com/r/secopsconsult/proxmark3)
- [ Iceman fork based container v1.7 ](https://hub.docker.com/r/iceman1001/proxmark3/)
+14 -7
View File
@@ -233,7 +233,7 @@ uint32_t BigBuf_get_traceLen(void) {
by 'hf list -t raw', alternatively 'hf list -t <proto>' for protocol-specific
annotation of commands/responses.
**/
bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool reader2tag) {
bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, const uint8_t *parity, bool reader2tag) {
if (tracing == false) {
return false;
}
@@ -290,7 +290,7 @@ bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_
}
// specific LogTrace function for ISO15693: the duration needs to be scaled because otherwise it won't fit into a uint16_t
bool LogTrace_ISO15693(const uint8_t *bytes, uint16_t len, uint32_t ts_start, uint32_t ts_end, uint8_t *parity, bool reader2tag) {
bool LogTrace_ISO15693(const uint8_t *bytes, uint16_t len, uint32_t ts_start, uint32_t ts_end, const uint8_t *parity, bool reader2tag) {
uint32_t duration = ts_end - ts_start;
duration /= 32;
ts_end = ts_start + duration;
@@ -306,17 +306,24 @@ bool RAMFUNC LogTraceBits(const uint8_t *btBytes, uint16_t bitLen, uint32_t time
}
// Emulator memory
uint8_t emlSet(uint8_t *data, uint32_t offset, uint32_t length) {
uint8_t emlSet(const uint8_t *data, uint32_t offset, uint32_t length) {
uint8_t *mem = BigBuf_get_EM_addr();
if (offset + length < CARD_MEMORY_SIZE) {
if (offset + length <= CARD_MEMORY_SIZE) {
memcpy(mem + offset, data, length);
return 0;
}
Dbprintf("Error, trying to set memory outside of bounds! %d > %d", (offset + length), CARD_MEMORY_SIZE);
Dbprintf("Error, trying to set memory outside of bounds! " _RED_("%d") " > %d", (offset + length), CARD_MEMORY_SIZE);
return 1;
}
uint8_t emlGet(uint8_t *out, uint32_t offset, uint32_t length) {
uint8_t *mem = BigBuf_get_EM_addr();
if (offset + length <= CARD_MEMORY_SIZE) {
memcpy(out, mem + offset, length);
return 0;
}
Dbprintf("Error, trying to read memory outside of bounds! " _RED_("%d") " > %d", (offset + length), CARD_MEMORY_SIZE);
return 1;
}
// get the address of the ToSend buffer. Allocate part of Bigbuf for it, if not yet done
tosend_t *get_tosend(void) {
+4 -3
View File
@@ -51,11 +51,12 @@ void set_tracing(bool enable);
void set_tracelen(uint32_t value);
bool get_tracing(void);
bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool reader2tag);
bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, const uint8_t *parity, bool reader2tag);
bool RAMFUNC LogTraceBits(const uint8_t *btBytes, uint16_t bitLen, uint32_t timestamp_start, uint32_t timestamp_end, bool reader2tag);
bool LogTrace_ISO15693(const uint8_t *bytes, uint16_t len, uint32_t ts_start, uint32_t ts_end, uint8_t *parity, bool reader2tag);
bool LogTrace_ISO15693(const uint8_t *bytes, uint16_t len, uint32_t ts_start, uint32_t ts_end, const uint8_t *parity, bool reader2tag);
uint8_t emlSet(uint8_t *data, uint32_t offset, uint32_t length);
uint8_t emlSet(const uint8_t *data, uint32_t offset, uint32_t length);
uint8_t emlGet(uint8_t *out, uint32_t offset, uint32_t length);
typedef struct {
int max;
+1 -1
View File
@@ -53,7 +53,7 @@ void LCDFill(unsigned char xs, unsigned char ys, unsigned char width, unsigned c
}
}
void LCDString(char *lcd_string, const char *font_style, unsigned char x, unsigned char y, unsigned char fcolor, unsigned char bcolor) {
void LCDString(const char *lcd_string, const char *font_style, unsigned char x, unsigned char y, unsigned char fcolor, unsigned char bcolor) {
unsigned int i;
unsigned char mask = 0, px, py, xme, yme, offset;
const char *data;
+1 -1
View File
@@ -130,7 +130,7 @@ void LCDInit(void);
void LCDReset(void);
void LCDSetXY(unsigned char x, unsigned char y);
void LCDSetPixel(unsigned char x, unsigned char y, unsigned char color);
void LCDString(char *lcd_string, const char *font_style, unsigned char x, unsigned char y, unsigned char fcolor, unsigned char bcolor);
void LCDString(const char *lcd_string, const char *font_style, unsigned char x, unsigned char y, unsigned char fcolor, unsigned char bcolor);
void LCDFill(unsigned char xs, unsigned char ys, unsigned char width, unsigned char height, unsigned char color);
#endif
+4 -4
View File
@@ -127,7 +127,7 @@ THUMBSRC = start.c \
$(SRC_SMARTCARD) \
$(SRC_FPC) \
$(SRC_HITAG) \
$(SRC_EM4x50) \
$(SRC_EM4x50) \
$(SRC_EM4x70) \
$(SRC_SPIFFS) \
$(SRC_HF) \
@@ -181,10 +181,10 @@ showinfo:
.DELETE_ON_ERROR:
# version_pm3.c should be remade on every time fullimage.stage1.elf should be remade
# version_pm3.c should be checked on every time fullimage.stage1.elf should be remade
version_pm3.c: default_version_pm3.c $(OBJDIR)/fpga_version_info.o $(OBJDIR)/fpga_all.o $(THUMBOBJ) $(ARMOBJ) .FORCE
$(info [-] GEN $@)
$(Q)$(SH) ../tools/mkversion.sh > $@ || $(CP) $< $@
$(info [-] CHECK $@)
$(Q)$(SH) ../tools/mkversion.sh $@ || $(CP) $< $@
fpga_version_info.c: $(FPGA_BITSTREAMS) $(FPGA_COMPRESSOR)
$(info [-] GEN $@)
+5 -2
View File
@@ -86,6 +86,9 @@ define KNOWN_STANDALONE_DEFINITIONS
| HF_BOG | 14a sniff with ULC/ULEV1/NTAG auth |
| (RDV4 only) | storing in flashmem - Bogito |
+----------------------------------------------------------+
| HF_CARDHOPPER | Relay 14a protocols over long distances|
| (RDV4 only) | (w/ IP backbone) - Sam Haskins |
+----------------------------------------------------------+
| HF_COLIN | Mifare ultra fast sniff/sim/clone |
| (RDV4 only) | - Colin Brigato |
+----------------------------------------------------------+
@@ -130,9 +133,9 @@ endef
STANDALONE_MODES := LF_SKELETON
STANDALONE_MODES += LF_EM4100EMUL LF_EM4100RSWB LF_EM4100RSWW LF_EM4100RWC LF_HIDBRUTE LF_HIDFCBRUTE LF_ICEHID LF_MULTIHID LF_NEDAP_SIM LF_NEXID LF_PROXBRUTE LF_PROX2BRUTE LF_SAMYRUN LF_THAREXDE
STANDALONE_MODES += HF_14ASNIFF HF_14BSNIFF HF_15SNIFF HF_AVEFUL HF_BOG HF_COLIN HF_CRAFTBYTE HF_ICECLASS HF_LEGIC HF_LEGICSIM HF_MATTYRUN HF_MFCSIM HF_MSDSAL HF_REBLAY HF_TCPRST HF_TMUDFORD HF_YOUNG
STANDALONE_MODES += HF_14ASNIFF HF_14BSNIFF HF_15SNIFF HF_AVEFUL HF_BOG HF_CARDHOPPER HF_COLIN HF_CRAFTBYTE HF_ICECLASS HF_LEGIC HF_LEGICSIM HF_MATTYRUN HF_MFCSIM HF_MSDSAL HF_REBLAY HF_TCPRST HF_TMUDFORD HF_YOUNG
STANDALONE_MODES += DANKARMULTI
STANDALONE_MODES_REQ_BT := HF_REBLAY
STANDALONE_MODES_REQ_BT := HF_CARDHOPPER HF_REBLAY
STANDALONE_MODES_REQ_SMARTCARD :=
STANDALONE_MODES_REQ_FLASH := LF_HIDFCBRUTE LF_ICEHID LF_NEXID LF_THAREXDE HF_BOG HF_COLIN HF_ICECLASS HF_LEGICSIM HF_MFCSIM
ifneq ($(filter $(STANDALONE),$(STANDALONE_MODES)),)
+4
View File
@@ -97,6 +97,10 @@ endif
ifneq (,$(findstring WITH_STANDALONE_HF_BOG,$(APP_CFLAGS)))
SRC_STANDALONE = hf_bog.c
endif
# WITH_STANDALONE_HF_CARDHOPPER
ifneq (,$(findstring WITH_STANDALONE_HF_CARDHOPPER,$(APP_CFLAGS)))
SRC_STANDALONE = hf_cardhopper.c
endif
# WITH_STANDALONE_HF_COLIN
ifneq (,$(findstring WITH_STANDALONE_HF_COLIN,$(APP_CFLAGS)))
SRC_STANDALONE = vtsend.c hf_colin.c frozen.c nprintf.c
+2 -1
View File
@@ -43,7 +43,7 @@
* 1. mem spiffs dump -s hf_14asniff.trace -d hf_14asniff.trace
* Copies trace data file from flash to your PC.
*
* 2. trace load hf_14asniff.trace
* 2. trace load -f hf_14asniff.trace
* Loads trace data from a file into PC-side buffers.
*
* 3. For ISO14a: trace list -t 14a -1
@@ -55,6 +55,7 @@
* the lab connected to PM3 client before taking it into the field.
*
* To delete the trace data from flash:
* mem spiffs remove -f hf_14asniff.trace
*
* Caveats / notes:
* - Trace buffer will be cleared on starting stand-alone mode. Data in flash
Executable → Regular
+15
View File
@@ -14,9 +14,24 @@
* - LED3: sniffed reader command, turns off when finished sniffing tag command
* - LED4: unmounting/sync'ing flash (normally < 100ms)
*
* To retrieve trace data from flash:
*
* 1. mem spiffs dump -s hf_14bsniff.trace -d hf_14bsniff.trace
* Copies trace data file from flash to your PC.
*
* 2. trace load -f hf_14bsniff.trace
* Loads trace data from a file into PC-side buffers.
*
* 3. For ISO14a: trace list -t 14b -1
*
* Lists trace data from buffer without requesting it from PM3.
*
* This module emits debug strings during normal operation -- so try it out in
* the lab connected to PM3 client before taking it into the field.
*
* To delete the trace data from flash:
* mem spiffs remove -f hf_14bsniff.trace
*
* Caveats / notes:
* - Trace buffer will be cleared on starting stand-alone mode.
* - This module will terminate if the trace buffer is full.
+2 -1
View File
@@ -43,7 +43,7 @@
* 1. mem spiffs dump -s hf_15693sniff.trace -d hf_15693sniff.trace
* Copies trace data file from flash to your PC.
*
* 2. trace load hf_15693sniff.trace
* 2. trace load -f hf_15693sniff.trace
* Loads trace data from a file into PC-side buffers.
*
* 3. For ISO15693: trace list -t 15 -1
@@ -54,6 +54,7 @@
* the lab connected to PM3 client before taking it into the field.
*
* To delete the trace data from flash:
* mem spiffs remove -f hf_15693sniff.trace
*
* Caveats / notes:
* - Trace buffer will be cleared on starting stand-alone mode. Data in flash
+417
View File
@@ -0,0 +1,417 @@
/*
* hf_cardhopper standalone mode by Sam Haskins
*
* A component of our (me + Trevor Stevado) research on long-range relay
* attacks against 14a-based protocols (as presented at DEF CON '31).
* Works with a CardHopper (recommended) or BlueShark add-on.
*
* If you're reading this, you're clearly a very interesting person---
* do reach out if you get any fun results? [ sam AT loudmouth DOT io ]
* Good luck, and may the odds be ever in your favour!
*
* The companion Android app is available on our gitlab: gitlab.com/loudmouth-security
*
* For more information, see: https://media.defcon.org/DEF%20CON%2031/DEF%20CON%2031%20presentations/Trevor%20Stevado%20Sam%20Haskins%20-%20Unlocking%20Doors%20from%20Half%20a%20Continent%20Away.pdf
*/
#include <string.h>
#include "appmain.h"
#include "BigBuf.h"
#include "dbprint.h"
#include "fpgaloader.h"
#include "iso14443a.h"
#include "protocols.h"
#include "proxmark3_arm.h"
#include "standalone.h"
#include "ticks.h"
#include "util.h"
#include "usart.h"
void ModInfo(void) {
DbpString(" HF - Long-range relay 14a over serial<->IP - a.k.a. CardHopper (Sam Haskins)");
}
typedef struct PACKED {
uint8_t len;
uint8_t dat[255];
} packet_t;
// Magic numbers
static const uint8_t magicREAD[4] = "READ";
static const uint8_t magicCARD[4] = "CARD";
static const uint8_t magicEND [4] = "\xff" "END";
static const uint8_t magicRSRT[7] = "RESTART";
static const uint8_t magicERR [4] = "\xff" "ERR";
static uint8_t magicACK [1] = "\xfe"; // is constant, but must be passed to API that doesn't like that
// Forward declarations
static void become_reader(void);
static void select_card(void);
static void become_card(void);
static void prepare_emulation(uint8_t *, uint16_t *, uint8_t *, packet_t *);
static void cook_ats(packet_t *, uint8_t, uint8_t);
static bool try_use_canned_response(const uint8_t *, int, tag_response_info_t *);
static void reply_with_packet(packet_t *);
static void read_packet(packet_t *);
static void write_packet(packet_t *);
static bool GetIso14443aCommandFromReaderInterruptible(uint8_t *, uint8_t *, int *);
void RunMod(void) {
StandAloneMode();
DbpString(_CYAN_("[@]") " CardHopper has started - waiting for mode");
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
clear_trace();
set_tracing(true);
// Indicate we are alive and in CardHopper
LEDsoff();
LED_A_ON();
LED_D_ON();
while (1) {
WDT_HIT();
packet_t modeRx = { 0 };
read_packet(&modeRx);
if (memcmp(magicREAD, modeRx.dat, sizeof(magicREAD)) == 0) {
DbpString(_CYAN_("[@]") " I am a READER. I talk to a CARD.");
become_reader();
} else if (memcmp(magicCARD, modeRx.dat, sizeof(magicCARD)) == 0) {
DbpString(_CYAN_("[@]") " I am a CARD. I talk to a READER.");
become_card();
} else if (memcmp(magicEND, modeRx.dat, sizeof(magicEND)) == 0) {
break;
} else {
DbpString(_YELLOW_("[!]") " unknown mode!");
Dbhexdump(modeRx.len, modeRx.dat, true);
}
}
DbpString(_CYAN_("[@]") " exiting ...");
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
}
static void become_reader(void) {
iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD);
select_card(); // also sends UID, ATS
DbpString(_CYAN_("[@]") " entering reader main loop ...");
packet_t packet = { 0 };
packet_t *rx = &packet;
packet_t *tx = &packet;
uint8_t toCard[256] = { 0 };
uint8_t parity[MAX_PARITY_SIZE] = { 0 };
while (1) {
WDT_HIT();
read_packet(rx);
if (memcmp(magicRSRT, rx->dat, sizeof(magicRSRT)) == 0) break;
memcpy(toCard, rx->dat, rx->len);
AddCrc14A(toCard, rx->len);
ReaderTransmit(toCard, rx->len + 2, NULL);
tx->len = ReaderReceive(tx->dat, parity);
if (tx->len == 0) {
tx->len = sizeof(magicERR);
memcpy(tx->dat, magicERR, sizeof(magicERR));
} else tx->len -= 2; // cut off the CRC
write_packet(tx);
}
}
static void select_card(void) {
iso14a_card_select_t card = { 0 };
while (1) {
WDT_HIT();
int ret = iso14443a_select_card(NULL, &card, NULL, true, 0, false);
if (ret && ret != 1)
Dbprintf(_RED_("[!]") " Error selecting card: %d", ret);
if (ret == 1) break;
SpinDelay(20);
}
DbpString(_CYAN_("[@]") " UID:");
Dbhexdump(card.uidlen, card.uid, false);
DbpString(_CYAN_("[@]") " ATS:");
Dbhexdump(card.ats_len - 2 /* no CRC */, card.ats, false);
packet_t tx = { 0 };
tx.len = card.uidlen;
memcpy(tx.dat, card.uid, tx.len);
write_packet(&tx);
tx.len = card.ats_len - 2;
memcpy(tx.dat, card.ats, tx.len);
write_packet(&tx);
}
static void become_card(void) {
iso14443a_setup(FPGA_HF_ISO14443A_TAGSIM_LISTEN);
uint8_t tagType;
uint16_t flags;
uint8_t data[PM3_CMD_DATA_SIZE] = { 0 };
packet_t ats = { 0 };
prepare_emulation(&tagType, &flags, data, &ats);
tag_response_info_t *canned;
uint32_t cuid;
uint32_t counters[3] = { 0 };
uint8_t tearings[3] = { 0xbd, 0xbd, 0xbd };
uint8_t pages;
SimulateIso14443aInit(tagType, flags, data, &canned, &cuid, counters, tearings, &pages);
DbpString(_CYAN_("[@]") " Setup done - entering emulation loop");
int fromReaderLen;
uint8_t fromReaderDat[256] = { 0 };
uint8_t parity[MAX_PARITY_SIZE] = { 0 };
packet_t packet = { 0 };
packet_t *tx = &packet;
packet_t *rx = &packet;
while (1) {
WDT_HIT();
if (!GetIso14443aCommandFromReaderInterruptible(fromReaderDat, parity, &fromReaderLen)) {
if (usart_rxdata_available()) {
read_packet(rx);
if (memcmp(magicRSRT, rx->dat, sizeof(magicRSRT)) == 0) {
DbpString(_CYAN_("[@]") " Breaking from reader loop");
break;
}
}
continue;
}
// Option 1: Use a canned response
if (try_use_canned_response(fromReaderDat, fromReaderLen, canned)) continue;
// Option 2: Reply with our cooked ATS
if (fromReaderDat[0] == ISO14443A_CMD_RATS && fromReaderLen == 4) {
reply_with_packet(&ats);
continue;
}
// Option 3: Relay the message
tx->len = fromReaderLen - 2; // cut off the crc
memcpy(tx->dat, fromReaderDat, tx->len);
write_packet(tx);
read_packet(rx);
reply_with_packet(rx);
}
}
static void prepare_emulation(uint8_t *tagType, uint16_t *flags, uint8_t *data, packet_t *ats) {
packet_t tagTypeRx = { 0 };
read_packet(&tagTypeRx);
packet_t timeModeRx = { 0 };
read_packet(&timeModeRx);
packet_t uidRx = { 0 };
read_packet(&uidRx);
read_packet(ats);
*tagType = tagTypeRx.dat[0];
Dbprintf(_CYAN_("[@]") " Using tag type: %hhu", *tagType);
DbpString(_CYAN_("[@]") " Time control parameters:");
Dbhexdump(timeModeRx.len, timeModeRx.dat, false);
uint8_t fwi = timeModeRx.dat[0] & 0x0f;
uint8_t sfgi = timeModeRx.dat[1] & 0x0f;
Dbprintf(_CYAN_("[@]") " Parsed as fwi = %hhu, sfgi = %hhu", fwi, sfgi);
if (fwi == 0xf) {
DbpString(_YELLOW_("[!]") " Refusing to use 15 as FWI - will use 14");
fwi = 0xe;
}
if (sfgi == 0xf) {
DbpString(_YELLOW_("[!]") " Refusing to use 15 as SFGI - will use 14");
sfgi = 0xe;
}
memcpy(data, uidRx.dat, uidRx.len);
*flags = (uidRx.len == 10 ? FLAG_10B_UID_IN_DATA : (uidRx.len == 7 ? FLAG_7B_UID_IN_DATA : FLAG_4B_UID_IN_DATA));
DbpString(_CYAN_("[@]") " UID:");
Dbhexdump(uidRx.len, data, false);
Dbprintf(_CYAN_("[@]") " Flags: %hu", *flags);
DbpString(_CYAN_("[@]") " Original ATS:");
Dbhexdump(ats->len, ats->dat, false);
cook_ats(ats, fwi, sfgi);
DbpString(_CYAN_("[@]") " Cooked ATS:");
Dbhexdump(ats->len, ats->dat, false);
}
static void cook_ats(packet_t *ats, uint8_t fwi, uint8_t sfgi) {
if (ats->len != ats->dat[0]) {
DbpString(_RED_("[!]") " Malformed ATS - unable to cook; things may go wrong!");
return;
}
// If the ATS is too short (unusual), pad it to length with hopefully-sensible data
// Might be better for the phone side to do this tbh
if (ats->len == 1) {
ats->len = 4;
ats->dat[0] = 0x04;
ats->dat[1] = 0x78;
ats->dat[2] = 0x77;
// ats->dat[3] = 0x80;
} else if (ats->len == 2) {
ats->len = 4;
ats->dat[0] = 0x04;
ats->dat[2] = 0x77;
// ats->dat[3] = 0x80;
} else if (ats->len == 3) {
ats->len = 4;
ats->dat[0] = 0x04;
// ats->dat[3] = 0x80;
}
// Set the SFGI as well as the FWI - needed for some older readers (firmware revs?)
uint8_t cookedTB0 = (fwi << 4) | sfgi;
ats->dat[3] = cookedTB0;
}
static bool try_use_canned_response(const uint8_t *dat, int len, tag_response_info_t *canned) {
if ((dat[0] == ISO14443A_CMD_REQA || dat[0] == ISO14443A_CMD_WUPA) && len == 1) {
EmSendPrecompiledCmd(canned + RESP_INDEX_ATQA);
return true;
}
if (dat[1] == 0x20 && len == 2) {
if (dat[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT) {
EmSendPrecompiledCmd(canned + RESP_INDEX_UIDC1);
return true;
} else if (dat[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2) {
EmSendPrecompiledCmd(canned + RESP_INDEX_UIDC2);
return true;
} else if (dat[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_3) {
EmSendPrecompiledCmd(canned + RESP_INDEX_UIDC3);
return true;
}
}
if (dat[1] == 0x70 && len == 9) {
if (dat[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT) {
EmSendPrecompiledCmd(canned + RESP_INDEX_SAKC1);
return true;
} else if (dat[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2) {
EmSendPrecompiledCmd(canned + RESP_INDEX_SAKC2);
return true;
} else if (dat[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_3) {
EmSendPrecompiledCmd(canned + RESP_INDEX_SAKC3);
return true;
}
}
if (dat[0] == ISO14443A_CMD_PPS) {
EmSendPrecompiledCmd(canned + RESP_INDEX_PPS);
return true;
}
// No response is expected to these 14a commands
if ((dat[0] == 0xf2 && len == 4) || dat[0] == 0xfa) return true;
if (dat[0] == ISO14443A_CMD_HALT && len == 4) return true;
// Ignore Apple ECP2 polling
if (dat[0] == 0x6a) return true;
return false;
}
static uint8_t g_responseBuffer [512 ] = { 0 };
static uint8_t g_modulationBuffer[1024] = { 0 };
static void reply_with_packet(packet_t *packet) {
tag_response_info_t response = { 0 };
response.response = g_responseBuffer;
response.modulation = g_modulationBuffer;
memcpy(response.response, packet->dat, packet->len);
AddCrc14A(response.response, packet->len);
response.response_n = packet->len + 2;
prepare_tag_modulation(&response, sizeof(g_modulationBuffer));
EmSendPrecompiledCmd(&response);
}
static void read_packet(packet_t *packet) {
while (!usart_rxdata_available()) {
WDT_HIT();
SpinDelayUs(100);
}
uint32_t dataReceived = usart_read_ng((uint8_t *) packet, sizeof(packet_t)) - 1;
while (dataReceived != packet->len) {
while (!usart_rxdata_available()) WDT_HIT();
dataReceived += usart_read_ng(packet->dat + dataReceived, 255 - dataReceived);
}
usart_writebuffer_sync(magicACK, sizeof(magicACK));
}
static void write_packet(packet_t *packet) {
usart_writebuffer_sync((uint8_t *) packet, packet->len + 1);
}
static bool GetIso14443aCommandFromReaderInterruptible(uint8_t *received, uint8_t *par, int *len) {
LED_D_OFF();
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_LISTEN);
Uart14aInit(received, par);
uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
(void)b;
uint8_t flip = 0;
uint16_t checker = 4000;
for (;;) {
WDT_HIT();
if (flip == 3) {
if (usart_rxdata_available())
return false;
flip = 0;
}
if (checker-- == 0) {
flip++;
checker = 4000;
}
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
if (MillerDecoding(b, 0)) {
*len = GetUart14a()->len;
return true;
}
}
}
return false;
}
+4 -4
View File
@@ -293,7 +293,7 @@ static void ReadLastTagFromFlash(void) {
rdv40_spiffs_read_as_filetype((char *)HFCOLIN_LASTTAG_SYMLINK, (uint8_t *)mem, len, RDV40_SPIFFS_SAFETY_SAFE);
// copy 64blocks (16bytes) starting w block0, to emulator mem.
emlSetMem(mem, 0, 64);
emlSetMem_xt(mem, 0, 64, 16);
DbprintfEx(FLAG_NEWLINE, "[OK] Last tag recovered from FLASHMEM set to emulator");
cjSetCursLeft();
@@ -650,7 +650,7 @@ failtag:
for (uint8_t t = 0; t < 2; t++) {
memcpy(mblock + t * 10, foundKey[t][sectorNo], 6);
}
emlSetMem(mblock, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 1);
emlSetMem_xt(mblock, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 1, 16);
}
cjSetCursLeft();
@@ -827,12 +827,12 @@ int e_MifareECardLoad(uint32_t numofsectors, uint8_t keytype) {
};
if (isOK) {
if (blockNo < NumBlocksPerSector(s) - 1) {
emlSetMem(dataoutbuf, FirstBlockOfSector(s) + blockNo, 1);
emlSetMem_xt(dataoutbuf, FirstBlockOfSector(s) + blockNo, 1, 16);
} else {
// sector trailer, keep the keys, set only the AC
emlGetMem(dataoutbuf2, FirstBlockOfSector(s) + blockNo, 1);
memcpy(&dataoutbuf2[6], &dataoutbuf[6], 4);
emlSetMem(dataoutbuf2, FirstBlockOfSector(s) + blockNo, 1);
emlSetMem_xt(dataoutbuf2, FirstBlockOfSector(s) + blockNo, 1, 16);
}
}
}

Some files were not shown because too many files have changed in this diff Show More