Saturday, March 13, 2021

Successful Recovery of BTC from a HW.1 Ledger Wallet with Firmware 1.0.0 (seed lost!)

HW.1 ledger Wallet

TL;RD - Don’t lose your seed!

In spring 2015, our client went to an event at “La Maison du Bitcoin“ in Paris, where he met the president of a hardware startup called Btchip, that was presenting a revolutionary USB device called HW.1 Ledger Wallet, designed to secure Bitcoin private keys. He bought a HW.1 ledger, and took their offer to set it up with a BTC account loaded some Bitcoin, which, at the time, were about €200 per BTC. Then he just put it in a box and forgot about it.

Fast-forward to 2021: “La Maison du Bitcoin” merged with Btchip and a small exchange to form the Ledger Company, which designed and commercialized the very successful Ledger Nano S and Nano X.

And our client found his old HW.1 Ledger, with its unlocking PIN and its “security card” (a challenge-response system designed to generate a confirmation PIN when signing transactions, since the HW.1 device has no screen and no buttons). No trace of his 24-word recovery phrase... So the only option was to recover his Bitcoin by using the actual HW.1 Ledger device to sign a transaction.

The old Chrome extension that used to work with the HW.1 Ledger cannot be used anymore (and its back-end server has been discontinued), so Electrum looked like the only option. Electrum could unlock his HW.1, access his account, and see his BTC balance, which is good news, but unfortunately, Electrum always displayed an error when signing a transaction.

We agreed on our bounty (if the recovery was successful) and started working on it. We got lucky that our client is a very nice French-speaking IT guy (located in Montreal Quebec), familiar with Linux and comfortable with running virtual machines and editing script files.

To start, we modified the ledger plugin in Electrum to figure out what was causing the error in Electrum, and we found that the function of the Bitcoin app (firmware) on the device that was normally used to sign BTC transactions, was in fact not implemented on his HW.1.

The Electrum Ledger plugin relies on the ledger device supporting the so-called “alternate protocol”, via a function called “finalizeInputFull”. Unfortunately, this function was not implemented until Bitcoin firmware 1.0.2, and it turned out that we had firmware 1.0.0, which was supporting a different tx signature protocol, limited to tx with only one output address and one “change” address (and only BTC “legacy” addresses). For some reason, the code handling this old ledger firmware was removed from future version the Electrum ledger plugin (probably to simplify its maintenance when segwit was later added).

So from there, we had to figure out how to support the “old protocol” used by version 1.0.0, and to hack a very customized version of the ledger plugin that we hoped might be able to sign a correct transaction with his ledger.

We found that Electrum 2.2, which dated from about April 2015, had a plugin called btchipwallet.py that was implementing the “old protocol”. Unfortunately, even if we could rebuild a working Electrum 2.2, it would not have worked because Electrum completely changed the API they use for communicating with their backend servers, around their version 3.0. So this was not an option.

And using the old btchipwallet.py in the current Electrum was not an option either, for two reasons: Electrum is now running on python3, while the old plugin was written in python2, and more importantly, the API between Electrum and its plugins has completely changed.

So the only option was to try to understand what the old btchipwallet.py plugin was doing, and hack a completely custom plugin using pieces of the old ledger plugin code (modified and ported to python3), and to integrate them into the current ledger plugin to use the old protocol instead of the ”alternate protocol” to sign the tx.

We thought that our work would be simpler if we had access to a HW.1 device for testing. Fortunately a reddit user was nice enough to sell us their old HW.1 that was just taking dust, so we could test some of our code. Unfortunately this HW.1 turned out to have firmware version 1.0.4, which only implemented the “alternate protocol”, so we could not test all our code, but we could test about half of it. A few old python2 test scripts from the Github repository for the bitcoin app dating from April 2015 also helped us understand how the old protocol was working.

We did all the development and testing work on a Kali (Debian) Linux virtual machine, running in virtualbox on a Win10 system. About 5 or 6 times, we tested our new hacked electrum plugin with the client’s actual device, and the copious amount of traces in the terminal showed that we were making progress and helped moving forward. Overall the entire effort took a few weeks of work (and a few hours from our client), and would have been much harder if our client had not been an engineer familiar with Linux.

Finally, a couple of days ago, we shipped a Linux virtual image with our hacked Electrum plugin to our client, and while sharing a google-meet view of our client’s screen, we were able to successfully sign a valid transaction that transferred all his BTC to another account!

We were both really happy to finally see the Tx being confirmed on the BTC network!


No comments:

Post a Comment