このブログは、Defensics SDKを利用して独自のビットコイン・ネットワークをセットアップする方法を説明する、2部構成の上級者向けテクニカル・チュートリアルの第1部です。
このブログは、Defensics®ソフトウェア開発キット(SDK)を利用してビットコイン・ソフトウェアのファジングを行う方法を説明する2部構成の記事の第1部です。具体的には、ビットコイン・ネットワークのプロトコル・メッセージをモデル化し、Defensics SDKを用いてbitcoind
プロセスに対してファジングを実行する方法を説明します。
内容は上級者向けのテクニカル・チュートリアルなので、次のような一定の背景知識が必要になります。
この記事では、ビットコイン
のバイナリとWiresharkを用いてテストベッドを設定する方法について説明します。次回の記事では、Defensics SDKを用いてビットコイン・プロトコル・メッセージをモデル化し、最終的にDefensics SDKでビットコイン
のファジングを実行する方法を説明します。
Defensicsは、さまざまなネットワーク・プロトコルやファイル形式に対応する250を超えるテスト製品群を備えたファジングテスト・プラットフォームです。
Defensics SDKを使用すれば、独自のテスト・スイートを作成し、あらゆるプロトコルやファイル形式に対してDefensicsの機能をフルに発揮させることができます。必要な作業はデータモデルの指定だけです。その後は、本格的なDefensicsテスト・スイートを作成して、高性能なジェネレーショナル・テストケース・エンジンやDefensicsプラットフォームが提供するその他のすべての機能を活用できます。
ビットコインは数学の暗号理論によってサポートされている暗号通貨です。暗号通貨は、政府が発行する通貨のように一元管理されるのではなく、ピアツーピア・ネットワークを利用してコミュニティによって管理されます。ビットコインなどの暗号通貨は、すべてのトランザクションのリストを暗号化によって保護したブロックチェーンを基盤にしています。ネットワーク上の各ピア(ノード)は、暗号によって改ざんから保護されたブロックチェーンのコピーを保持します。ネットワーク上のピアが使用しているアルゴリズムでは、新しいトランザクションが生じると、ブロックチェーンに追加することに合意しています。これによりネットワーク全体としても、ピア同士が互いに信用する処理を省略してトランザクションを行うことが可能になりました。
暗号通貨は比較的新しい技術です。その最初は2007年に導入されたビットコインでした。やや実験的な性質があるにもかかわらず、この通貨には巨額が投じられています。この記事の執筆時点でビットコインの時価総額は3,500億ドルを超えています。
この記事を読むに際して、ビットコインやその他のプロトコルに関する詳細を知っている必要はありません。ビットコインのピア間でbitcoind
と呼ばれるプロセスを実行するということさえ知っておけば十分です。ネットワーク上のピア同士がビットコイン・ネットワーク・プロトコルを使用して情報を交換します。
bitcoind
を実行するだけなら仮想マシンとDockerコンテナは不要です。以下で概要を説明します。Bitcoinパッケージをダウンロードし、bitcoind -regtest
を実行するだけです。
以下のテストベッドを設定すると、いくつかの利点があります。
bitcoind
インスタンスを簡単にスピンアップできるため、インスタンス間の相互作用を理解できます。bitcoind
ピアの仮想ネットワークを簡単に調査できるので、ネットワーク通信に関する有益な知見を得ることができます。bitcoind
のファジングの最初のステップは、テストベッド(危害なくファジングを実行できる安全な場所)を作成することです。ファジングは、実稼働システムで実行すると障害を引き起こしたり、セキュリティアラームをトリガーする可能性が高いため、実稼働システムでは実行しないでください。
Bitcoinは本番ネットワーク(mainnet)、テストネットワーク(testnet)、回帰テストネットワーク(regtest)をサポートしています。私は、ファジングに最適な非公開の隔離されたビットコイン・ネットワークを設定できるという点から、regtestネットワークを使用してファジングを行いました。
まず、regtest用のピア、fleurとviktorを保持する仮想マシンを作成することから始めました。私はUbuntu 20.04を使用しましたが、任意のLinuxを使用できます。この手順は厳密には必要ではなく、ホストOS上でDockerインスタンスを直接作成するだけで済むのですが、私は隔離のレイヤーを追加したいと思いました。
Dockerの素晴らしい機能によって、仮想マシンのポートはfleurコンテナとviktorコンテナのポートに割り当てられます。起動が完了すると、次のようになります。
次の記事では、Defensics SDKを使用してbitcoind
インスタンスのファジングを行います。Defensicsは同じ仮想マシン上、別の仮想マシン上、またはホストOS上のいずれでも実行できます。
私はLinuxを新規にインストールしたコンピューターに、まずgit
とdocker
をインストールしました。
$ sudo apt-get install -y git docker.io
最新のビットコイン・プロトコルのディセクタを取得するため、次のようにWiresharkをインストールしました。
$ sudo add-apt-repository ppa:wireshark-dev/stable ... $ sudo apt-get update ... $ sudo apt-get install -y wireshark ...
これで、私のスクリプトを利用して、bitcoind
を実行するDockerコンテナを作成し、使用することができるようになります (この方法のヒントを与えてくれたGerald Kaszubaに感謝します)。
最初に私のリポジトリのクローンを作成します。
$ git clone https://github.com/jknudsen-synopsys/bitcoinzz-testbed.git
build.shを実行してDockerイメージをビルドします。
$ cd bitcoinzz-testbed $ ./build.sh
コンテナ・イメージは、ほとんどUbuntuベース・イメージとBitcoinバイナリだけの単純なものです。このスクリプトを実行すると、本稿執筆時点で最新バージョンのBitcoin 0.20.1がダウンロードされます。バージョンを変更する場合は、bitcoinzz.dockerを編集して任意のバージョンを指定します。
2つの別々のターミナルウィンドウを使用すると、run_fleur.sh
とrun_viktor.sh
でコンテナ・イメージの2つのインスタンスをスピンアップできます。
ビットコイン・デーモンbitcoind
はコンテナ内で自動的に起動され、bitcoin-cli -regtest
のエイリアスrt
が生成されます。これで、エイリアスを使用してコマンドをbitcoind
に渡し、情報を取得できます。
$ ./run-fleur.sh Bitcoin Core starting root@fleur:~# rt -getinfo { "version": 200100, "blocks": 0, "headers": 0, "verificationprogress": 1, "timeoffset": 0, "connections": 0, "proxy": "", "difficulty": 4.656542373906925e-10, "chain": "regtest", "balance": 0.00000000, "keypoolsize": 1000, "paytxfee": 0.00000000, "relayfee": 0.00001000, "warnings": "" } root@fleur:~#
実行されている2つのbitcoind
インスタンスは、互いに他方のインスタンスについての情報を知りません。
両者が連携していることを実証したい場合は、Wiresharkを実行し、docker0
インターフェイスをリッスンします。次に、IPアドレスを使用して、一方のbitcoind
インスタンスで他方のインスタンスを指定します。
私はhostname
を使用してfleurのIPアドレスを見つけました。
root@fleur:~# hostname -I 172.17.0.3
次に、viktorのbitcoind
にfleurの情報を次のように通知しました。
root@viktor:~# rt addnode 172.17.0.3 onetry
これによってfleurとviktorのbitcoind
プロセスの間で交換されたビットコイン・メッセージが次々と返ってきました。
おめでとうございます!これで独自のプライベート・ビットコイン・ネットワークが出来上がりました。
次回は、ビットコイン・ネットワーク・プロトコルのモデルを構築し、そのモデルをDefensics SDKで使用してbitcoind
に対してファジングを実行します。