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でうまくいくものといかないものがありました。
とりあえず以下のリンクの通りに試したものは成功しました。
リンクにある環境を以下のような 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/ にアクセスします。
開発者コンソールを開いた状態で、このサイトにアクセスすると、「/DATA/」から始まる長い文字列を含むURLがあります。
この「/DATA/」以降の文字列が、シリアライズ化したJAVAのオブジェクトとなっており、ここに細工した Expression Language (EL) オブジェクトを投げると、それを解釈してコード実行が行われます。
ここで、「/DATA/」以降に適当な値を入れてアクセスすると、その値をJAVAオブジェクトとして正しく認識できずにエラーが返ってきます。
では、PoCを投げてみます。
PoCは上記のリンクにありますが、同様のURLの「/DATA/」以降の文字列を細工したものになっています。
ここでの実行コマンドは「touch /tmp/richfaces0day_joaomatosf」です。
正しく処理が行われ、レスポンスとして200が返ってきます。
ということで、コンテナの中に入って、コマンドが実行されていることを確認します。
コマンドが実行され、「/tmp」配下にファイルが作成されました。
このURLに含まれる長い文字列ですが、これはシリアライズ化したオブジェクトをzlibで圧縮し、BASE64でエンコードしたものとなっています。
そのため、以下のようにして逆処理をしてやると、シリアライズ化されたオブジェクトが現れ、実行コマンドが確認できるようになります(念のため、ペイロードを一部マスクしています)。
後、この辺りあまりちゃんと理解できていないのですが、インジェクションするオブジェクトである javax.el.MethodExpression の「serialVersionUID」というパラメータが共通のものがないため、PoC生成の段階でアプリケーション毎に別の値を指定してやる必要があるようです。
そのため、攻撃先の環境によって、別々の値を指定する必要があり、共通のPoCが利用できないようです。
以下の検証動画ではアプリケーションサーバとして、Tomcat 8 を利用している場合と、JBOSS EAP を利用している場合の検証が行われいます。
まとめ
シリアライズ関係の脆弱性は理解しにくいところがあって、なかなか難しいです。 JAVAオブジェクトをシリアライズ化してそのままやり取りするようなアプリケーションは危険だということは理解していますが、今回のようなURLに一見してわからない形で入ってくることもあるんですね。この場合、通常通信と攻撃通信が見ただけで判断できないのがちょっと辛いです。
すでにEOLを迎えているフレームワークであり、利用しているところはないだろうと思ってはいますが……。
参考
Red Hat JBoss EAP RichFaces - unserialize + el = RCE - 【CVE-2018-14667】 - 先知社区