- ブロックチェーン世界の無法者
- 実装のミスやシステムの考慮不足等が原因で「弱い鍵」が生まれることがある。ブロックチェーン世界における「無法者」は、その脆弱性を利用し不正に仮想通貨を大量に搾取していることが調査によって明らかになった。
ミスを狙う無法者
Independent Security Evaluators(以下 ISE)は直近、イーサリアムに関する報告書を公表した。これはシステムの脆弱性を利用したものではなく、利用者や開発者のミスを狙ったものだが、非常に興味深い事例となっている。本記事ではこの報告書の重要内容をピックアップする。
脆弱性をもつ鍵
イーサリアムにおける鍵の空間は2の256乗の広さがある。つまり、他の人のアドレスと同じものが生成される確率が限りなく低いということだ。この数字は、2進数で表すと256桁ということだが、これは10進数だと77桁の数字になる。1秒に1兆個のアドレスを生成できたとしても、せいぜい12桁程度でしかないのでこれは途方もない数字だ。また、パブリックネットワーク上には、現時点で5000万から6000万のウォレットアドレスが存在している。
しかし一方で、弱い鍵というものが存在する。この原因は実装のミスであったり、システムの考慮不足であったり様々だ。今回、ISEは攻撃者のふるまいを調査し、13319のウォレットアドレスからETHやその他のトークンが盗まれていたことを確認した。また、加えて無効なウォレットアドレスに多くの流入があることも発見した。
イーサリアムの仕組み
イーサリムは楕円曲線暗号を用いる。ぐねぐねした曲線の2点を指定して直線をひき、延長線上でどこかにぶつかったときの点を計算する、そういったイメージが近いだろう。
このように計算された数値は、予測しにくく、逆の計算(点から直線を逆算する)が困難という性質を持つ。より厳密には256ビットの秘密鍵を用意し、楕円曲線暗号secp256k1によって秘密鍵から公開鍵を計算、keccak256ハッシュする。その上で下位160ビットをとると、ウォレットアドレスになる。
一番シンプルな実装のミスは、256ビットの鍵を切り詰めてしまうことだ。例えば、C言語のintのように、32ビットしか保持できないものを経由すると情報量が減ってしまう。
たとえば、次のような‘256ビットの秘密鍵があったとして、
・0x47579DA2BEA463533DBFAD6FCF8E90876C2FE9760DC1162ACC4059EE37BDDB5C
32ビットに切り詰められてしまうと、次のような結果になってしまう。・0x0000000000000000000000000000000000000000000000000000000037BDDB5C
※報告書から抜粋
これをもとに秘密鍵を推測して見ていく。例えば0x000…001という秘密鍵のアドレスは、0x7e5f4552091a69125d5dfcb7b8c2659029395bdfになる。600以上のトランザクションが記録されており、このウォレットアドレスが頻繁に使われていることがわかる。この秘密鍵がランダムに生成される確率は極めて低いので、明らかに人為的なミス、つまり実装に不備があったり、エラーが発生した結果、このようになってしまったと言えるだろう。
調査結果
ISEのチームは上記をもとに、以下のような範囲で探索を行った。
・0x00….001 から 0x00…00FFFFFFFF
・0x00…0100000000 から 0x00…000FFFFFFFF00000000
…・000000010..00 から FFFFFFFF000…00
と分類し、8グループについて調査を行った。
全体について探索を行うことは非現実的なので、一部分だけを1…FFFFFFFF として増やしていき、その他の部分は0で埋めた形だ。計算コストについては恐らくクラウドを利用したと思うが、かなり大量の計算リソースも用いていたとの記述がある。興味がある方はぜひ元記事を参照されたい。
結果、これら”弱い鍵”として732のアドレスが見つかり、ERC20トークンは調査できていないそうだが、総計で30ETH以上が転送された痕跡が見つかった。加えて興味深い結果として、”弱い鍵”のウォレットアドレスからETHが転送された 0x957cd4ff9b3894fc78b5134a8dc72b032ffbc464というウォレットアドレスが見つかった。
壊滅的な被害
さらに悪いことに、ウォレットアドレス0x957cd4ff9b3894fc78b5134a8dc72b032ffbc464を調査すると、壊滅的な被害を受けていたことが分かった。アドレス0x00a329c0648769a73afac7f9381e08fb43dbea72がそれだ。これは、”空のリカバリーフレーズ“によって生成されたウォレットだった。
このアドレスには5215以上のETHが転送されてきた形跡があり、2017年3月から継続してトランザクションが記録されている。これは実装のミス(空のフレーズを許可してしまった)かもしれないし、ユーザーの怠慢かもしれない。
無法者(Blockchain Bandit)
ISEの調査によって、ウォレットアドレス0x957cd4ff9b3894fc78b5134a8dc72b032ffbc464は、他にも漏洩した秘密鍵のアドレスから資金を集めていた形跡が確認されている。個人なのか組織なのかは定かではないが、トランザクションからは2016年から継続的に収集されていること、約1年前に送出トランザクションが記録されているので、少なくともその時点までは活動していたということが分かる。
ISEはさらに、どれくらいのペースで略奪が行われているかを確認するため、”弱い鍵”のアドレスのうち、0x4C636a08FDF3692A9bCa111e8a7F4A0E28Eb4457 に少額のETHを送信した。結果、受理されてから実に13秒後には転送のトランザクションが記録され、資金は0x957cd4ff9b3894fc78b5134a8dc72b032ffbc464へ転送されてしまった。
永久に失われたトークン
一方で、永久に失われてしまったものもある。0xdcc703c0e500b653ca82273b7bfad8045d85a470 と 0x0000000000000000000000000000000000000000だ。それぞれ815ETHと7658ETH、それに加えてトークンもあり、かなりの金額が格納されている。
前者は秘密鍵として空の文字列を入れてしまったために生成されたアドレス、後者は単純に送信先の指定ミスだろう。最初に説明したように、公開鍵やウォレットアドレスから秘密鍵を推測することはできない仕組みになっている上、総当たりで計算することも困難だ。
secp256k1は、量子耐性までは考慮されていないため、今後量子コンピュータによって計算できてしまう可能性はゼロではないが、その前にイーサリアムの仕組み自体がハードフォークで変わってしまう可能性が高いだろう。
最後に
“弱い鍵”のアドレスを巡回し、その資金をかすめ取っていく手口から、ISEは”Blockchain Bandit“という言葉を生み出した。そして、国家単位での関与も疑われていることから、このようなハッキングキャンペーン、一連の活動は今後も絶えないだろう。また、イーサリアムのみならず、ビットコイン、リップル、イーサリアム・クラシックいった他の実装においても、同じ問題が発生している可能性は高いと言える。
坪 和樹
Twitter:https://twitter.com/TSB_KZK
Linkedin:https://www.linkedin.com/in/tsubo/
プロフィール:AWSで働くエンジニア、アイルランド在住。MtGoxやThe DAO では被害を受けたが、ブロックチェーンのセキュリティに興味を持ち続けている。セキュリティカンファレンスでの講演、OWASP Japanの運営協力やMini Hardeningといったイベント立ち上げなど、コミュニティ活動も実績あり。