前言#
この記事は、今年の USENIX で発表された php デブローティングに関する記事の前置き(略して LIM、Less is More)です。
profiles:設定、シナリオ;profilling:分析(性能分析、行動分析など);profiler:分析器
bloat:膨張;debloat:去膨張
ambient authority: 環境権限は、システムアクセス制御研究における用語です。主体が必要な対象の名前と、その対象に対して実行するアクションを指定すると、そのアクションを完了できる場合、主体は環境権限を使用していると呼ばれます。
monkey testing: モンキー テストは、ユーザーがランダムな入力を提供し、動作を確認したり、アプリケーションやシステムがクラッシュするかどうかを確認することでアプリケーションやシステムをテストする技術です。モンキー テストは通常、ランダムな自動化ユニット テストとして実装されます。
Overview of paper#
この記事では、動的分析を利用して php ウェブアプリケーションのコードカバレッジを取得し、未使用のコードを削除して去膨張を達成します。
概括すると、以下のいくつかの部分があります:
- CVE 脆弱性を選択し、ウェブアプリにマッピングする
- 4 つの異なるユーザーセットを選択し、アプリの使用をシミュレートする
- コードカバレッジを記録し、未使用のファイル / 関数を分析する
- カバレッジに基づいてデブロートし、デブロートされたアプリを得る(主にファイルレベルのデブローティングと関数レベルのデブローティング)
- デブロートされたアプリの通常の使用シミュレーションを行い、機能が正常であるかどうかを評価する
- デブロートされたアプリと元のアプリを同時に既知の CVE でエクスプロイトし、デブローティングの効果を評価する(つまり、デブローティングが脆弱性を引き起こす重要なコードを削除したかどうか)、およびその他の評価と比較
ここには Figure 1 があり、誤字 Expoits があります。
background#
ソフトウェアデブローティングの原理は、オペレーティングシステム(Linux カーネルから不要なコードを削除)、共有ライブラリ、およびコンパイルされたバイナリアプリケーションで成功しています。
この記事では、ウェブアプリでのデブローティングの適用性を評価し、脆弱性を引き起こす重要なコードを削除できるかどうかを確認します。
web debloating の motivation#
著者は Symfony の CVE-2018-14773 を使用して説明します。
このフレームワークは、悪用を引き起こす可能性のあるレガシー IIS ヘッダーをサポートしています。サーバーがそのヘッダーを使用する必要がない場合、関連するサポートコードを削除できます。つまり、デブローティングです。
目標 php ウェブアプリ#
- phpmyadmin:データベース管理
- wordpress:ブログ管理
- mediawiki:ウィキ管理
- magento:e コマース管理
脆弱性マッピング至ソースコード#
各ウェブアプリは CVSS スコアに基づいて最もクリティカルな 20 の CVE を選択し、すべて 2013 年以降の CVE です。
異なる CVE の影響を受けるバージョンが異なるため、これらの CVE をすべて適用するためには、複数のバージョンにまたがって脆弱性をマッピングする必要があります(下表参照)。
各 CVE が影響を与えるバージョンと行番号はデータベースに記録されています。
Web Application | Version | Known CVEs(≥2013) |
---|---|---|
Magento | 1.9.0, 2.0.5 | 10 |
MediaWiki | 1.19.1, 1.21.1, 1.24.0, 1.28.0 | 111 |
phpMyAdmin | 4.0.0, 4.4.0, 4.6.0, 4.7.0 | 130 |
WordPress | 3.9.0, 4.0, 4.2.3, 4.6, 4.7, 4.7.1 | 131 |
ウェブアプリ使用シミュレーション#
アプリの使用をシミュレートするために、できるだけ広範囲かつ深い機能カバレッジ、つまりコードカバレッジを達成するための 4 つの方法があります。
- 一般的なチュートリアル(selenium スクリプトを使用)
- モンキー テスト
- クローラー
- 脆弱性スキャン
ウェブアプリコードカバレッジの記録#
php 分析器は php 拡張として提供され、原理は php エンジンを変更してコードカバレッジを収集することです。文中で使用されているのは XDebug です。
直接的な考えは、xdebug_start_code_coverage()
とxdebug_get_code_coverage()
を各 php ファイルの末尾に追加することですが、著者はいくつかの困難に直面しました。
任意の php ファイルがexit()
またはdie()
を呼び出して早期に終了できるため、上記の 2 つの記録関数を終了関数の前に追加する必要があります。
次に、シャットダウン関数を登録し、それをシャットダウン関数キューの末尾に追加する必要があります。
最後に、デストラクタです。クラスがシャットダウン関数の後に破棄される場合、この部分はカバーされません。そのため、実行時に自分自身を登録するようにデストラクタをオーバーライドしました。
デブローティング戦略#
- ファイルレベルのデブロート:実行されていない php ファイルを削除する
- 関数レベルのデブロート:ファイルレベルよりも細かい粒度のデブロートで、関数内の未実行のコードブロックを削除できます。
ここでのデブローティングは、コードを完全に削除するのではなく、プレースホルダーに置き換えることです。コードがこれらのプレースホルダーに到達すると、プログラムは終了し、関連する欠落関数の情報を記録します。
その後、この方法が非常に効果的であることが証明され、多くの削除すべきでないファイル / 関数が記録されました。
実験結果#
コード数の測定基準は単純なコード行数ではなく、Logical Lines Of Code(LLOC)であり、コメント、空行、必要な構文構造などの行数は含まれません。
明らかに、関数レベルのデブローティングはファイルレベルのデブローティングよりも多くのコードを削減しますが、これは 4 つの異なるプロジェクトのコード実践スタイルにも関連しています(たとえば、wordpress は外部パッケージにあまり依存せず、magento と mediawiki はよりモジュール化された方法で開発されています)。
- サイクル複雑度の減少
サイクル複雑度(Cyclomatic complexity、CC)は条件複雑度とも呼ばれ、独立したパスの数として表され、すべての可能な状況をカバーするために必要な最小のテストケースの数と理解できます。
大三のソフトウェア工学の授業でこの概念を学んだことを発見しました。
デブロートプロセス中に、サイクル複雑度も低下し、アプリケーションのデブロート方法が複雑な命令や実行パスを削除できることを示しています。
- デブローティング後の CVE の減少
結果として、38% の脆弱性はファイルレベルのデブローティングによって削除でき、10%〜60% は関数レベルのデブローティングによって削除されました(外部ライブラリが多い phpmyadmin と magento と比較して、より単純な wordpress は 2 つの極端です)。
注意:ここで本文が考える脆弱性がデブロートされたかどうかのルールは、元々ある脆弱性の利用がカバーするすべてのファイル / 関数が削除されることであり、単にその一部を削除することではありません(ほとんどの場合、これにより利用チェーンが破壊され、脆弱性が実際には利用できなくなります)。
この部分で著者がデブローティングがどのように前述の 4 つのシナリオに基づいて具体的なルールを持っているかについては、あまり明確に述べていないと思います。
2 つの状況があり、一つは正常な使用で、脆弱性を引き起こさない(チュートリアルなど)、もう一つは意図的に脆弱性を利用する(脆弱性スキャンなど)か、アプリケーションを異常な状態にするものであり、モンキー テストは同時に 2 つの状況を生み出します。
私は以下のルールに基づいてデブローティングが行われると仮定します:
- プログラムが正常に動作することを保証し、機能性と脆弱性を引き起こす可能性の衝突の中で機能性を優先する。
- 正常な使用によってカバーされているファイル / 関数以外のコードを削除する。
- 悪意のある利用がカバーするパスと正常な使用がカバーするパスが部分的に重複している場合、非重複部分は削除され、重複部分は最初のルールの要件を満たすために保持される。
要するに、正常な使用によってカバーされていないコードを削除する必要があります。
- 異なる脆弱性タイプの影響
異なる脆弱性タイプのデブロートの程度も異なります。たとえば、コマンド実行や SQL インジェクションなどの脆弱性はデブロートしやすい(通常はあまり使用されないモジュールに存在します)が、crypto や cookie 関連の脆弱性はデブロートしにくい(主要な暗号化関数に存在し、削除できないコアコンポーネントに属します)。
- POI 脆弱性のチェック
POI、すなわち PHP オブジェクトインジェクションは、CTF では PHP 逆シリアル化脆弱性です。
著者は PHPGGC を使用し、POP 利用チェーンを生成するツールを使用してデブロートされたアプリのエクスプロイトを行いました。
結果は、関数レベルのデブローティングが PHPGGC に存在するすべての利用チェーンに対応する脆弱性を成功裏に削除したことを示しています(wordpress は外部ソフトウェアパッケージに依存していないため、ここには含まれません)。
- dev パッケージの不適切な導入
composer はデフォルトで外部ソフトウェアを vendor ディレクトリに配置します。このディレクトリがサーバーの誤った設定によってアクセス可能である場合、RCE を行うために利用される可能性があります(たとえば、PHPUnit)。
実験結果は、phpmyadmin と magento にこの問題が存在することを示しています。
- 削除されたコードの定性的分析
削除されたファイルとコードが多すぎるため、この記事では k-means クラスタリングアルゴリズムを使用してファイルグループを生成し、TFIDF 最大頻度制限を使用して 50% 以上のファイルパスに出現する共通部分を無視します。
- デブロートされたアプリのエクスプロイトテスト
最後に、著者は metasploit フレームワークに存在する 4 つの php ウェブアプリに対する CVE を収集し、公開された脆弱性情報に基づいて POC を作成しました。
元のバージョンのウェブアプリがすべて成功裏に利用できることを確認した後、デブロートされたバージョンをテストしたところ、半分が失敗しました(8 のうち 4)。
この結果は、デブローティングがウェブアプリのセキュリティにおいて万能ではないものの、効果的であることを示しています。
性能分析#
コードカバレッジツールは性能にオーバーヘッドを追加するため、本節では XDebug ツールのオーバーヘッド分析を行います。つまり、selenium スクリプトが XDebug ありとなしで比較されます。
結果は、4 つのウェブアプリのオーバーヘッドが実行時間、CPU 消費、メモリ消費のすべてで増加したことを示しています。
しかし、このオーバーヘッドはカバレッジ計算方法を改善することで削減可能であり、たとえばオフラインでカバレッジを計算するなどの方法があります。この部分の作業は今後の議論に残します。
限界と今後の作業#
前述の作業をまとめると、デブローティングは数十万行の無関係なコードを削減し、サイクル複雑度を 30%〜50% 削減し、CVE に関連する脆弱性を引き起こすコードの約半分を削除します。削除できない脆弱性に対しても、デブローティングは一部の gadgets を削除し、利用を難しくします。
著者は、この記事の作業がまだ不完全であり、以下の限界があると考えています。
- 利用可能な脆弱性の欠如
公開されている利用可能な脆弱性が不足しており、さまざまな脆弱性利用の再現や詳細説明などが欠けています。
著者は、ウェブアプリに対する自動利用スクリプト(たとえば BugBox)が不足していることにも言及しています。これにより、研究者の作業が大幅に助けられるでしょう。
- 動的コードカバレッジ
ウェブデブローティングは動的コードカバレッジ分析に大きく依存しており、4 つの再現可能で偏りのないアプリケーション使用設定があっても、ウェブアプリのすべての良性状態をカバーしているとは言えません。
要するに、カバレッジの深さが不十分であり、著者はクラウドソーシングやユーザー研究を通じてこれを追跡する予定です。
さらに、このパイプラインは特定のユーザーセットに対して不要な機能を削除するため、一般的な静的分析作業を行うことはできませんが、著者はデブローティング後のコードに基づいて静的分析作業を行い、これらのユーザーセットにとって必要な機能が依然として存在することを確認できると提案しています。
- 削除されたコードへのリクエストの処理
実際のユーザーが削除されたコードにリクエストを送信した場合、どのように処理しますか?単にアプリケーションを終了し、エラーを返すだけでは不十分です。削除されたコードを再導入し、ユーザーのリクエストを処理する必要があります。その前に、そのリクエストが悪意のあるものであるかどうかを確認する必要があります。
- デブローティングの有効性を測定する指標
この記事では、サイクル複雑度の減少、論理コード行(LLOC)の減少、CVE の減少、POP チェーンの 4 つの指標を使用してその有効性を測定しています。
しかし、各行のコードがプログラムの攻撃面に与える寄与は異なり、CVE の基準は専有ソフトウェアには適用できず、CVE は手動でマッピングして利用可能性を検証する必要があり、作業量が膨大です。
- デブローティングの効率
モジュール化アプリケーションのデブローティング効率は、単一アプリケーション(wordpress など)よりも明らかに低下します。
関連作業#
ここで著者は、多くの静的分析のデブローティング作業や、ウェブクライアントのデブローティング作業(chrome の攻撃面を減少させる)、およびカスタム php ウェブアプリの動的分析作業(この作業の限界は、削除された脆弱性の数を定量的に特定できないことです)について言及しています。
まとめ#
私自身の考えの要約は前述の Overview of paper に書かれているので、ここでは原文の要約と結論を貼り付けます。
要約
ソフトウェアがますます複雑になるにつれて、その攻撃面が拡大し、さまざまな脆弱性の悪用が可能になります。ウェブアプリケーションも例外ではなく、現代の HTML5 標準と JavaScript の能力の向上が、リッチなウェブアプリケーションの構築に利用され、しばしば従来のデスクトップアプリケーションの必要性を超えています。この増加した複雑さに対処する 1 つの方法は、ソフトウェアデブローティングのプロセスを通じて、死んだコードだけでなく、特定のユーザーセットが必要としない機能に対応するコードを削除することです。デブローティングはオペレーティングシステム、ライブラリ、およびコンパイルされたプログラムに成功裏に適用されていますが、ウェブアプリケーションへの適用性はまだ調査されていません。本論文では、ウェブアプリケーションのデブローティングのセキュリティ上の利点の最初の分析を提示します。私たちは 4 つの人気のある PHP アプリケーションに焦点を当て、それらを動的に実行して、クライアント側のリクエストの結果として実行されるサーバー側のコードに関する情報を取得します。2 つの異なるデブローティング戦略(ファイルレベルのデブローティングと関数レベルのデブローティング)を評価し、元のバージョンよりも 46% 小さく、元のサイクル複雑度の半分を示す機能的なウェブアプリケーションを生成できることを示します。さらに、私たちの結果は、デブローティングのプロセスが歴史的な脆弱性に関連するコードを削除し、不要な外部パッケージや悪用可能な PHP ガジェットを削除することによってウェブアプリケーションの攻撃面をさらに縮小することを示しています。
結論
本論文では、ソフトウェアデブローティングと呼ばれるプロセスを通じて、現代のウェブアプリケーションにおける不要なコードの削除の影響を分析しました。私たちは、PHP アプリケーションがどのように使用され、クライアント側のリクエストの結果としてどのサーバー側のコードがトリガーされるかを記録することを可能にするエンドツーエンドのモジュラー デブローティング フレームワークのパイプラインの詳細を提示しました。コードカバレッジ情報を取得した後、私たちのデブローティングフレームワークは、ファイルレベルと関数レベルのデブローティングを使用してアプリケーションの未使用部分を削除します。4 つの人気のある PHP アプリケーション(phpMyAdmin、MediaWiki、Magento、WordPress)でフレームワークを評価した結果、ウェブアプリケーションのデブローティングの明確なセキュリティ上の利点を目の当たりにしました。ファイルレベルのデブローティングで 9% から 64% の LLOC の大幅な減少を観察し、関数レベルのデブローティングでさらに 24% の減少を示しました。次に、外部パッケージがデブローティングの主な原因の 1 つであることを示しました。私たちのデブローティングフレームワークは、Composer を使用したバージョンで 84% 以上の未使用コードを削除することができました。重要な CVE に関連するコードの削除を定量化することにより、高影響の歴史的脆弱性の最大 60% の削減を観察しました。最後に、デブローティングのプロセスが攻撃者がガジェットを構築し、POI 攻撃を実行するための主要なソースである命令やクラスを削除することも示しました。私たちの結果は、ウェブアプリケーションのデブローティングが具体的なセキュリティ上の利点を提供し、したがってウェブアプリケーションのデプロイメントの攻撃面を削減する実用的な方法として真剣に考慮されるべきであることを示しています。