A look at Ledger Live genuine check reveals it's impossible to avoid being tracked

Ledger Live embeds the genuine check into the apps listing procedure. As it is, they always doxx your device when installing or updating apps and firmware. I removed most tracking in Lecce Libre, but they still track you regardless.

For the past couple days I'd been trying to find the ACTUAL genuine check code in Ledger Live

Why "actual"? Because There's "genuine check" labeled code everywhere, but I added tracing prints to it and none of that code was ever run when it checked the device. I thought that was funny so I continued digging.

Looking at the Python code (below) instead of the convoluted Typescript from Ledger Live desktop, I finally understood what's happening

Ledger's genuine device check is embedded with the listApps subroutine. It's kinda hidden there TBH

I tried disabling the remote tracking and it's impossible, it breaks if you do.

Which means Ledger knows it's you every time you plug the device in. During that procedure it lists which apps are installed in your device, so they also know what you're running on your HW.

So right now there's no way to operate Ledger HW's anonymously. They know every time you plug your device in and which apps you have installed. It was even worse before Lecce Libre, it also tracked your crypto balances!

So, the obvious question is why did they glue together apps listing and genuine check? They're not trying to save network calls, that's for sure because their software makes 2 thousand network calls for all sorts of unnecessary stuff (I've removed them from the sources and the system still works).

Here's the relevant genuine check in Python code

1703680415934.png

The genuine check is much harder to find in the Typescript code on Ledger Live! First of all, it's not labeled as a genuine check.

Here's how it works.

1703680540399.png

This is the entry point to the applications listing code on Ledger Live.

The magic happens starting on line 48 in the above snippet.

ManagerAPI.listInstalledApps opens a bidirectional channel between your device and
wss://scriptrunner.api.live.ledger.com/update/apps/list

As the hostname suggests, this is a script runner endpoint. It takes control of your device remotely by injecting APDU's into it straight from the network.

So, while it starts by listing your installed apps (APDU prefix 0xe0040000 IIRC) it runs the genuine check in between websocket messages, without ever labeling it as such.

At that moment, your device is doxxed. Why? Because it does a sort of mTLS exchange. Ledger has your device's keys in their servers. They send you a challenge. You sign that challenge and return it to them. They then execute the same signing on their end, using your unique device key, and then check if your device came from their factory....

So there's no way to use Ledgers anonymously at this time.

We desperately need a way to operate these devices completely offline but that's not possible right now.
 
This is great research! I am curious, are there any popular hardware wallets that we know don't do this? It would be illuminating if Trezor, GridPlus and others are also doing this. Telemetry is a silent beast.
 
This is great research! I am curious, are there any popular hardware wallets that we know don't do this? It would be illuminating if Trezor, GridPlus and others are also doing this. Telemetry is a silent beast.

Last I checked the Trezor manager also has analytics code in it. Though they've mentioned somewhere it's opt-in.

Not familiar with GridPlus tho, but I was overall surprised to find out that very popular wallet manager software does this routinely. I always assumed none of them did.
 
Hello! I've tried to build your code (https://github.com/rektbuildr/lecce-libre) on MacOS first and Ubuntu than.

On Mac unsuccessful (i think is connected with node / nvm / pnpm versions.
On Linux I've done the build but the result code shows there is an error there.

So, I ask you to share required packets versions to build the app correctly.
Or, maybe tell the Ledger Live version from which you took the source.

I used this setup on Mac npm: '8.19.4', node: '16.20.2', pnpm 8.15.4, Python 3.9.6
On Ubuntu 22: npm: '8.19.4', node: '16.20.2', pnpm 8.15.4, Python 3.10.12

I also want to ask you about the build script you published.
DEV_TOOLS=true DEV_TOOLS_MODE=detach pnpm dev:lld

Why do you make the build in dev mode? Why you just don't do a final desktop app:
pnpm i
pnpm build:lld:deps
pnpm desktop build

There is nothing described about the normal version (not developer).

Thank you so much, very good work. Appreciate it!
 

Attachments

  • Screenshot 2024-02-29 at 02.34.22.png
    Screenshot 2024-02-29 at 02.34.22.png
    825.4 KB · Views: 1
Back
Top