title: Introducing ChainLock, A Linux Tool for Locking Down Important Files
Let’s say you have a valuable file on your computer, such as a bitcoin
wallet.dat file. You want to keep the wallet secure, so you put a password on it. But it’s a short password, so you can type it in more easily. Or it’s a reused password, so you can remember it. Or maybe you only keep a small amount of currency there, so you don’t bother with a password.
Maybe you’ve taken steps to protect yourself from clipboard hijacking malware, and now you’re wondering what to do next. Or maybe you haven’t. Either way, you still have a problem. It is common for malware to target and steal your
wallet.dat file. The attacker only needs to exfiltrate the file so they can crack your password offline, then they can transfer your funds to an account they control.
In addition, in July we discovered clipboard hijacking malware that now targets our CCW tool. Clearly we need to step our game up a bit.
Since the original CCW tool was for Windows, we wanted to create something for Linux users. We wanted the tool to be accessible, so it could be used to protect sensitive files without doing things like recompiling the kernel or configuring SELinux. We ended up with a new tool, dubbed ChainLock, which can lock any file on your Linux computer such that it can only be opened by a specific application. For example, it can ensure your
wallet.dat file can only be accessed by your bitcoin core application and can’t be opened or copied by malware.
You can find the
.deb for 64 bit systems here and the Android
.apk here. Note that you need tor and python3 installed on Linux and Orbot installed on Android. You will also need a kernel with fanotify support, check
$ wget https://chainlock.e-paths.com/static/chainlock-1.0.0_amd64.deb $ sudo dpkg -i chainlock-1.0.0_amd64.deb
You can verify your download with the following hashes:
$ sha256sum chainlock-1.0.0_amd64.deb 72be011da373273f87675ba18389be269122205833b496c4e827ea302c1db582 chainlock-1.0.0_amd64.deb $ sha256sum ChainlockCompanion.apk 2fa1ee1e1ac9873098d2a1f55204c098dae1970d9f7753f8b86a8713b60b675d ChainlockCompanion.apk
Here’s how it works, with example commands so you can follow along. We’re going to use an empty
wallet.dat file in a user’s
$ chainlock --help usage: chainlock [-h] [-l | -u | -i INITIALIZE INITIALIZE] [-t] optional arguments: -h, --help show this help message and exit -l, --lock Lock all unlocked files. -u, --unlock unlock the protected file -i INITIALIZE INITIALIZE, --initialize INITIALIZE INITIALIZE Start protecting the target file (first argument), allowing access with the specified binary (second argument). Use the full path. -p UPGRADE, --upgrade UPGRADE Change the authorized binary for a file. -t, --testing
First, we onboard a file with the CLI program. This encrypts the target file with a strong password (under the hood it’s using gocryptfs), moves the encrypted file to a special folder, and replaces the original with a symlink to the encrypted file. Then a QR code pops up on screen which we can scan with the companion application. This QR code contains the key to decrypt the encrypted file, a code to identify the file being protected, and the hash of the binary allowed to access the protected file.
$ mkdir -p ~/.bitcoin $ cd ~/.bitcoin/ $ echo "Test Wallet." > wallet.txt $ chainlock -i /home/user/.bitcoin/wallet.txt /usr/bin/cat Please scan the QR code that pops up in your companion app.
Now the key to unlock the protected file is only stored on your phone and can’t be found on your computer. An attacker must compromise both devices to unlock your file without permission.
$ ll wallet.txt lrwxrwxrwx 1 root root 93 Aug 31 15:47 wallet.txt -> /opt/chainlock/dfs/9c14786eb41fd5edd2f834dbb0f39b57a95081d6f64ad07052270e5f67b6b765/protected
That takes care of protecting the file at rest, but locked files aren’t very helpful when you’re trying to use them. We need a way to decrypt the file but still only allow a single application to access it. Enter fanotify. Fanotify lets us insert ourselves between an application and a file. When the application requests to read that file, we get to decide whether or not the request is allowed.
We can use the CLI tool to unlock the file. Note that we don’t need to specify anything other than that we are unlocking a file. In the background, a tor instance and hidden service is launched. Then QR code pops up, which contains information on how to reach the hidden service such as it’s onion address and the public key that can be used to submit information. With the companion app we can select the file we want to unlock, then scan the QR code. The app will send the information necessary to unlock the file to the hidden service.
$ chainlock -u Please open the Chainlock Android app, select the file you wish to unlock, and scan the QR code. You may need to scan a few times. You may now close the QR code popup. Reading Password from stdin Decrypting master key $ The option "-allow_other" is set. Make sure the file permissions protect your data from unwanted access. Filesystem mounted and ready.
ChainLock now starts a daemon to watch over the file and only allow access from the allowed binary, and then decrypts the file so it can be used. Now the wallet can only be used with the specified application. Nothing else works!
$ cat wallet.txt Test Wallet. $ tac wallet.txt tac: failed to open 'wallet.txt' for reading: Operation not permitted $ sudo su # cat wallet.txt Test Wallet. # tac wallet.txt tac: failed to open 'wallet.txt' for reading: Operation not permitted # exit exit $
“But,” you ask, “what if the authorized binary changes or upgrades?” Not a problem. Simply select the file in the companion app, run the upgrade CLI command with the path to the upgraded or new binary, and scan the QR code. Now when you unlock the file you selected your phone will tell ChainLock to allow the new binary.
$ chainlock -p /usr/bin/less $ chainlock -u Please open the Chainlock Android app, select the file you wish to unlock, and scan the QR code. You may need to scan a few times. You may now close the QR code popup. Reading Password from stdin Decrypting master key The option "-allow_other" is set. Make sure the file permissions protect your data from unwanted access. Filesystem mounted and ready. $ cat wallet.txt cat: wallet.txt: Operation not permitted $ tac wallet.txt tac: failed to open 'wallet.txt' for reading: Operation not permitted $ less wallet.txt Test Wallet. wallet.txt (END) $
Don’t take my word for it, here’s a video: