コインチェックからのNEM流出 発表された調査結果の疑問点
コインチェックは3月8日、同社からのNEMの流出について発生原因の調査結果を発表した。発表によると従業員の端末がマルウェアに感染し、遠隔操作ツールによってNEMのサーバー上で通信傍受を行い、NEMの秘密鍵を窃取した上で、窃取した秘密鍵を利用して外部の不審通信先にNEMを不正送金したという。調査結果の詳細をレビューしないことには分からないことも多いが、どうにも釈然としない疑問点が残る。
なぜ端末がマルウェアに感染しただけで本番システムに入れたのか
まず従業員の端末がマルウェア感染したとして、なぜ本番システムに侵入できたのだろうか。コインチェックのシステムはAmazon Web Serviceを利用しているが、AWSではシステム管理者権限を持つユーザーについて、多要素認証を使うことが推奨されている。多要素認証を導入していれば、仮に遠隔操作ツールに感染したとしても、端末利用者が端末の目の前で明示的に操作しない限りはシステムに入ることが難しい。
また社内システムや開発環境と本番システムとはネットワークを分離して、そう簡単には本番システムにはアクセスできない構成とするのが一般的である。金融系のシステムであれば業務端末や基幹システムをインターネットから分離した環境に設置するが、仮想通貨の特性上NEMウォレット・サーバー(ホットウォレット)をインターネット環境から分離できなかったことは仕方がない。その場合も外部インターネットの通信先はNEMブロックチェーンの同期に必要な最小限のIPアドレス・ポートに絞り込み、業務システムからの接続も、適切に認証認可された最小限のAPIアクセスに絞り込むべきだろう。
なぜウォレット・サーバーの秘密鍵を簡単に窃取できたか
通信傍受によってNEMの秘密鍵が漏洩したというのも不可解だ。仮にNEMウォレット・サーバーにAWSのEC2インスタンスを利用していたとして、秘密鍵を平文でネットワーク経由でやりとりする実装は考えづらい。秘密鍵を抜き取ることができないように、耐タンパー性のあるHSM(Hardware Security Module)上で保管するか、サーバー上に置かざるを得ない場合ディスク上の鍵は別の鍵で暗号化しておくか、秘密分散などの手法を用いることで簡単には抜けないように実装すべきである。
現時点でAWSのCloud HSMがNEMの利用しているEDDSA鍵形式Ed25519に対応していないことから、NEMウォレット・サーバーの鍵をHSM内に閉じ込められなかったのは仕方なかった。とはいえフラットファイルでサーバー上のファイルシステムに置くのではなく、HSMの鍵で暗号化してメモリ上でしか保持しない等の工夫はできたはずだ。秘密鍵をNEMウォレット・サーバー上で簡単に持ち出せるフラットファイルとして保持していたとしても、秘密鍵を平文でネットワークに流して傍受可能な状態にしておいたとしても、いずれにしても不適切な実装といえる。
秘密鍵の窃取よりもAPIで偽の送金指示を出す方が容易
ところで交換所のシステム構成を想定した場合に、ウォレットの秘密鍵を抜き取るよりも容易なのはウォレット・サーバーに対する出金指示のAPIアクセスを偽装することである。ウォレット・サーバーに対してAPIを通じて出金指示を出すのは、その他のAPサーバーやWebサーバーの役割となるが、これらはウォレット・サーバーと比べてノード数が多く、プログラムが複雑で、利用者からのリクエストを直接受け付けることとなるため、ウォレット・サーバーと比べてずっと防御が難しいからだ。
なぜ犯人は小出しに間隔をあけて出金したのか
1月26日の犯人による出金パターンを見ると、最初0時2分13秒に10XEMを引き出して、次いで2分43秒後の0時4分56秒から1億XEMずつ引き出している。もし仮にウォレット・サーバーの秘密鍵を抜いたのであれば、犯人は一気に全額を引き出してもおかしくなかった。秘密鍵を取得できていればウォレット上の仮想通貨を全て自由に引き出せることが技術的に自明だからである。わざわざ最初に10XEMを引き出して、次いで1億XEMを引き出したことから推察するに、犯人は一度に大きな仮想通貨を動かせない可能性を想定していたのではないだろうか。
犯人がリスク検知エンジンでの監視を意識していた可能性
決済に係る情報システムの多くは、異常な出金パターンに対してはリクエストを遮断するリスク検知エンジンを実装している。例えばクレジットカードを使ってECサイトで普段は買わないような高額なカメラを買ったり、いきなり地球の裏側で高額な買い物をしたときに決済に失敗するのは、異常を検知して取引を遮断するリスク検知エンジンが作動しているからだ。
犯人はコインチェック社のAPIゲートウェイがリスク検知エンジンで監視されていることを想定して、まずは10XEMを出金指示を行い、NEMブロックチェーン上で出金記録を見て侵入の成功を確認したところで、ウォレット残高からみた最大桁数の1億XEMで出金指示を行って、失敗したら間の額で再挑戦するつもりだったのではないだろうか。
途中から「いつ発見されるか」を意識しはじめた犯人
1億XEMの出金に成功した後も、続く4回の出金指示で1分毎の間をとっているのは、金額だけでなくAPIリクエスト頻度もリスク検知エンジンが監視していることを警戒したからではないだろうか。そして侵入から約8分後の0時10分36秒以降、犯人の関心はウォレットから全額を盗むことから、自分の行動がいつ発覚するかに移ったように見える。
出金する金額を減らしてペースを落とし、見つかったかどうか様子を見るように0時21分14秒、3時35分19秒、4時33分20秒、そして最後8時26分13秒に80万XEMを出金している。高額出金を遮断されることもなく、それから数時間が経ってもバレずに、自由に出金できることに拍子抜けした犯人の姿が目に浮かぶようだ。
秘密鍵よりも保護が難しく攻撃の容易なAPIアクセス
もし仮に今回のNEM流出の原因がウォレット・サーバーからの秘密鍵の流出ではなくて、他のノードからウォレット・サーバーに対する不正なAPIアクセスだったとしたら、乗っ取られたノードでの通信傍受やコードの解析によって、APIリクエストを偽装する方法を見つけられてしまい、不正な出金指示が作出された可能性が考えられる。このシナリオは、通信傍受によってウォレット・サーバーの秘密鍵を抜き取るよりは防ぐことが難しく、攻撃者にとっての難易度が低いと考えられる。
再発防止にはAPIの保護と出金指示の確認が必要では
コインチェック社はプレスリリースで、サービス再開に向けてネットワークの再構築に加えて、サーバーの再設計及び再構築、端末のセキュリティー強化、セキュリティー監視、仮想通貨の入出金等の安全性の検証を行うとしている。仮にAPIアクセスを偽装されてウォレット・サーバーに対して不正な出金指示が行われたのだとしたら、サーバーの再設計にあたっては、下記の点に留意する必要があるだろう。
まず不正なAPIリクエストが難しくなるようにシステム内部のAPIの認証認可方式を見直して、通信傍受によるAPIキーの推定や、不正なAPIアクセスから保護する必要がある。さらに正当なAPIリクエストをそのまま通すのではなく、リスク検知エンジンを挟むことで異常なパターンの出金を遮断した方が良い。そして特にリスクの高い金額の出金指示の処理に当たっては、金融機関と同様に人間によるチェックを介在させることも検討した方がいいのではないだろうか。
事件を教訓とすべく業界全体の再発防止に資する情報開示を
残念なことに2014年のMtGOX事件に続いて、再び日本で世界最大規模の仮想通貨流出事件が起きてしまった。いまにして反省すれば、私たちはいまだにMtGOX事件についての詳細を知らず、教訓を得られていない。幸いコインチェックはセキュリティーを改善して、業務を再開しようとしている。利用者と国際社会からの信頼を取り戻して、業界全体のセキュリティー水準の底上げを図るためにも、業務の再開に当たっては事件の詳細と再発防止策について、外部から検証できるレベルで明らかにされることを期待したい。
謝辞:この記事は3月1日に行われたサイバーセキュリティシンポジウム道後 2018のナイトセッションで行った議論を参考にさせていただきました。また本日19時から行われるゲンロンカフェのイベント「仮想通貨と人工知能――技術は経済を変えるのか?」で詳しく解説させていただく予定です。
訂正履歴:3月10日11時半、読みやすいように見出しを追加し、「取引所」を「交換所」と修正しました。