第32回 PHPセキュリティ月間
今回は静的にPHPソースコードを分析しセキュリティ脆弱性を検査するツールの紹介です。
- MOPS Submission 09: RIPS - A static source code analyser for vulnerabilities in PHP scripts
 - http://
www. php-security. org/ 2010/ 05/ 24/ mops-submission-09-rips-a-static-source-code-analyser-for-vulnerabilities-in-php-scripts/ index. html  
昨年発見された脆弱性のおよそ3割がPHPアプリケーション関連の脆弱性とされています。PHPは簡単にWebアプリケーションが作れるため、
Johannes Dahse氏はこのような状況を改善するためにRIPSと呼ばれる、
この記事を執筆するにあたり、
RIPSの基本設計
RIPSは危険性がある関数をPVF
RIPSは構文解析を行いPVFを見つけ、
静的なソースコード脆弱性スキャナと聞くとコマンドラインアプリケーションを想像するかも知れませんが、
脆弱性スキャン
RIPSが脆弱性を検出する過程を簡単なスクリプトで解説します。
<?php
    $a = $_GET['a'];
    $b = $a;
    system($b, $ret);
?>
Tokenizerでトークンに分解されたスクリプト情報から、
4 : system($b ,$ret);
    3 : $b = $a;
        2 : $a = $_GET['a'];
危険なデータソースである$_GET['a']と危険な関数であるsystem関数が識別され、
今度は危険でないサンプルコードをスキャンしてみます。
<?php
    $a = $_GET['a'];
    $b = 'date';
    system($b, $ret);
?>
期待通りに脆弱性はレポートされませんでした。
次にもう少し複雑なサンプルコードをスキャンしてみます。
<?php
    $a = $_GET['a'];
    $b = escapeshellarg($a);
    $c = 'cal ' . $b;
    system($c, $ret);
?>
脆弱性はないので、
3行目で対策が取られていることがわかります。これはsystem関数の最初のパラメータが危険なパラメータで、
"system" => array (
    array(1), array("escapeshellarg", "escapeshellcmd")
);
実際にはconfig/
include/
Tokenizer
RIPSのコアとなるTokenizerモジュールを使ったことがある方は少ないのではないでしょうか? 筆者も何年も前にコードカバレッジツールを作成する際に利用したきりです。
Tokenizerの利用は簡単でtoken_
<?php
    $a = $ GET['a'];
    system($a, $ret);
?>
をトークンに分解すると以下のようになります。
name: T_OPEN_TAG            value: <?php    line: 1
name: T_VARIABLE            value: $a   line: 2
name: T_WHITESPACE          value:      line: 2
                        =
name: T_WHITESPACE          value:      line: 2
name: T_VARIABLE            value: $_GET    line: 2
                        [
name: T_CONSTANT_ENCAPSED_STRING    value: 'a'  line: 2
                        ]
                        ;
name: T_WHITESPACE          value:      line: 2
name: T_STRING              value: system   line: 3
                        (
name: T_VARIABLE            value: $a   line: 3
                        ,
name: T_WHITESPACE          value:      line: 3
name: T_VARIABLE            value: $ret     line: 3
                        )
                        ;
name: T_WHITESPACE          value:      line: 3
name: T_CLOSE_TAG           value: ?>   line: 4
RIPSはこのようにして取得したトークンから分析に必要なトークンを抽出して処理します。
| T_ | include/ | 
| T_ | 関数 | 
| T_ | return文 | 
| T_ | 変数 | 
| T_ | 文字列 | 
| T_ | プログラムの終了 | 
| Curly braces {} | 制御構造の判定に必要 | 
これらに加えて、
RIPSが各トークンをどのように処理するか、
Web UI
RIPSのWeb UIはシンブルで分かりやすいです。スキャンしたいPHPのスクリプトファイルをWebサーバがアクセスできるディレクトリ
デフォルトではJavaScriptインジェクション
左側のアイコンをクリックするとソースコードや攻撃コードの生成ウィンドウが開きます。攻撃コードの生成ウィンドウはCURLモジュールを使った攻撃用のPHPスクリプトが生成できるようになっていました。筆者が使ったバージョンまたは環境では問題があるようで、
RIPSはスキャンする脆弱性のタイプ、
| Level1 | 安全性を確保するための関数を呼ばずに、 | 
|---|---|
| Level2 | include文とデータベースクエリのスキャンも含める | 
| Level3 | 安全性を確保するための関数を呼び出してPVF関数を呼び出すケースも含める | 
| Level4 | RIPSがスキャンした際の脆弱性以外の情報も含める | 
| Level5 | すべてのPVF関数呼び出しを含める | 
Level1の場合はfalse-positive
一時的なJavaScriptインジェクションを十分に検出するにはLevel2、
実際のアプリケーションのスキャン
論文にはセキュリティ研修用の脆弱性があるプログラムのスキャン結果が載っていました。実際のアプリケーションではどのような結果になるのか、
修正されるかどう分かりませんが、
WebFileBrowser
Verbosity level 1で的確に脆弱なコードを検出しました。このアプリケーションは非常に古いアプリケーションらしく、
必ずしも危険な訳ではありませんが、
RIPSが検出可能なJavaScriptインジェクションをすべてレポートさせるにはVerbosity level 3以上が必要と書かれていましたが、
SimpleQuiz
このアプリケーションもVerbosity level 1で的確に脆弱なコードを検出しました。今回は典型的なSQLインジェクション脆弱性です。mysql_
このアプリケーションでもLocationヘッダの不具合を2つ検出しました。Verbosity Level 1から3までは検出されるJavaScriptインジェクションの数には変化がありませんでした。
phpMyInventory
このアプリケーションは2003年からメンテナンスされておらず、
流石にregister_
JavaScriptインジェクションの検出もVerbosity level 1では何らかのエラーで脆弱性が検出できないようでした。Level 2、
まとめ
RIPSはアプリケーションのセキュリティ状態の概要を見るには非常に有用なアプリケーションです。セキュアなPHPアプリケーション開発や受け入れ検査の最低ラインとして利用するのもよいでしょう。ただし、
また、
いずれにせよPHPアプリケーションのセキュリティ状態の概要を把握するには便利なツールであることには変わりありません。インストールはPHPをインストールしたWebサーバに展開するだけです。一度自分が開発したアプリケーションや使用中のアプリケーションをスキャンしてみてはいかがでしょうか?
Dahse氏が参考文献としてあげたURL
- 1.Fabien Coelho, PHP-related vulnerabilities on the National Vulnerability Database
 - http://
www. coelho. net/ php_ cve. html  - 2.The PHP Group, Predefined Variables
 - http://
www. php. net/ manual/ en/ reserved. variables. php  - 3.The PHP Group, system - Execute an external program and display the output
 - http://
www. php. net/ system  - 4.The PHP Group, escapeshellarg - Escape a string to be used as a shell argument
 - http://
www. php. net/ escapeshellarg  - 5.The PHP Group, token get all - Split given source into PHP tokens
 - http://
www. php. net/ token-get-all  - 6.The PHP Group, token name - Get the symbolic name of a given PHP token
 - http://
www. php. net/ token-name  - 7.The PHP Group, Execution Operators
 - http://
php. net/ manual/ en/ language. operators. execution. php  - 8.The PHP Group, Control Structures
 - http://
php. net/ manual/ en/ language. control-structures. php  - 9.The PHP Group, List of Parser Tokens
 - http://
php. net/ manual/ en/ tokens. php  - 10.Nenad Jovanovic, Christopher Kruegel, Engin Kirda, Pixy: A Static Analysis Tool
 - for Detecting Web Application Vulnerabilities (Short Paper)
 - http://
www. seclab. tuwien. ac. at/ papers/ pixy. pdf  - 11.Nenad Jovanovic, Christopher Kruegel, Engin Kirda, Pixy: A Static Analysis Tool
 - for Detecting Web Application Vulnerabilities (Technical Report)
 - http://
www. seclab. tuwien. ac. at/ papers/ pixy_ techreport. pdf  - 12.Nenad Jovanovic, Christopher Kruegel, Engin Kirda, Precise Alias Analysis for
 - Static Detection of Web Application Vulnerabilities
 - http://
www. iseclab. org/ papers/ pixy2. pdf  - 13.Davide Balzarotti, Marco Cova, Vika Felmetsger, Nenad Jovanovic, Engin Kirda,
 - Christopher Kruegel, Giovanni Vigna, Saner: Composing Static and Dynamic Analysis to Validate Sanitization inWeb Applications
 - http://
www. iseclab. org/ papers/ oakland-saner. pdf  - 14.OWASP, OWASP SWAAT Project
 - http://
www. owasp. org/ index. php/ Category:OWASP_ SWAAT_ Project  
