話題の Fake Stake 攻撃についての解説

はじめに

みなさんこんにちは。

VIPPOOL でエンジニアをやっています、星月です。

今回は普段の連載ではなく、先日、米国研究グループから公表された、
Fake Stake 攻撃に関するレポートについて、解説してみようと思います。

この記事は、脆弱性を周知することでコインノードを運用している方々に指摘があったことを
認知していただくためのものであり、決して DoS 攻撃を推奨するものではありません。
実際に攻撃を行った場合、法律により罰せられますのでご注意ください。

前提知識

昨今の暗号通貨の系譜

暗号通貨っていろいろ種類がありますが、その大半は、bitcoin の実装を元に、
ソースコードを改造して作られたものです。

bitcoin から派生していない暗号通貨といえば、Ethereum が筆頭にあがりますが、
それ以外はほとんどが、bitcoin をベースに開発されたものとなっています。

つまり、bitcoin を改造して作られている以上、bitcoin の性質を色濃く受け継いでいるわけです。

今回、問題になっている「チェーンベース PoS」というのも、
元々は PoW で実装されていた bitcoin を改造して、
PoS を導入した暗号通貨のことを指しています。

bitcoin のシステム構造

bitcoin は、それぞれのノードが自分のデータベースを持っていて、
相互に通信しながらそれを同期する仕組みになっています。

f:id:y-hoshizuki:20190125183135p:plain

そして、誰かがマイニングに成功したら、それをブロードキャストして、
それぞれのノードが自分で新しいブロックを検証してから、自分のデータベースに追記します。

f:id:y-hoshizuki:20190125183152p:plain

bitcoin のブロックの構造

ブロックは、大きく分けて2つのデータから成り立っています。

  1. ブロックヘッダ(ブロックの中身のハッシュ値、タイムスタンプ、Nonce など)
  2. ブロック本体(トランザクションデータ)

PoW と PoS

そもそも PoW, PoS とはなんでしょう。

PoW は、ブロックヘッダに Nonce と呼ばれるフィールドを用意して、
ブロックヘッダのハッシュ値が一定値以下になる Nonce を探し当てるゲームです。

SHA256(ブロックヘッダ) < target (difficulty から算出)

この等式を成り立たせる Nonce を総当りで探します。
difficulty は、ブロック発見頻度が概ね 10 分(bitcoin の場合)になるように、
自動で調整される値です。

一方、PoS は、Stake、つまり今持ってる資産に応じて当選確率が上がる抽選です。

SHA256(ブロックヘッダ) < target * 今持ってる資産

この抽選を一定時間ごとに行い、当選したらマイニング成功というわけです。

PoS にもいくつかバリエーションがありますが、この先、
単純に PoS と書いた場合は PoSv3 のことを指すとお考えください。

PoW の欠点、PoS の欠点

PoW の欠点はもう有名ですが、とにかく大量に電力に消費するところです。

これを解決するのが、PoS ですが、こちらはこちらで、
お金持ち(暗号資産をたくさん持っている人)ほどマイニング報酬を得やすくなり、
経済格差が広がる一方、という問題が既に指摘されています。

とはいえ、PoW だって、現金を持っている人ほどいい ASIC や GPU を買えるので、
どっちもどっちと言えなくはないと思います。

もう1つ、今回の鍵になる PoS の欠点ですが、
各ノードが新規に追加されるブロックを検証するときに、
PoW なら「ブロックヘッダのハッシュ値を求めて比較するだけ」で済むのに対して、
PoS だと、「マイナーの資産を確認する」必要があるという点があります。

つまり、PoS はマイナーの資産を確認する分だけ、検証が重い、という問題があるわけです。
今回の脆弱性はすべて、ここが発端となります。

bitcoin から派生した PoS コインの仕組み

bitcoin には、マイナーが報酬を得るためのトランザクション
coinbase トランザクションが、各ブロックに 1 つあります。

coinbase トランザクションは、入力を持たず、出力で 50BTC や 25BTC などを、
マイナー宛に送金するトランザクションです。

bitcoin から派生した PoS コインでは、この coinbase トランザクションに加え、
新たに coinstake トランザクションというものを追加しました。

これは、マイニングに成功したか否かを確認するために、
マイナーの未使用資産(UTXO)を入力としているトランザクションで、
PoS でマイニングされたブロックには 1 つあるものです。

また、coinstake トランザクションでは手数料をマイナスの数にすることができます。
これによって実質のマイニング報酬としています。
そのため、coinbase トランザクションは未使用として運用されています。

このあたりに、bitcoin の血を受け継いでいる感じがありますね。

チェーンの分岐

bitcoin はマイナーが複数人いる上、ネットワークの伝播にラグがある関係上、
チェーンが分岐する場合があります。

そのため、同じブロック高で複数種類のブロックを受け取った場合には、
どちらも正当なものとして一旦保存しておきます。
ある程度伸びた時点で、長く伸びたほうにはたくさんの計算量(マイナー)が集まっている
という仮定のもと、短いほうを廃棄する、という仕組みになっています。

それまでは、分岐した両方のチェーンを保持しています。

そしてこの仕組みは、bitcoin から派生した PoS コインにも受け継がれています。

今回の脆弱性

メモリを大量に消費する DoS 攻撃

bitcoin では、ブロックヘッダの伝播と、ブロックデータの伝播は分けて行われます。

それは、まずブロックヘッダだけ受け取って検証してから、
中身であるブロックデータを受け取れば済むからです。

ところが、bitcoin から派生した PoS コインでは、
ブロックヘッダだけでは検証ができません。ブロックデータに含まれる
coinstake トランザクションに検証用のデータが入っているからです。

そのため、新規にブロックを受け取った際には、
ブロック全体をダウンロードしてメモリに載せる必要があります。
つまり、PoW だった bitcoin と比べて、新規ブロック受け取り時の
メモリ消費量が桁違いに多いわけです。

ここを突くのが、1 つめの攻撃方法です。

例えば、ターゲットのノードに複数のプロセスから同時に接続し、
同時に適当なブロックヘッダとブロックデータを流し込むと、
ターゲットのノードは律儀に全部メモリに載せようとします。

これでメモリを大量に消費してクラッシュする場合もあります。

この攻撃は、特に暗号資産を持っている必要がなく実行できます。

ディスクを大量に消費する DoS 攻撃

前述の通り、coinstake の検証には、マイナーの保有資産を確認する必要があるため、
非常に重いという問題があります。

マイナーの保有資産は、UTXO set と呼ばれるデータベースで管理していますが、
これは現在一番長いチェーンの先端時点での情報であり、
分岐したチェーンの状態ではありません。

そのため、分岐したチェーンでは、coinstake が UTXO として指し示す先が、
トランザクションの出力として存在するか、という最低限の検査のみ行い、
実際に未使用か否かの検査は省略してディスクに保存します。

これがこの脆弱性の肝ともいえる部分です。

そのため、実際には使用済みのトランザクション出力を UTXO と偽って
coinstake を作成し、ターゲットのノードに受信させることで、
ディスクをどんどん圧迫することができます。

これが 2 つめの攻撃方法で、メモリの消費に比べて
「ただの再起動じゃ直らない」という点においてより悪質と書かれています。

ただし、この攻撃を実現させるためには、少なくともハッシュ値は十分、
当選に値するものである必要があるため、ある程度多くの暗号資産を持つ必要があります。

攻撃をしやすくする、Stake Amplification

前述の攻撃手法をとるためには、少なくともハッシュ値の計算で
当選した coinstake を量産しなければならないという問題があります。

そのため、ある程度多くの暗号資産を持つ必要があるわけですが、
ここでポイントとなるのは、coinstake の指し示す先が使用済みであってもよい、
という事実です。

そのため、自分への送金を何度も何度も繰り返します。
そうすると、自分宛のトランザクション出力(ただし使用済み)が大量に生まれます。

これを前述の攻撃に使用することが可能、というわけです。

まとめ

一次ソースの情報を斜め読みして、ざっくりと攻撃の仕組みを解説してみました。
攻撃について、まとめると以下の通りです。

攻撃を受ける可能性があるコイン:bitcoin から派生した PoS 型の暗号通貨(おそらく全て)
攻撃を受ける可能性のある人:コインノードを立てている人(マイニングを行っている人とほぼ同義)
攻撃を受けた結果:メモリ使用量が増えてクラッシュ、もしくはディスクを食いつぶしてシステム停止
攻撃では出来ないこと:他人の暗号資産を奪うこと、など

おそらく、近いうちに対策を施したバージョンがリリースされると思いますので、
今回対象となっている暗号通貨のコインノードを立てている人は、
可能な限り、早めのバージョンアップを心がけると良いのではないでしょうか。

もしくは、リスクを少しでも避けるならば、対策バージョンがでるまで、
マイニングをおやすみしてコインノードを止めるのが、もっとも確実かもしれません。

今回の脆弱性の発見についての記事では、既に多くの暗号通貨において、
何らかの緩和策が取られているとのことですので、その場合はあまり問題にならないかも知れません。
しかし、bitcoin から派生した PoS コインでは仕組み上「完全な解決」は不可能なため、
各自で具体的な対応状況や、リスクの大小など、判断していただくよう、お願いいたします。

ご質問、ご意見等ありましたらお気軽にリプライください。