MONOKH

نخبه break things
Github @monokh Twitter @mo_nokh

Ledger App Isolation Bypass

ledger device

This post will disclose a vulnerability in the Ledger hardware wallets that can lead to theft of user funds.

An attacker can exploit this method to transfer Bitcoin while the user is under the impression that a transaction of another, less valuable altcoin (e.g. Litecoin, Testnet Bitcoins, Bitcoin Cash, etc.) is being executed

If you use bitcoin forks on your device, you could be affected. You should avoid using these ledger apps until fixes are available.

The issue has been disclosed to Ledger but remains unaddressed. See Disclosure Timeline.

Update: Ledger has released new application versions that warn the user in these scenarios.

Summary

The ledger device exposes bitcoin (mainnet) public key and signing functionality outside of the "Bitcoin" app. It presents misleading transaction confirmation requests indicating the selected app's addresses and amounts when in fact different transactions are being signed.

Background

To support an asset on Ledger devices, you must install the corresponding app. Ledger devices support multiple apps and typically users will use it to store a variety of cryptocurrencies.

Ledger apps are intended to be isolated. Such that only one app is unlocked on the device at once. Unlocking the asset allows external communication to prompt for various functions for example:

  1. Exporting public keys
  2. Signing messages
  3. Confirming transactions

Thus, from a security perspective, the expectation is that locked apps are untouchable by external messages.

The issue

It was discovered that for Bitcoin and Bitcoin forks, the device exposes it's functions for any of the assets. In other words, having unlocked the Litecoin app, you will receive a confirmation request for a Bitcoin transfer while the interface presents it as a transfer of Litecoins to a Litecoin address. Accepting the confirmation produces a fully valid signed Bitcoin (mainnet) transaction.

Steps to reproduce:

  1. Open the Litecoin app

  2. Retrieve mainnet bitcoin (segwit) addresses using getWalletPublicKey('84'/0'/0'/').publicKey

  3. Query UTXOs and construct a bitcoin transaction to spend outputs

  4. Send createPaymentTransactionNew(...) to prompt device for signing this transaction

  5. Receive Bitcoin Mainnet valid signed transaction

Expectation: Ledger device should throw an error at step 2 and step 4 and prevent execution

Actual: Ledger prompts user for a litecoin transaction and produces a valid signed transaction spending the Bitcoin utxos

 +----------------------------------+
++              Amount              ++
++  ☓       LTC 5.25512356       ✓  ++
 +----------------------------------+

 +----------------------------------+
++              Address             ++
++  ☓         ltc1q3fjf...       ✓  ++
 +----------------------------------+

Proof of Concept

https://github.com/monokh/ledger-app-isolation-bypass-poc

The PoC demonstrates retrieving a valid signed bitcoin mainnet transaction from the ledger device while user is under the impression that a litecoin transaction is being signed.

It spends from the first 20 receive and change addresses of the native segwit bitcoin wallet.

Impact

The implications are serious. As briefly covered, users expect to be protected by the ledger device when they have not unlocked their Bitcoin app. Yet, while having an altcoin unlocked, external applications can still:

Attack methods

The methods of attack here are many. Essentially, any trust placed on altcoin ledger apps can be exploited. Consider the following:

No investigation has been done on instances of this exploit in the wild.

Affected Versions

Firmware: All versions. Currently 1.6.0
App Versions: All versions. Currently 1.4.3
Apps: Any apps deriving from the Bitcoin app as per btchip_context.h
Apps Tested: Bitcoin Testnet, Litecoin

Mitigation

Recommendations for Ledger and users.

Ledger

Apps should be completely isolated with regards to the derivation paths that they are allocated to. No public key info or signing functionality should be exposed while they are not open.

Users

Interactions with Ledger

Based on my experience from the first disclosure (Jan 19), I understood that that they weren't motivated to see this issue to completion.

Ledger was aware of the issue before the disclosure as they indicated the latest firmware update includes fixes. Post disclosure, they described that the app updates were under QA and that the issue would be disclosed publicly once updates have been made. No further progress was observed and requests for update received no response.

With the second, more serious disclosure, expectations were already low. I observed that:

Based on the interactions described above, it was apparent that there was no intention to address the issue and the disclosure period would not yield any results. Nonetheless I gave them the benefit of the doubt and afforded some patience.

Conclusions

I do not consider myself a security expert. Despite this, I was able to discover this issue while developing and experimenting with Ledger support on Liquality. It is worrying that the vulnerability did not utilise any complicated techniques such as side-channel attacks, buffer overflows etc. This could indicate that there are other issues undiscovered or in plain sight.

Perhaps the most shocking conclusion is the negligence from Ledger regarding the handling of this issue. For an issue with this severity, to not attempt a fix, not communicate progress and avoid disclosure, is disrespectful towards the trust that people (including myself) have placed on them. With their increased focus in other departments (integrating alt coins, trading), I urge them to reconsider their attention to security. Such should be the commitment to a hardware wallet.

Disclosure Timeline