From 8917c48cde33ec562253dd34cfedb105a8d903f2 Mon Sep 17 00:00:00 2001 From: Matthew Carroll Date: Wed, 30 Sep 2026 10:48:42 -0700 Subject: [PATCH] lf t55xx detect: do not send a password the PWD bit has not confirmed `lf t55xx detect -p ` reached for the password whenever detection failed without one, and sent it across every downlink mode and again after a wake. On a tag that is not password protected those frames can be taken for a write: the PWD bit gets set and the tag's data is destroyed, leaving it locked behind whatever block 7 already held. `lf t55xx read` and `lf t55xx dump` already guard against this. They verify the PWD bit in the configuration block before using a password, and expose -o/--override to bypass the check deliberately. detect had neither, and T55xxReadBlockEx() treats a live `detect -p` as proof the bit is set. detect cannot run the same check -- reading the configuration is what it is for, and the password is only reached for once that has failed -- so the risk has to be the user's to accept. Gate it behind -o/--override to match read and dump, and carry read's warning banner into the help. No change in behaviour for anyone not passing -p. Co-Authored-By: Claude Opus 5 --- CHANGELOG.md | 1 + client/src/cmdlft55xx.c | 35 +++++++++++++++++++++++++---------- doc/commands.json | 7 ++++--- 3 files changed, 30 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 519a157f9..afb459bc7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] +- Fixed `lf t55xx detect -p` - the password is no longer sent to a tag whose PWD bit could not be confirmed, which could set it and destroy the tag's data; pass `-o` to override (@mfcarroll) - Added `A1856618` (an EM4305 anti-clone card password) to the `t55xx_default_pwds` dictionary used by `lf em 4x05 chk` (@nemanjan00) - Added `hw bwm ble` - the BWM's BLE settings: `on`/`off` (persisted radio switch), `pairing` (require a 6-digit passkey, LE Secure Connections; the module ships open), `forget` bonded devices, `txpower`, `status` (@Msprg) - Changed `hw bwm autooff` - `--idle ` adds an opt-in power-off after that long idle on battery (no command, button press or BLE/WiFi client), off by default; `--unplug off` makes an unplug only restart that idle clock instead of powering off at once; all stored on the BWM, `hw status` shows it (@Msprg) diff --git a/client/src/cmdlft55xx.c b/client/src/cmdlft55xx.c index 76675b2f5..ee4c4ac78 100644 --- a/client/src/cmdlft55xx.c +++ b/client/src/cmdlft55xx.c @@ -1090,19 +1090,24 @@ static int CmdT55xxWakeUp(const char *Cmd) { static int CmdT55xxDetect(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "lf t55xx detect", - "Try detecting the tag modulation from reading the configuration block", + "Try detecting the tag modulation from reading the configuration block.\n\n" + _RED_(" * * * WARNING * * *") "\n" + _CYAN_("Use of detect with password on a tag not configured") "\n" + _CYAN_("for a password can damage the tag") "\n" + _RED_(" * * * * * * * * * *"), "lf t55xx detect\n" "lf t55xx detect -1\n" - "lf t55xx detect -p 11223344\n" + "lf t55xx detect -p 11223344 -o\n" ); - // 1 (help) + 2 (two user specified params) + (6 T55XX_DLMODE_ALL) - void *argtable[3 + 6] = { + // 1 (help) + 3 (three user specified params) + (6 T55XX_DLMODE_ALL) + void *argtable[4 + 6] = { arg_param_begin, arg_lit0("1", NULL, "extract using data from graphbuffer"), arg_str0("p", "pwd", "", "password (4 hex bytes)"), + arg_lit0("o", "override", "override safety check"), }; - uint8_t idx = 3; + uint8_t idx = 4; arg_add_t55xx_downloadlink(argtable, &idx, T55XX_DLMODE_ALL, config.downlink_mode); CLIExecWithReturn(ctx, Cmd, argtable, true); @@ -1122,11 +1127,13 @@ static int CmdT55xxDetect(const char *Cmd) { password = tmp_pwd; } - bool r0 = arg_get_lit(ctx, 3); - bool r1 = arg_get_lit(ctx, 4); - bool r2 = arg_get_lit(ctx, 5); - bool r3 = arg_get_lit(ctx, 6); - bool ra = arg_get_lit(ctx, 7); + bool override = arg_get_lit(ctx, 3); + + bool r0 = arg_get_lit(ctx, 4); + bool r1 = arg_get_lit(ctx, 5); + bool r2 = arg_get_lit(ctx, 6); + bool r3 = arg_get_lit(ctx, 7); + bool ra = arg_get_lit(ctx, 8); CLIParserFree(ctx); if ((r0 + r1 + r2 + r3 + ra) > 1) { @@ -1134,6 +1141,14 @@ static int CmdT55xxDetect(const char *Cmd) { return PM3_EINVARG; } + // A password frame on an unprotected tag can land as a write, and detect cannot + // check the PWD bit first the way read does -- finding the config is its job. + if (usepwd && (override == false)) { + PrintAndLogEx(WARNING, "Safety check: Could not confirm PWD bit is set. Detecting without password..."); + PrintAndLogEx(HINT, "Hint: Consider using the override parameter to force detect with password."); + usepwd = false; + } + bool try_all_dl_modes = false; uint8_t downlink_mode = config.downlink_mode; if (r0) diff --git a/doc/commands.json b/doc/commands.json index 7aadd9acc..93f5d4b37 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -14594,24 +14594,25 @@ }, "lf t55xx detect": { "command": "lf t55xx detect", - "description": "Try detecting the tag modulation from reading the configuration block", + "description": "Try detecting the tag modulation from reading the configuration block. * * * WARNING * * * Use of detect with password on a tag not configured for a password can damage the tag * * * * * * * * * *", "notes": [ "lf t55xx detect", "lf t55xx detect -1", - "lf t55xx detect -p 11223344" + "lf t55xx detect -p 11223344 -o" ], "offline": true, "options": [ "-h, --help This help", "-1 extract using data from graphbuffer", "-p, --pwd password (4 hex bytes)", + "-o, --override override safety check", "--r0 downlink - fixed bit length (detected def)", "--r1 downlink - long leading reference", "--r2 downlink - leading zero", "--r3 downlink - 1 of 4 coding reference", "--all try all downlink modes" ], - "usage": "lf t55xx detect [-h1] [-p ] [--r0] [--r1] [--r2] [--r3] [--all]" + "usage": "lf t55xx detect [-h1o] [-p ] [--r0] [--r1] [--r2] [--r3] [--all]" }, "lf t55xx deviceconfig": { "command": "lf t55xx deviceconfig",