【背景】
日本国内でもApache Struts2(以下、Struts2)の脆弱性を利用した攻撃による被害が相次いでいます。
公表されているものでは「JINS」が有名ですね。(発表資料)
少し前に、はやりだった(はやっている)ものは
S2-008(CVE-2012-0391)(脆弱性検証レポート)
S2-013(CVE-2013-1966)(脆弱性検証レポート)
S2-016(CVE-2013-2251)(脆弱性検証レポート)
あたりでしょうか。
推測の域を出ませんが、被害の大小問わず公表されていない被害も発生していると考えられます。
ボクはセキュリティの診断に長らく関わっています。その経験と観点から少しお話をしたいと思います。
(あくまでボクの経験ですので診断を提供している企業の中にはボクの定義が当てはまらないものがある可能性についてはご了承ください。)
セキュリティの診断には大きく分けて
「ネットワーク(プラットフォーム)診断(以下、NW診断)」と「Webアプリケーション診断」(以下、Web診断)があります。違いを凄く簡単に説明するとNW診断では主にOSやサーバアプリケーションの部分を、Web診断ではその上で動く、診断依頼者、つまり、「お客様の独自に作りこまれたアプリケーション」にセキュリティ上の問題点、脆弱性が存在しないかどうかを診断します。
「お客さんの独自に作りこまれたアプリケーション」と言っているのは、NW診断の範疇とWeb診断の範疇を可能な限り明確にするためです。ネットワーク機器やアプライアンス製品の多くはブラウザで設定、管理を行うことが可能です。この機能自体はWebアプリケーションであることには間違いはないのですが「お客様独自に作りこまれたアプリケーション」ではないため、NW診断の範疇となるわけです。
さて、問題のWebアプリケーションフレームワークである「Struts2」はどちらの検査の範疇となるのでしょうか。
勘の良い方はもうお気づきかと思いますが。
フレームワーク自体は「お客様独自に作りこまれたアプリケーション」ではないためNW診断の範疇であるとボクは考えてます。しかし、診断を受ける側のお客様はWeb診断の範疇であると考えている方もいらっしゃると思います。このブログをお読みいただいている方にもいらっしゃるかもしれません。もちろん、どちらか一方の診断でしか診てはいけないというものではないため診断を行う際に診断業者とお客様の間で取り決めをしている場合もあるとは思います。
ボクが危惧していることは、WebアプリケーションフレームワークだからWeb診断で見てくれているだろうというお客様の思い込みと説明しなくても分かっているだろうという診断業者の思い込みがあってはいけないということです。
それに加えて、診断対象にネットワークを介して診断した場合はStruts2は非常に発見しずらいものだということです。どのWebアプリケーションからStruts2が使われているかということもですが、1つの診断対象内に複数のStruts2が共存している場合も大いにあります。
一言でいうと非効率であるということです。
もしかするとNW診断であったとしても発見できない場合もあれば、そもそも診ていないという場合もあるかもしれません。
診断を受けようとしている方はこの点を確認しておいたほうがいいでしょう。
場合によっては追加料金が発生する可能性があります。
(ボク個人としては、この程度のことで追加料金をもらうほどのことではないと考えていますが)
診てくれなかったり、予算がなかったり、足りなかったり
今すぐこれだけでも確認したいという場合に自身でチェックする方法について解説させていただきます。
(みなさんの環境と異なる点などあるかと思いますが、そこは適宜読み替えていただければと思います。)
【バージョン確認方法】
■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
ここで表示されるファイル名に含まれるバージョンが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系
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のバージョンとなります。
念の為、マニフェストファイル内に記述されているバージョンの調査方法も記載しておきます。
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ファイルを解凍ソフトを使用し解凍します。
解凍してできたファイルの中のマニフェストファイル内に記述されているバージョンの調査方法は下記の通りです。
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
これでバージョンが判明しましたのでセキュリティ情報系のサイトやStruts2のサイトなどで脆弱性の影響を受けるバージョンかどうかをチェックすることができます。
【さいごに】
Struts2は潜在的に脆弱性が存在するという点においてまだまだ枯れていない印象があります。必ずしもこれから発見されないとは言い切れませんがApacheやsendmailなどなど過去にインパクトの大きな脆弱性が発見されてきて現在ではクリティカルなものはそれほど見つかっていません。
そのあたりの脆弱性が発見されないこともあってか攻撃の対象が移り変わってきたのかもしれません。
これはボクの推測でしかありませんが、攻撃者は普段から情報の収集を行っているのだと思います。どこでどのようなアプリケーションが使われているか。どのポートがオープンしているかといった調査を日常的に行い、来る脆弱性(その攻撃方法)が判明する日、つまり攻撃を行う日に備えてリスト化しているのではないかと考えています。
(例えばStruts2で言えば、Googleで「filetype:action」で検索しておけばStruts2を使っているインターネットに公開されているページをすべてではないにしても知ることができます。)
脆弱性(攻撃方法)が公表されてから実際の攻撃が行われるまでの時間が短くなっているきているのも頷けるのではないでしょうか。
しっかりと脆弱性情報を追いかけ、その対処を行うサイクルを回している組織でも脆弱性(攻撃方法)が公表されてから1日や2日で攻撃が来てしまうことを考えると侵入されることを完全に防ぐことはほぼ不可能な場合も起こり得るということになると思います。かなり前から言われていることではありますが、1つ目の砦を突破されてもその後の仕組みで早期発見、対処できる仕組みの大切さに気付き、アクションを起こすことの重要性を改めて感じますね。