0x00 はじめに
中国では公開されている PHP 自動監査技術資料がほとんどありません。これとは対照的に、海外では比較的優れた自動監査実装が登場しています。たとえば、RIPS はトークン フローに基づいて一連のコード分析を実行します。データフロー分析や汚染伝播分析などの従来の静的分析手法は、PHPなどの動的スクリプト言語分析に適用されることは比較的まれですが、ホワイトボックス自動化技術を実現する上で重要な技術ポイントです。本日は、国内のセキュリティ研究者がより多くのPHP自動監査技術の有意義な分野に力を注いでくれることを願って、最近の研究と実装の成果を中心に紹介します。
0x01 基本知識
自動監査を実装するには、位置決めと照合に正規表現ルール ライブラリを直接使用するなど、さまざまな方法があります。この方法は最も単純ですが、精度は最も低くなります。最も信頼できるアイデアは、静的解析技術の分野の知識に基づいて設計することです。一般に、静的解析セキュリティ ツールのプロセスは、次の図の形式になることがほとんどです。
静的分析で最初に行うことは、ソース コードをモデル化することです。平たく言えば、文字列のソース コードを、その後の脆弱性分析に便利な中間表現、つまり一連のデータ構造に変換することです。このコードを表します。コンパイル テクノロジの分野のメソッドは、一般に、トークン、抽象構文ツリー、制御フローチャートを生成するための字句解析などのモデリング作業に使用されます。モデリング作業の品質は、その後の汚染伝播分析とデータ フロー分析の結果に直接影響します。
実行分析では、セキュリティの知識を組み合わせて、読み込まれたコードの脆弱性を分析および処理します。最後に、静的解析ツールが判定結果を生成して、この段階の作業は終了します。
0x02 実装アイデア
一定期間の苦労の末、著者と私の友人たちは自動化のための静的解析ツールを大まかに実装しました。具体的な実装アイデアは静的解析技術を使用しています。実装アイデアを詳しく知りたい場合は、以前に公開された記事を参照してください。
このツールでは、自動監査プロセスは次のとおりです。2 番目に、グローバル データを収集します。収集される重要な情報は、クラスが配置されているファイル パス、クラスの属性、クラスのメソッドとパラメーターなど、スキャン対象のプロジェクト内のクラス情報の定義です。およびその他の情報。同時に、ファイルごとにファイル概要が生成されます。このファイル概要は、各代入ステートメントの情報と、代入ステートメント内の関連する変数の精製情報およびエンコード情報の収集に重点を置いています。
- グローバル初期化後、フロントエンド モジュールのコンパイルに関連する作業を実行し、オープン ソース ツール PHP-Parser を使用して、分析する PHP コードの抽象構文ツリー (AST) を構築します。 AST に基づいて、CFG 構築アルゴリズムを使用して制御フロー グラフを構築し、基本ブロックの概要情報をリアルタイムで生成します。
- フロントエンドのコンパイル中に、機密関数への呼び出しが見つかった場合は、停止して汚染伝播分析を実行し、プロセス間分析とプロセス内分析を実行して、対応する汚染されたデータを見つけます。そして、データフロー解析処理で収集した情報をもとに、精製された情報と暗号化された情報を判定し、脆弱なコードであるかどうかを判定します。
- 前のステップが脆弱なコードである場合は、脆弱性レポート モジュールに移行して、脆弱なコード セグメントを収集します。その実装の基本は、システム環境でシングルトン モードの結果セット コンテキスト オブジェクトを維持することです。脆弱性レコードが生成されると、それが結果セットに追加されます。スキャン プロジェクト全体の結果が得られた後、Smarty を使用して結果セットをフロント エンドに出力し、フロント エンドでスキャン結果を視覚化します。
- 0x03 初期化作業
実際の PHP 監査では、次のような
mysql_query
,我们就会不由自主地去手动分析第一个参数,看是否可控。事实上,很多CMS都会将一些数据库查询的方法进行封装,使得调用方便且程序逻辑清晰,比如封装为一个类MysqlDB。这时,在审计中我们就不会搜索mysql_query
关键字了,而是去找比如db->getOne
呼び出しなどの機密関数の呼び出しに遭遇しました。
そこで問題は、自動プログラムが分析しているときに、db->getOne 関数がデータベース アクセス クラス メソッドであることをどのようにして知るかということです。
これには、自動分析の初期段階でプロジェクト全体のすべてのクラスと定義されたメソッドを収集し、プログラムが分析中にフォローアップする必要があるメソッド本体を見つけられるようにする必要があります。
クラス情報とメソッド情報の収集は、フレームワークの初期化の一部として完了し、シングルトン コンテキストに保存する必要があります:
同時に、分析された PHP ファイルが実際にユーザーリクエストを処理するファイルであるかどうかを識別する必要があります。これは、一部の CMS では、カプセル化されたクラスが通常、データベース操作クラスやファイルにカプセル化されたファイル操作クラスなど、別のファイルに書き込まれるためです。 。これらのファイルについては汚染伝播解析を行っても意味がないので、フレームワークの初期化時に識別する必要があり、呼び出し型文と定義型文の割合を解析し、閾値に基づいて判定するだけです。エラー率は非常に小さいです。
最後に、各ファイルに対して要約操作を実行します。このステップの目的は、後続の分析中に require、include などのステートメントが見つかったときにファイル間分析を実行することです。主に変数の代入、変数のエンコード、変数の精製に関する情報を収集します。0x04 ユーザー関数の処理
一般的な Web 脆弱性は、一般に、ユーザーが制御可能な危険なパラメーターによって引き起こされます。この種の脆弱性は、一般的な SQLI、XSS などの汚染タイプの脆弱性と呼ばれます。
PHP の組み込み関数の中には、反射 XSS を引き起こす可能性があるエコーなど、本質的に危険なものもあります。ただし、実際のコードでは、一部の組み込み関数を直接呼び出す人はいません。次のようなカスタム関数として再カプセル化します。<code><span><span>function</span><span>myexec</span><span>(<span>$cmd</span>)</span> {</span> exec(<span>$cmd</span>) ; }</code>ログイン後にコピー実装では、処理フローは次のとおりです。
- 初期化の使用 コンテキスト情報の取得対応するメソッド コード セグメントを見つけます
- このコード スニペットを分析して危険な関数 (ここでは exec) を見つけます
- 危険な関数内の危険なパラメーターを見つけます (ここでは cmd)
- 分析中にこの問題に遭遇しなかった場合このパラメーターが感染している可能性があることを示す浄化情報が取得され、ユーザー関数 myexec の最初のパラメーター cmd にマッピングされ、このユーザー定義関数は危険な関数としてコンテキスト構造に保存されます
- 再帰的に開始に戻ります汚染分析プロセス
一言でまとめると、対応するクラスメソッド、静的メソッド、関数に従い、これらのコードセグメントから危険な関数や危険なパラメーターへの呼び出しがないかどうかを確認します。 PHP に組み込まれているパラメータの場所は、設定ファイル内で設定が完了しており、これらの関数とパラメータが検出され、危険なパラメータがフィルタリングされなかった場合、そのユーザー定義関数は危険なユーザー定義関数とみなされます。これらの関数が後続の分析で呼び出されていることが判明すると、テイント分析がすぐに開始されます。
0x05 変数の精製とエンコードの処理
実際の監査プロセスでは、危険なパラメータが制御可能であることが判明したら、プログラマが変数を効果的にフィルタリングまたはエンコードしたかどうかを確認するのが待ちきれません。脆弱性があります。
例えば、3行目では変数aの精製情報は1つのintvalだけですが、5行目では変数aの精製情報をマージしてintvalとhtmlspecialcharsのリストセットにまとめる必要があります。先行コード情報内のすべてのデータ ストリームを収集し、バックトラッキングを実行します。
この考え方は自動監査でも踏襲されています。実装では、まず、PHP の各セキュリティ機能の統計と設定を実行する必要があります。プログラム分析中に、次のようなデータ フロー情報ごとに必要な精製およびエンコード情報を遡及的に収集する必要があります。コード スニペットは少し奇妙に見えますが、デモンストレーションのみを目的としています。コード スニペットからわかるように、変数 a は intval および htmlspecialchars によって精製されており、構成ファイルによれば、この情報は正常に収集されました。このとき、バックトラッキングが実行され、現在のコード行から上方向に精製情報とエンコード情報がマージされます。1.
詳細は、ユーザーが同じ変数に対してbase64_encodeとbase64_decodeなどの2つの関数を同時に呼び出すと、変数のbase64エンコーディングが削除されるということです。同様に、エスケープとアンチエスケープが同時に実行される場合は、それらも削除する必要があります。しかし、呼び出し順序が間違っていたり、デコードのみが実行されたりした場合、それは非常に危険です。
0x06 変数バックトラッキングと汚染分析すべての危険なシンク ポイントのパラメーター (traceSymbol) を見つけるために、現在のブロックに接続されているすべての基本ブロックを順方向にトレースします。具体的なプロセスは次のとおりです。
- 現在の基本ブロックのすべてのエントリ エッジをループします。精製されていないtraceSymbolを見つけて、基本ブロックのDataFlowプロパティでtraceSymbolの名前を探します。
- 見つかったら、マッピングされたシンボルに置き換え、シンボルのすべての精製情報とエンコード情報をコピーします。その後、すべての入り口で追跡が実行されます。
- 最後に、CFG 上の異なるパスの結果が返されます。
traceSymbol が静的文字列、数値などのタイプの静的オブジェクトにマップされている場合、または現在の基本ブロックにエントリ エッジがない場合、アルゴリズムは停止します。 traceSymbol が変数または配列の場合は、それがスーパーグローバル配列内にあるかどうかを確認します。
2. テイント分析
テイント分析は、プロセス間分析および組み込みおよびユーザー定義関数の処理のプロセス中に開始され、プログラム分析中に機密関数呼び出しが発生した場合は、バックトラッキングを使用するか、危険なパラメーター ノードを取得します。コンテキストを確認し、汚染分析の実行を開始します。平たく言えば、危険なパラメータが脆弱性を引き起こす可能性があるかどうかを判断することです。汚染分析作業はコード
TaintAnalyser
で実装されます。危険なパラメーターを取得した後の具体的な手順は次のとおりです:
- まず、現在の基本ブロックで危険なパラメーターの割り当てを探し、ユーザーが存在するかどうかを確認します。 DataFlow の右側のノードの入力ソース。
GEなど。 T 上記では、PHP の自動ホワイトボックス監査のテクノロジーと実装について、その側面も含めて紹介しています。PHP チュートリアルに興味のある友人に役立つことを願っています。