生産性のない話

趣味の範囲でサイバーセキュリティの話

JBOSS Richfacesの脆弱性(CVE-2018-14667)を検証してみた

久しぶりの検証記事です。

今回は JBOSS RIchfaces というフレームワーク脆弱性ですが、このフレームワークは2016年6月でEOLを迎えており、すでにサポートは終了しています。

RichFaces End-Of-Life Questions & Answers |JBoss Developer

そのため、パッチなどのリリースはなく、万が一脆弱性のあるフレームワークを利用している場合、すぐに別のフレームワークへの移行が推奨されます。

CVE-2018-14667

UserResource を通じて、シリアライズ化されたJAVAのオブジェクトを利用してリモートから認証なしでコード実行を行うことが可能となります。

影響を受けるバージョン

  • RichFaces Framework 3.X through 3.3.4 (all versions)

検証

色々試したのですが、アプリケーションサーバなどの環境によって条件が異なるようで、公開されているPoCでうまくいくものといかないものがありました。

とりあえず以下のリンクの通りに試したものは成功しました。

Full Disclosure: Unauthenticated Remote Code execution in WebApps using Richfaces 3.X all versions (CVE-2018-14667)

リンクにある環境を以下のような Dockerfile にしました。

FROM java:8-jdk

RUN apt-get update && apt-get install -y wget unzip --no-install-recommends && \
  rm -rf /var/lib/apt/lists/*

COPY ./jboss-5.1.0.GA.zip /tmp/

RUN unzip /tmp/jboss-5.1.0.GA.zip -d /opt/ && \
  wget http://downloads.jboss.org/richfaces/releases/3.3.X/3.3.4.Final/richfaces-examples-3.3.4.Final.zip -P /tmp/ && \
  unzip /tmp/richfaces-examples-3.3.4.Final.zip -d /tmp/ && \
  mv /tmp/richfaces-examples-3.3.4.Final/photoalbum/dist/photoalbum-ear-3.3.4.Final.ear /opt/jboss-5.1.0.GA/server/default/deploy/ && \
  rm -rf /tmp/*

EXPOSE 8080

CMD ["/opt/jboss-5.1.0.GA/bin/run.sh", "-b", "0.0.0.0"]

アプリケーションサーバとして、JBoss AS 5.1.0.GA(jboss-5.1.0.GA.zip) を用意します。

それをDockerfileと同じディレクトリにおいてビルドします。

docker build -t richfaces-sample .

出来上がったイメージを起動します。

docker run -d -p 8080:8080 richfaces-sample

これで http://localhost:8080/ にアクセスすると、JBOSS AS の画面が表示されます。

今回の検証の対象となるアプリケーションは richfaces のサンプルアプリケーションの photoalbum です。

http://localhost:8080/photoalbum/ にアクセスします。

f:id:blueBLUE:20181202003244p:plain

開発者コンソールを開いた状態で、このサイトにアクセスすると、「/DATA/」から始まる長い文字列を含むURLがあります。

f:id:blueBLUE:20181202003341p:plain

この「/DATA/」以降の文字列が、シリアライズ化したJAVAのオブジェクトとなっており、ここに細工した Expression Language (EL) オブジェクトを投げると、それを解釈してコード実行が行われます。

ここで、「/DATA/」以降に適当な値を入れてアクセスすると、その値をJAVAオブジェクトとして正しく認識できずにエラーが返ってきます。

f:id:blueBLUE:20181202003450p:plain

では、PoCを投げてみます。

PoCは上記のリンクにありますが、同様のURLの「/DATA/」以降の文字列を細工したものになっています。

ここでの実行コマンドは「touch /tmp/richfaces0day_joaomatosf」です。

正しく処理が行われ、レスポンスとして200が返ってきます。

f:id:blueBLUE:20181202003554p:plain

ということで、コンテナの中に入って、コマンドが実行されていることを確認します。

f:id:blueBLUE:20181202003631p:plain

コマンドが実行され、「/tmp」配下にファイルが作成されました。

このURLに含まれる長い文字列ですが、これはシリアライズ化したオブジェクトをzlibで圧縮し、BASE64エンコードしたものとなっています。

そのため、以下のようにして逆処理をしてやると、シリアライズ化されたオブジェクトが現れ、実行コマンドが確認できるようになります(念のため、ペイロードを一部マスクしています)。

f:id:blueBLUE:20181202004101p:plain

後、この辺りあまりちゃんと理解できていないのですが、インジェクションするオブジェクトである javax.el.MethodExpression の「serialVersionUID」というパラメータが共通のものがないため、PoC生成の段階でアプリケーション毎に別の値を指定してやる必要があるようです。

そのため、攻撃先の環境によって、別々の値を指定する必要があり、共通のPoCが利用できないようです。

以下の検証動画ではアプリケーションサーバとして、Tomcat 8 を利用している場合と、JBOSS EAP を利用している場合の検証が行われいます。

www.youtube.com

まとめ

シリアライズ関係の脆弱性は理解しにくいところがあって、なかなか難しいです。 JAVAオブジェクトをシリアライズ化してそのままやり取りするようなアプリケーションは危険だということは理解していますが、今回のようなURLに一見してわからない形で入ってくることもあるんですね。この場合、通常通信と攻撃通信が見ただけで判断できないのがちょっと辛いです。

すでにEOLを迎えているフレームワークであり、利用しているところはないだろうと思ってはいますが……。

参考

Full Disclosure: Unauthenticated Remote Code execution in WebApps using Richfaces 3.X all versions (CVE-2018-14667)

Red Hat JBoss EAP RichFaces - unserialize + el = RCE - 【CVE-2018-14667】 - 先知社区

JBoss RichFaces EL Injection RCE Analysis(CVE-2018-14667)