サプライチェーン攻撃:ソフトウェアサプライチェーンを攻撃から守るための6つのステップ

この記事ではソフトウェアサプライチェーン攻撃について考察し、ソフトウェアサプライチェーン攻撃とは具体的にどういうものか、そしてソフトウェアサプライチェーンを攻撃から守り、攻撃の影響を軽減するために実行すべき6つのステップについて解説します。

ソフトウェアサプライチェーン攻撃に関する記事は以下も併せてお読みください。

Supply Chain Attacks: 6 Steps to protect your software supply chain

この記事はGitGuardian社のブログを翻訳したものです。

原題:Supply Chain Attacks: 6 Steps to protect your software supply chain

https://blog.gitguardian.com/supply-chain-attack-6-steps-to-harden-your-supply-chain/

この数年で、ソフトウェアサプライチェーン攻撃の件数は大幅に増加しています。

ところでサプライチェーン攻撃とは何でしょうか?

サプライチェーン攻撃とはサイバーセキュリティ攻撃の一種で、攻撃者が悪意のあるコードやプログラムの構成要素(「コンポーネント」)を信頼されたソフトウェアあるいはハードウェアに忍び込ませるタイプの攻撃のことをいいます。攻撃の目的は、攻撃を受けたコンポーネントの「下流」にある組織への侵入です。最近のサプライチェーン攻撃はハードウェアに対する不正アクセスに偏り気味ですが、著名な攻撃事例を見る限り、矛先がソフトウェアに移ってきているように感じています。この記事では、ソフトウェア関連のサプライチェーン攻撃について考察し、最近の事例を参考に、このような攻撃から身を守るために企業にできることについてみていこうと思います。

“攻撃者が悪意のあるコードあるいはコンポーネントを信頼されたソフトウェアあるいはハードウェアに忍び込ませる手法”

ソフトウェアサプライチェーン

ソフトウェアサプライチェーン攻撃を理解するには、最近のアプリケーションは一枚岩的な構造ではなく、様々な要素が複雑に入り組んで構成されているという事実を知っておく必要があります。

つまり、最近のアプリケーションは、オープンソースのライブラリやパッケージ、SaaSツール、デプロイシステム、クラウドインフラ等、いくつもの構成要素で構築されているのです。

こうした構成要素は、さらに多くの構成要素でできているため、事態は一層複雑です。たとえばこれを「層」という概念で考えてみた場合、ソフトウェアとは、互いに依存関係を持つコンポーネントがCPUの命令セットに到達するまで折り重なった無数の層と考えることができます。開発者がよく耳にするフレーズに「亀の下はずっと亀」という言い回しがあります。これは、亀を支える亀の下には無限に亀が続くという無限後退を表す表現ですが、これをソフトウェアに置き換えると、ソフトウェアサプライチェーンがらみの際限無きスコープ問題の具現化ということになります。私たちがソフトウェアサプライチェーンで直面している問題の一部です。

「亀の下はずっと亀」

“世界は互いにつながり、そのつながりは日ごとに増しています。しかし、セキュリティにおいて、私たちはその逆の動きをしているのです”

―エリック・ドア(Black Hat 2019)

サプライチェーン攻撃を憂慮すべき理由。それは、サプライチェーン攻撃に対して組織はしばしば無力であるという現実です。

ソースコードは管理できている。自社が選んだコンポーネント(プログラムの構成部品)についてもある程度の管理はできている。
しかし、自社以外が選んだコンポーネントやツールのコントロールはほぼ不可能です。100%セキュアあるいは「ハッキング不可」は無理ということはわかっている。だからこそ、ソフトウェアサプライチェーン内の構成要素にあり得ないほどの注意を払っているのに、それでもサプライチェーン攻撃のリスクを取り除くことはできません。

ただし、軽減はできます。そのため、この記事では、こうした攻撃のリスクと被害の両方を軽減するために取るべき6つのステップについて考察していこうと思います。 以下は、サプライチェーンに複数存在するアタックサーフェス(攻撃対象領域)事例です:

サプライチェーンに複数存在するアタックサーフェス事例

“私たちは皆、攻撃耐性が万全なサプライチェーンに頼り切っていますが、現実にそんなものは存在しないのです”

―ジェフ・モス(Black Hat 2021)

最近のサプライチェーン攻撃事例

組織に侵入する足掛かりとして様々なコンポーネントを狙ったソフトウェアサプライチェーン攻撃には非常に多くの種類があります。今回は、こうした種類の中から最近の攻撃事例3件を取り上げ、考察していこうと思います。

SolarWinds – 特権アクセスによる信頼されたアクセス経由の攻撃

SolarWindsのサプライチェーン攻撃

サプライチェーン攻撃について記事を書くのであれば、SolarWinds攻撃に触れないわけにはいきません。SolarWindsは、サプライチェーン攻撃がもたらす危険性の象徴的存在となっています。SolarWindsのケースでは、攻撃に権限昇格で監視を行うITインフラが使われました。この攻撃は史上最悪レベルのシナリオと言われています。攻撃を受けたシステムが軍組織や政府組織といった注目度の高い組織内のシステムであったというだけでなく、ソフトウェアにインストール先のネットワークの管理者レベルのアクセス権があったというのがその理由です。SolarWinds Orionと呼ばれるターゲットは2019年9月には不正アクセスを受けていました。エクスプロイトのテスト用に攻撃者により使用されたコードの最初の痕跡は2019年10月です。その後、2020年2月にSunburstと呼ばれる悪意のあるコードがOrionに投入され、3月には18,000件のユーザーへの拡散が始まりました。

このOrionコードからのSunburst攻撃では、SolarWindsの顧客にバックドアが仕込まれました。被害を受けた顧客には、国土安全保障、商務省、財務省、FireEye、マイクロソフト、Intel、Cisco、Deloitteといった組織があります。

SolarWindsソフトウェアを標的としてセキュリティ上の欠陥を悪用することで(これについては今現在も議論中ですが)、攻撃者は世界で最もセキュリティの厳しい組織への侵入に成功しました。被害にあった組織の多くは「侵入不可」(有能なセキュリティ専門家であれば「不可能」と言うレベル)あるいは少なくとも最先端のセキュリティ対策が行われていたとされる組織です。しかし、攻撃者は特権アクセスできるサプライチェーンの一部を悪用することでセキュリティを突破し、侵入不可と言われていた組織に侵入し、かなりの期間検出を免れていました。

Codecov – ソフトウェアのデプロイとテストツールを使った攻撃

CodeCovサプライチェーン攻撃

次は、ソフトウェアのデプロイツール、具体的にはCI/CD環境を狙った攻撃を見てみましょう。CI/CD(継続的インテグレーション/継続的デプロイ)パイプラインをご存じなければ、ソフトウェアを自動でテストし、自動でデプロイするプロセスのようなものと思ってください。CI/CDはソフトウェアサプライチェーンの根幹となるもので、ソフトウェアのテストに複数のツールを使用している組織であれば、コードリポジトリの運用ブランチに新しいコードがプッシュされるたびに発生するプロセスです。

こうしたツールの一つで、特にユーザー数が多いのがCodecovです。Codecovは、CI環境内でアプリケーションのどれくらいの部分がテストされているかを可視化するコードカバレッジツールです。このツールは、CI環境で使われるため、アプリケーションがテストに使用する機密情報(シークレット)にアクセスします。つまり、アプリケーションのテストのために、データベースやサードパーティーサービス、コードリポジトリにアクセスする必要があるというわけです。

Codecovの事例の場合、攻撃者はまずCodecovのプライベートコードリポジトリに侵入し、ソースコードに不正なコードを挿入しました。この不正なコードはたった一行で、動作は非常にシンプル。CI環境のシークレット(gitトークン等)を抜き出し、攻撃者のリモートサーバーに送信する働きをします。シンプルにいうと、アプリケーションのビルドやテストに使用する認証情報を攻撃者に受け渡すということになります。こうすることで、攻撃者はTwilio Rapid7やHashiCorp、Monday.comといった多くのCodecovユーザーのプライベートコードリポジトリにアクセスし、こうしたユーザーのソースコードに不正なコードを組み込むことが可能になります。プライベートコードリポジトリは、シークレットのような機密情報が保管されていることが多く、攻撃者にとって格好の攻撃対象となっています。攻撃者が、正規のアクセス権を持つ攻撃者が、自らのトークンを使って不正なコードを埋め込むこともあります。 Codecov攻撃の詳細については、こちら(英語)を参照してください。

EventStream – ソフトウェアの依存関係を利用した攻撃

オープンソースの依存関係を利用したサプライチェーン攻撃

最後の事例では、オープンソースの依存関係についてみていくことにします。最近のソフトウェアアプリケーションはほぼすべてオープンソースの依存関係を持つといっても過言ではありません。Synopsysの調査によると、最新アプリケーションの91%が実際にオープンソースコードであるとの結果が出ています。オープンソースコードを使えるということは、エンジニアにとっては非常にありがたい状況です。なぜなら、開発するアプリケーションごとにコンポーネントを設計しなおす必要がなく、その分、固有の価値に専念することができるからです。


攻撃者が下流の依存関係を攻撃できるということは、「初期アクセス」という重要ステップを達成できるということです。このよい例が、EventStreamに対する攻撃です。このパッケージは、Node.jsでのストリームの実装を容易にするツールキットで、非常に人気が高く何百万というアプリケーションで使用されている人気のパッケージです。ただし、このEventStreamには、FlatMapというモジュールを含む依存関係がありました。この事例の場合、攻撃者はFlatMapのメンテナンスを引き受け、最終的にこのオープンソースモジュールの所有者となりました。その後、FlatMapに悪意のあるコードを忍ばせ、このモジュールは下流のユーザーを標的とした武器になりました。さらに、このモジュールにはEventStreamへのバックドアが仕込まれ、最終的にEventStreamユーザーにも拡散することになりました。つまり、この攻撃者は、依存関係のそのまた依存関係を攻撃することでターゲットへのアクセスを可能にしたのです。

サプライチェーン攻撃を回避するには

ここまで、サプライチェーン攻撃の手法をいくつか見てきたところで、サプライチェーンの体制を強化し、また自社を攻撃から守るためにどうすればよいかについてみていくことにしましょう。この手の攻撃の難しいところは、自身を守る行動はできても、それ以外に対しては無力であるということです。

アプリケーションでは信頼された依存関係のみを使用する

アプリケーションで使用するソフトウェアコンポーネント(依存関係)を選ぶときは、必ず以下の条件を満たすソフトウェアを使用してください:

アップデートが継続的に記録され、管理状態が良好であること。これにより、脆弱性が見つかった場合、効果的なリサーチと修正プログラムの更新が可能です。また、悪意のあるコードを埋め込もうとする質の悪い管理者というリスクも軽減されます。

スペルミスがないこと!人気のオープンソースコードのタイプミスを狙ったタイポスクワッティング攻撃という攻撃があります。通常、タイポスクワッティング攻撃で使われるモジュールは本物と同じ動作をするため、疑いをもたれることはありません。ただし、悪意のあるコードというおまけがついてきます。

オープンソースソフトウェアは既知の脆弱性がないかスキャンする

Open Source ScanningやSnyk、WhiteSourceといったOSSソフトウェアは、サプライチェーンを強化する上で基本中の基本です。こうしたソフトウェアは、パッケージで使われている依存関係を検索し、脆弱性なパッケージやバージョンのデータベースに照らし合わせて、アプリケーションに既知の脆弱性が存在しないか確認してくれます。依存関係に既知の脆弱性(特に重大と分類されたもの)がある場合は、パッケージを安全な最新バージョンに自動でアップデートすることもできます。ただし、アップデートが提供されていない場合、そのソフトウェアはメンテナンスされていないというサインでもあるため、別のモジュールあるいはパッケージを使用することを強く推奨します。

よく考えてから修正プログラムを適用する(即時ではなく規則正しく)

セキュリティに関する記事を読んだことがあれば、システムを定期的にアップデートするあるいは更新プログラムを適用すべしという情報を見たことがあるでしょう。もちろん、その通りです。既知の脆弱性がもはや脅威ではないという安心を得るためには最新バージョンが必要です。ただし、だからといって、即座にアップデートすればいいというわけではありません。矛盾しているようにも思えますが、ここまで見てきた過去事例を見ていると、慌ててアップデートするようなことがなければ、被害にあうことはなかった可能性があるという共通点があるのです。画面の前の怒鳴り声が聞こえてきそうなのでこのへんでやめておきますが、私は何も修正プログラムを適用しないことやランダムな適用を提唱しているわけではありません。一考が必要といっているのです。

Snykのデベロッパーアドボケイトを務めるLiran Talによると、脆弱性は発見、報告、修正プログラムの適用までに60日ほどかかるということである。

このことは、上で紹介した事例とも一致します。この点を念頭に、ソフトウェアサプライチェーンを構成する依存システムにセキュリティ上の欠陥が見つかった場合に速やかに最新バージョンにアップデートする、そうでなければ一定の待機期間を設けるといった「賢い」修正プログラム適用ポリシーの策定を推奨します。

ネットワークをセグメント化する

サプライチェーン攻撃で組織に侵入した攻撃者は、さっさとネットワークの別のエリアに移動したいと考えるはずです。ネットワークのセグメント化は、攻撃の際の「被害領域」を限定する効果的な手段であり、規模の大きいネットワークを、相互接続を制限したより小規模なサブネットワークに分割する手法のことをいいます。ネットワークのセグメント化は、サブネットワーク間のトラフィックフローを管理し、攻撃者の水平移動を制限することで、不正なユーザーによる組織データへのアクセスを回避できます。セグメント化の方法には以下のようものがあります:

VLANによるネットワークのセグメント化:この場合、分割にIPアドレスを使用し、VLANまたはサブネットでネットワーク内にセグメントを構築します。

ファイアウォールによるセグメント化:ネットワークセグメント内にファイアウォールを設置すると、攻撃対象領域を制限できます。ただし、この方法では、何千単位のファイアウォールルールが必要になるため、システム側の複雑さとコストが増大します。

SDN(Software Defined Network:ソフトウェア定義のネットワーク)を使ったセグメント化:SDN利用のネットワークのセグメント化は、オートメーションやプログラミングとの相性が抜群です。ただし、セキュリティの可視化という点はあまり配慮されておらず、どちらかというとネットワークポリシーの実装に主眼が置かれています。

マイクロセグメンテーション:この方法では、ネットワークセグメントの実行にホストのワークロードを、許可されたもの以外の全トラフィックのブロックにホワイとリストモデルを使用します。

高度な認証と最小権限の実装

セキュリティには「ゼロトラスト」という考え方があります。認証情報があるからといって、それを信頼するものではないという考え方です。たとえば、多要素認証の使用と、システムへのアクセスが可能なIPアドレスの制限等が具体例として挙げられます。

サプライチェーン攻撃の場合、攻撃者の最終的な信頼の「量」を制限し、攻撃者の動きを止めることのできる、ゼロトラストの考え方に基づく強力な認証を実装する必要があります。 また、最小限のアクセスという原則を徹底することも重要です。つまり、ユーザーもそしてサービスも、追加のデータやサービスへのアクセス権限は最小にするという考え方です。
攻撃者は信頼されたシステムから攻撃を開始することがあるため、ゼロトラストの原則をもってしても、そうした攻撃を検出・阻止することはできません。ただし、攻撃者がアクセスできる情報量を制限することは可能です。

リポジトリにシークレット(認証情報)を保管しない

サプライチェーン攻撃でコードリポジトリやバックアップサーバーをターゲットにするのは、もはや定番となっています。gitリポジトリが標的となったCodecovのケースがこれに該当します。自身の正当性を証明し、組織に奥深く侵入したい攻撃者にとって、gitリポジトリはパーフェクトな「初期アクセス」ポイントです。こうしたシステムには、攻撃者に使われる可能性のある機密情報を保管しないようにする必要があります。Gitに保管されたシークレットが問題になる理由については、こちらをご覧ください。

確実に言えるのは、どれだけ注意を払い、ベストプラクティスを実践したとしても、サプライチェーン攻撃を確実に阻止することはできないということです。だからこそ、攻撃者に少しでも隙を与えるようなことがあってはいけません。GitGuardianのようなシークレットスキャンツールを使用することも重要です。こうしたツールは、リポジトリ上で過去データを含む履歴のフルスキャンを実行し、さらにリアルタイムスキャンを継続的に実行して、リポジトリに放置されているシークレットを一掃します。

まとめ

このところ、サプライチェーン攻撃は劇的に増えています。確実に言えるのは、そうした攻撃から免れることのできる人はいないということです。アプリケーションの構築に使われる分散型アーキテクチャは、攻撃者にとって何百あるいは何千もの組織を一度に標的にできる格好の機会となります。このような変化は、攻撃者の経済状況を一変し、かなりのリソースを個々の企業を標的とした攻撃ではなくサプライチェーン攻撃に投じることが可能になっています。

サプライチェーン攻撃において被害者になるというリスクを回避することは不可能ですが、何らかのベストプラクティスを実践することで、被害者となるリスクと攻撃発生時の潜在的な被害リスクの両方とも軽減することができるのです。