連載
» 2013年11月20日 18時00分 公開

セキュリティ・ダークナイト(14):存在に気付かないふり? Struts (2/2)

[辻 伸弘(ソフトバンク・テクノロジー株式会社),@IT]
前のページへ 1|2       

まずは自分でApache Strutsを見つけよう

 「Apache Strutsがインストールされているか、それだけでもいますぐに確認したい」という場合に備え、自身でチェックする方法について解説しよう。この方法は筆者が所属する組織のネットワーク診断でも用いている。皆さんの環境と異なる点などあるかと思うが、そこは適宜読み替えていただきたい。

 今回は「Apache Struts2」を例に紹介させていただく。

【バージョン確認方法】

Unix系の場合

 まず、findコマンドを利用して、バージョン情報が含まれるjarファイルを検索する。

root@struts2:~# find / -name struts2-core*.jar
/opt/CVE-2013-2251/tomcat/webapps/struts2-showcase/WEB-INF/lib/struts2-core-2.3.15.1.jar
/opt/CVE-2013-2251/tomcat/webapps/struts2-blank/WEB-INF/lib/struts2-core-2.3.15.1.jar

 ここで表示されるファイル名に含まれるバージョンが、Apache Struts2のバージョンである。念のため、マニフェストファイル内に記述されているバージョンの調査方法も紹介しておく。

 jarファイルを解凍するので作業用ディレクトリを作成し、コピーする。そして、grepコマンドを利用して「Bundle-Version」の行を抽出して確認を行う。

root@struts2:~# mkdir /tmp/StrutsCheck
root@struts2:~# cp -p /opt/CVE-2013-2251/tomcat/webapps/struts2-blank/WEB-INF/lib/struts2-core-2.3.15.1.jar /tmp/StrutsCheck
root@struts2:~# cd /tmp/StrutsCheck
root@struts2:/tmp/StrutsCheck# unzip struts2-core-2.3.15.1.jar
Archive: struts2-core-2.3.15.1.jar
creating: META-INF/
inflating: META-INF/MANIFEST.MF
creating: org/
creating: org/apache/
〜 略 〜
creating: META-INF/maven/
creating: META-INF/maven/org.apache.struts/
creating: META-INF/maven/org.apache.struts/struts2-core/
inflating: META-INF/maven/org.apache.struts/struts2-core/pom.xml
inflating: META-INF/maven/org.apache.struts/struts2-core/pom.properties
root@struts2:/tmp/StrutsCheck# grep Bundle-Version META-INF/MANIFEST.MF
Bundle-Version: 2.3.15.1  <- バージョンを示している。
root@struts2:/tmp/StrutsCheck# cd
root@struts2:~# rm -fr /tmp/StrutsCheck

Windows系の場合

 Windowsの場合、まずdirコマンドを利用して、バージョン情報が含まれるjarファイルを検索する。

C:\>dir /S /B struts2-core*.jar
C:\Program Files\Apache Software Foundation\Tomcat 7.0\webapps\struts2-blank\WEB-INF\lib\struts2-core-2.3.15.1.jar

 ここで表示されるファイル名に含まれるバージョンがStruts2のバージョンとなる。

 Unix系同様、念のためマニフェストファイル内に記述されているバージョンの調査方法も紹介しておく。jarファイルを解凍するので作業用ディレクトリを作成し、コピーする。

C:\>md C:\Temp\StrutsCheck
C:\>copy “C:\Program Files\Apache Software Foundation\Tomcat 7.0\webapps\struts2-blank\WEB-INF\lib\struts2-core-2.3.15.1.jar” C:\Temp\StrutsCheck
1 個のファイルをコピーしました。
C:\>cd C:\Temp\StrutsCheck
C:\Temp\StrutsCheck>dir
ドライブ C のボリューム ラベルがありません。
ボリューム シリアル番号は xxx-xxxx です
C:\Temp\StrutsCheck のディレクトリ
2013/09/12 10:50 <DIR> .
2013/09/12 10:50 >DIR> ..
2013/07/14 21:02 802,044 struts2-core-2.3.15.1.jar
1 個のファイル 802,044 バイト
2 個のディレクトリ 17,165,873,152 バイトの空き領域

 そして、コピーしたjarファイルを解凍ソフトを使用し解凍する。

jarファイルを解凍する

 その中に含まれる、マニフェストファイル内に記述されているバージョンの調査方法は下記の通りである。

C:\Temp\StrutsCheck>dir
ドライブ C のボリューム ラベルがありません。
ボリューム シリアル番号は xxx-xxxx です
C:\Temp\StrutsCheck のディレクトリ
2013/09/12 10:51 <DIR> .
2013/09/12 10:51 <DIR> ..
2013/07/14 21:01 2,653 FREEMARKER-LICENSE.txt
2013/07/14 21:01 10,141 LICENSE.txt
2013/09/12 10:51 <DIR> META-INF
2013/07/14 21:01 418 NOTICE.txt
2013/07/14 21:01 2,563 OGNL-LICENSE.txt
2013/07/14 21:01 <DIR> org
2013/07/14 21:01 1,060 overview.html
2013/07/14 21:01 3,446 struts-2.0.dtd
2013/07/14 21:01 3,816 struts-2.1.7.dtd
2013/07/14 21:01 3,765 struts-2.1.dtd
2013/07/14 21:01 3,764 struts-2.3.dtd
2013/07/14 21:01 23,810 struts-default.xml
2013/07/14 21:01 1,239 struts.vm
2013/07/14 21:02 802,044 struts2-core-2.3.15.1.jar
2013/07/14 21:01 <DIR> template
2013/07/14 21:01 2,567 XWORK-LICENSE.txt
13 個のファイル 861,286 バイト
5 個のディレクトリ 17,162,178,560 バイトの空き領域
C:\Temp\StrutsCheck>findstr Bundle-Version META-INF\MANIFEST.MF
Bundle-Version: 2.3.15.1     <- バージョンを示している。
C:\Temp\StrutsCheck>cd \
C:\>rd /S /Q C:\Temp\StrutsCheck

 これでバージョンが判明したので、セキュリティ情報系のサイトやApache Struts2の公式サイトなどで、脆弱性の影響を受けるバージョンかどうかをチェックできるだろう。

攻撃者はApache Strutsに熱い視線を注ぐ――その準備もできている?

 Apache Strutsは潜在的に脆弱性が存在し、発見され続けているという点において、まだまだ枯れていない印象がある。過去にインパクトの大きな脆弱性が発見されたApache HTTP Serverやsendmailなどは、現在においてはクリティカルな脆弱性はそれほど見つかっていない。そのため、攻撃の対象がこれらの枯れたプロダクトから、Apache Strutsなどに移り変わっているのではないかと、筆者は推測している。

 おそらく攻撃者は、普段から脆弱性情報の収集を行っているのだろう。どこでどのようなアプリケーションが使われているか、どのポートがオープンしているかといった調査を日常的に行い、来たる日――つまり攻撃可能となる日――に備え、リスト化しているのではないだろうか。

 例えばApache Strutsにおいては、Googleで「filetype:action」で検索しておけば、Apache Strutsを利用し、かつインターネットに公開されているページを、全てではないにしても労力をかけずある程度把握できる。脆弱性(攻撃方法)が公表されてから実際の攻撃が行われるまでの時間が、徐々に短くなってきているのもうなずけるだろう。

Apache Struts突破事例――これは人ごとではない

 とはいえ、実際に被害に遭った事例の話をしないことにはピンと来ないだろう。今回は筆者が「Apach Struts2」の脆弱性「S2-016(CVE-2013-2251)」(2013年7月16日に公表)によって侵入されてしまった複数の組織にヒアリングを行ったので、その内容の一部を紹介させていただこうと思う。

 それらの組織ではセキュリティと運用のチームが分かれており、通常時においては、セキュリティチームは自組織で使用しているシステムの脆弱性情報を調査、検証している。インパクトが大きいと判断される脆弱性があれば、それを説明する文書とともに運用チームに情報を提供し、アップデートなど必要な処理を行うというサイクルを回しているとのことだ。筆者の知っている範囲においては、かなりしっかりとした体制を構築している組織ばかりである。

 その組織の1つは当該脆弱性の情報を入手しており、検証を行った結果、インパクトの大きなものであるという判断がなされた。そしてすぐさま運用チームに情報を共有し、アップデートを1週間ほどで完了することが決定し、チームのメンバーはよい週末を迎えることができた。

 しかし、週明けの月曜、2013年7月22日に異変に気付くこととなる。ネットワークの監視を行う侵入検知システムが、アラートを報告してきたためである。

 アラートの内容は当該脆弱性(S2-16)を利用した攻撃として検知してはいなかったが、別の古いApache Struts2の脆弱性を狙った攻撃や、内部のとあるファイルが外部の人物に参照された可能性を示すものだった。そのアラートを手掛かりに、セキュリティチームがログの調査を行った結果、当該脆弱性が利用された攻撃であるという事実にたどり着いたのである。

 調査の結果、2013年7月17日にはすでに攻撃を受けて侵入されていたことが分かった。これは、脆弱性情報を公表されてからわずか1日後(実際には24時間未満)のことである。他にも数多くのバックドアが設置されており、外部から任意のコマンドを実行やファイルのアップロード、ダウンロードが行える状態にされていたようだ。

攻撃の一例

 この環境の復旧についてもコメントしておこう。個人情報やシステム上のユーザーの個人情報、システム上の重要情報などは盗み出されておらず、情報の更新もほぼなかった。このため再構築と多少の設定変更という選択を行い、7月23日には復旧したそうである。

 復旧に多大な時間を要しなかった要因としては、インシデント発見時、幸いにも関係者がそろっており、バックアップからの復元手順が普段から周知、徹底され、定期的にテストしていたことが挙げられる。不幸中の幸いといったところだろう。

 取った対策は、「Apache Struts2」経由で実行されたコマンドでは公開ディレクトリに書き込みをさせないようにすること、およびApache Strutsのバージョンアップである。おそらく、今後は改ざん検知システムの導入検討が必要だろうと筆者は考えている。

日付 できごと
2013年7月16日 「Apach Struts2」の脆弱性「CVE-2013-2251」検証結果発表
 7月16日 検証結果からアップデート作業を1週間後の7月23日をめどに実施決定
 7月17日 攻撃、侵入が成功
 7月22日 侵入検知システムが侵入を検知
 7月23日 該当環境の再構築、およびアップデート作業完了

「来週バージョンアップしましょう」でも間に合わない――だからセキュリティの考え方を変える

 このヒアリング結果から分かることは、脆弱性情報の公表から実際の攻撃が発生するまでのタイムラグが、どんどん短くなってきていることだ。それと同時に、侵入を防ぐための対策として「ソフトウェアを最新の状態に保つ」ということが、とてもハードルの高いものであることも分かる。

 前述した通り、セキュリティと運用のサイクルをしっかりと回している組織であっても、脆弱性情報の公表から24時間以内に最新のものへアップデートすることはまず不可能だろう。インターネット上でサービスを提供している以上、何の検証もなしにソフトウェアのアップデートを行うこともできない。ましてや、危険だからといっていきなりサービスを停止するわけにもいかないだろう。

 筆者が、記事やセミナーなどで「やられないためのセキュリティ意識はもう捨ててください」と表現してから久しい。もちろん、無傷であることが最も望ましいのではあるが、どんなに努力をしても侵入を許してしまう条件がそろってしまう場合もある。それを皆さんには理解していただきたいのである。

 また、やられないという言葉の定義を一考していただきたい。一般的にやられないという言葉は、「侵入されない」とか「マルウェアに感染しない」といったリスクゼロの状態を保つことを指すことが多いように筆者は感じているが、もはやそれは不可能である。であるならば、やられないの言葉の定義を変えてしまうことが必要であると筆者は考える。

 これは別にごまかしたいわけではない。「何をやられたら嫌なのか」「何をやられたら困るのか」「どのような状態を避けたいのか」を考え、それをやられないようにと考えてほしいのである。極端な言い方になるが、サーバに保存された重要な情報を盗まれてしまうことを避けたい場合、仮に侵入を許してしまったとしても、重要な情報を盗まれなければよいのである。

 外壁だけを高く、分厚いものにしたとしても、その壁はいつまでも完璧な存在にはならない。そして許可せざるを得ない通信は確実に存在し、それは中に入れざるを得ない。公開サービスへの通信、メールなどがその顕著な例だろう。

 セキュリティは壁ではなく、「ふるい」「フィルタ」であると筆者は考えている。ネットワーク監視や改ざん検知、適切な権限分与など、そのふるいを増やすことで、可能な限り発生し得るリスクを低減させるようコントロールするという発想への転換をすべき時期ではないだろうか。

「セキュリティ・ダークナイト」バックナンバー
前のページへ 1|2       

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。